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

/zombie-stick-level-editor-workspace/level-editor/src/com/jxl/zombiestick/LevelCanvas.as

https://github.com/JesterXL/ZombieStick
ActionScript | 415 lines | 330 code | 56 blank | 29 comment | 23 complexity | d067934dd5b7e3dd9e5aae3c83190857 MD5 | raw file
  1. package com.jxl.zombiestick
  2. {
  3. import com.jxl.zombiestick.controls.GameObjectView;
  4. import com.jxl.zombiestick.events.LevelCanvasEvent;
  5. import com.jxl.zombiestick.vo.GameObjectVO;
  6. import com.jxl.zombiestick.vo.LevelVO;
  7. import flash.display.DisplayObject;
  8. import flash.display.Graphics;
  9. import flash.events.Event;
  10. import flash.events.KeyboardEvent;
  11. import flash.events.MouseEvent;
  12. import flash.geom.Point;
  13. import flash.geom.Rectangle;
  14. import flash.ui.Keyboard;
  15. import flash.utils.Dictionary;
  16. import mx.collections.ArrayCollection;
  17. import mx.controls.Alert;
  18. import mx.core.UIComponent;
  19. import mx.events.CloseEvent;
  20. import mx.events.CollectionEvent;
  21. import mx.events.CollectionEventKind;
  22. import mx.graphics.BitmapScaleMode;
  23. import spark.components.Image;
  24. import spark.layouts.BasicLayout;
  25. import spark.primitives.Rect;
  26. public class LevelCanvas extends UIComponent
  27. {
  28. private var _level:LevelVO;
  29. private var levelDirty:Boolean = false;
  30. private var dragging:Boolean = false;
  31. private var startClick:Point;
  32. private var backgroundImage:Image;
  33. private var gameObjects:UIComponent;
  34. //private var lastSelected:GameObjectView;
  35. public function get level():LevelVO { return _level; }
  36. public function set level(value:LevelVO):void
  37. {
  38. if(_level)
  39. {
  40. _level.removeEventListener("backgroundImageChanged", onBackgroundImageChanged);
  41. _level.events.removeEventListener(CollectionEvent.COLLECTION_CHANGE, onEventsChanged);
  42. }
  43. _level = value;
  44. if(_level)
  45. {
  46. _level.addEventListener("backgroundImageChanged", onBackgroundImageChanged);
  47. _level.events.addEventListener(CollectionEvent.COLLECTION_CHANGE, onEventsChanged);
  48. }
  49. levelDirty = true;
  50. invalidateProperties();
  51. }
  52. public function LevelCanvas()
  53. {
  54. super();
  55. init();
  56. }
  57. private function init():void
  58. {
  59. addEventListener(Event.ADDED_TO_STAGE, onAdded);
  60. }
  61. private function onAdded(event:Event):void
  62. {
  63. stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
  64. stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
  65. }
  66. public function newGameObject(x:Number=0, y:Number=0):void
  67. {
  68. var gameObject:GameObjectVO = new GameObjectVO();
  69. _level.events.addItem(gameObject);
  70. gameObject.x = x;
  71. gameObject.y = y;
  72. }
  73. protected override function createChildren():void
  74. {
  75. super.createChildren();
  76. backgroundImage = new Image();
  77. addChild(backgroundImage);
  78. backgroundImage.scaleMode = BitmapScaleMode.LETTERBOX;
  79. backgroundImage.addEventListener(Event.COMPLETE, onImageLoadComplete);
  80. backgroundImage.mouseChildren = false;
  81. backgroundImage.mouseEnabled = false;
  82. backgroundImage.tabChildren = false;
  83. backgroundImage.tabEnabled = false;
  84. gameObjects = new UIComponent();
  85. addChild(gameObjects);
  86. gameObjects.mouseEnabled = false;
  87. gameObjects.tabEnabled = false;
  88. gameObjects.tabChildren = false;
  89. gameObjects.mouseChildren = true;
  90. gameObjects.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  91. gameObjects.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
  92. }
  93. protected override function commitProperties():void
  94. {
  95. super.commitProperties();
  96. if(levelDirty)
  97. {
  98. levelDirty = false;
  99. if(_level)
  100. {
  101. updateImage();
  102. var len:int = _level.events.length;
  103. for(var index:int = 0; index < len; index++)
  104. {
  105. var obj:Object = _level.events[index];
  106. if(obj is GameObjectVO)
  107. {
  108. addNewGameObject(obj as GameObjectVO);
  109. }
  110. }
  111. }
  112. else
  113. {
  114. backgroundImage.source = null;
  115. }
  116. }
  117. }
  118. protected override function updateDisplayList(w:Number, h:Number):void
  119. {
  120. super.updateDisplayList(w, h);
  121. var g:Graphics = graphics;
  122. g.clear();
  123. g.beginFill(0xFFFFFF);
  124. g.lineStyle(0, 0x000000);
  125. g.drawRect(0, 0, width, height);
  126. g.endFill();
  127. backgroundImage.setActualSize(backgroundImage.sourceWidth, backgroundImage.sourceHeight);
  128. }
  129. private function updateImage():void
  130. {
  131. backgroundImage.source = _level.backgroundImage;
  132. }
  133. private function onBackgroundImageChanged(event:Event):void
  134. {
  135. updateImage();
  136. }
  137. private function onImageLoadComplete(event:Event):void
  138. {
  139. invalidateSize();
  140. }
  141. protected override function measure():void
  142. {
  143. var rect:Rectangle = new Rectangle();
  144. var len:int = gameObjects.numChildren;
  145. while(len--)
  146. {
  147. var child:DisplayObject = gameObjects.getChildAt(len);
  148. rect.x = Math.min(child.x, rect.x);
  149. rect.y = Math.min(child.y, rect.y);
  150. rect.width = Math.max(child.x + child.width, rect.width);
  151. rect.height = Math.max(child.y + child.height, rect.height);
  152. }
  153. if(isNaN(backgroundImage.sourceWidth) == false)
  154. {
  155. rect.width = Math.max(backgroundImage.sourceWidth, rect.width);
  156. rect.height = Math.max(backgroundImage.sourceHeight, rect.height);
  157. }
  158. width = explicitWidth = measuredWidth = rect.width;
  159. height = explicitHeight = measuredHeight = rect.height;
  160. }
  161. private function onMouseDown(event:MouseEvent):void
  162. {
  163. var selectionEvent:LevelCanvasEvent;
  164. if(event.shiftKey == false)
  165. {
  166. selectionEvent = new LevelCanvasEvent(LevelCanvasEvent.SET_SELECTION);
  167. selectionEvent.gameObject = GameObjectView(event.target).gameObject;
  168. dispatchEvent(selectionEvent);
  169. //setSelected(event.target as GameObjectView);
  170. }
  171. else
  172. {
  173. selectionEvent = new LevelCanvasEvent(LevelCanvasEvent.ADD_SELECTION);
  174. selectionEvent.gameObject = GameObjectView(event.target).gameObject;
  175. dispatchEvent(selectionEvent);
  176. //addSelected(event.target as GameObjectView);
  177. }
  178. if(dragging == false)
  179. {
  180. startClick = new Point(mouseX, mouseY);
  181. addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveInitial);
  182. dispatchEvent(new LevelCanvasEvent(LevelCanvasEvent.START_MOVE_SELECTIONS));
  183. }
  184. event.stopImmediatePropagation();
  185. }
  186. private function onMouseUp(event:MouseEvent):void
  187. {
  188. }
  189. private function onMouseMoveInitial(event:MouseEvent):void
  190. {
  191. var deltaX:Number = mouseX - startClick.x;
  192. var deltaY:Number = mouseY - startClick.y;
  193. var dist:Number = Math.sqrt((deltaX * deltaX) + (deltaY * deltaY));
  194. if(dist > 4)
  195. {
  196. removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveInitial);
  197. dragging = true;
  198. stage.addEventListener(MouseEvent.MOUSE_UP, onDragMouseUp, true, 10);
  199. addEventListener(MouseEvent.MOUSE_MOVE, onDragMouseMove);
  200. }
  201. }
  202. private function onDragMouseMove(event:MouseEvent):void
  203. {
  204. /*
  205. var len:int = _selections.length;
  206. while(len--)
  207. {
  208. var gameObject:GameObjectVO = _selections[len] as GameObjectVO;
  209. gameObject.x = gameObject.originalPoint.x - (startClick.x - mouseX);
  210. gameObject.y = gameObject.originalPoint.y - (startClick.y - mouseY);
  211. }
  212. */
  213. var dragEvent:LevelCanvasEvent = new LevelCanvasEvent(LevelCanvasEvent.DRAG_GAME_OBJECTS);
  214. dragEvent.offsetX = startClick.x - mouseX;
  215. dragEvent.offsetY = startClick.y - mouseY;
  216. dispatchEvent(dragEvent);
  217. event.updateAfterEvent();
  218. event.stopImmediatePropagation();
  219. }
  220. private function onDragMouseUp(event:MouseEvent):void
  221. {
  222. trace("LevelCanvas::onDragMouseUp, dragging: " + dragging);
  223. dragging = false;
  224. stage.removeEventListener(MouseEvent.MOUSE_UP, onDragMouseUp, true);
  225. removeEventListener(MouseEvent.MOUSE_MOVE, onDragMouseMove);
  226. startClick = null;
  227. removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveInitial);
  228. event.stopImmediatePropagation();
  229. }
  230. private function onStageMouseUp(event:MouseEvent):void
  231. {
  232. trace("onStageMouseUp, target: " + event.target + ", dragging: " + dragging);
  233. removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveInitial);
  234. if(event.target == this || event.target == gameObjects)
  235. {
  236. dispatchEvent(new LevelCanvasEvent(LevelCanvasEvent.CLEAR_ALL_SELECTIONS));
  237. //setSelected(null);
  238. }
  239. }
  240. private function onEventsChanged(event:CollectionEvent):void
  241. {
  242. switch(event.kind)
  243. {
  244. case CollectionEventKind.ADD:
  245. addNewGameObject(event.items[0] as GameObjectVO);
  246. break;
  247. case CollectionEventKind.REMOVE:
  248. var len:int = event.items.length;
  249. while(len--)
  250. {
  251. removeGameObject(event.items[len]);
  252. }
  253. break;
  254. }
  255. invalidateSize();
  256. }
  257. private function addNewGameObject(gameObject:GameObjectVO):void
  258. {
  259. var view:GameObjectView = new GameObjectView();
  260. view.gameObject = gameObject;
  261. view.addEventListener("childSizeChanged", onChildSizeChanged, false, 0, true);
  262. gameObjects.addChild(view);
  263. }
  264. private function removeGameObject(gameObject:GameObjectVO):void
  265. {
  266. var len:int = gameObjects.numChildren;
  267. while(len--)
  268. {
  269. var view:GameObjectView = gameObjects.getChildAt(len) as GameObjectView;
  270. if(view.gameObject == gameObject)
  271. {
  272. view.gameObject = null;
  273. view.removeEventListener("childSizeChanged", onChildSizeChanged);
  274. gameObjects.removeChildAt(len);
  275. return;
  276. }
  277. }
  278. }
  279. // TODO: 2.5.2011, I don't like this guy just manually deleting his crap; he should be listening to the
  280. // level's events chanigng, and act accordingly.
  281. private function onDelete():void
  282. {
  283. dispatchEvent(new LevelCanvasEvent(LevelCanvasEvent.DELETE_SELECTED));
  284. }
  285. private function onChildSizeChanged(event:Event):void
  286. {
  287. //invalidateSize();
  288. measure();
  289. }
  290. private function onKeyDown(event:KeyboardEvent):void
  291. {
  292. var amount:Number;
  293. if(event.shiftKey)
  294. {
  295. amount = 10;
  296. }
  297. else
  298. {
  299. amount = 1;
  300. }
  301. switch(event.keyCode)
  302. {
  303. case Keyboard.DOWN:
  304. moveGameObjects(0, amount);
  305. break;
  306. case Keyboard.RIGHT:
  307. moveGameObjects(amount, 0);
  308. break;
  309. case Keyboard.UP:
  310. moveGameObjects(0, -amount);
  311. break;
  312. case Keyboard.LEFT:
  313. moveGameObjects(-amount, 0);
  314. break;
  315. case Keyboard.DELETE:
  316. Alert.yesLabel = "Delete";
  317. Alert.show("Are you sure you wish to delete?", "Confirm Delete", Alert.YES | Alert.CANCEL, this, onConfirm, null, Alert.CANCEL);
  318. break;
  319. case Keyboard.D:
  320. if(event.commandKey)
  321. {
  322. duplicateObjects();
  323. }
  324. break;
  325. }
  326. }
  327. private function moveGameObjects(xAmount:Number, yAmount:Number):void
  328. {
  329. var moveEvent:LevelCanvasEvent = new LevelCanvasEvent(LevelCanvasEvent.MOVE_GAME_OBJECTS);
  330. moveEvent.x = xAmount;
  331. moveEvent.y = yAmount;
  332. dispatchEvent(moveEvent);
  333. /*
  334. if(_selections)
  335. {
  336. var len:int = _selections.length;
  337. while(len--)
  338. {
  339. var gameObject:GameObjectVO = _selections[len] as GameObjectVO;
  340. gameObject.x += xAmount;
  341. gameObject.y += yAmount;
  342. }
  343. }
  344. */
  345. }
  346. private function duplicateObjects():void
  347. {
  348. dispatchEvent(new LevelCanvasEvent(LevelCanvasEvent.DUPLICATE_OBJECTS));
  349. }
  350. private function onConfirm(event:CloseEvent):void
  351. {
  352. if(event.detail == Alert.YES)
  353. {
  354. //dispatchEvent(new GameObjectViewEvent(GameObjectViewEvent.DELETE));
  355. onDelete();
  356. }
  357. }
  358. }
  359. }