littlejsengine 1.14.10 → 1.14.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -78,12 +78,12 @@ declare module "littlejsengine" {
78
78
  * @example
79
79
  * // Basic engine startup
80
80
  * engineInit(
81
- * () => { console.log('Game initialized!'); }, // gameInit
82
- * () => { updateGameLogic(); }, // gameUpdate
83
- * () => { updateUI(); }, // gameUpdatePost
84
- * () => { drawBackground(); }, // gameRender
85
- * () => { drawHUD(); }, // gameRenderPost
86
- * ['tiles.png', 'tilesLevel.png'] // images to load
81
+ * () => { LOG('Game initialized!'); }, // gameInit
82
+ * () => { updateGameLogic(); }, // gameUpdate
83
+ * () => { updateUI(); }, // gameUpdatePost
84
+ * () => { drawBackground(); }, // gameRender
85
+ * () => { drawHUD(); }, // gameRenderPost
86
+ * ['tiles.png', 'tilesLevel.png'] // images to load
87
87
  * );
88
88
  * @memberof Engine */
89
89
  export function engineInit(gameInit: Function | (() => Promise<any>), gameUpdate: Function, gameUpdatePost: Function, gameRender: Function, gameRenderPost: Function, imageSources?: Array<string>, rootElement?: HTMLElement): Promise<void>;
@@ -143,11 +143,15 @@ declare module "littlejsengine" {
143
143
  * @default
144
144
  * @memberof Debug */
145
145
  export let showWatermark: boolean;
146
- /** Asserts if the expression is false, does not do anything in release builds
146
+ /** Asserts if the expression is false, does nothing in release builds
147
147
  * @param {boolean} assert
148
148
  * @param {...Object} [output] - error message output
149
149
  * @memberof Debug */
150
150
  export function ASSERT(assert: boolean, ...output?: any[]): void;
151
+ /** Log to console if debug is enabled, does nothing in release builds
152
+ * @param {...Object} [output] - message output
153
+ * @memberof Debug */
154
+ export function LOG(...output?: any[]): void;
151
155
  /** Draw a debug rectangle in world space
152
156
  * @param {Vector2} pos
153
157
  * @param {Vector2} [size=Vector2()]
@@ -952,10 +956,7 @@ declare module "littlejsengine" {
952
956
  /** Returns the integer direction of this vector, corresponding to multiples of 90 degree rotation (0-3)
953
957
  * @return {number} */
954
958
  direction(): number;
955
- /** Returns a copy of this vector that has been inverted
956
- * @return {Vector2} */
957
- invert(): Vector2;
958
- /** Returns a copy of this vector absolute values
959
+ /** Returns a copy of this vector with absolute values
959
960
  * @return {Vector2} */
960
961
  abs(): Vector2;
961
962
  /** Returns a copy of this vector with each axis floored
@@ -33,7 +33,7 @@ const engineName = 'LittleJS';
33
33
  * @type {string}
34
34
  * @default
35
35
  * @memberof Engine */
36
- const engineVersion = '1.14.10';
36
+ const engineVersion = '1.14.11';
37
37
 
38
38
  /** Frames per second to update
39
39
  * @type {number}
@@ -122,12 +122,12 @@ function engineAddPlugin(updateFunction, renderFunction)
122
122
  * @example
123
123
  * // Basic engine startup
124
124
  * engineInit(
125
- * () => { console.log('Game initialized!'); }, // gameInit
126
- * () => { updateGameLogic(); }, // gameUpdate
127
- * () => { updateUI(); }, // gameUpdatePost
128
- * () => { drawBackground(); }, // gameRender
129
- * () => { drawHUD(); }, // gameRenderPost
130
- * ['tiles.png', 'tilesLevel.png'] // images to load
125
+ * () => { LOG('Game initialized!'); }, // gameInit
126
+ * () => { updateGameLogic(); }, // gameUpdate
127
+ * () => { updateUI(); }, // gameUpdatePost
128
+ * () => { drawBackground(); }, // gameRender
129
+ * () => { drawHUD(); }, // gameRenderPost
130
+ * ['tiles.png', 'tilesLevel.png'] // images to load
131
131
  * );
132
132
  * @memberof Engine */
133
133
  async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
@@ -173,16 +173,20 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
173
173
  if (!debugSpeedUp)
174
174
  frameTimeBufferMS = min(frameTimeBufferMS, 50); // clamp min framerate
175
175
 
176
+ let wasUpdated = false;
176
177
  if (paused)
177
178
  {
179
+ // update everything except the game and objects
180
+ wasUpdated = true;
178
181
  updateCanvas();
182
+ inputUpdate();
183
+ pluginUpdateList.forEach(f=>f());
179
184
 
180
185
  // update object transforms even when paused
181
186
  for (const o of engineObjects)
182
187
  o.parent || o.updateTransforms();
183
188
 
184
- inputUpdate();
185
- pluginUpdateList.forEach(f=>f());
189
+ // do post update
186
190
  debugUpdate();
187
191
  gameUpdatePost();
188
192
  inputUpdatePost();
@@ -199,12 +203,13 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
199
203
  }
200
204
 
201
205
  // update multiple frames if necessary in case of slow framerate
202
- for (;frameTimeBufferMS >= 0; frameTimeBufferMS -= 1e3 / frameRate)
206
+ for (; frameTimeBufferMS >= 0; frameTimeBufferMS -= 1e3 / frameRate)
203
207
  {
204
208
  // increment frame and update time
205
209
  time = frame++ / frameRate;
206
210
 
207
211
  // update game and objects
212
+ wasUpdated = true;
208
213
  updateCanvas();
209
214
  inputUpdate();
210
215
  gameUpdate();
@@ -215,7 +220,6 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
215
220
  debugUpdate();
216
221
  gameUpdatePost();
217
222
  inputUpdatePost();
218
-
219
223
  if (debugVideoCaptureIsActive())
220
224
  renderFrame();
221
225
  }
@@ -232,6 +236,10 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
232
236
  {
233
237
  if (headlessMode) return;
234
238
 
239
+ // canvas must be updated before rendering
240
+ if (!wasUpdated)
241
+ updateCanvas();
242
+
235
243
  // render sort then render while removing destroyed objects
236
244
  enginePreRender();
237
245
  gameRender();
@@ -391,7 +399,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
391
399
  promises.push(new Promise(resolve =>
392
400
  {
393
401
  let t = 0;
394
- console.log(`${engineName} Engine v${engineVersion}`);
402
+ LOG(`${engineName} Engine v${engineVersion}`);
395
403
  updateSplash();
396
404
  function updateSplash()
397
405
  {
@@ -688,12 +696,6 @@ function drawEngineSplashScreen(t)
688
696
  * @memberof Debug */
689
697
  const debug = true;
690
698
 
691
- /** True if asserts are enabled
692
- * @type {boolean}
693
- * @default
694
- * @memberof Debug */
695
- const enableAsserts = true;
696
-
697
699
  /** Size to render debug points by default
698
700
  * @type {number}
699
701
  * @default
@@ -724,15 +726,16 @@ let debugPrimitives = [], debugPhysics = false, debugRaycast = false, debugParti
724
726
  ///////////////////////////////////////////////////////////////////////////////
725
727
  // Debug helper functions
726
728
 
727
- /** Asserts if the expression is false, does not do anything in release builds
729
+ /** Asserts if the expression is false, does nothing in release builds
728
730
  * @param {boolean} assert
729
731
  * @param {...Object} [output] - error message output
730
732
  * @memberof Debug */
731
- function ASSERT(assert, ...output)
732
- {
733
- if (enableAsserts)
734
- console.assert(assert, ...output);
735
- }
733
+ function ASSERT(assert, ...output) { console.assert(assert, ...output); }
734
+
735
+ /** Log to console if debug is enabled, does nothing in release builds
736
+ * @param {...Object} [output] - message output
737
+ * @memberof Debug */
738
+ function LOG(...output) { console.log(...output); }
736
739
 
737
740
  /** Draw a debug rectangle in world space
738
741
  * @param {Vector2} pos
@@ -1226,7 +1229,7 @@ function debugVideoCaptureStart()
1226
1229
  }
1227
1230
 
1228
1231
  // start recording
1229
- console.log('Video capture started.');
1232
+ LOG('Video capture started.');
1230
1233
  debugVideoCapture.start();
1231
1234
  debugVideoCaptureTimer = new Timer(0);
1232
1235
 
@@ -1253,7 +1256,7 @@ function debugVideoCaptureStop()
1253
1256
  return; // not recording
1254
1257
 
1255
1258
  // stop recording
1256
- console.log(`Video capture ended. ${debugVideoCaptureTimer.get().toFixed(2)} seconds recorded.`);
1259
+ LOG(`Video capture ended. ${debugVideoCaptureTimer.get().toFixed(2)} seconds recorded.`);
1257
1260
  debugVideoCapture.stop();
1258
1261
  debugVideoCapture = 0;
1259
1262
  debugVideoCaptureIcon.style.display = 'none';
@@ -1487,7 +1490,12 @@ function wave(frequency=1, amplitude=1, t=time, offset=0)
1487
1490
  * @param {number} t - time in seconds
1488
1491
  * @return {string}
1489
1492
  * @memberof Utilities */
1490
- function formatTime(t) { return (t/60|0) + ':' + (t%60<10?'0':'') + (t%60|0); }
1493
+ function formatTime(t)
1494
+ {
1495
+ const sign = t < 0 ? '-' : '';
1496
+ t = abs(t)|0;
1497
+ return sign + (t/60|0) + ':' + (t%60<10?'0':'') + t%60;
1498
+ }
1491
1499
 
1492
1500
  /** Fetches a JSON file from a URL and returns the parsed JSON object. Must be used with await!
1493
1501
  * @param {string} url - URL of JSON file
@@ -1823,11 +1831,7 @@ class Vector2
1823
1831
  direction()
1824
1832
  { return abs(this.x) > abs(this.y) ? this.x < 0 ? 3 : 1 : this.y < 0 ? 2 : 0; }
1825
1833
 
1826
- /** Returns a copy of this vector that has been inverted
1827
- * @return {Vector2} */
1828
- invert() { return new Vector2(this.y, -this.x); }
1829
-
1830
- /** Returns a copy of this vector absolute values
1834
+ /** Returns a copy of this vector with absolute values
1831
1835
  * @return {Vector2} */
1832
1836
  abs() { return new Vector2(abs(this.x), abs(this.y)); }
1833
1837
 
@@ -1869,13 +1873,10 @@ class Vector2
1869
1873
  toString(digits=3)
1870
1874
  {
1871
1875
  ASSERT_NUMBER_VALID(digits);
1872
- if (debug)
1873
- {
1874
- if (this.isValid())
1875
- return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`;
1876
- else
1877
- return `(${this.x}, ${this.y})`;
1878
- }
1876
+ if (this.isValid())
1877
+ return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`;
1878
+ else
1879
+ return `(${this.x}, ${this.y})`;
1879
1880
  }
1880
1881
 
1881
1882
  /** Checks if this is a valid vector
@@ -2264,7 +2265,7 @@ class Timer
2264
2265
 
2265
2266
  /** Returns this timer expressed as a string
2266
2267
  * @return {string} */
2267
- toString() { if (debug) { return this.isSet() ? Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ) : 'unset'; }}
2268
+ toString() { return this.isSet() ? Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ) : 'unset'; }
2268
2269
 
2269
2270
  /** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
2270
2271
  * @return {number} */
@@ -5631,6 +5632,12 @@ function tileCollisionLoad(tileMapData, tileInfo=tile(), renderOrder=0, collisio
5631
5632
  const tileLayer = new TileCollisionLayer(vec2(), levelSize, tileInfo, layerRenderOrder);
5632
5633
  tileLayers[layerIndex] = tileLayer;
5633
5634
 
5635
+ // apply layer color
5636
+ const layerColor = dataLayer.color || WHITE;
5637
+ if (dataLayer.tintcolor)
5638
+ layerColor.setHex(dataLayer.tintcolor);
5639
+ ASSERT(isColor(layerColor), 'layer color is not a color');
5640
+
5634
5641
  for (let x=levelSize.x; x--;)
5635
5642
  for (let y=levelSize.y; y--;)
5636
5643
  {
@@ -5638,7 +5645,7 @@ function tileCollisionLoad(tileMapData, tileInfo=tile(), renderOrder=0, collisio
5638
5645
  const data = dataLayer.data[x + y*levelSize.x];
5639
5646
  if (data)
5640
5647
  {
5641
- const layerData = new TileLayerData(data-1);
5648
+ const layerData = new TileLayerData(data-1, 0, false, layerColor);
5642
5649
  tileLayer.setData(pos, layerData);
5643
5650
 
5644
5651
  // set collision for top layer
@@ -7532,7 +7539,7 @@ class NewgroundsPlugin
7532
7539
  // get medals
7533
7540
  const medalsResult = this.call('Medal.getList');
7534
7541
  this.medals = medalsResult ? medalsResult.result.data['medals'] : [];
7535
- debugMedals && console.log(this.medals);
7542
+ debugMedals && LOG(this.medals);
7536
7543
  for (const newgroundsMedal of this.medals)
7537
7544
  {
7538
7545
  const medal = medals[newgroundsMedal['id']];
@@ -7555,7 +7562,7 @@ class NewgroundsPlugin
7555
7562
  // get scoreboards
7556
7563
  const scoreboardResult = this.call('ScoreBoard.getBoards');
7557
7564
  this.scoreboards = scoreboardResult ? scoreboardResult.result.data.scoreboards : [];
7558
- debugMedals && console.log(this.scoreboards);
7565
+ debugMedals && LOG(this.scoreboards);
7559
7566
 
7560
7567
  // keep the session alive with a ping every minute
7561
7568
  const keepAliveMS = 60 * 1e3;
@@ -7624,10 +7631,10 @@ class NewgroundsPlugin
7624
7631
  try { xmlHttp.send(formData); }
7625
7632
  catch(e)
7626
7633
  {
7627
- debugMedals && console.log('newgrounds call failed', e);
7634
+ debugMedals && LOG('newgrounds call failed', e);
7628
7635
  return;
7629
7636
  }
7630
- debugMedals && console.log(xmlHttp.responseText);
7637
+ debugMedals && LOG(xmlHttp.responseText);
7631
7638
  return xmlHttp.responseText && JSON.parse(xmlHttp.responseText);
7632
7639
  }
7633
7640
  }
@@ -10224,7 +10231,7 @@ async function box2dInit()
10224
10231
  }
10225
10232
  function box2dRender()
10226
10233
  {
10227
- if (box2dDebug || debugPhysics && debugOverlay)
10234
+ if (box2dDebug || debugPhysics)
10228
10235
  box2d.world.DrawDebugData();
10229
10236
  }
10230
10237
 
@@ -10461,6 +10468,7 @@ export
10461
10468
 
10462
10469
  // Debug
10463
10470
  ASSERT,
10471
+ LOG,
10464
10472
  debugRect,
10465
10473
  debugPoly,
10466
10474
  debugCircle,