您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

923 行
21 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. 'js/system/globals',
  11. 'js/rendering/renderLoginBackground',
  12. 'js/rendering/helpers/resetRenderer',
  13. 'js/rendering/textures'
  14. ], function (
  15. resources,
  16. events,
  17. physics,
  18. effects,
  19. tileOpacity,
  20. particles,
  21. shaderOutline,
  22. spritePool,
  23. globals,
  24. renderLoginBackground,
  25. resetRenderer,
  26. textures
  27. ) {
  28. const mRandom = Math.random.bind(Math);
  29. const particleLayers = ['particlesUnder', 'particles'];
  30. const particleEngines = {};
  31. return {
  32. stage: null,
  33. layers: {
  34. particlesUnder: null,
  35. objects: null,
  36. mobs: null,
  37. characters: null,
  38. attacks: null,
  39. effects: null,
  40. particles: null,
  41. lightPatches: null,
  42. lightBeams: null,
  43. tileSprites: null,
  44. hiders: null
  45. },
  46. titleScreen: false,
  47. width: 0,
  48. height: 0,
  49. showTilesW: 0,
  50. showTilesH: 0,
  51. pos: {
  52. x: 0,
  53. y: 0
  54. },
  55. moveTo: null,
  56. moveSpeed: 0,
  57. moveSpeedMax: 1.50,
  58. moveSpeedInc: 0.5,
  59. lastUpdatePos: {
  60. x: 0,
  61. y: 0
  62. },
  63. zoneId: null,
  64. textures: {},
  65. textureCache: {},
  66. sprites: [],
  67. lastTick: null,
  68. hiddenRooms: null,
  69. init: function () {
  70. PIXI.settings.GC_MODE = PIXI.GC_MODES.AUTO;
  71. PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
  72. PIXI.settings.SPRITE_MAX_TEXTURES = Math.min(PIXI.settings.SPRITE_MAX_TEXTURES, 16);
  73. PIXI.settings.RESOLUTION = 1;
  74. events.on('onToggleFullscreen', this.toggleScreen.bind(this));
  75. events.on('onMoveSpeedChange', this.adaptCameraMoveSpeed.bind(this));
  76. events.on('resetRenderer', resetRenderer.bind(this));
  77. this.width = $('body').width();
  78. this.height = $('body').height();
  79. this.showTilesW = Math.ceil((this.width / scale) / 2) + 3;
  80. this.showTilesH = Math.ceil((this.height / scale) / 2) + 3;
  81. this.renderer = new PIXI.Renderer({
  82. width: this.width,
  83. height: this.height,
  84. backgroundColor: '0x2d2136'
  85. });
  86. window.addEventListener('resize', this.onResize.bind(this));
  87. $(this.renderer.view).appendTo('.canvas-container');
  88. this.stage = new PIXI.Container();
  89. let layers = this.layers;
  90. Object.keys(layers).forEach(l => {
  91. layers[l] = new PIXI.Container();
  92. layers[l].layer = (l === 'tileSprites') ? 'tiles' : l;
  93. this.stage.addChild(layers[l]);
  94. });
  95. const textureList = globals.clientConfig.textureList;
  96. const sprites = resources.sprites;
  97. textureList.forEach(t => {
  98. this.textures[t] = new PIXI.BaseTexture(sprites[t]);
  99. this.textures[t].scaleMode = PIXI.SCALE_MODES.NEAREST;
  100. this.textures[t].size = this.textures[t].width / 8;
  101. });
  102. particleLayers.forEach(p => {
  103. const engine = $.extend({}, particles);
  104. engine.init({
  105. r: this,
  106. renderer: this.renderer,
  107. stage: this.layers[p]
  108. });
  109. particleEngines[p] = engine;
  110. });
  111. },
  112. toggleScreen: function () {
  113. let isFullscreen = (window.innerHeight === screen.height);
  114. if (isFullscreen) {
  115. let doc = document;
  116. (doc.cancelFullscreen || doc.msCancelFullscreen || doc.mozCancelFullscreen || doc.webkitCancelFullScreen).call(doc);
  117. return 'Windowed';
  118. }
  119. let el = $('body')[0];
  120. (el.requestFullscreen || el.msRequestFullscreen || el.mozRequestFullscreen || el.webkitRequestFullscreen).call(el);
  121. return 'Fullscreen';
  122. },
  123. buildTitleScreen: function () {
  124. this.titleScreen = true;
  125. renderLoginBackground(this);
  126. },
  127. onResize: function () {
  128. if (isMobile)
  129. return;
  130. this.width = $('body').width();
  131. this.height = $('body').height();
  132. this.showTilesW = Math.ceil((this.width / scale) / 2) + 3;
  133. this.showTilesH = Math.ceil((this.height / scale) / 2) + 3;
  134. this.renderer.resize(this.width, this.height);
  135. if (window.player) {
  136. this.setPosition({
  137. x: (window.player.x - (this.width / (scale * 2))) * scale,
  138. y: (window.player.y - (this.height / (scale * 2))) * scale
  139. }, true);
  140. }
  141. if (this.titleScreen) {
  142. this.clean();
  143. this.buildTitleScreen();
  144. }
  145. events.emit('onResize');
  146. },
  147. getTexture: function (baseTex, cell) {
  148. try {
  149. let textureName = baseTex + '_' + cell;
  150. let textureCache = this.textureCache;
  151. let cached = textureCache[textureName];
  152. if (!cached) {
  153. let y = ~~(cell / 8);
  154. let x = cell - (y * 8);
  155. const texture = this.textures[baseTex];
  156. const size = texture.size;
  157. cached = new PIXI.Texture(texture, new PIXI.Rectangle(x * size, y * size, size, size));
  158. textureCache[textureName] = cached;
  159. }
  160. return cached;
  161. } catch (e) {
  162. console.log(e, baseTex, cell);
  163. }
  164. },
  165. clean: function () {
  166. this.stage.removeChild(this.layers.hiders);
  167. this.layers.hiders = new PIXI.Container();
  168. this.layers.hiders.layer = 'hiders';
  169. this.stage.addChild(this.layers.hiders);
  170. let container = this.layers.tileSprites;
  171. this.stage.removeChild(container);
  172. this.layers.tileSprites = container = new PIXI.ParticleContainer(30000);
  173. container.layer = 'tiles';
  174. this.stage.addChild(container);
  175. this.stage.children.sort((a, b) => {
  176. if (a.layer === 'hiders')
  177. return 1;
  178. else if (b.layer === 'hiders')
  179. return -1;
  180. else if (a.layer === 'tiles')
  181. return -1;
  182. else if (b.layer === 'tiles')
  183. return 1;
  184. return 0;
  185. });
  186. this.textureCache = {};
  187. },
  188. buildTile: function (c, i, j) {
  189. let alpha = tileOpacity.map(c);
  190. let canFlip = tileOpacity.canFlip(c);
  191. let tile = new PIXI.Sprite(this.getTexture('sprites', c));
  192. tile.alpha = alpha;
  193. tile.position.x = i * scale;
  194. tile.position.y = j * scale;
  195. tile.width = scale;
  196. tile.height = scale;
  197. if (canFlip && mRandom() < 0.5) {
  198. tile.position.x += scale;
  199. tile.scale.x = -scaleMult;
  200. }
  201. return tile;
  202. },
  203. onGetMap: async function (msg) {
  204. tileOpacity.initMap(msg);
  205. //Load sprite atlas
  206. let spriteAtlas = null;
  207. await new Promise(res => {
  208. spriteAtlas = new Image();
  209. spriteAtlas.onload = res;
  210. spriteAtlas.src = msg.spriteAtlasPath;
  211. });
  212. //Build sprite texture
  213. this.textures.sprites = new PIXI.BaseTexture(spriteAtlas);
  214. this.textures.sprites.scaleMode = PIXI.SCALE_MODES.NEAREST;
  215. this.textures.sprites.size = 8;
  216. //Misc
  217. this.titleScreen = false;
  218. physics.init(msg.collisionMap);
  219. let map = this.map = msg.map;
  220. let w = this.w = map.length;
  221. let h = this.h = map[0].length;
  222. for (let i = 0; i < w; i++) {
  223. let row = map[i];
  224. for (let j = 0; j < h; j++) {
  225. if (!row[j].split)
  226. row[j] += '';
  227. row[j] = row[j].split(',');
  228. }
  229. }
  230. this.clean();
  231. spritePool.clean();
  232. this.stage.filters = [new PIXI.filters.AlphaFilter()];
  233. this.stage.filterArea = new PIXI.Rectangle(0, 0, Math.max(w * scale, this.width), Math.max(h * scale, this.height));
  234. this.hiddenRooms = msg.hiddenRooms;
  235. this.sprites = _.get2dArray(w, h, 'array');
  236. this.stage.children.sort((a, b) => {
  237. if (a.layer === 'tiles')
  238. return -1;
  239. else if (b.layer === 'tiles')
  240. return 1;
  241. return 0;
  242. });
  243. if (this.zoneId !== null)
  244. events.emit('onRezone', this.zoneId);
  245. this.zoneId = msg.zoneId;
  246. msg.clientObjects.forEach(c => {
  247. c.zoneId = this.zoneId;
  248. events.emit('onGetObject', c);
  249. });
  250. },
  251. setPosition: function (pos, instant) {
  252. pos.x += 16;
  253. pos.y += 16;
  254. let player = window.player;
  255. if (player) {
  256. let px = player.x;
  257. let py = player.y;
  258. let hiddenRooms = this.hiddenRooms || [];
  259. let hLen = hiddenRooms.length;
  260. for (let i = 0; i < hLen; i++) {
  261. let h = hiddenRooms[i];
  262. if (!h.discoverable)
  263. continue;
  264. if (
  265. px < h.x ||
  266. px >= h.x + h.width ||
  267. py < h.y ||
  268. py >= h.y + h.height ||
  269. !physics.isInPolygon(px, py, h.area)
  270. )
  271. continue;
  272. h.discovered = true;
  273. }
  274. }
  275. if (instant) {
  276. this.moveTo = null;
  277. this.pos = pos;
  278. this.stage.x = -~~this.pos.x;
  279. this.stage.y = -~~this.pos.y;
  280. } else
  281. this.moveTo = pos;
  282. this.updateSprites();
  283. },
  284. isVisible: function (x, y) {
  285. let stage = this.stage;
  286. let sx = -stage.x;
  287. let sy = -stage.y;
  288. let sw = this.width;
  289. let sh = this.height;
  290. return (!(x < sx || y < sy || x >= sx + sw || y >= sy + sh));
  291. },
  292. isHidden: function (x, y) {
  293. let hiddenRooms = this.hiddenRooms;
  294. let hLen = hiddenRooms.length;
  295. if (!hLen)
  296. return false;
  297. const { player: { x: px, y: py } } = window;
  298. let foundVisibleLayer = null;
  299. let foundHiddenLayer = null;
  300. hiddenRooms.forEach(h => {
  301. const { discovered, layer, interior } = h;
  302. const { x: hx, y: hy, width, height, area } = h;
  303. //Is the tile outside the hider
  304. if (
  305. x < hx ||
  306. x >= hx + width ||
  307. y < hy ||
  308. y >= hy + height
  309. ) {
  310. //If the hider is an interior, the tile should be hidden if the player is inside the hider
  311. if (interior) {
  312. if (physics.isInPolygon(px, py, area))
  313. foundHiddenLayer = layer;
  314. }
  315. return;
  316. }
  317. //Is the tile inside the hider
  318. if (!physics.isInPolygon(x, y, area))
  319. return;
  320. if (discovered) {
  321. foundVisibleLayer = layer;
  322. return;
  323. }
  324. //Is the player outside the hider
  325. if (
  326. px < hx ||
  327. px >= hx + width ||
  328. py < hy ||
  329. py >= hy + height
  330. ) {
  331. foundHiddenLayer = layer;
  332. return;
  333. }
  334. //Is the player inside the hider
  335. if (!physics.isInPolygon(px, py, area)) {
  336. foundHiddenLayer = layer;
  337. return;
  338. }
  339. foundVisibleLayer = layer;
  340. });
  341. //We compare hider layers to cater for hiders inside hiders
  342. return (foundHiddenLayer > foundVisibleLayer) || (foundHiddenLayer === 0 && foundVisibleLayer === null);
  343. },
  344. updateSprites: function () {
  345. if (this.titleScreen)
  346. return;
  347. const player = window.player;
  348. if (!player)
  349. return;
  350. const { w, h, width, height, stage, map, sprites } = this;
  351. const x = ~~((-stage.x / scale) + (width / (scale * 2)));
  352. const y = ~~((-stage.y / scale) + (height / (scale * 2)));
  353. this.lastUpdatePos.x = stage.x;
  354. this.lastUpdatePos.y = stage.y;
  355. const container = this.layers.tileSprites;
  356. const sw = this.showTilesW;
  357. const sh = this.showTilesH;
  358. let lowX = Math.max(0, x - sw + 1);
  359. let lowY = Math.max(0, y - sh + 2);
  360. let highX = Math.min(w, x + sw - 2);
  361. let highY = Math.min(h, y + sh - 2);
  362. let addedSprite = false;
  363. const checkHidden = this.isHidden.bind(this);
  364. const buildTile = this.buildTile.bind(this);
  365. const newVisible = [];
  366. const newHidden = [];
  367. for (let i = lowX; i < highX; i++) {
  368. let mapRow = map[i];
  369. let spriteRow = sprites[i];
  370. for (let j = lowY; j < highY; j++) {
  371. const cell = mapRow[j];
  372. if (!cell)
  373. continue;
  374. const cLen = cell.length;
  375. if (!cLen)
  376. return;
  377. const rendered = spriteRow[j];
  378. const isHidden = checkHidden(i, j);
  379. if (isHidden) {
  380. const nonFakeRendered = rendered.filter(r => !r.isFake);
  381. const rLen = nonFakeRendered.length;
  382. for (let k = 0; k < rLen; k++) {
  383. const sprite = nonFakeRendered[k];
  384. sprite.visible = false;
  385. spritePool.store(sprite);
  386. rendered.spliceWhere(s => s === sprite);
  387. }
  388. if (cell.visible) {
  389. cell.visible = false;
  390. newHidden.push({
  391. x: i,
  392. y: j
  393. });
  394. }
  395. const hasFake = cell.some(c => c[0] === '-');
  396. if (hasFake) {
  397. const isFakeRendered = rendered.some(r => r.isFake);
  398. if (isFakeRendered)
  399. continue;
  400. } else
  401. continue;
  402. } else {
  403. const fakeRendered = rendered.filter(r => r.isFake);
  404. const rLen = fakeRendered.length;
  405. for (let k = 0; k < rLen; k++) {
  406. const sprite = fakeRendered[k];
  407. sprite.visible = false;
  408. spritePool.store(sprite);
  409. rendered.spliceWhere(s => s === sprite);
  410. }
  411. if (!cell.visible) {
  412. cell.visible = true;
  413. newVisible.push({
  414. x: i,
  415. y: j
  416. });
  417. }
  418. const hasNonFake = cell.some(c => c[0] !== '-');
  419. if (hasNonFake) {
  420. const isNonFakeRendered = rendered.some(r => !r.isFake);
  421. if (isNonFakeRendered)
  422. continue;
  423. } else
  424. continue;
  425. }
  426. for (let k = 0; k < cLen; k++) {
  427. let c = cell[k];
  428. if (c === '0' || c === '')
  429. continue;
  430. const isFake = +c < 0;
  431. if (isFake && !isHidden)
  432. continue;
  433. else if (!isFake && isHidden)
  434. continue;
  435. if (isFake)
  436. c = -c;
  437. c--;
  438. let flipped = '';
  439. if (tileOpacity.canFlip(c)) {
  440. if (mRandom() < 0.5)
  441. flipped = 'flip';
  442. }
  443. let tile = spritePool.getSprite(flipped + c);
  444. if (!tile) {
  445. tile = buildTile(c, i, j);
  446. container.addChild(tile);
  447. tile.type = c;
  448. tile.sheetNum = tileOpacity.getSheetNum(c);
  449. addedSprite = true;
  450. } else {
  451. tile.position.x = i * scale;
  452. tile.position.y = j * scale;
  453. if (flipped !== '')
  454. tile.position.x += scale;
  455. tile.visible = true;
  456. }
  457. if (isFake)
  458. tile.isFake = isFake;
  459. tile.z = k;
  460. rendered.push(tile);
  461. }
  462. }
  463. }
  464. lowX = Math.max(0, lowX - 10);
  465. lowY = Math.max(0, lowY - 10);
  466. highX = Math.min(w - 1, highX + 10);
  467. highY = Math.min(h - 1, highY + 10);
  468. for (let i = lowX; i < highX; i++) {
  469. const mapRow = map[i];
  470. let spriteRow = sprites[i];
  471. let outside = ((i >= x - sw) && (i < x + sw));
  472. for (let j = lowY; j < highY; j++) {
  473. if ((outside) && (j >= y - sh) && (j < y + sh))
  474. continue;
  475. const cell = mapRow[j];
  476. if (cell.visible) {
  477. cell.visible = false;
  478. newHidden.push({ x: i, y: j });
  479. }
  480. let list = spriteRow[j];
  481. let lLen = list.length;
  482. for (let k = 0; k < lLen; k++) {
  483. let sprite = list[k];
  484. sprite.visible = false;
  485. spritePool.store(sprite);
  486. }
  487. spriteRow[j] = [];
  488. }
  489. }
  490. events.emit('onTilesVisible', newVisible, true);
  491. events.emit('onTilesVisible', newHidden, false);
  492. if (addedSprite)
  493. container.children.sort((a, b) => a.z - b.z);
  494. },
  495. update: function () {
  496. let time = +new Date();
  497. if (this.moveTo) {
  498. let deltaX = this.moveTo.x - this.pos.x;
  499. let deltaY = this.moveTo.y - this.pos.y;
  500. if (deltaX !== 0 || deltaY !== 0) {
  501. let distance = Math.max(Math.abs(deltaX), Math.abs(deltaY));
  502. let moveSpeedMax = this.moveSpeedMax;
  503. if (this.moveSpeed < moveSpeedMax)
  504. this.moveSpeed += this.moveSpeedInc;
  505. let moveSpeed = this.moveSpeed;
  506. if (moveSpeedMax < 1.6)
  507. moveSpeed *= 1 + (distance / 200);
  508. let elapsed = time - this.lastTick;
  509. moveSpeed *= (elapsed / 15);
  510. if (moveSpeed > distance)
  511. moveSpeed = distance;
  512. deltaX = (deltaX / distance) * moveSpeed;
  513. deltaY = (deltaY / distance) * moveSpeed;
  514. this.pos.x = this.pos.x + deltaX;
  515. this.pos.y = this.pos.y + deltaY;
  516. } else {
  517. this.moveSpeed = 0;
  518. this.moveTo = null;
  519. }
  520. let stage = this.stage;
  521. if (window.staticCamera !== true) {
  522. stage.x = -~~this.pos.x;
  523. stage.y = -~~this.pos.y;
  524. }
  525. let halfScale = scale / 2;
  526. if (Math.abs(stage.x - this.lastUpdatePos.x) > halfScale || Math.abs(stage.y - this.lastUpdatePos.y) > halfScale)
  527. this.updateSprites();
  528. events.emit('onSceneMove');
  529. }
  530. this.lastTick = time;
  531. },
  532. buildContainer: function (obj) {
  533. let container = new PIXI.Container();
  534. this.layers[obj.layerName || obj.sheetName].addChild(container);
  535. return container;
  536. },
  537. buildRectangle: function (obj) {
  538. let graphics = new PIXI.Graphics();
  539. let alpha = obj.alpha;
  540. if (obj.has('alpha'))
  541. graphics.alpha = alpha;
  542. let fillAlpha = obj.fillAlpha;
  543. if (obj.has('fillAlpha'))
  544. fillAlpha = 1;
  545. graphics.beginFill(obj.color || '0x48edff', fillAlpha);
  546. if (obj.strokeColor)
  547. graphics.lineStyle(scaleMult, obj.strokeColor);
  548. graphics.drawRect(0, 0, obj.w, obj.h);
  549. graphics.endFill();
  550. (obj.parent || this.layers[obj.layerName || obj.sheetName]).addChild(graphics);
  551. graphics.position.x = obj.x;
  552. graphics.position.y = obj.y;
  553. return graphics;
  554. },
  555. moveRectangle: function (obj) {
  556. obj.sprite.position.x = obj.x;
  557. obj.sprite.position.y = obj.y;
  558. obj.sprite.width = obj.w;
  559. obj.sprite.height = obj.h;
  560. },
  561. buildObject: function (obj) {
  562. const { sheetName, parent: container, layerName, visible = true } = obj;
  563. const sprite = new PIXI.Sprite();
  564. obj.sprite = sprite;
  565. this.setSprite(obj);
  566. sprite.visible = visible;
  567. const spriteContainer = container || this.layers[layerName || sheetName] || this.layers.objects;
  568. spriteContainer.addChild(sprite);
  569. obj.w = sprite.width;
  570. obj.h = sprite.height;
  571. return sprite;
  572. },
  573. addFilter: function (sprite) {
  574. let thickness = (sprite.width > scale) ? 8 : 16;
  575. let filter = new shaderOutline(this.renderer.width, this.renderer.height, thickness, '0xffffff');
  576. if (!sprite.filters)
  577. sprite.filters = [filter];
  578. else
  579. sprite.filters.push();
  580. return filter;
  581. },
  582. removeFilter: function (sprite, filter) {
  583. if (sprite.filters)
  584. sprite.filters = null;
  585. },
  586. buildText: function (obj) {
  587. let textSprite = new PIXI.Text(obj.text, {
  588. fontFamily: 'bitty',
  589. fontSize: (obj.fontSize || 14),
  590. fill: obj.color || 0xF2F5F5,
  591. stroke: 0x2d2136,
  592. strokeThickness: 4,
  593. align: 'center'
  594. });
  595. textSprite.x = obj.x - (textSprite.width / 2);
  596. textSprite.y = obj.y;
  597. let parentSprite = obj.parent || this.layers[obj.layerName];
  598. parentSprite.addChild(textSprite);
  599. return textSprite;
  600. },
  601. buildEmitter: function (config) {
  602. const { layerName = 'particles' } = config;
  603. const particleEngine = particleEngines[layerName];
  604. return particleEngine.buildEmitter(config);
  605. },
  606. destroyEmitter: function (emitter) {
  607. const particleEngine = emitter.particleEngine;
  608. particleEngine.destroyEmitter(emitter);
  609. },
  610. loadTexture: async function (textureName, texturePath) {
  611. texturePath = texturePath ?? textureName;
  612. if (!texturePath.includes('.png'))
  613. texturePath = `images/${texturePath}.png`;
  614. const image = await textures.getLoader(texturePath);
  615. //Build sprite texture
  616. this.textures[textureName] = new PIXI.BaseTexture(image);
  617. this.textures[textureName].scaleMode = PIXI.SCALE_MODES.NEAREST;
  618. this.textures[textureName].size = this.textures[textureName].width / 8;
  619. },
  620. setSprite: async function (obj) {
  621. const { sprite, sheetName, cell } = obj;
  622. const textureExists = this.textures.hasOwnProperty(sheetName);
  623. if (!textureExists)
  624. await this.loadTexture(sheetName);
  625. sprite.texture = this.getTexture(sheetName, cell);
  626. const newSize = sprite.texture.width;
  627. obj.w = newSize * scaleMult;
  628. obj.h = obj.w;
  629. sprite.width = obj.w;
  630. sprite.height = obj.h;
  631. if (newSize !== sprite.size) {
  632. sprite.size = newSize;
  633. this.setSpritePosition(obj);
  634. }
  635. },
  636. setSpritePosition: function (obj) {
  637. const { sprite, x, y, flipX, offsetX = 0, offsetY = 0 } = obj;
  638. sprite.x = (x * scale) + (flipX ? scale : 0) + offsetX;
  639. const oldY = sprite.y;
  640. sprite.y = (y * scale) + offsetY;
  641. if (sprite.width > scale) {
  642. if (flipX)
  643. sprite.x += scale;
  644. else
  645. sprite.x -= scale;
  646. sprite.y -= (scale * 2);
  647. }
  648. if (oldY !== sprite.y)
  649. this.reorder();
  650. sprite.scale.x = flipX ? -scaleMult : scaleMult;
  651. },
  652. reorder: function () {
  653. this.layers.mobs.children.sort((a, b) => b.y - a.y);
  654. },
  655. destroyObject: function (obj) {
  656. if (obj.sprite.parent)
  657. obj.sprite.parent.removeChild(obj.sprite);
  658. },
  659. //Changes the moveSpeedMax and moveSpeedInc variables
  660. // moveSpeed changes when mounting and unmounting
  661. // moveSpeed: 0 | moveSpeedMax: 1.5 | moveSpeedInc: 0.5
  662. // moveSpeed: 200 | moveSpeedMax: 5.5 | moveSpeedInc: 0.2
  663. // Between these values we should follow an exponential curve for moveSpeedInc since
  664. // a higher chance will proc more often, meaning the buildup in distance becomes greater
  665. adaptCameraMoveSpeed: function (moveSpeed) {
  666. const factor = Math.sqrt(moveSpeed);
  667. const maxValue = Math.sqrt(200);
  668. this.moveSpeedMax = 1.5 + ((moveSpeed / 200) * 3.5);
  669. this.moveSpeedInc = 0.2 + (((maxValue - factor) / maxValue) * 0.3);
  670. },
  671. updateMapAtPosition: function (x, y, mapCellString) {
  672. const { map, sprites, layers: { tileSprites: container } } = this;
  673. const row = sprites[x];
  674. if (!row)
  675. return;
  676. const cell = row[y];
  677. if (!cell)
  678. return;
  679. cell.forEach(c => {
  680. c.visible = false;
  681. spritePool.store(c);
  682. });
  683. cell.length = 0;
  684. map[x][y] = mapCellString.split(',');
  685. map[x][y].forEach(m => {
  686. m--;
  687. let tile = spritePool.getSprite(m);
  688. if (!tile) {
  689. tile = this.buildTile(m, x, y);
  690. container.addChild(tile);
  691. tile.type = m;
  692. tile.sheetNum = tileOpacity.getSheetNum(m);
  693. } else {
  694. tile.position.x = x * scale;
  695. tile.position.y = y * scale;
  696. tile.visible = true;
  697. }
  698. cell.push(tile);
  699. cell.visible = true;
  700. });
  701. },
  702. render: function () {
  703. if (!this.stage)
  704. return;
  705. effects.render();
  706. particleLayers.forEach(p => particleEngines[p].update());
  707. this.renderer.render(this.stage);
  708. }
  709. };
  710. });