littlejsengine 1.18.24 → 1.18.26

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.
package/src/engineDraw.js CHANGED
@@ -1463,9 +1463,15 @@ class ImageFont
1463
1463
  tileInfo.pos.x = x*sizePaddedX + padding;
1464
1464
  tileInfo.pos.y = y*sizePaddedY + padding;
1465
1465
 
1466
- // draw the tile
1467
- drawPos.x = pos.x + i * size.x - centerOffset |0;
1468
- drawPos.y = pos.y + j * size.y |0;
1466
+ // snap the glyph edges to whole pixels
1467
+ // tiles are drawn from their center, so snapping the center
1468
+ // to a whole pixel puts the edges on half pixels when the
1469
+ // size is even, and a row or column of the glyph then has
1470
+ // no pixel center inside it and is not rasterized at all
1471
+ // ceil picks the nearest aligned position, breaking ties
1472
+ // downward to match how this used to truncate
1473
+ drawPos.x = ceil(pos.x + i * size.x - centerOffset - size.x/2) + size.x/2 - .5;
1474
+ drawPos.y = ceil(pos.y + j * size.y - size.y/2) + size.y/2 - .5;
1469
1475
  drawTile(drawPos, size, tileInfo, color, 0, false, undefined, useWebGL, true, context);
1470
1476
  }
1471
1477
  });
@@ -19,6 +19,7 @@ export
19
19
  getPaused,
20
20
  setPaused,
21
21
  engineInit,
22
+ engineStep,
22
23
  engineObjectsUpdate,
23
24
  engineObjectsDestroy,
24
25
  engineObjectsCollect,
@@ -66,6 +67,7 @@ export
66
67
  fontDefault,
67
68
  showSplashScreen,
68
69
  headlessMode,
70
+ engineManualStep,
69
71
  tileDefaultSize,
70
72
  tileDefaultPadding,
71
73
  tileDefaultBleed,
@@ -120,6 +122,7 @@ export
120
122
  setFontDefault,
121
123
  setShowSplashScreen,
122
124
  setHeadlessMode,
125
+ setEngineManualStep,
123
126
  setGLEnable,
124
127
  setTileDefaultSize,
125
128
  setTileDefaultPadding,
@@ -121,6 +121,13 @@ let showSplashScreen = false;
121
121
  * @memberof Settings */
122
122
  let headlessMode = false;
123
123
 
124
+ /** Disables the automatic requestAnimationFrame loop so the engine only
125
+ * advances when engineStep is called, for tests and frame-stepping tools
126
+ * @type {boolean}
127
+ * @default
128
+ * @memberof Settings */
129
+ let engineManualStep = false;
130
+
124
131
  ///////////////////////////////////////////////////////////////////////////////
125
132
  // WebGL settings
126
133
 
@@ -471,6 +478,12 @@ function setShowSplashScreen(show) { showSplashScreen = show; }
471
478
  * @memberof Settings */
472
479
  function setHeadlessMode(headless) { headlessMode = headless; }
473
480
 
481
+ /** Set if the engine only advances when engineStep is called
482
+ * Must be set before engineInit
483
+ * @param {boolean} [enable]
484
+ * @memberof Settings */
485
+ function setEngineManualStep(enable=true) { engineManualStep = enable; }
486
+
474
487
  /** Set if WebGL rendering is enabled
475
488
  * @param {boolean} enable
476
489
  * @memberof Settings */
@@ -190,12 +190,17 @@ function shareURL(title, url, callback)
190
190
 
191
191
  /** Read save data from local storage
192
192
  * @param {string} saveName - unique name for the game/save
193
- * @param {Object} [defaultSaveData] - default values for save
193
+ * @param {Object} [defaultSaveData] - default values, result is {...default, ...loaded} so this must be an object
194
194
  * @return {Object}
195
195
  * @memberof Utilities */
196
196
  function readSaveData(saveName, defaultSaveData)
197
197
  {
198
- ASSERT(isStringLike(saveName), 'loadData requires saveName string');
198
+ ASSERT(isStringLike(saveName), 'readSaveData requires saveName string');
199
+ ASSERT(defaultSaveData === undefined ||
200
+ (typeof defaultSaveData === 'object' && defaultSaveData !== null),
201
+ 'readSaveData: default must be an object - the result is ' +
202
+ '{...default, ...loaded}, so a scalar default yields {}. ' +
203
+ 'Use readSaveData(key, {best:0}).best');
199
204
 
200
205
  // tolerate localStorage being unavailable (iOS private mode, sandboxed
201
206
  // iframes) and corrupt JSON in stored data
@@ -219,7 +224,7 @@ function readSaveData(saveName, defaultSaveData)
219
224
  * @memberof Utilities */
220
225
  function writeSaveData(saveName, saveData)
221
226
  {
222
- ASSERT(isStringLike(saveName), 'saveData requires saveName string');
227
+ ASSERT(isStringLike(saveName), 'writeSaveData requires saveName string');
223
228
  // tolerate localStorage being unavailable or quota exceeded
224
229
  try { localStorage[saveName] = JSON.stringify(saveData); }
225
230
  catch { LOG('writeSaveData: failed to write', saveName); }