Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 

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