You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

839 lines
26 KiB

  1. define([
  2. 'js/resources',
  3. 'js/system/events',
  4. 'js/misc/physics',
  5. 'js/rendering/effects',
  6. 'js/rendering/tileOpacity',
  7. 'js/rendering/particles',
  8. 'js/rendering/shaders/outline',
  9. 'js/rendering/spritePool',
  10. 'picture'
  11. ], function(
  12. resources,
  13. events,
  14. physics,
  15. effects,
  16. tileOpacity,
  17. particles,
  18. shaderOutline,
  19. spritePool,
  20. picture
  21. ) {
  22. var scale = 40;
  23. var scaleMult = 5;
  24. var pixi = PIXI;
  25. return {
  26. stage: null,
  27. layers: {
  28. objects: null,
  29. mobs: null,
  30. characters: null,
  31. attacks: null,
  32. effects: null,
  33. particles: null,
  34. lightPatches: null,
  35. lightBeams: null,
  36. tileSprites: null,
  37. hiders: null
  38. },
  39. titleScreen: false,
  40. width: 0,
  41. height: 0,
  42. showTilesW: 0,
  43. showTilesH: 0,
  44. pos: {
  45. x: 0,
  46. y: 0
  47. },
  48. moveTo: null,
  49. moveSpeed: 0,
  50. moveSpeedMax: 1.50,
  51. moveSpeedInc: 0.5,
  52. lastUpdatePos: {
  53. x: 0,
  54. y: 0
  55. },
  56. zoneId: null,
  57. textures: {},
  58. textureCache: {},
  59. sprites: [],
  60. lastTick: null,
  61. hiddenRooms: null,
  62. init: function() {
  63. PIXI.GC_MODES.DEFAULT = PIXI.GC_MODES.AUTO;
  64. PIXI.SCALE_MODES.DEFAULT = PIXI.SCALE_MODES.NEAREST;
  65. events.on('onGetMap', this.onGetMap.bind(this));
  66. events.on('onDeath', this.onDeath.bind(this));
  67. events.on('onToggleFullscreen', this.toggleScreen.bind(this));
  68. this.width = $('body').width();
  69. this.height = $('body').height();
  70. this.showTilesW = Math.ceil((this.width / scale) / 2) + 3;
  71. this.showTilesH = Math.ceil((this.height / scale) / 2) + 3;
  72. this.renderer = pixi.autoDetectRenderer(this.width, this.height, {
  73. backgroundColor: '0x2d2136'
  74. });
  75. window.onresize = this.onResize.bind(this);
  76. $(this.renderer.view)
  77. .appendTo('.canvasContainer');
  78. this.stage = new pixi.Container();
  79. var layers = this.layers;
  80. Object.keys(layers).forEach(function(l) {
  81. if (l == 'tileSprites') {
  82. layers[l] = new pixi.Container();
  83. layers[l].layer = 'tiles';
  84. } else
  85. layers[l] = new pixi.Container();
  86. this.stage.addChild(layers[l])
  87. }, this);
  88. var spriteNames = ['tiles', 'mobs', 'bosses', 'bigObjects', 'objects', 'characters', 'attacks', 'auras', 'walls', 'ui', 'animChar', 'animMob', 'animBoss', 'white', 'ray'];
  89. resources.spriteNames.forEach(function(s) {
  90. if (s.indexOf('.png') > -1)
  91. spriteNames.push(s);
  92. });
  93. spriteNames.forEach(function(t) {
  94. this.textures[t] = new pixi.BaseTexture(resources.sprites[t].image);
  95. this.textures[t].scaleMode = pixi.SCALE_MODES.NEAREST;
  96. }, this);
  97. particles.init({
  98. r: this,
  99. renderer: this.renderer,
  100. stage: this.layers.particles
  101. });
  102. this.buildSpritesTexture();
  103. },
  104. buildSpritesTexture: function() {
  105. var container = new pixi.Container();
  106. var totalHeight = 0;
  107. ['tiles', 'walls', 'objects'].forEach(function(t) {
  108. var texture = this.textures[t];
  109. var tile = new pixi.Sprite(new pixi.Texture(texture));
  110. tile.width = texture.width;
  111. tile.height = texture.height;
  112. tile.x = 0;
  113. tile.y = totalHeight;
  114. container.addChild(tile);
  115. totalHeight += tile.height;
  116. }, this);
  117. var renderTexture = pixi.RenderTexture.create(this.textures.tiles.width, totalHeight);
  118. this.renderer.render(container, renderTexture);
  119. this.textures.sprites = renderTexture;
  120. this.textures.scaleMult = pixi.SCALE_MODES.NEAREST;
  121. },
  122. toggleScreen: function() {
  123. var screenMode = 0;
  124. var isFullscreen = (window.innerHeight == screen.height);
  125. if (isFullscreen)
  126. screenMode = 0;
  127. else
  128. screenMode = 1;
  129. if (screenMode == 0) {
  130. (document.cancelFullscreen || document.msCancelFullscreen || document.mozCancelFullscreen || document.webkitCancelFullScreen).call(document);
  131. return 'Windowed';
  132. } else if (screenMode == 1) {
  133. var el = $('body')[0];
  134. (el.requestFullscreen || el.msRequestFullscreen || el.mozRequestFullscreen || el.webkitRequestFullscreen).call(el);
  135. return 'Fullscreen';
  136. }
  137. },
  138. buildTitleScreen: function() {
  139. this.titleScreen = true;
  140. this.setPosition({
  141. x: 0,
  142. y: 0
  143. }, true);
  144. var w = Math.ceil(this.width / scale) + 1;
  145. var h = Math.ceil(this.height / scale) + 1;
  146. var container = this.layers.tileSprites;
  147. for (var i = 0; i < w; i++) {
  148. for (var j = 0; j < h; j++) {
  149. var ii = i / 10;
  150. var alpha = Math.sin(((j * 0.2) % 5) + Math.cos(ii % 8));
  151. var tile = 5;
  152. if (j < 7)
  153. tile = 5;
  154. //else if (j > 26)
  155. // tile = 3;
  156. else if (alpha < -0.2)
  157. tile = 3;
  158. else if (alpha < 0.2)
  159. tile = 4;
  160. else if ((alpha < 0.5) && (j > 7))
  161. tile = 53;
  162. alpha = Math.random();
  163. if (tile == 5)
  164. alpha *= 2;
  165. else if (tile == 3)
  166. alpha *= 1;
  167. else if (tile == 4)
  168. alpha *= 1;
  169. else if (tile == 53)
  170. alpha *= 2;
  171. alpha = Math.min(Math.max(0.1, alpha), 0.8);
  172. if (Math.random() < 0.35) {
  173. tile = {
  174. '5': 6,
  175. '3': 0,
  176. '4': 1,
  177. '53': 54
  178. }[tile];
  179. }
  180. var tile = new pixi.Sprite(this.getTexture('sprites', tile));
  181. tile.alpha = alpha;
  182. tile.position.x = i * scale;
  183. tile.position.y = j * scale;
  184. tile.width = scale;
  185. tile.height = scale;
  186. if (Math.random() < 0.5) {
  187. tile.position.x += scale;
  188. tile.scale.x = -scaleMult;
  189. }
  190. container.addChild(tile);
  191. }
  192. }
  193. },
  194. onDeath: function(pos) {
  195. this.setPosition({
  196. x: (pos.x - (this.width / (scale * 2))) * scale,
  197. y: (pos.y - (this.height / (scale * 2))) * scale
  198. }, true);
  199. },
  200. onResize: function() {
  201. var zoom = window.devicePixelRatio;
  202. this.width = $('body').width() * zoom;
  203. this.height = $('body').height() * zoom;
  204. this.showTilesW = Math.ceil((this.width / scale) / 2) + 3;
  205. this.showTilesH = Math.ceil((this.height / scale) / 2) + 3;
  206. this.renderer.resize(this.width, this.height);
  207. if (window.player) {
  208. this.setPosition({
  209. x: (window.player.x - (this.width / (scale * 2))) * scale,
  210. y: (window.player.y - (this.height / (scale * 2))) * scale
  211. }, true);
  212. }
  213. if (this.titleScreen) {
  214. this.clean();
  215. this.buildTitleScreen();
  216. }
  217. events.emit('onResize');
  218. },
  219. getTexture: function(baseTex, cell, size) {
  220. size = size || 8;
  221. var name = baseTex + '_' + cell;
  222. var textureCache = this.textureCache;
  223. var cached = textureCache[name];
  224. if (!cached) {
  225. var y = ~~(cell / 8);
  226. var x = cell - (y * 8);
  227. cached = new pixi.Texture(this.textures[baseTex], new pixi.Rectangle(x * size, y * size, size, size));
  228. textureCache[name] = cached;
  229. }
  230. return cached;
  231. },
  232. clean: function() {
  233. var container = this.layers.tileSprites;
  234. this.stage.removeChild(container);
  235. this.layers.tileSprites = container = new pixi.Container();
  236. container.layer = 'tiles';
  237. this.stage.addChild(container);
  238. this.stage.children.sort(function(a, b) {
  239. if (a.layer == 'tiles')
  240. return -1;
  241. else if (b.layer == 'tiles')
  242. return 1;
  243. else
  244. return 0;
  245. }, this);
  246. },
  247. onGetMapCustomization: function(msg) {
  248. if (!msg.collide) {
  249. var children = this.layers.tiles.children;
  250. var cLen = children.length;
  251. var x = msg.x * scale;
  252. var y = msg.y * scale;
  253. for (var i = cLen - 1; i >= 0; i--) {
  254. var c = children[i];
  255. var cx = c.x;
  256. if (c.scale.x < 0)
  257. cx -= scale;
  258. if ((cx == x) && (c.y == y)) {
  259. c.parent.removeChild(c);
  260. break;
  261. }
  262. }
  263. }
  264. var tile = new pixi.Sprite(this.getTexture('sprites', msg.tile))
  265. tile.alpha = tileOpacity.map(msg.tile);
  266. tile.position.x = msg.x * scale;
  267. tile.position.y = msg.y * scale;
  268. tile.width = scale;
  269. tile.height = scale;
  270. if (Math.random() < 0.5) {
  271. tile.position.x += scale;
  272. tile.scale.x = -scaleMult;
  273. }
  274. this.layers.tiles.addChild(tile);
  275. physics.collisionMap[msg.x][msg.y] = msg.collide;
  276. physics.graph.grid[msg.x][msg.y] = !msg.collide;
  277. },
  278. buildTile: function(c, i, j) {
  279. var alpha = tileOpacity.map(c);
  280. var canFlip = tileOpacity.canFlip(c);
  281. var tile = new pixi.Sprite(this.getTexture('sprites', c));
  282. tile.alpha = alpha;
  283. tile.position.x = i * scale;
  284. tile.position.y = j * scale;
  285. tile.width = scale;
  286. tile.height = scale;
  287. if (canFlip) {
  288. if (Math.random() < 0.5) {
  289. tile.position.x += scale;
  290. tile.scale.x = -scaleMult;
  291. }
  292. }
  293. return tile;
  294. },
  295. onGetMap: function(msg) {
  296. this.titleScreen = false;
  297. physics.init(msg.collisionMap);
  298. var map = this.map = msg.map;
  299. var w = this.w = map.length;
  300. var h = this.h = map[0].length;
  301. this.clean();
  302. spritePool.clean();
  303. this.stage.filters = [new PIXI.filters.VoidFilter()];
  304. this.stage.filterArea = new PIXI.Rectangle(0, 0, w * scale, h * scale);
  305. this.buildHiddenRooms(msg);
  306. this.sprites = _.get2dArray(w, h, 'array');
  307. this.stage.children.sort(function(a, b) {
  308. if (a.layer == 'tiles')
  309. return -1;
  310. else if (b.layer == 'tiles')
  311. return 1;
  312. else
  313. return 0;
  314. }, this);
  315. if (this.zoneId != null)
  316. events.emit('onRezone', this.zoneId);
  317. this.zoneId = msg.zoneId;
  318. msg.clientObjects.forEach(function(c) {
  319. c.zoneId = this.zoneId;
  320. events.emit('onGetObject', c);
  321. }, this);
  322. },
  323. buildHiddenRooms: function(msg) {
  324. var hiddenWalls = msg.hiddenWalls;
  325. var hiddenTiles = msg.hiddenTiles;
  326. this.hiddenRooms = msg.hiddenRooms;
  327. this.hiddenRooms.forEach(function(h) {
  328. h.container = new pixi.Container();
  329. this.layers.hiders.addChild(h.container);
  330. this.buildRectangle({
  331. x: h.x * scale,
  332. y: h.y * scale,
  333. w: h.width * scale,
  334. h: h.height * scale,
  335. color: 0x2d2136,
  336. parent: h.container
  337. });
  338. for (var i = h.x; i < h.x + h.width; i++) {
  339. for (var j = h.y; j < h.y + h.height; j++) {
  340. [hiddenTiles, hiddenWalls].forEach(function(k) {
  341. var cell = k[i][j];
  342. if (cell == 0)
  343. return;
  344. var tile = this.buildTile(cell - 1, i, j);
  345. tile.width = scale;
  346. tile.height = scale;
  347. h.container.addChild(tile);
  348. }, this);
  349. }
  350. }
  351. }, this);
  352. },
  353. hideHiders: function() {
  354. var player = window.player;
  355. if (!player)
  356. return;
  357. var x = player.x;
  358. var y = player.y;
  359. var hiddenRooms = this.hiddenRooms;
  360. var hLen = hiddenRooms.length;
  361. for (var i = 0; i < hLen; i++) {
  362. var h = hiddenRooms[i];
  363. h.container.visible = (
  364. (x < h.x) ||
  365. (x >= h.x + h.width) ||
  366. (y < h.y) ||
  367. (y >= h.y + h.height)
  368. );
  369. }
  370. },
  371. setPosition: function(pos, instant) {
  372. pos.x += 16;
  373. pos.y += 16;
  374. this.hideHiders();
  375. if (instant) {
  376. this.moveTo = null;
  377. this.pos = pos;
  378. this.stage.x = -~~this.pos.x;
  379. this.stage.y = -~~this.pos.y;
  380. } else
  381. this.moveTo = pos;
  382. this.updateSprites();
  383. },
  384. updateSprites: function() {
  385. var player = window.player;
  386. if (!player)
  387. return;
  388. var w = this.w;
  389. var h = this.h;
  390. var x = ~~((-this.stage.x / scale) + (this.width / (scale * 2)));
  391. var y = ~~((-this.stage.y / scale) + (this.height / (scale * 2)));
  392. this.lastUpdatePos.x = this.stage.x;
  393. this.lastUpdatePos.y = this.stage.y;
  394. var sprites = this.sprites;
  395. var map = this.map;
  396. var container = this.layers.tileSprites;
  397. var sw = this.showTilesW;
  398. var sh = this.showTilesH;
  399. var lowX = Math.max(0, x - sw) + 2;
  400. var lowY = Math.max(0, y - sh) + 2;
  401. var highX = Math.min(w - 1, x + sw) - 2;
  402. var highY = Math.min(h - 1, y + sh) - 2;
  403. var addedSprite = false;
  404. for (var i = lowX; i < highX; i++) {
  405. for (var j = lowY; j < highY; j++) {
  406. cell = map[i][j];
  407. if (!cell)
  408. continue;
  409. var rendered = sprites[i][j];
  410. if (rendered.length > 0)
  411. continue;
  412. else if (!cell.split)
  413. cell += '';
  414. cell = cell.split(',');
  415. for (var k = 0; k < cell.length; k++) {
  416. var c = cell[k];
  417. if (c == 0)
  418. continue;
  419. c--;
  420. var flipped = '';
  421. if (tileOpacity.canFlip(c)) {
  422. if (Math.random() < 0.5)
  423. flipped = 'flip';
  424. }
  425. var tile = spritePool.getSprite(flipped + c);
  426. if (!tile) {
  427. tile = this.buildTile(c, i, j);
  428. container.addChild(tile);
  429. tile.type = c;
  430. tile.sheetNum = tileOpacity.getSheetNum(c);
  431. addedSprite = true;
  432. } else {
  433. tile.position.x = i * scale;
  434. tile.position.y = j * scale;
  435. if (flipped != '')
  436. tile.position.x += scale;
  437. tile.visible = true;
  438. }
  439. rendered.push(tile);
  440. }
  441. }
  442. }
  443. lowX = Math.max(0, lowX - 10);
  444. lowY = Math.max(0, lowY - 10);
  445. highX = Math.min(w - 1, highX + 10);
  446. highY = Math.min(h - 1, highY + 10);
  447. for (var i = lowX; i < highX; i++) {
  448. var outside = ((i >= x - sw) && (i < x + sw));
  449. for (var j = lowY; j < highY; j++) {
  450. if ((outside) && (j >= y - sh) && (j < y + sh))
  451. continue;
  452. var list = sprites[i][j];
  453. var lLen = list.length;
  454. for (var k = 0; k < lLen; k++) {
  455. var sprite = list[k];
  456. sprite.visible = false;
  457. spritePool.store(sprite);
  458. }
  459. sprites[i][j] = [];
  460. }
  461. }
  462. //Reorder
  463. if (addedSprite) {
  464. container.children.sort(function(a, b) {
  465. return (a.sheetNum - b.sheetNum);
  466. });
  467. }
  468. },
  469. update: function() {
  470. var time = +new Date;
  471. if (this.moveTo) {
  472. var deltaX = this.moveTo.x - this.pos.x;
  473. var deltaY = this.moveTo.y - this.pos.y;
  474. if ((deltaX != 0) || (deltaY != 0)) {
  475. var moveSpeed = this.moveSpeed;
  476. var distance = Math.max(Math.abs(deltaX), Math.abs(deltaY));
  477. var moveSpeedMax = this.moveSpeedMax;
  478. if (distance > 100)
  479. moveSpeedMax *= 1.75;
  480. if (this.moveSpeed < moveSpeedMax)
  481. this.moveSpeed += this.moveSpeedInc;
  482. var elapsed = time - this.lastTick;
  483. moveSpeed *= (elapsed / 16.67);
  484. if (moveSpeed > distance)
  485. moveSpeed = distance;
  486. deltaX = (deltaX / distance) * moveSpeed;
  487. deltaY = (deltaY / distance) * moveSpeed;
  488. this.pos.x = this.pos.x + (deltaX);
  489. this.pos.y = this.pos.y + (deltaY);
  490. } else {
  491. this.moveSpeed = 0;
  492. this.moveTo = null;
  493. }
  494. var stage = this.stage;
  495. stage.x = -~~this.pos.x;
  496. stage.y = -~~this.pos.y;
  497. var halfScale = scale / 2;
  498. if ((Math.abs(stage.x - this.lastUpdatePos.x) > halfScale) || (Math.abs(stage.y - this.lastUpdatePos.y) > halfScale))
  499. this.updateSprites();
  500. events.emit('onSceneMove');
  501. }
  502. this.lastTick = time;
  503. },
  504. buildContainer: function(obj) {
  505. var container = new pixi.Container;
  506. this.layers[obj.layerName || obj.sheetName].addChild(container);
  507. return container;
  508. },
  509. buildRectangle: function(obj) {
  510. var graphics = new pixi.Graphics;
  511. var alpha = obj.alpha;
  512. if (alpha != null)
  513. graphics.alpha = alpha;
  514. var fillAlpha = obj.fillAlpha;
  515. if (fillAlpha == null)
  516. fillAlpha = 1;
  517. graphics.beginFill(obj.color || '0x48edff', fillAlpha);
  518. if (obj.strokeColor)
  519. graphics.lineStyle(scaleMult, obj.strokeColor);
  520. graphics.drawRect(0, 0, obj.w, obj.h);
  521. graphics.endFill();
  522. (obj.parent || this.layers[obj.layerName || obj.sheetName]).addChild(graphics);
  523. graphics.position.x = obj.x;
  524. graphics.position.y = obj.y;
  525. return graphics;
  526. },
  527. moveRectangle: function(obj) {
  528. obj.sprite.position.x = obj.x;
  529. obj.sprite.position.y = obj.y;
  530. obj.sprite.width = obj.w;
  531. obj.sprite.height = obj.h;
  532. return;
  533. var points = obj.sprite.graphicsData[0].shape.points;
  534. if (!points)
  535. return;
  536. graphics.clear();
  537. graphics.beginFill(obj.color || '0x48edff', fillAlpha);
  538. if (obj.strokeColor)
  539. graphics.lineStyle(scaleMult, obj.strokeColor);
  540. graphics.drawRect(0, 0, obj.w, obj.h);
  541. /*graphics.moveTo(obj.x, obj.y);
  542. graphics.lineTo(obj.x + obj.w, obj.y);
  543. graphics.lineTo(obj.x + obj.w, obj.y + obj.h);
  544. graphics.lineTo(obj.x, obj.y + obj.h);
  545. graphics.lineTo(obj.x, obj.y);*/
  546. graphics.endFill();
  547. graphics.position.x = obj.x;
  548. graphics.position.y = obj.y;
  549. /*obj.sprite.dirty = true;
  550. obj.sprite.clearDirty = true;
  551. points[0] = obj.x;
  552. points[1] = obj.y;
  553. points[2] = obj.x + obj.w;
  554. points[3] = obj.y;
  555. points[4] = obj.x + obj.w;
  556. points[5] = obj.y + obj.h;
  557. points[6] = obj.x;
  558. points[7] = obj.y + obj.h;
  559. points[8] = obj.x;
  560. points[9] = obj.y;*/
  561. },
  562. buildObject: function(obj) {
  563. var w = 8;
  564. var h = 8;
  565. if (obj.w) {
  566. w = obj.w / scaleMult;
  567. h = obj.h / scaleMult;
  568. }
  569. if (obj.sheetName == 'bosses') {
  570. obj.layerName = 'mobs';
  571. w = 24;
  572. h = 24;
  573. obj.w = w * scaleMult;
  574. obj.h = h * scaleMult;
  575. } else if (obj.sheetName == 'bigObjects') {
  576. obj.layerName = 'mobs';
  577. w = 24;
  578. h = 24;
  579. obj.w = w * scaleMult;
  580. obj.h = h * scaleMult;
  581. }
  582. var sprite = new pixi.Sprite(this.getTexture(obj.sheetName, obj.cell, w))
  583. sprite.x = obj.x * scale;
  584. sprite.y = obj.y * scale;
  585. sprite.width = obj.w || scale;
  586. sprite.height = obj.h || scale;
  587. if (obj.sheetName == 'bosses') {
  588. sprite.x -= scale;
  589. sprite.y -= (scale * 2);
  590. } else if (obj.sheetName == 'bigObjects') {
  591. sprite.x -= scale;
  592. sprite.y -= (scale * 2);
  593. sprite.alpha = 0.80;
  594. }
  595. if (obj.flipX) {
  596. sprite.scale.x *= -1;
  597. if ((obj.sheetName == 'bosses') || (obj.sheetName == 'bigObjects'))
  598. sprite.x += (scale * 2);
  599. else
  600. sprite.x += scale;
  601. }
  602. (this.layers[obj.layerName || obj.sheetName] || this.layers.objects).addChild(sprite);
  603. return sprite;
  604. },
  605. addFilter: function(sprite) {
  606. var thickness = 16;
  607. if (sprite.width > scale)
  608. thickness = 8;
  609. var filter = new shaderOutline(this.renderer.width, this.renderer.height, thickness, '0xffffff');
  610. if (!sprite.filters)
  611. sprite.filters = [filter];
  612. else
  613. sprite.filters.push();
  614. return filter;
  615. },
  616. removeFilter: function(sprite, filter) {
  617. if (!sprite.filters)
  618. return;
  619. sprite.filters = null;
  620. },
  621. buildText: function(obj) {
  622. var textSprite = new pixi.Text(obj.text, {
  623. fontFamily: 'bitty',
  624. fontSize: (obj.fontSize || 14),
  625. fill: obj.color || 0xF2F5F5,
  626. stroke: 0x2d2136,
  627. strokeThickness: 4,
  628. align: 'center'
  629. });
  630. textSprite.x = obj.x - (textSprite.width / 2);
  631. textSprite.y = obj.y;
  632. var parent = obj.parent || this.layers[obj.layerName]
  633. parent.addChild(textSprite);
  634. return textSprite;
  635. },
  636. buildEmitter: function(config) {
  637. return particles.buildEmitter(config);
  638. },
  639. destroyEmitter: function(emitter) {
  640. particles.destroyEmitter(emitter);
  641. },
  642. setSprite: function(obj) {
  643. var cell = obj.cell;
  644. var y = ~~(cell / 8);
  645. var x = cell - (y * 8);
  646. var baseTex = this.textures[obj.sheetName];
  647. obj.sprite.texture = this.getTexture(obj.sheetName, obj.cell, obj.sprite.width / scaleMult);
  648. },
  649. reorder: function(sprite) {
  650. var mobLayer = this.layers.mobs;
  651. var mobs = mobLayer.children;
  652. mobs.sort(function(a, b) {
  653. return (b.y - a.y);
  654. });
  655. },
  656. destroyObject: function(obj) {
  657. if (!obj.sprite.parent)
  658. return;
  659. obj.sprite.parent.removeChild(obj.sprite);
  660. },
  661. render: function() {
  662. if (!this.stage)
  663. return;
  664. effects.render();
  665. particles.update();
  666. this.renderer.render(this.stage);
  667. }
  668. };
  669. });