PageRenderTime 68ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/net/flashpunk/debug/Console.as

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