PageRenderTime 7179ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/flash/com/boomtown/exp/gridtest/Main.as

https://github.com/dtalley/BoomTown
ActionScript | 509 lines | 475 code | 33 blank | 1 comment | 147 complexity | 365b61f40dfaec01f9089d32a3ed014f MD5 | raw file
  1. package com.boomtown.exp.gridtest {
  2. import com.boomtown.utils.Hexagon;
  3. import com.boomtown.utils.HexagonAxisGrid;
  4. import com.boomtown.utils.HexagonMetrics;
  5. import com.kuro.kuroexpress.ByteMap;
  6. import com.kuro.kuroexpress.KuroExpress;
  7. import com.kuro.kuroexpress.text.KuroText;
  8. import flash.display.Bitmap;
  9. import flash.display.BitmapData;
  10. import flash.display.Sprite;
  11. import flash.events.MouseEvent;
  12. import flash.events.TimerEvent;
  13. import flash.geom.Matrix;
  14. import flash.geom.Point;
  15. import flash.text.TextField;
  16. import flash.utils.Timer;
  17. public class Main extends Sprite {
  18. private var _roads:Number = .5;
  19. private var _buildings:Number = .5;
  20. private var _forests:Number = .5;
  21. private var _hills:Number = .1;
  22. private var _water:Number = .8;
  23. private var _sides:Array = [
  24. [ -1, 0 ],
  25. [ 0, -1 ],
  26. [ 1, 0 ],
  27. [ 0, 1 ],
  28. [ 1, -1 ],
  29. [ -1, 1 ]
  30. ];
  31. private var _map:Bitmap;
  32. private var _key:ByteMap;
  33. private var _temp:ByteMap;
  34. private var _data:BitmapData;
  35. private var _vis:BitmapData;
  36. private var _step:Timer;
  37. private var _phase:uint = 0;
  38. private var _started:Boolean = false;
  39. private var _max:uint = 30;
  40. private var _width:uint = 100;
  41. private var _height:uint = 100;
  42. private var _points:Array;
  43. private var _seeds:Array;
  44. private var _scale:uint = 1;
  45. private var _arrows:Sprite;
  46. public function Main() {
  47. HexagonAxisGrid.metrics = new HexagonMetrics( 4, 8, 90 );
  48. _key = new ByteMap( 4 );
  49. _temp = new ByteMap( 4 );
  50. _data = new BitmapData( stage.stageWidth, stage.stageHeight, false, 0xFFFFFFFF );
  51. _vis = new BitmapData( _width, _height, false, 0xFFFFFFFF );
  52. _map = new Bitmap( _data );
  53. addChild( _map );
  54. _map.scaleX = _scale;
  55. _map.scaleY = _scale;
  56. _map.smoothing = false;
  57. _map.x = Math.round( stage.stageWidth / 2 - _map.width / 2 );
  58. _map.y = Math.round( stage.stageHeight / 2 - _map.height / 2 );
  59. var newmap:Bitmap = new Bitmap( _vis );
  60. addChild( newmap );
  61. newmap.rotation = -90;
  62. newmap.scaleX = 4;
  63. newmap.scaleY = 4;
  64. newmap.x = stage.stageWidth - newmap.width;
  65. newmap.y = stage.stageHeight;
  66. _arrows = new Sprite();
  67. addChild( _arrows );
  68. _arrows.x = _map.x;
  69. _arrows.y = _map.y;
  70. _points = new Array();
  71. _seeds = new Array();
  72. _step = new Timer(1);
  73. _step.addEventListener( TimerEvent.TIMER, stepAutomata );
  74. _step.start();
  75. }
  76. private function createHexagon( color:uint ):Sprite {
  77. var hex:Sprite = new Sprite();
  78. hex.graphics.beginFill( color );
  79. Hexagon.drawHexagon( hex, HexagonAxisGrid.metrics.width, HexagonAxisGrid.metrics.height, HexagonAxisGrid.metrics.width / 2, HexagonAxisGrid.metrics.height / 2, HexagonAxisGrid.metrics.rotation );
  80. hex.graphics.endFill();
  81. return hex;
  82. }
  83. private function copyHexagon( map:BitmapData, hex:Sprite, x:uint, y:uint ):void {
  84. var matrix:Matrix = new Matrix();
  85. matrix.translate(
  86. ( -1 * HexagonAxisGrid.calculateX( x, y ) ) - ( HexagonAxisGrid.metrics.width / 2 ) + 450,
  87. ( 1 * HexagonAxisGrid.calculateY( x, y ) ) - ( HexagonAxisGrid.metrics.height / 2 ) + 400
  88. );
  89. map.draw( hex, matrix, null, null, null, true );
  90. }
  91. private function drawArrow( x:uint, y:uint, side:uint, color:uint = 0 ):void {
  92. return;
  93. _arrows.graphics.beginFill( color );
  94. _arrows.graphics.drawRect( x * _scale, y * _scale, _scale, _scale );
  95. _arrows.graphics.endFill();
  96. _arrows.graphics.beginFill( 0xFFFF00 );
  97. if ( side == 0 ) {
  98. _arrows.graphics.moveTo( x * _scale, y * _scale );
  99. _arrows.graphics.lineTo( x * _scale + _scale, y * _scale + _scale / 2 );
  100. _arrows.graphics.lineTo( x * _scale, y * _scale + _scale );
  101. } else if ( side == 1 ) {
  102. _arrows.graphics.moveTo( x * _scale, y * _scale );
  103. _arrows.graphics.lineTo( x * _scale + _scale / 2, y * _scale + _scale );
  104. _arrows.graphics.lineTo( x * _scale + _scale, y * _scale );
  105. } else if ( side == 2 ) {
  106. _arrows.graphics.moveTo( x * _scale + _scale, y * _scale );
  107. _arrows.graphics.lineTo( x * _scale, y * _scale + _scale / 2 );
  108. _arrows.graphics.lineTo( x * _scale + _scale, y * _scale + _scale );
  109. } else {
  110. _arrows.graphics.moveTo( x * _scale, y * _scale + _scale );
  111. _arrows.graphics.lineTo( x * _scale + _scale / 2, y * _scale );
  112. _arrows.graphics.lineTo( x * _scale + _scale, y * _scale + _scale );
  113. }
  114. _arrows.graphics.endFill();
  115. }
  116. private function addText( text:String ):void {
  117. //field.text = text + "\n" + field.text;
  118. }
  119. private var _rep:uint = 0;
  120. private function stepAutomata( e:TimerEvent ):void {
  121. switch( _phase ) {
  122. case 0:
  123. stepRoads();
  124. break;
  125. case 1:
  126. stepBuildings();
  127. break;
  128. case 2:
  129. stepForests();
  130. break;
  131. case 3:
  132. stepHills();
  133. break;
  134. case 4:
  135. stepWater();
  136. break;
  137. }
  138. if ( _points.length == 0 && _started ) {
  139. _started = false;
  140. _points = _seeds;
  141. _seeds = new Array();
  142. _temp.clear();
  143. _phase++;
  144. trace( "Switched to phase " + _phase );
  145. }
  146. }
  147. private function position( x:uint, y:uint ):uint {
  148. return ( y * _height ) + x;
  149. }
  150. private function stepRoads():void {
  151. if ( !_started ) {
  152. var roads:uint = Math.ceil( 10 * _roads );
  153. var side:uint = 0;
  154. var i:uint;
  155. var x:uint;
  156. var y:uint;
  157. for ( i = 0; i < roads; i++ ) {
  158. var pixel:uint = Math.round( Math.random() * ( _width - 1 ) );
  159. x = side == 0 ? 0 : ( side == 2 ? _width - 1 : pixel );
  160. y = side == 1 ? 0 : ( side == 3 ? _height - 1 : pixel );
  161. makeRoad( x, y, side, false );
  162. side = side < 3 ? side + 1 : 0;
  163. }
  164. _started = true;
  165. } else {
  166. var total:uint = _points.length;
  167. for ( i = 0; i < Math.min( _max, total ); i++ ) {
  168. var point:Point = _points.shift();
  169. var pos:uint = position( point.x, point.y );
  170. side = _key.read( pos, 3, 5 );
  171. x = side == 0 ? point.x + 1 : ( side == 2 ? point.x - 1 : point.x );
  172. y = side == 1 ? point.y + 1 : ( side == 3 ? point.y - 1 : point.y );
  173. if ( ( x < 2 || x > _width - 3 ) && side % 2 == 1 ) {
  174. continue;
  175. }
  176. if ( ( y < 2 || y > _height - 3 ) && side % 2 == 0 ) {
  177. continue;
  178. }
  179. var newpos:uint = position( x, y );
  180. var type:uint = _key.read( newpos, 0, 2 );
  181. if ( type == 0 && KuroExpress.pointInBounds( x, y, _width, _height ) ) {
  182. var created:Boolean = makeRoad( x, y, side );
  183. if( created && 1 ) {
  184. var chance:uint = Math.round( Math.random() * ( 150 - ( 149 * _roads ) ) );
  185. if ( chance <= 1 && _points.length < 40 * _roads ) {
  186. var newside:uint = Math.round( Math.random() );
  187. if ( side == 0 || side == 2 ) {
  188. makeRoad( point.x, point.y, newside == 0 ? 1 : 3, false );
  189. } else {
  190. makeRoad( point.x, point.y, newside == 0 ? 0 : 2, false );
  191. }
  192. }
  193. }
  194. } else if ( type == 1 ) {
  195. _seeds.push( new Point( point.x + 1, point.y ) );
  196. _seeds.push( new Point( point.x - 1, point.y ) );
  197. _seeds.push( new Point( point.x, point.y + 1 ) );
  198. _seeds.push( new Point( point.x, point.y - 1 ) );
  199. }
  200. }
  201. }
  202. }
  203. private function getRoadPoints( x:uint, y:uint, side:uint, front:Boolean = true ):Array {
  204. var addition:int = front ? -1 : 1;
  205. var points:Array = new Array();
  206. if ( side % 2 == 0 ) {
  207. points.push( new Point( x, y + addition ) );
  208. points.push( new Point( x, y - addition ) );
  209. if ( side == 0 ) {
  210. points.push( new Point( x - addition, y + addition ) );
  211. points.push( new Point( x - addition, y - addition ) );
  212. } else {
  213. points.push( new Point( x + addition, y + addition ) );
  214. points.push( new Point( x + addition, y - addition ) );
  215. }
  216. } else {
  217. points.push( new Point( x + addition, y ) );
  218. points.push( new Point( x - addition, y ) );
  219. if ( side == 1 ) {
  220. points.push( new Point( x + addition, y - addition ) );
  221. points.push( new Point( x - addition, y - addition ) );
  222. } else {
  223. points.push( new Point( x + addition, y + addition ) );
  224. points.push( new Point( x - addition, y + addition ) );
  225. }
  226. }
  227. return points;
  228. }
  229. private function makeRoad( x:uint, y:uint, side:uint, redirect:Boolean = true ):Boolean {
  230. var pts:Array = getRoadPoints( x, y, side );
  231. for ( var i:uint = 0; i < pts.length; i++ ) {
  232. var pos:uint = position( pts[i].x, pts[i].y );
  233. var type:uint = _key.read( pos, 0, 2 );
  234. if ( type == 1 && KuroExpress.pointInBounds( pts[i].x, pts[i].y, _width, _height ) ) {
  235. var addpts:Array = getRoadPoints( x, y, side, false );
  236. var chkpts:Array = [false, false, false, false];
  237. for ( var j:uint = 0; j < addpts.length; j++ ) {
  238. var newpos:uint = position( addpts[j].x, addpts[j].y );
  239. var addtype:uint = _key.read( newpos, 0, 2 );
  240. if ( addtype == 1 ) {
  241. chkpts[j] = true;
  242. }
  243. }
  244. if ( ( chkpts[0] && chkpts[2] ) || ( chkpts[1] && chkpts[3] ) ) {
  245. return false;
  246. }
  247. }
  248. }
  249. if( redirect ) {
  250. var chance:uint = Math.round( Math.random() * ( 1000 - ( 850 * _roads ) ) );
  251. if ( chance <= 1 ) {
  252. var newside:uint = Math.round( Math.random() );
  253. if ( side == 0 || side == 2 ) {
  254. side = newside == 0 ? 1 : 3;
  255. } else {
  256. side = newside == 0 ? 0 : 2;
  257. }
  258. }
  259. }
  260. var pos:uint = position( x, y );
  261. var oldtype:uint = _key.read( pos, 0, 2 );
  262. _key.write( pos, 0, 2, 1 );
  263. _key.write( pos, 3, 5, side );
  264. _points.push( new Point( x, y ) );
  265. return true;
  266. }
  267. private function stepBuildings():void {
  268. if ( !_started ) {
  269. _started = true;
  270. }
  271. var total:uint = _points.length;
  272. for ( var i:uint = 0; i < Math.min( _max, total ); i++ ) {
  273. var point:Point = _points.shift();
  274. var pos:uint = position( point.x, point.y );
  275. var checked:uint = _temp.read( pos, 8, 8 );
  276. if ( checked ) {
  277. continue;
  278. }
  279. _temp.write( pos, 8, 8, 1 );
  280. var type:uint = _key.read( pos, 0, 2 );
  281. var filled:uint = _temp.read( pos, 0, 0 );
  282. if ( !filled && type == 2 ) {
  283. _key.write( pos, 0, 2, 0 );
  284. }
  285. var distance:uint = _temp.read( pos, 1, 7 );
  286. var tgt:Array = [];
  287. if ( type == 1 ) {
  288. var side:uint = _key.read( pos, 3, 5 );
  289. if ( side == 0 || side == 2 ) {
  290. tgt.push( { point:new Point( point.x, point.y + 1 ), side:4 } );
  291. tgt.push( { point:new Point( point.x, point.y - 1 ), side:4 } );
  292. } else {
  293. tgt.push( { point:new Point( point.x + 1, point.y ), side:5 } );
  294. tgt.push( { point:new Point( point.x - 1, point.y ), side:5 } );
  295. }
  296. } else if ( type == 2 ) {
  297. side = _key.read( pos, 3, 5 );
  298. if ( side == 0 ) {
  299. tgt.push( { point:new Point( point.x + 1, point.y ), side:0 } );
  300. } else if ( side == 1 ) {
  301. tgt.push( { point:new Point( point.x - 1, point.y ), side:1 } );
  302. } else if ( side == 2 ) {
  303. tgt.push( { point:new Point( point.x, point.y + 1 ), side:2 } );
  304. } else if ( side == 3 ) {
  305. tgt.push( { point:new Point( point.x, point.y - 1 ), side:3 } );
  306. } else if ( side == 4 ) {
  307. tgt.push( { point:new Point( point.x + 1, point.y ), side:0 } );
  308. tgt.push( { point:new Point( point.x - 1, point.y ), side:1 } );
  309. } else if ( side == 5 ) {
  310. tgt.push( { point:new Point( point.x, point.y + 1 ), side:2 } );
  311. tgt.push( { point:new Point( point.x, point.y - 1 ), side:3 } );
  312. }
  313. }
  314. var count:uint = tgt.length;
  315. for ( var j:uint = 0; j < count; j++ ) {
  316. var target:Object = tgt.shift();
  317. var x:uint = target.point.x;
  318. var y:uint = target.point.y;
  319. pos = position( target.point.x, target.point.y );
  320. checked = _temp.read( pos, 8, 8 );
  321. var ntype:uint = _key.read( pos, 0, 2 );
  322. if ( ntype == 0 && KuroExpress.pointInBounds( x, y, _width, _height ) ) {
  323. makeBuilding( x, y, target.side, distance + 1 );
  324. }
  325. }
  326. }
  327. }
  328. private function makeBuilding( x:uint, y:uint, side:uint, distance:uint ):void {
  329. var pts:Array = getPoints( new Point( x, y ) );
  330. var cnt:uint = 0;
  331. for ( var i:uint = 0; i < 4; i++ ) {
  332. var pos:uint = position( pts[i].x, pts[i].y );
  333. var type:uint = _key.read( pos, 0, 2 );
  334. if ( type == 1 ) {
  335. cnt++;
  336. }
  337. }
  338. if ( !cnt ) {
  339. return;
  340. }
  341. var chance:uint = Math.round( Math.random() * ( distance + 1 ) / ( 4 * _buildings ) );
  342. var pos:uint = position( x, y );
  343. _key.write( pos, 0, 2, 2 );
  344. _key.write( pos, 3, 5, side );
  345. _temp.write( pos, 1, 7, distance );
  346. if ( chance <= 1 ) {
  347. _temp.write( pos, 0, 0, 1 );
  348. chance = Math.round( Math.random() * ( 300 - ( 299 * _buildings ) ) );
  349. if ( chance <= 1 && side < 4 ) {
  350. jumpBuilding( x, y, side );
  351. }
  352. }
  353. _points.push( new Point( x, y ) );
  354. }
  355. private function jumpBuilding( x:uint, y:uint, side:uint ):void {
  356. var pts:Array = new Array();
  357. var newside:uint = 0;
  358. if ( side == 0 || side == 1 ) {
  359. pts.push( new Point( x, y + 1 ) );
  360. pts.push( new Point( x, y - 1 ) );
  361. newside = 4;
  362. } else {
  363. pts.push( new Point( x + 1, y ) );
  364. pts.push( new Point( x - 1, y ) );
  365. newside = 5;
  366. }
  367. for ( var i:uint = 0; i < 2; i++ ) {
  368. var pt:Point = pts.shift();
  369. var pos:uint = position( pt.x, pt.y );
  370. var type:uint = _key.read( pos, 0, 2 );
  371. if ( type == 1 ) {
  372. _points.push( new Point( pt.x, pt.y ) );
  373. }
  374. }
  375. }
  376. private function stepForests():void {
  377. if ( !_started ) {
  378. var forests:uint = Math.round( ( 30 * _forests ) );
  379. for ( var i:uint = 0; i < forests; i++ ) {
  380. var point:Point = new Point( Math.round( Math.random() * ( _width - 1 ) ), Math.round( Math.random() * ( _height - 1 ) ) );
  381. var pos:uint = position( point.x, point.y );
  382. var type:uint = _key.read( pos, 0, 2 );
  383. makeForest( point.x, point.y, 0, 0, type == 0 ? true : false );
  384. }
  385. _started = true;
  386. } else {
  387. var total:uint = _points.length;
  388. for ( i = 0; i < Math.min( _max, total ); i++ ) {
  389. point = _points.shift();
  390. pos = position( point.x, point.y );
  391. var checked:uint = _temp.read( pos, 18, 18 );
  392. if ( checked ) {
  393. continue;
  394. }
  395. _temp.write( pos, 18, 18, 1 );
  396. var modifier:int = _temp.read( pos, 0, 4 );
  397. var distance:uint = _temp.read( pos, 5, 17 );
  398. var pts:Array = getPoints( new Point( point.x, point.y ) );
  399. for ( var j:uint = 0; j < 4; j++ ) {
  400. point = pts.shift();
  401. pos = position( point.x, point.y );
  402. var checked:uint = _temp.read( pos, 18, 18 );
  403. if ( checked ) {
  404. continue;
  405. }
  406. type = _key.read( pos, 0, 2 );
  407. var chance:uint = Math.round( Math.random() * ( 30 * ( ( type == 0 ? modifier : distance ) / 100 ) ) );
  408. if ( chance < 1 && KuroExpress.pointInBounds( point.x, point.y, _width, _height ) ) {
  409. makeForest( point.x, point.y, modifier + 1, distance + 1, type == 0 ? true : false );
  410. }
  411. }
  412. }
  413. }
  414. }
  415. private function makeForest( x:uint, y:uint, modifier:int, distance:uint, useable:Boolean = true ):Boolean {
  416. if ( modifier < 16 ) {
  417. var chance:uint = Math.round( Math.random() * ( ( ( ( ( .76 - ( .54 * _forests ) ) * ( 2.7 * ( 1.2 - .9 + ( .1 * .6 ) ) ) ) + ( Math.min( distance, 127 ) / 128 ) ) ) * 100 / ( .6 * 100 ) ) );
  418. if ( chance < 1 ) {
  419. modifier -= ( chance + 1 );
  420. }
  421. if ( modifier < 0 ) {
  422. modifier = 0;
  423. }
  424. } else {
  425. modifier = 15;
  426. }
  427. var pos:uint = position( x, y );
  428. if ( useable ) {
  429. _key.write( pos, 0, 2, 3 );
  430. _key.write( pos, 3, 5, 0 );
  431. _vis.setPixel32( x, y, 0xFF00FF00 );
  432. copyHexagon( _data, createHexagon( 0xFF00FF00 ), x, y );
  433. }
  434. _temp.write( pos, 0, 4, modifier );
  435. _temp.write( pos, 5, 17, distance );
  436. _points.push( new Point( x, y ) );
  437. return true;
  438. }
  439. private function stepHills():void {
  440. }
  441. private function stepWater():void {
  442. }
  443. private function getPointInformation( x:uint, y:uint ):Object {
  444. var pos:uint = position( x, y );
  445. var ret:Object = {
  446. type: _key.read( pos, 0, 2 ),
  447. side: _key.read( pos, 3, 5 )
  448. };
  449. return ret;
  450. }
  451. private function getBuildingInformation( x:uint, y:uint ):Object {
  452. var pos:uint = position( x, y );
  453. var ret:Object = {
  454. filled: _temp.read( pos, 0, 0 ),
  455. distance: _temp.read( pos, 1, 7 )
  456. };
  457. return ret;
  458. }
  459. private function getForestInformation( x:uint, y:uint ):Object {
  460. var pos:uint = position( x, y );
  461. var ret:Object = {
  462. modifier: _temp.read( pos, 0, 4 ),
  463. distance: _temp.read( pos, 5, 17 )
  464. };
  465. return ret;
  466. }
  467. private function getPoints( point:Point ):Array {
  468. var arr:Array = [];
  469. arr.push( new Point( point.x + 1, point.y ) );
  470. arr.push( new Point( point.x - 1, point.y ) );
  471. arr.push( new Point( point.x, point.y + 1 ) );
  472. arr.push( new Point( point.x, point.y - 1 ) );
  473. return arr;
  474. }
  475. }
  476. }