選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

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