PageRenderTime 61ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/src/net/flashpunk/debug/Console.as

https://github.com/discolingua/FpTutorial
ActionScript | 878 lines | 651 code | 87 blank | 140 comment | 106 complexity | 48896c0cf9f746715aa68ce44eb2131d MD5 | raw file
  1. package net.flashpunk.debug
  2. {
  3. import flash.display.Bitmap;
  4. import flash.display.BitmapData;
  5. import flash.display.BlendMode;
  6. import flash.display.Graphics;
  7. import flash.display.Sprite;
  8. import flash.display.Stage;
  9. import flash.geom.ColorTransform;
  10. import flash.geom.Rectangle;
  11. import flash.text.TextField;
  12. import flash.text.TextFormat;
  13. import net.flashpunk.Entity;
  14. import net.flashpunk.FP;
  15. import net.flashpunk.utils.Draw;
  16. import net.flashpunk.utils.Input;
  17. import net.flashpunk.utils.Key;
  18. /**
  19. * FlashPunk debug console; can use to log information or pause the game and view/move Entities and step the frame.
  20. */
  21. public class Console
  22. {
  23. /**
  24. * The key used to toggle the Console on/off. Tilde (~) by default.
  25. */
  26. public var toggleKey:uint = 192;
  27. /**
  28. * Constructor.
  29. */
  30. public function Console()
  31. {
  32. Input.define("_ARROWS", Key.RIGHT, Key.LEFT, Key.DOWN, Key.UP);
  33. }
  34. /**
  35. * Logs data to the console.
  36. * @param ...data The data parameters to log, can be variables, objects, etc. Parameters will be separated by a space (" ").
  37. */
  38. public function log(...data):void
  39. {
  40. var s:String;
  41. if (data.length > 1)
  42. {
  43. s = "";
  44. var i:int = 0;
  45. while (i < data.length)
  46. {
  47. if (i > 0) s += " ";
  48. s += data[i ++].toString();
  49. }
  50. }
  51. else s = data[0].toString();
  52. if (s.indexOf("\n") >= 0)
  53. {
  54. var a:Array = s.split("\n");
  55. for each (s in a) LOG.push(s);
  56. }
  57. else LOG.push(s);
  58. if (_enabled && _sprite.visible) updateLog();
  59. }
  60. /**
  61. * Adds properties to watch in the console's debug panel.
  62. * @param ...properties The properties (strings) to watch.
  63. */
  64. public function watch(...properties):void
  65. {
  66. var i:String;
  67. if (properties.length > 1)
  68. {
  69. for each (i in properties) WATCH_LIST.push(i);
  70. }
  71. else if (properties[0] is Array || properties[0] is Vector.<*>)
  72. {
  73. for each (i in properties[0]) WATCH_LIST.push(i);
  74. }
  75. else WATCH_LIST.push(properties[0]);
  76. }
  77. /**
  78. * Enables the console.
  79. */
  80. public function enable():void
  81. {
  82. // Quit if the console is already enabled.
  83. if (_enabled) return;
  84. // Enable it and add the Sprite to the stage.
  85. _enabled = true;
  86. FP.engine.addChild(_sprite);
  87. // Used to determine some text sizing.
  88. var big:Boolean = width >= 480;
  89. // The transparent FlashPunk logo overlay bitmap.
  90. _sprite.addChild(_back);
  91. _back.bitmapData = new BitmapData(width, height, true, 0xFFFFFFFF);
  92. var b:BitmapData = (new CONSOLE_LOGO).bitmapData;
  93. FP.matrix.identity();
  94. FP.matrix.tx = Math.max((_back.bitmapData.width - b.width) / 2, 0);
  95. FP.matrix.ty = Math.max((_back.bitmapData.height - b.height) / 2, 0);
  96. FP.matrix.scale(Math.min(width / _back.bitmapData.width, 1), Math.min(height / _back.bitmapData.height, 1));
  97. _back.bitmapData.draw(b, FP.matrix, null, BlendMode.MULTIPLY);
  98. _back.bitmapData.draw(_back.bitmapData, null, null, BlendMode.INVERT);
  99. _back.bitmapData.colorTransform(_back.bitmapData.rect, new ColorTransform(1, 1, 1, 0.5));
  100. // The entity and selection sprites.
  101. _sprite.addChild(_entScreen);
  102. _entScreen.addChild(_entSelect);
  103. // The entity count text.
  104. _sprite.addChild(_entRead);
  105. _entRead.addChild(_entReadText);
  106. _entReadText.defaultTextFormat = format(16, 0xFFFFFF, "right");
  107. _entReadText.embedFonts = true;
  108. _entReadText.width = 100;
  109. _entReadText.height = 20;
  110. _entRead.x = width - _entReadText.width;
  111. // The entity count panel.
  112. _entRead.graphics.clear();
  113. _entRead.graphics.beginFill(0, .5);
  114. _entRead.graphics.drawRoundRectComplex(0, 0, _entReadText.width, 20, 0, 0, 20, 0);
  115. // The FPS text.
  116. _sprite.addChild(_fpsRead);
  117. _fpsRead.addChild(_fpsReadText);
  118. _fpsReadText.defaultTextFormat = format(16);
  119. _fpsReadText.embedFonts = true;
  120. _fpsReadText.width = 70;
  121. _fpsReadText.height = 20;
  122. _fpsReadText.x = 2;
  123. _fpsReadText.y = 1;
  124. // The FPS and frame timing panel.
  125. _fpsRead.graphics.clear();
  126. _fpsRead.graphics.beginFill(0, .75);
  127. _fpsRead.graphics.drawRoundRectComplex(0, 0, big ? 200 : 100, 20, 0, 0, 0, 20);
  128. // The frame timing text.
  129. if (big) _sprite.addChild(_fpsInfo);
  130. _fpsInfo.addChild(_fpsInfoText0);
  131. _fpsInfo.addChild(_fpsInfoText1);
  132. _fpsInfoText0.defaultTextFormat = format(8, 0xAAAAAA);
  133. _fpsInfoText1.defaultTextFormat = format(8, 0xAAAAAA);
  134. _fpsInfoText0.embedFonts = true;
  135. _fpsInfoText1.embedFonts = true;
  136. _fpsInfoText0.width = _fpsInfoText1.width = 60;
  137. _fpsInfoText0.height = _fpsInfoText1.height = 20;
  138. _fpsInfo.x = 75;
  139. _fpsInfoText1.x = 60;
  140. // The output log text.
  141. _sprite.addChild(_logRead);
  142. _logRead.addChild(_logReadText0);
  143. _logRead.addChild(_logReadText1);
  144. _logReadText0.defaultTextFormat = format(16, 0xFFFFFF);
  145. _logReadText1.defaultTextFormat = format(big ? 16 : 8, 0xFFFFFF);
  146. _logReadText0.embedFonts = true;
  147. _logReadText1.embedFonts = true;
  148. _logReadText0.selectable = false;
  149. _logReadText0.width = 80;
  150. _logReadText0.height = 20;
  151. _logReadText1.width = width;
  152. _logReadText0.x = 2;
  153. _logReadText0.y = 3;
  154. _logReadText0.text = "OUTPUT:";
  155. _logHeight = height - 60;
  156. _logBar = new Rectangle(8, 24, 16, _logHeight - 8);
  157. _logBarGlobal = _logBar.clone();
  158. _logBarGlobal.y += 40;
  159. _logLines = _logHeight / (big ? 16.5 : 8.5);
  160. // The debug text.
  161. _sprite.addChild(_debRead);
  162. _debRead.addChild(_debReadText0);
  163. _debRead.addChild(_debReadText1);
  164. _debReadText0.defaultTextFormat = format(16, 0xFFFFFF);
  165. _debReadText1.defaultTextFormat = format(8, 0xFFFFFF);
  166. _debReadText0.embedFonts = true;
  167. _debReadText1.embedFonts = true;
  168. _debReadText0.selectable = false;
  169. _debReadText0.width = 80;
  170. _debReadText0.height = 20;
  171. _debReadText1.width = 160;
  172. _debReadText1.height = int(height / 4);
  173. _debReadText0.x = 2;
  174. _debReadText0.y = 3;
  175. _debReadText1.x = 2;
  176. _debReadText1.y = 24;
  177. _debReadText0.text = "DEBUG:";
  178. _debRead.y = height - (_debReadText1.y + _debReadText1.height);
  179. // The button panel buttons.
  180. _sprite.addChild(_butRead);
  181. _butRead.addChild(_butDebug = new CONSOLE_DEBUG);
  182. _butRead.addChild(_butOutput = new CONSOLE_OUTPUT);
  183. _butRead.addChild(_butPlay = new CONSOLE_PLAY).x = 20;
  184. _butRead.addChild(_butPause = new CONSOLE_PAUSE).x = 20;
  185. _butRead.addChild(_butStep = new CONSOLE_STEP).x = 40;
  186. updateButtons();
  187. // The button panel.
  188. _butRead.graphics.clear();
  189. _butRead.graphics.beginFill(0, .75);
  190. _butRead.graphics.drawRoundRectComplex(-20, 0, 100, 20, 0, 0, 20, 20);
  191. // Set the state to unpaused.
  192. paused = false;
  193. }
  194. /**
  195. * If the console should be visible.
  196. */
  197. public function get visible():Boolean { return _sprite.visible; }
  198. public function set visible(value:Boolean):void
  199. {
  200. _sprite.visible = value;
  201. if (_enabled && value) updateLog();
  202. }
  203. /**
  204. * Console update, called by game loop.
  205. */
  206. public function update():void
  207. {
  208. // Quit if the console isn't enabled.
  209. if (!_enabled) return;
  210. // If the console is paused.
  211. if (_paused)
  212. {
  213. // Update buttons.
  214. updateButtons();
  215. // While in debug mode.
  216. if (_debug)
  217. {
  218. // While the game is paused.
  219. if (FP.engine.paused)
  220. {
  221. // When the mouse is pressed.
  222. if (Input.mousePressed)
  223. {
  224. // Mouse is within clickable area.
  225. if (Input.mouseFlashY > 20 && (Input.mouseFlashX > _debReadText1.width || Input.mouseFlashY < _debRead.y))
  226. {
  227. if (Input.check(Key.SHIFT))
  228. {
  229. if (SELECT_LIST.length) startDragging();
  230. else startPanning();
  231. }
  232. else startSelection();
  233. }
  234. }
  235. else
  236. {
  237. // Update mouse movement functions.
  238. if (_selecting) updateSelection();
  239. if (_dragging) updateDragging();
  240. if (_panning) updatePanning();
  241. }
  242. // Select all Entities
  243. if (Input.pressed(Key.A)) selectAll();
  244. // If the shift key is held.
  245. if (Input.check(Key.SHIFT))
  246. {
  247. // If Entities are selected.
  248. if (SELECT_LIST.length)
  249. {
  250. // Move Entities with the arrow keys.
  251. if (Input.pressed("_ARROWS")) updateKeyMoving();
  252. }
  253. else
  254. {
  255. // Pan the camera with the arrow keys.
  256. if (Input.check("_ARROWS")) updateKeyPanning();
  257. }
  258. }
  259. }
  260. else
  261. {
  262. // Update info while the game runs.
  263. updateEntityLists(FP.world.count != ENTITY_LIST.length);
  264. renderEntities();
  265. updateFPSRead();
  266. updateEntityCount();
  267. }
  268. // Update debug panel.
  269. updateDebugRead();
  270. }
  271. else
  272. {
  273. // log scrollbar
  274. if (_scrolling) updateScrolling();
  275. else if (Input.mousePressed) startScrolling();
  276. }
  277. }
  278. else
  279. {
  280. // Update info while the game runs.
  281. updateFPSRead();
  282. updateEntityCount();
  283. }
  284. // Console toggle.
  285. if (Input.pressed(toggleKey)) paused = !_paused;
  286. }
  287. /**
  288. * If the Console is currently in paused mode.
  289. */
  290. public function get paused():Boolean { return _paused; }
  291. public function set paused(value:Boolean):void
  292. {
  293. // Quit if the console isn't enabled.
  294. if (!_enabled) return;
  295. // Set the console to paused.
  296. _paused = value;
  297. FP.engine.paused = value;
  298. // Panel visibility.
  299. _back.visible = value;
  300. _entScreen.visible = value;
  301. _butRead.visible = value;
  302. // If the console is paused.
  303. if (value)
  304. {
  305. // Set the console to paused mode.
  306. if (_debug) debug = true;
  307. else updateLog();
  308. }
  309. else
  310. {
  311. // Set the console to running mode.
  312. _debRead.visible = false;
  313. _logRead.visible = true;
  314. updateLog();
  315. ENTITY_LIST.length = 0;
  316. SCREEN_LIST.length = 0;
  317. SELECT_LIST.length = 0;
  318. }
  319. }
  320. /**
  321. * If the Console is currently in debug mode.
  322. */
  323. public function get debug():Boolean { return _debug; }
  324. public function set debug(value:Boolean):void
  325. {
  326. // Quit if the console isn't enabled.
  327. if (!_enabled) return;
  328. // Set the console to debug mode.
  329. _debug = value;
  330. _debRead.visible = value;
  331. _logRead.visible = !value;
  332. // Update console state.
  333. if (value) updateEntityLists();
  334. else updateLog();
  335. renderEntities();
  336. }
  337. /** @private Steps the frame ahead. */
  338. private function stepFrame():void
  339. {
  340. FP.engine.update();
  341. FP.engine.render();
  342. updateEntityCount();
  343. updateEntityLists();
  344. renderEntities();
  345. }
  346. /** @private Starts Entity dragging. */
  347. private function startDragging():void
  348. {
  349. _dragging = true;
  350. _entRect.x = Input.mouseX;
  351. _entRect.y = Input.mouseY;
  352. }
  353. /** @private Updates Entity dragging. */
  354. private function updateDragging():void
  355. {
  356. moveSelected(Input.mouseX - _entRect.x, Input.mouseY - _entRect.y);
  357. _entRect.x = Input.mouseX;
  358. _entRect.y = Input.mouseY;
  359. if (Input.mouseReleased) _dragging = false;
  360. }
  361. /** @private Move the selected Entitites by the amount. */
  362. private function moveSelected(xDelta:int, yDelta:int):void
  363. {
  364. for each (var e:Entity in SELECT_LIST)
  365. {
  366. e.x += xDelta;
  367. e.y += yDelta;
  368. }
  369. FP.engine.render();
  370. renderEntities();
  371. updateEntityLists(true);
  372. }
  373. /** @private Starts camera panning. */
  374. private function startPanning():void
  375. {
  376. _panning = true;
  377. _entRect.x = Input.mouseX;
  378. _entRect.y = Input.mouseY;
  379. }
  380. /** @private Updates camera panning. */
  381. private function updatePanning():void
  382. {
  383. if (Input.mouseReleased) _panning = false;
  384. panCamera(_entRect.x - Input.mouseX, _entRect.y - Input.mouseY);
  385. _entRect.x = Input.mouseX;
  386. _entRect.y = Input.mouseY;
  387. }
  388. /** @private Pans the camera. */
  389. private function panCamera(xDelta:int, yDelta:int):void
  390. {
  391. FP.camera.x += xDelta;
  392. FP.camera.y += yDelta;
  393. FP.engine.render();
  394. updateEntityLists(true);
  395. renderEntities();
  396. }
  397. /** @private Sets the camera position. */
  398. private function setCamera(x:int, y:int):void
  399. {
  400. FP.camera.x = x;
  401. FP.camera.y = y;
  402. FP.engine.render();
  403. updateEntityLists(true);
  404. renderEntities();
  405. }
  406. /** @private Starts Entity selection. */
  407. private function startSelection():void
  408. {
  409. _selecting = true;
  410. _entRect.x = Input.mouseFlashX;
  411. _entRect.y = Input.mouseFlashY;
  412. _entRect.width = 0;
  413. _entRect.height = 0;
  414. }
  415. /** @private Updates Entity selection. */
  416. private function updateSelection():void
  417. {
  418. _entRect.width = Input.mouseFlashX - _entRect.x;
  419. _entRect.height = Input.mouseFlashY - _entRect.y;
  420. if (Input.mouseReleased)
  421. {
  422. selectEntities(_entRect);
  423. renderEntities();
  424. _selecting = false;
  425. _entSelect.graphics.clear();
  426. }
  427. else
  428. {
  429. _entSelect.graphics.clear();
  430. _entSelect.graphics.lineStyle(1, 0xFFFFFF);
  431. _entSelect.graphics.drawRect(_entRect.x, _entRect.y, _entRect.width, _entRect.height);
  432. }
  433. }
  434. /** @private Selects the Entitites in the rectangle. */
  435. private function selectEntities(rect:Rectangle):void
  436. {
  437. if (rect.width < 0) rect.x -= (rect.width = -rect.width);
  438. else if (!rect.width) rect.width = 1;
  439. if (rect.height < 0) rect.y -= (rect.height = -rect.height);
  440. else if (!rect.height) rect.height = 1;
  441. FP.rect.width = FP.rect.height = 6;
  442. var sx:Number = FP.screen.scaleX * FP.screen.scale,
  443. sy:Number = FP.screen.scaleY * FP.screen.scale,
  444. e:Entity;
  445. if (Input.check(Key.CONTROL))
  446. {
  447. // Append selected Entitites with new selections.
  448. for each (e in SCREEN_LIST)
  449. {
  450. if (SELECT_LIST.indexOf(e) < 0)
  451. {
  452. FP.rect.x = (e.x - FP.camera.x) * sx - 3;
  453. FP.rect.y = (e.y - FP.camera.y) * sy - 3;
  454. if (rect.intersects(FP.rect)) SELECT_LIST.push(e);
  455. }
  456. }
  457. }
  458. else
  459. {
  460. // Replace selections with new selections.
  461. SELECT_LIST.length = 0;
  462. for each (e in SCREEN_LIST)
  463. {
  464. FP.rect.x = (e.x - FP.camera.x) * sx - 3;
  465. FP.rect.y = (e.y - FP.camera.y) * sy - 3;
  466. if (rect.intersects(FP.rect)) SELECT_LIST.push(e);
  467. }
  468. }
  469. }
  470. /** @private Selects all entities on screen. */
  471. private function selectAll():void
  472. {
  473. SELECT_LIST.length = 0;
  474. for each (var e:Entity in SCREEN_LIST) SELECT_LIST.push(e);
  475. renderEntities();
  476. }
  477. /** @private Starts log text scrolling. */
  478. private function startScrolling():void
  479. {
  480. if (LOG.length > _logLines) _scrolling = _logBarGlobal.contains(Input.mouseFlashX, Input.mouseFlashY);
  481. }
  482. /** @private Updates log text scrolling. */
  483. private function updateScrolling():void
  484. {
  485. _scrolling = Input.mouseDown;
  486. _logScroll = FP.scaleClamp(Input.mouseFlashY, _logBarGlobal.y, _logBarGlobal.bottom, 0, 1);
  487. updateLog();
  488. }
  489. /** @private Moves Entities with the arrow keys. */
  490. private function updateKeyMoving():void
  491. {
  492. FP.point.x = (Input.pressed(Key.RIGHT) ? 1 : 0) - (Input.pressed(Key.LEFT) ? 1 : 0);
  493. FP.point.y = (Input.pressed(Key.DOWN) ? 1 : 0) - (Input.pressed(Key.UP) ? 1 : 0);
  494. if (FP.point.x != 0 || FP.point.y != 0) moveSelected(FP.point.x, FP.point.y);
  495. }
  496. /** @private Pans the camera with the arrow keys. */
  497. private function updateKeyPanning():void
  498. {
  499. FP.point.x = (Input.check(Key.RIGHT) ? 1 : 0) - (Input.check(Key.LEFT) ? 1 : 0);
  500. FP.point.y = (Input.check(Key.DOWN) ? 1 : 0) - (Input.check(Key.UP) ? 1 : 0);
  501. if (FP.point.x != 0 || FP.point.y != 0) panCamera(FP.point.x, FP.point.y);
  502. }
  503. /** @private Update the Entity list information. */
  504. private function updateEntityLists(fetchList:Boolean = true):void
  505. {
  506. // If the list should be re-populated.
  507. if (fetchList)
  508. {
  509. ENTITY_LIST.length = 0;
  510. FP.world.getAll(ENTITY_LIST);
  511. }
  512. // Update the list of Entities on screen.
  513. SCREEN_LIST.length = 0;
  514. for each (var e:Entity in ENTITY_LIST)
  515. {
  516. if (e.collideRect(e.x, e.y, FP.camera.x, FP.camera.y, FP.width, FP.height))
  517. SCREEN_LIST.push(e);
  518. }
  519. }
  520. /** @private Renders the Entities positions and hitboxes. */
  521. private function renderEntities():void
  522. {
  523. // If debug mode is on.
  524. _entScreen.visible = _debug;
  525. if (_debug)
  526. {
  527. var g:Graphics = _entScreen.graphics,
  528. sx:Number = FP.screen.scaleX * FP.screen.scale,
  529. sy:Number = FP.screen.scaleY * FP.screen.scale;
  530. g.clear();
  531. for each (var e:Entity in SCREEN_LIST)
  532. {
  533. // If the Entity is not selected.
  534. if (SELECT_LIST.indexOf(e) < 0)
  535. {
  536. // Draw the normal hitbox and position.
  537. if (e.width && e.height)
  538. {
  539. g.lineStyle(1, 0xFF0000);
  540. g.drawRect((e.x - e.originX - FP.camera.x) * sx, (e.y - e.originY - FP.camera.y) * sy, e.width * sx, e.height * sy);
  541. }
  542. g.lineStyle(1, 0x00FF00);
  543. g.drawRect((e.x - FP.camera.x) * sx - 3, (e.y - FP.camera.y) * sy - 3, 6, 6);
  544. }
  545. else
  546. {
  547. // Draw the selected hitbox and position.
  548. if (e.width && e.height)
  549. {
  550. g.lineStyle(1, 0xFFFFFF);
  551. g.drawRect((e.x - e.originX - FP.camera.x) * sx, (e.y - e.originY - FP.camera.y) * sy, e.width * sx, e.height * sy);
  552. }
  553. g.lineStyle(1, 0xFFFFFF);
  554. g.drawRect((e.x - FP.camera.x) * sx - 3, (e.y - FP.camera.y) * sy - 3, 6, 6);
  555. }
  556. }
  557. }
  558. }
  559. /** @private Updates the log window. */
  560. private function updateLog():void
  561. {
  562. // If the console is paused.
  563. if (_paused)
  564. {
  565. // Draw the log panel.
  566. _logRead.y = 40;
  567. _logRead.graphics.clear();
  568. _logRead.graphics.beginFill(0, .75);
  569. _logRead.graphics.drawRoundRectComplex(0, 0, _logReadText0.width, 20, 0, 20, 0, 0);
  570. _logRead.graphics.drawRect(0, 20, width, _logHeight);
  571. // Draw the log scrollbar.
  572. _logRead.graphics.beginFill(0x202020, 1);
  573. _logRead.graphics.drawRoundRectComplex(_logBar.x, _logBar.y, _logBar.width, _logBar.height, 8, 8, 8, 8);
  574. // If the log has more lines than the display limit.
  575. if (LOG.length > _logLines)
  576. {
  577. // Draw the log scrollbar handle.
  578. _logRead.graphics.beginFill(0xFFFFFF, 1);
  579. var h:uint = FP.clamp(_logBar.height * (_logLines / LOG.length), 12, _logBar.height - 4),
  580. y:uint = _logBar.y + 2 + (_logBar.height - 16) * _logScroll;
  581. _logRead.graphics.drawRoundRectComplex(_logBar.x + 2, y, 12, 12, 6, 6, 6, 6);
  582. }
  583. // Display the log text lines.
  584. if (LOG.length)
  585. {
  586. var i:int = LOG.length > _logLines ? Math.round((LOG.length - _logLines) * _logScroll) : 0,
  587. n:int = i + Math.min(_logLines, LOG.length),
  588. s:String = "";
  589. while (i < n) s += LOG[i ++] + "\n";
  590. _logReadText1.text = s;
  591. }
  592. else _logReadText1.text = "";
  593. // Indent the text for the scrollbar and size it to the log panel.
  594. _logReadText1.height = _logHeight;
  595. _logReadText1.x = 32;
  596. _logReadText1.y = 24;
  597. // Make text selectable in paused mode.
  598. _fpsReadText.selectable = true;
  599. _fpsInfoText0.selectable = true;
  600. _fpsInfoText1.selectable = true;
  601. _entReadText.selectable = true;
  602. _debReadText1.selectable = true;
  603. }
  604. else
  605. {
  606. // Draw the single-line log panel.
  607. _logRead.y = height - 40;
  608. _logReadText1.height = 20;
  609. _logRead.graphics.clear();
  610. _logRead.graphics.beginFill(0, .75);
  611. _logRead.graphics.drawRoundRectComplex(0, 0, _logReadText0.width, 20, 0, 20, 0, 0);
  612. _logRead.graphics.drawRect(0, 20, width, 20);
  613. // Draw the single-line log text with the latests logged text.
  614. _logReadText1.text = LOG.length ? LOG[LOG.length - 1] : "";
  615. _logReadText1.x = 2;
  616. _logReadText1.y = 21;
  617. // Make text non-selectable while running.
  618. _logReadText1.selectable = false;
  619. _fpsReadText.selectable = false;
  620. _fpsInfoText0.selectable = false;
  621. _fpsInfoText1.selectable = false;
  622. _entReadText.selectable = false;
  623. _debReadText0.selectable = false;
  624. _debReadText1.selectable = false;
  625. }
  626. }
  627. /** @private Update the FPS/frame timing panel text. */
  628. private function updateFPSRead():void
  629. {
  630. _fpsReadText.text = "FPS: " + FP.frameRate.toFixed();
  631. _fpsInfoText0.text =
  632. "Update: " + String(FP._updateTime) + "ms\n" +
  633. "Render: " + String(FP._renderTime) + "ms";
  634. _fpsInfoText1.text =
  635. "Game: " + String(FP._gameTime) + "ms\n" +
  636. "Flash: " + String(FP._flashTime) + "ms";
  637. }
  638. /** @private Update the debug panel text. */
  639. private function updateDebugRead():void
  640. {
  641. // Find out the screen size and set the text.
  642. var big:Boolean = width >= 480;
  643. // Update the Debug read text.
  644. var s:String =
  645. "Mouse: " + String(FP.world.mouseX) + ", " + String(FP.world.mouseY) +
  646. "\nCamera: " + String(FP.camera.x) + ", " + String(FP.camera.y);
  647. if (SELECT_LIST.length)
  648. {
  649. if (SELECT_LIST.length > 1)
  650. {
  651. s += "\n\nSelected: " + String(SELECT_LIST.length);
  652. }
  653. else
  654. {
  655. var e:Entity = SELECT_LIST[0];
  656. s += "\n\n- " + String(e) + " -\n";
  657. for each (var i:String in WATCH_LIST)
  658. {
  659. if (e.hasOwnProperty(i)) s += "\n" + i + ": " + e[i].toString();
  660. }
  661. }
  662. }
  663. // Set the text and format.
  664. _debReadText1.text = s;
  665. _debReadText1.setTextFormat(format(big ? 16 : 8));
  666. _debReadText1.width = Math.max(_debReadText1.textWidth + 4, _debReadText0.width);
  667. _debReadText1.height = _debReadText1.y + _debReadText1.textHeight + 4;
  668. // The debug panel.
  669. _debRead.y = int(height - _debReadText1.height);
  670. _debRead.graphics.clear();
  671. _debRead.graphics.beginFill(0, .75);
  672. _debRead.graphics.drawRoundRectComplex(0, 0, _debReadText0.width, 20, 0, 20, 0, 0);
  673. _debRead.graphics.drawRoundRectComplex(0, 20, _debReadText1.width + 20, height - _debRead.y - 20, 0, 20, 0, 0);
  674. }
  675. /** @private Updates the Entity count text. */
  676. private function updateEntityCount():void
  677. {
  678. _entReadText.text = String(FP.world.count) + " Entities";
  679. }
  680. /** @private Updates the Button panel. */
  681. private function updateButtons():void
  682. {
  683. // Button visibility.
  684. _butRead.x = _fpsInfo.x + _fpsInfo.width + int((_entRead.x - (_fpsInfo.x + _fpsInfo.width)) / 2) - 30;
  685. _butDebug.visible = !_debug;
  686. _butOutput.visible = _debug;
  687. _butPlay.visible = FP.engine.paused;
  688. _butPause.visible = !FP.engine.paused;
  689. // Debug/Output button.
  690. if (_butDebug.bitmapData.rect.contains(_butDebug.mouseX, _butDebug.mouseY))
  691. {
  692. _butDebug.alpha = _butOutput.alpha = 1;
  693. if (Input.mousePressed) debug = !_debug;
  694. }
  695. else _butDebug.alpha = _butOutput.alpha = .5;
  696. // Play/Pause button.
  697. if (_butPlay.bitmapData.rect.contains(_butPlay.mouseX, _butPlay.mouseY))
  698. {
  699. _butPlay.alpha = _butPause.alpha = 1;
  700. if (Input.mousePressed)
  701. {
  702. FP.engine.paused = !FP.engine.paused;
  703. renderEntities();
  704. }
  705. }
  706. else _butPlay.alpha = _butPause.alpha = .5;
  707. // Frame step button.
  708. if (_butStep.bitmapData.rect.contains(_butStep.mouseX, _butStep.mouseY))
  709. {
  710. _butStep.alpha = 1;
  711. if (Input.mousePressed) stepFrame();
  712. }
  713. else _butStep.alpha = .5;
  714. }
  715. /** @private Gets a TextFormat object with the formatting. */
  716. private function format(size:uint = 16, color:uint = 0xFFFFFF, align:String = "left"):TextFormat
  717. {
  718. _format.size = size;
  719. _format.color = color;
  720. _format.align = align;
  721. return _format;
  722. }
  723. /**
  724. * Get the unscaled screen size for the Console.
  725. */
  726. private function get width():uint { return FP.width * FP.screen.scaleX * FP.screen.scale; }
  727. private function get height():uint { return FP.height * FP.screen.scaleY * FP.screen.scale; }
  728. // Console state information.
  729. /** @private */ private var _enabled:Boolean;
  730. /** @private */ private var _paused:Boolean;
  731. /** @private */ private var _debug:Boolean;
  732. /** @private */ private var _scrolling:Boolean;
  733. /** @private */ private var _selecting:Boolean;
  734. /** @private */ private var _dragging:Boolean;
  735. /** @private */ private var _panning:Boolean;
  736. // Console display objects.
  737. /** @private */ private var _sprite:Sprite = new Sprite;
  738. /** @private */ private var _format:TextFormat = new TextFormat("console");
  739. /** @private */ private var _back:Bitmap = new Bitmap;
  740. // FPS panel information.
  741. /** @private */ private var _fpsRead:Sprite = new Sprite;
  742. /** @private */ private var _fpsReadText:TextField = new TextField;
  743. /** @private */ private var _fpsInfo:Sprite = new Sprite;
  744. /** @private */ private var _fpsInfoText0:TextField = new TextField;
  745. /** @private */ private var _fpsInfoText1:TextField = new TextField;
  746. // Output panel information.
  747. /** @private */ private var _logRead:Sprite = new Sprite;
  748. /** @private */ private var _logReadText0:TextField = new TextField;
  749. /** @private */ private var _logReadText1:TextField = new TextField;
  750. /** @private */ private var _logHeight:uint;
  751. /** @private */ private var _logBar:Rectangle;
  752. /** @private */ private var _logBarGlobal:Rectangle;
  753. /** @private */ private var _logScroll:Number = 0;
  754. // Entity count panel information.
  755. /** @private */ private var _entRead:Sprite = new Sprite;
  756. /** @private */ private var _entReadText:TextField = new TextField;
  757. // Debug panel information.
  758. /** @private */ private var _debRead:Sprite = new Sprite;
  759. /** @private */ private var _debReadText0:TextField = new TextField;
  760. /** @private */ private var _debReadText1:TextField = new TextField;
  761. /** @private */ private var _debWidth:uint;
  762. // Button panel information
  763. /** @private */ private var _butRead:Sprite = new Sprite;
  764. /** @private */ private var _butDebug:Bitmap;
  765. /** @private */ private var _butOutput:Bitmap;
  766. /** @private */ private var _butPlay:Bitmap;
  767. /** @private */ private var _butPause:Bitmap;
  768. /** @private */ private var _butStep:Bitmap;
  769. // Entity selection information.
  770. /** @private */ private var _entScreen:Sprite = new Sprite;
  771. /** @private */ private var _entSelect:Sprite = new Sprite;
  772. /** @private */ private var _entRect:Rectangle = new Rectangle;
  773. // Log information.
  774. /** @private */ private var _logLines:uint = 33;
  775. /** @private */ private const LOG:Vector.<String> = new Vector.<String>;
  776. // Entity lists.
  777. /** @private */ private const ENTITY_LIST:Vector.<Entity> = new Vector.<Entity>;
  778. /** @private */ private const SCREEN_LIST:Vector.<Entity> = new Vector.<Entity>;
  779. /** @private */ private const SELECT_LIST:Vector.<Entity> = new Vector.<Entity>;
  780. // Watch information.
  781. /** @private */ private const WATCH_LIST:Vector.<String> = Vector.<String>(["x", "y"]);
  782. // Embedded assets.
  783. [Embed(source = '../graphics/04B_03__.TTF', fontFamily = 'console')] private const FONT_SMALL:Class;
  784. [Embed(source = 'console_logo.png')] private const CONSOLE_LOGO:Class;
  785. [Embed(source = 'console_debug.png')] private const CONSOLE_DEBUG:Class;
  786. [Embed(source = 'console_output.png')] private const CONSOLE_OUTPUT:Class;
  787. [Embed(source = 'console_play.png')] private const CONSOLE_PLAY:Class;
  788. [Embed(source = 'console_pause.png')] private const CONSOLE_PAUSE:Class;
  789. [Embed(source = 'console_step.png')] private const CONSOLE_STEP:Class;
  790. }
  791. }