PageRenderTime 4157ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Level.as

http://github.com/MattThorson/Ogmo-Editor
ActionScript | 511 lines | 381 code | 82 blank | 48 comment | 65 complexity | 881c3ed9915777fd21bd988aecb65a8b MD5 | raw file
  1. package
  2. {
  3. import editor.*;
  4. import editor.tools.*;
  5. import editor.tools.object.*;
  6. import editor.ui.*;
  7. import editor.definitions.*;
  8. import editor.events.*;
  9. import flash.filesystem.File;
  10. import flash.display.Bitmap;
  11. import flash.display.BitmapData;
  12. import flash.display.Sprite;
  13. import flash.events.Event;
  14. import flash.events.KeyboardEvent;
  15. import flash.events.MouseEvent;
  16. import flash.geom.Point;
  17. import flash.geom.Rectangle;
  18. import flash.system.System;
  19. public class Level extends Sprite
  20. {
  21. //Zoom levels
  22. static public const ZOOMS:Array = [ 0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4 ];
  23. //Palettes
  24. public var selTileset:Tileset;
  25. public var selTilePoint:Point;
  26. public var selObject:ObjectDefinition;
  27. public var selObjectFolder:ObjectFolder;
  28. //The general stuff
  29. private var _levelWidth:int;
  30. private var _levelHeight:int;
  31. private var _currentLayerNum:int = 0;
  32. public var values:Vector.<Value>;
  33. public var levelName:String;
  34. public var saved:Boolean;
  35. //The holder, which holds the layers and the bg
  36. private var holder:Sprite; //Holds the layers AND the background
  37. public var layers:Sprite; //Parent of all the layers
  38. public var bg:Sprite; //The background color layer
  39. //For middle-click panning
  40. private var spaceHeld:Boolean;
  41. private var moving:Boolean;
  42. private var moveX:Number;
  43. private var moveY:Number;
  44. public function Level( name:String )
  45. {
  46. //Init name
  47. levelName = name;
  48. saved = false;
  49. //Init palettes
  50. selTilePoint = new Point;
  51. selTileset = null;
  52. selObject = null;
  53. //Not scrolling the view
  54. moving = false;
  55. spaceHeld = false;
  56. //Set up to initialize
  57. addEventListener( Event.ADDED_TO_STAGE, init );
  58. }
  59. private function init( e:Event ):void
  60. {
  61. //Delete the event listener
  62. removeEventListener( Event.ADDED_TO_STAGE, init );
  63. initListeners();
  64. //Init to default size properties
  65. _levelWidth = Ogmo.project.defaultWidth;
  66. _levelHeight = Ogmo.project.defaultHeight;
  67. //Set tileset and object to the defaults (first ones)
  68. if (Ogmo.project.tilesets.length > 0)
  69. setTileset(0);
  70. if (Ogmo.project.objects.length > 0)
  71. Ogmo.windows.setObjectFolder( Ogmo.project.objects );
  72. //Init the holder
  73. holder = new Sprite;
  74. holder.x = 400;
  75. holder.y = 300;
  76. addChild( holder );
  77. //Init the bg color
  78. bg = new Sprite;
  79. drawBackground();
  80. bg.x = -_levelWidth / 2;
  81. bg.y = -_levelHeight / 2;
  82. holder.addChild( bg );
  83. //Init layer holder
  84. holder.addChild( layers = new Sprite );
  85. layers.x = -_levelWidth / 2;
  86. layers.y = -_levelHeight / 2;
  87. //Init layers
  88. var layer:Layer;
  89. var l:LayerDefinition;
  90. for ( var i:int = 0; i < Ogmo.project.layers.length; i++ )
  91. {
  92. l = Ogmo.project.layers[ i ];
  93. if (l.type == LayerDefinition.TILES)
  94. {
  95. layer = new TileLayer( l.name, l.gridSize, l.gridColor, l.drawGridSize, l.multipleTilesets, l.exportTileSize, l.exportTileIDs );
  96. }
  97. else if (l.type == LayerDefinition.GRID)
  98. {
  99. layer = new GridLayer( l.name, l.gridSize, l.gridColor, l.drawGridSize, l.color, l.exportAsObjects, l.newLine );
  100. }
  101. else if (l.type == LayerDefinition.OBJECTS)
  102. {
  103. layer = new ObjectLayer( l.name, l.gridSize, l.gridColor, l.drawGridSize );
  104. }
  105. layers.addChild( layer );
  106. }
  107. //Init values
  108. if (Ogmo.project.levelValues)
  109. {
  110. values = new Vector.<Value>;
  111. var value:Value;
  112. for each ( var v:ValueDefinition in Ogmo.project.levelValues )
  113. {
  114. value = v.getValue();
  115. values.push( value );
  116. }
  117. }
  118. //Init the mouse co-ords
  119. addChild( new MouseCoords );
  120. //Set the layer to the first one
  121. setLayer(0);
  122. Ogmo.windows.updateVisibilities();
  123. }
  124. private function destroy( e:Event ):void
  125. {
  126. removeEventListener( Event.REMOVED_FROM_STAGE, destroy );
  127. stage.removeEventListener( MouseEvent.MOUSE_WHEEL, onMouseWheel );
  128. stage.removeEventListener( MouseEvent.MOUSE_DOWN, onMouseDown );
  129. stage.removeEventListener( MouseEvent.MOUSE_UP, onMouseUp );
  130. stage.removeEventListener( MouseEvent.MIDDLE_MOUSE_DOWN, onMiddleMouseDown );
  131. stage.removeEventListener( MouseEvent.MIDDLE_MOUSE_UP, onMiddleMouseUp );
  132. stage.removeEventListener( MouseEvent.MOUSE_MOVE, onMouseMove );
  133. stage.removeEventListener( Event.MOUSE_LEAVE, onMouseLeave );
  134. stage.removeEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
  135. stage.removeEventListener( KeyboardEvent.KEY_UP, onKeyUp );
  136. }
  137. public function initListeners():void
  138. {
  139. //Add the new event listeners
  140. addEventListener( Event.REMOVED_FROM_STAGE, destroy );
  141. stage.addEventListener( MouseEvent.MOUSE_WHEEL, onMouseWheel );
  142. stage.addEventListener( MouseEvent.MOUSE_DOWN, onMouseDown );
  143. stage.addEventListener( MouseEvent.MOUSE_UP, onMouseUp );
  144. stage.addEventListener( MouseEvent.MIDDLE_MOUSE_DOWN, onMiddleMouseDown );
  145. stage.addEventListener( MouseEvent.MIDDLE_MOUSE_UP, onMiddleMouseUp );
  146. stage.addEventListener( MouseEvent.MOUSE_MOVE, onMouseMove );
  147. stage.addEventListener( Event.MOUSE_LEAVE, onMouseLeave );
  148. stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
  149. stage.addEventListener( KeyboardEvent.KEY_UP, onKeyUp );
  150. }
  151. public function toggleGrid():void
  152. {
  153. Ogmo.gridOn = !Ogmo.gridOn;
  154. currentLayer.handleGridMode();
  155. Ogmo.windowMenu.refreshState();
  156. }
  157. public function centerView():void
  158. {
  159. holder.x = 400;
  160. holder.y = 300;
  161. }
  162. private function drawBackground():void
  163. {
  164. bg.graphics.clear();
  165. bg.graphics.beginFill( 0x000000, 0.5 );
  166. bg.graphics.drawRect( 6, 6, _levelWidth, _levelHeight );
  167. bg.graphics.endFill();
  168. bg.graphics.beginFill( Ogmo.project.bgColor );
  169. bg.graphics.drawRect( 0, 0, _levelWidth, _levelHeight );
  170. bg.graphics.endFill();
  171. }
  172. public function saveScreenshot():void
  173. {
  174. currentLayer.active = false;
  175. var bd:BitmapData = new BitmapData( _levelWidth, _levelHeight );
  176. bd.fillRect( new Rectangle( 0, 0, _levelWidth, _levelHeight ), 0xFF000000 + Ogmo.project.bgColor );
  177. for ( var i:int = 0; i < layers.numChildren; i++ )
  178. bd.draw( layers.getChildAt( i ) );
  179. var file:File = File.desktopDirectory;
  180. file.save( PNGEncoder.encode( bd ), "screenshot.png" );
  181. currentLayer.active = true;
  182. }
  183. /* ========================== SETTING THINGS ========================== */
  184. public function setLayer( to:int ):void
  185. {
  186. //Error if invalid layer
  187. if (to >= layers.numChildren || to < 0)
  188. throw new Error( "Switching to non-existent layer!" );
  189. //Deactivate old active layer
  190. if (currentLayerNum != -1)
  191. currentLayer.active = false;
  192. //Activate the new one
  193. _currentLayerNum = to;
  194. currentLayer.active = true;
  195. //Set alpha values of all layers
  196. var after:Boolean = false;
  197. var i:int;
  198. for ( i = 0; i < layers.numChildren; i++ )
  199. {
  200. layers.getChildAt( i ).alpha = 1;
  201. if (i == to)
  202. {
  203. after = true;
  204. continue;
  205. }
  206. if (after)
  207. layers.getChildAt( i ).alpha = 0.2;
  208. }
  209. Ogmo.windows.setLayer( to );
  210. //If the layer is a tile layer not allowed multiple tilesets, switch to its current tileset
  211. if (currentLayer is TileLayer)
  212. {
  213. var layer:TileLayer = currentLayer as TileLayer;
  214. if (layer.onlyTileset)
  215. setTileset( Ogmo.project.getTilesetNumFromName( layer.onlyTileset.tilesetName ) );
  216. }
  217. //Refresh menus for undo/redo
  218. Ogmo.windowMenu.refreshState();
  219. //dispatch the event
  220. stage.dispatchEvent(new LayerSelectEvent(currentLayer));
  221. }
  222. public function setTileset( to:int, enforce:Boolean = true ):void
  223. {
  224. //Do nothing if that's the current tileset
  225. if (Ogmo.project.tilesets[ to ] == selTileset)
  226. return;
  227. //Error if invalid tileset
  228. if (to >= Ogmo.project.tilesetsCount || to < 0)
  229. throw new Error( "Switching to non-existent tileset!" );
  230. selTileset = Ogmo.project.tilesets[ to ];
  231. selTilePoint.x = 0;
  232. selTilePoint.y = 0;
  233. //Set the tileset in the windows
  234. Ogmo.windows.setTileset( to );
  235. //If the layer is a tile layer not allowed multiple tilesets, switch its tileset
  236. if (currentLayer is TileLayer && enforce)
  237. {
  238. var layer:TileLayer = currentLayer as TileLayer;
  239. if (layer.onlyTileset)
  240. layer.onlyTileset = Ogmo.project.tilesets[ to ];
  241. }
  242. stage.dispatchEvent(new TilesetSelectEvent(selTileset));
  243. }
  244. public function setSize( newWidth:int, newHeight:int ):void
  245. {
  246. //Exit if no change
  247. if (newWidth == _levelWidth && newHeight == _levelHeight)
  248. return;
  249. //Resize all layers
  250. for ( var i:int = 0; i < layers.numChildren; i++ )
  251. (layers.getChildAt( i ) as Layer).resizeLevel( newWidth, newHeight );
  252. //Change the actual values
  253. _levelWidth = newWidth;
  254. _levelHeight = newHeight;
  255. //Readjust positions
  256. layers.x = -_levelWidth / 2;
  257. layers.y = -_levelHeight / 2;
  258. bg.x = -_levelWidth / 2;
  259. bg.y = -_levelHeight / 2;
  260. //Redraw the stage background
  261. drawBackground();
  262. }
  263. /* ========================== GETS/SETS ========================== */
  264. public function get zoom():int
  265. {
  266. for ( var i:int = 0; i < ZOOMS.length; i++ )
  267. {
  268. if (ZOOMS[ i ] == holder.scaleX)
  269. return i;
  270. }
  271. return -1;
  272. }
  273. public function set zoom( to:int ):void
  274. {
  275. var cur:int;
  276. cur = Utils.within( 0, to, ZOOMS.length - 1 );
  277. holder.scaleX = ZOOMS[ cur ];
  278. holder.scaleY = holder.scaleX;
  279. Ogmo.showMessage( "Zoom: " + (ZOOMS[ cur ] * 100) + "%" );
  280. Ogmo.windowMenu.refreshState();
  281. }
  282. public function get xml():XML
  283. {
  284. var temp:XML;
  285. var ret:XML = <level></level>;
  286. ret.setName( "level" );
  287. //values
  288. Reader.writeValues( ret, values );
  289. if (Ogmo.project.exportLevelSize)
  290. {
  291. //Stage width
  292. temp = <width></width>;
  293. temp.setChildren( _levelWidth );
  294. ret.appendChild( temp );
  295. //Stage height
  296. temp = <height></height>;
  297. temp.setChildren( _levelHeight );
  298. ret.appendChild( temp );
  299. }
  300. //Layers
  301. for ( var i:int = 0; i < layers.numChildren; i++ )
  302. {
  303. temp = (layers.getChildAt( i ) as Layer).xml;
  304. if (temp)
  305. ret.appendChild( temp );
  306. }
  307. return ret;
  308. }
  309. public function set xml( to:XML ):void
  310. {
  311. //values
  312. Reader.readValues( to, values );
  313. for each ( var o:XML in to.children() )
  314. {
  315. if (o.name().localName == "width")
  316. {
  317. //<WIDTH>
  318. setSize( Reader.readInt( o, Ogmo.project.defaultWidth, "width", Ogmo.project.minWidth, Ogmo.project.maxWidth ), levelHeight );
  319. }
  320. else if (o.name().localName == "height")
  321. {
  322. //<HEIGHT>
  323. setSize( levelWidth, Reader.readInt( o, Ogmo.project.defaultHeight, "height", Ogmo.project.minHeight, Ogmo.project.maxHeight ) );
  324. }
  325. else
  326. {
  327. //Layers!
  328. var b:Boolean = false;
  329. for ( var i:int = 0; i < layers.numChildren; i++ )
  330. {
  331. var layer:Layer = layers.getChildAt( i ) as Layer;
  332. if (o.name().localName == layer.layerName)
  333. {
  334. layer.xml = o;
  335. b = true;
  336. break;
  337. }
  338. }
  339. if (!b)
  340. throw new Error( "Layer \"" + o.name().localName + "\" not defined for this project!" );
  341. }
  342. }
  343. }
  344. public function get currentLayer():Layer
  345. {
  346. if (!layers)
  347. return null;
  348. else
  349. return layers.getChildAt(_currentLayerNum) as Layer;
  350. }
  351. public function get currentLayerNum():int
  352. {
  353. return _currentLayerNum;
  354. }
  355. public function get levelWidth():int
  356. {
  357. return _levelWidth;
  358. }
  359. public function get levelHeight():int
  360. {
  361. return _levelHeight;
  362. }
  363. /* ========================== EVENTS ========================== */
  364. private function onMouseWheel( e:MouseEvent ):void
  365. {
  366. zoom += (e.delta < 0)?( -1):(1);
  367. }
  368. private function onMouseDown( e:MouseEvent ):void
  369. {
  370. if (spaceHeld)
  371. {
  372. moving = true;
  373. moveX = e.stageX - holder.x;
  374. moveY = e.stageY - holder.y;
  375. }
  376. }
  377. private function onMouseUp( e:MouseEvent = null ):void
  378. {
  379. moving = false;
  380. }
  381. private function onMiddleMouseDown( e:MouseEvent ):void
  382. {
  383. moving = true;
  384. moveX = e.stageX - holder.x;
  385. moveY = e.stageY - holder.y;
  386. }
  387. private function onMiddleMouseUp( e:MouseEvent = null ):void
  388. {
  389. moving = false;
  390. }
  391. private function onMouseMove( e:MouseEvent ):void
  392. {
  393. if (moving)
  394. {
  395. holder.x = e.stageX - moveX;
  396. holder.y = e.stageY - moveY;
  397. }
  398. }
  399. private function onMouseLeave( e:Event ):void
  400. {
  401. onMiddleMouseUp();
  402. }
  403. private function onKeyDown( e:KeyboardEvent ):void
  404. {
  405. if (Ogmo.missKeys)
  406. return;
  407. //NUMBER KEYS
  408. if (e.ctrlKey && e.keyCode >= 49 && e.keyCode <= 57)
  409. {
  410. if (Ogmo.project.layers.length >= e.keyCode - 48)
  411. setLayer( e.keyCode - 49 );
  412. return;
  413. }
  414. else if (e.keyCode == 32)
  415. {
  416. layers.mouseChildren = false;
  417. spaceHeld = true;
  418. }
  419. }
  420. private function onKeyUp( e:KeyboardEvent ):void
  421. {
  422. if (e.keyCode == 32)
  423. {
  424. layers.mouseChildren = true;
  425. spaceHeld = false;
  426. }
  427. }
  428. }
  429. }