PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Engine/src/org/flashIso/engine/base/IsoMap.as

http://flashiso.googlecode.com/
ActionScript | 380 lines | 234 code | 40 blank | 106 comment | 36 complexity | 6bbb130b4f0d38c1aa9bf749fd4dbc2d MD5 | raw file
  1. package org.flashIso.engine.base {
  2. import flash.display.DisplayObject;
  3. import flash.display.Sprite;
  4. import flash.events.Event;
  5. import flash.utils.getDefinitionByName;
  6. import org.flashIso.engine.core.ILibrary;
  7. import org.flashIso.engine.core.ISerializableXML;
  8. import org.flashIso.engine.core.IsoObjectBase;
  9. import org.flashIso.engine.core.Point2D;
  10. import org.flashIso.engine.core.Point3D;
  11. import org.flashIso.engine.core.ValidateableSprite;
  12. import org.flashIso.engine.events.IsoEvent;
  13. import org.flashIso.engine.objects.IsoObject;
  14. import org.flashIso.engine.objects.IsoTile;
  15. /**
  16. *
  17. * IsoMap is a container and manager for IsoObjectBase objects.
  18. * Depth and flash coordinates are automaticaly adjusted based on.
  19. * objects' position property and map's perspective.
  20. * Use addElement and removeElement functions instead of addChild / removeChild.
  21. * When perspective object changes draw method is called for all childred.
  22. *
  23. */
  24. public class IsoMap extends ValidateableSprite implements ISerializableXML{
  25. protected var _perspective : IsoPerspective = new IsoPerspective();
  26. protected var _xAxis : IsoObject;
  27. protected var _yAxis : IsoObject;
  28. protected var _zAxis : IsoObject;
  29. protected var _showAxis:Boolean = false;
  30. protected var _axisInvalidated:Boolean = false;
  31. protected var _childredInvalidated:Boolean = false;
  32. public function IsoMap() {
  33. _perspective.addEventListener(Event.CHANGE, perspectiveChangeHandler, false, 0, true);
  34. }
  35. protected function perspectiveChangeHandler(e:Event) : void {
  36. invalidateChildren();
  37. }
  38. /**
  39. *
  40. * Setting this property true will create 3 objects of colors
  41. * red, green, blue representing X, Y and Z axis.
  42. *
  43. **/
  44. public function set showAxis(value : Boolean) : void {
  45. if (_showAxis != value) {
  46. _showAxis = value;
  47. invalidateAxis();
  48. }
  49. }
  50. public function get showAxis() : Boolean {
  51. return _showAxis;
  52. }
  53. /**
  54. *
  55. * Reference to perspective instance
  56. *
  57. **/
  58. public function set perspective(perspective : IsoPerspective) : void {
  59. _perspective.removeEventListener(Event.CHANGE, triggerValidation);
  60. _perspective = perspective;
  61. _perspective.addEventListener(Event.CHANGE, triggerValidation, false, 0, true);
  62. invalidateChildren();
  63. }
  64. public function get perspective() : IsoPerspective {
  65. return _perspective;
  66. }
  67. public function addElement(child : IsoObjectBase) : void {
  68. super.addChildAt(child, determineLevelForNewChild(child));
  69. //super.addChild(child);
  70. updateChildPosition(child);
  71. drawChild(child);
  72. child.addEventListener(IsoEvent.POSITION_CHANGE, childPositionChangeHandler, false, 0, true);
  73. child.addEventListener(Event.CHANGE, childChangeHandler, false, 0, true);
  74. }
  75. protected function childChangeHandler (e:Event) : void {
  76. drawChild(e.target as IsoObjectBase);
  77. }
  78. public function removeElement(child:IsoObjectBase):void {
  79. super.removeChild(child);
  80. child.removeEventListener(IsoEvent.POSITION_CHANGE, childPositionChangeHandler);
  81. child.removeEventListener(Event.CHANGE, triggerValidation);
  82. }
  83. /**
  84. * Use addElement function insted of addChild
  85. **/
  86. override public function addChild(child : DisplayObject) : DisplayObject {
  87. throw (new Error("Method addChild is not available! Use addElement instead."));
  88. return null;
  89. }
  90. /**
  91. * Use addElement function insted. Note that objects
  92. * depth is automaticaly handled by IsoMap container
  93. **/
  94. override public function addChildAt(child : DisplayObject, index : int) : DisplayObject {
  95. throw (new Error("Method addChildAt is not available! Use addElement instead."));
  96. return null;
  97. }
  98. /**
  99. * Use removeElement function instead
  100. **/
  101. override public function removeChild(child:DisplayObject):DisplayObject {
  102. throw (new Error("Method removeChild is not available! Use removeElement instead."));
  103. }
  104. /**
  105. * Use removeElement function instead
  106. **/
  107. override public function removeChildAt(index:int):DisplayObject {
  108. throw (new Error("Method removeChildAt is not available! Use removeElement instead."));
  109. }
  110. protected function invalidateChildren() : void {
  111. if (_childredInvalidated == false){
  112. _childredInvalidated = true;
  113. triggerValidation();
  114. }
  115. }
  116. protected function validateChildrenNow() : void {
  117. if (_childredInvalidated){
  118. _childredInvalidated = false;
  119. var i:uint;
  120. for (i = 0; i < numChildren; i++){
  121. if (getChildAt(i) is IsoObjectBase){
  122. drawChild(getChildAt(i) as IsoObjectBase);
  123. updateChildPosition(getChildAt(i) as IsoObjectBase);
  124. }
  125. }
  126. }
  127. }
  128. protected function invalidateAxis() : void {
  129. if (_axisInvalidated == false){
  130. _axisInvalidated = true;
  131. triggerValidation();
  132. }
  133. }
  134. protected function validateAxisNow() : void {
  135. if (_axisInvalidated){
  136. _axisInvalidated = false;
  137. if(_xAxis != null){
  138. removeElement(_xAxis);
  139. removeElement(_yAxis);
  140. removeElement(_zAxis);
  141. _xAxis = _yAxis = _zAxis = null;
  142. }
  143. if (_showAxis){
  144. _xAxis = new IsoObject();
  145. _xAxis.size = new Point3D(100, 5, 5);
  146. _xAxis.fillColor = 0xff0000;
  147. _xAxis.fillAlpha = 0.2;
  148. _xAxis.lineColor = 0xff0000;
  149. _xAxis.lineAlpha = 0.6;
  150. addElement(_xAxis);
  151. _yAxis = new IsoObject();
  152. _yAxis.size = new Point3D(5, 100, 5);
  153. _yAxis.fillColor = 0x00ff00;
  154. _yAxis.fillAlpha = 0.2;
  155. _yAxis.lineColor = 0x00ff00;
  156. _yAxis.lineAlpha = 0.6;
  157. addElement(_yAxis);
  158. _zAxis = new IsoObject();
  159. _zAxis.size = new Point3D(5, 5, 100);
  160. _zAxis.fillColor = 0x0000ff;
  161. _zAxis.fillAlpha = 0.2;
  162. _zAxis.lineColor = 0x0000ff;
  163. _zAxis.lineAlpha = 0.6;
  164. addElement(_zAxis);
  165. }
  166. }
  167. }
  168. override public function validateNow() : void {
  169. validateAxisNow();
  170. validateChildrenNow();
  171. super.validateNow();
  172. }
  173. protected function childChange(e:Event) : void {
  174. drawChild(e.target as IsoObjectBase);
  175. }
  176. protected function drawChild(child : IsoObjectBase) : void {
  177. child.draw(perspective);
  178. }
  179. protected function childPositionChangeHandler(e:Event) : void {
  180. updateChildPosition(e.target as IsoObjectBase);
  181. }
  182. protected function updateChildPosition(object : IsoObjectBase) : void {
  183. updateObjectZOrder(object);
  184. var p : Point2D = perspective.getProjection(object.position);
  185. object.x = p.x;
  186. object.y = p.y;
  187. }
  188. protected function determineLevelForNewChild(child : IsoObjectBase) : uint {
  189. var pos:Point3D = child.position;
  190. var min : int = 0;
  191. var max : int = numChildren;
  192. var middle : int;
  193. if (numChildren == 0) {
  194. return 0;
  195. }
  196. while (max - min > 1) {
  197. middle = min + (max - min) / 2;
  198. if (getPointDepthValue((getChildAt(middle) as IsoObjectBase).position) < getPointDepthValue(pos)) {
  199. max = middle;
  200. } else {
  201. min = middle;
  202. }
  203. }
  204. if (getPointDepthValue((getChildAt(min) as IsoObjectBase).position) < getPointDepthValue(pos)) {
  205. return min;
  206. }
  207. return max;
  208. }
  209. // protected function updateObjectZOrder(object : IsoObjectBase) : void {
  210. // var level : int = getChildIndex(object);
  211. // while ((level < (numChildren - 1)) && ((!(getChildAt(level + 1) is IsoObjectBase)) || (getPointDepthValue((getChildAt(level + 1) as IsoObjectBase).position) > getPointDepthValue(object.position) ))) {
  212. // level++;
  213. // }
  214. // if (level != getChildIndex(object)) {
  215. // super.addChildAt(object, level);
  216. // }
  217. //
  218. // level = getChildIndex(object);
  219. // while ((level > 0) && ((!(getChildAt(level - 1) is IsoObjectBase)) || (getPointDepthValue((getChildAt(level - 1) as IsoObjectBase).position) < getPointDepthValue(object.position)))) {
  220. // level--;
  221. // }
  222. // if (level != getChildIndex(object)) {
  223. // super.addChildAt(object, level);
  224. // }
  225. // }
  226. // protected function updateObjectZOrder(object : IsoObjectBase) : void {
  227. // var x:Number = object.position.x;
  228. // var y:Number = object.position.y;
  229. // var width:Number = object.size.x;
  230. // var height:Number = object.size.y;
  231. // var level : int = getChildIndex(object);
  232. // var child:IsoObjectBase;
  233. //
  234. // if (level < (numChildren - 1)) {
  235. // child = getChildAt(level + 1) as IsoObjectBase;
  236. // }
  237. // while ( (child != null) &&
  238. // ((x + width < child.position.x) ||
  239. // (y + height < child.position.y)) ) {
  240. //
  241. // level++;
  242. // if (level < (numChildren - 1)) {
  243. // child = getChildAt(level + 1) as IsoObjectBase;
  244. // }else{
  245. // child = null;
  246. // }
  247. // }
  248. // if (level > numChildren - 1){
  249. // level = numChildren - 1;
  250. // }
  251. //
  252. // if (level != getChildIndex(object)) {
  253. // super.addChildAt(object, level);
  254. // }
  255. //
  256. //
  257. // level = getChildIndex(object);
  258. //
  259. // if (level > 0){
  260. // child = getChildAt(level - 1) as IsoObjectBase;
  261. // }
  262. //
  263. // while ( (child != null) &&
  264. // ((child.position.x + child.size.x <= x) ||
  265. // (child.position.y + child.size.y <= y)) ) {
  266. // level--;
  267. // if (level > 0) {
  268. // child = getChildAt(level - 1) as IsoObjectBase;
  269. // }else{
  270. // child = null;
  271. // }
  272. // }
  273. // if (level < 0){
  274. // level = 0;
  275. // }
  276. // if (level != getChildIndex(object)) {
  277. // super.addChildAt(object, level);
  278. // }
  279. // }
  280. protected function updateObjectZOrder(object : IsoObjectBase) : void {
  281. var i:uint;
  282. for (i = 0; i < numChildren; i++) {
  283. var child:IsoObjectBase = getChildAt(i) as IsoObjectBase;
  284. if (child != null && child.hitTestObject(object)) {
  285. if ((child.position.x + child.size.x <= object.position.x) ||
  286. (child.position.y + child.size.y <= object.position.y)) {
  287. if (getChildIndex(child) < getChildIndex(object)){
  288. if (getChildIndex(child) > 0){
  289. super.addChildAt(object, getChildIndex(child) - 1);
  290. }else{
  291. super.addChildAt(object, 0);
  292. }
  293. }
  294. }else
  295. if ((object.position.x + object.size.x < child.position.x) ||
  296. (object.position.y + object.size.y < child.position.y)) {
  297. if (getChildIndex(child) > getChildIndex(object)){
  298. super.addChildAt(object, getChildIndex(child));
  299. }
  300. }
  301. }
  302. }
  303. }
  304. protected function getPointDepthValue(obj : Point3D) : Number {
  305. //return obj.x + obj.y * 100000;
  306. return obj.y;
  307. }
  308. public function toXML() : XML {
  309. var xml:XML = new XML("<" + className + " />");
  310. xml.appendChild(perspective.toXML());
  311. var i:uint;
  312. for (i = 0; i < numChildren; i++ ) {
  313. if (getChildAt(i) is ISerializableXML) {
  314. xml.appendChild((getChildAt(i) as ISerializableXML).toXML());
  315. }
  316. }
  317. return xml;
  318. }
  319. public function fromXML(xml:XML, library:ILibrary = null) : void {
  320. perspective.fromXML(xml.child(perspective.className)[0], library);
  321. while (numChildren > 0){
  322. removeElement(getChildAt(0) as IsoObjectBase);
  323. }
  324. var i:uint;
  325. for (i = 0; i < xml.children().length(); i++){
  326. var childXML:XML = xml.children()[i];
  327. if (childXML.name() == "IsoTile"){
  328. var tile:IsoTile = new IsoTile();
  329. tile.fromXML(childXML, library);
  330. addElement(tile);
  331. }
  332. if (childXML.name() == "IsoObject"){
  333. var object:IsoObject = new IsoObject();
  334. object.fromXML(childXML, library);
  335. addElement(object);
  336. }
  337. }
  338. }
  339. }
  340. }