littlejsengine 1.20.0 → 1.21.0
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/dist/littlejs.d.ts +408 -26
- package/dist/littlejs.esm.js +3360 -161
- package/dist/littlejs.esm.min.js +3 -3
- package/dist/littlejs.js +3344 -161
- package/dist/littlejs.min.js +2 -2
- package/dist/littlejs.release.js +1448 -141
- package/package.json +1 -1
- package/plugins/gltf.js +54 -8
- package/plugins/math3d.js +90 -10
- package/plugins/pluginExport.js +10 -0
- package/plugins/postProcess.js +41 -12
- package/plugins/render3d.js +424 -55
- package/plugins/render3dDebug.js +2 -1
- package/plugins/render3dEditor.js +1812 -0
- package/plugins/render3dExtras.js +199 -5
- package/plugins/render3dLevel.js +189 -0
- package/plugins/render3dVoxels.js +12 -0
- package/plugins/sceneSystem.js +58 -0
- package/plugins/tweenSystem.js +4 -2
- package/src/engine.js +199 -34
- package/src/engineAudio.js +2 -2
- package/src/engineBuild.mjs +3 -0
- package/src/engineDebug.js +55 -1
- package/src/engineDraw.js +97 -6
- package/src/engineEditor.js +41 -20
- package/src/engineExport.js +6 -0
- package/src/engineInput.js +8 -4
- package/src/engineLogo.js +19 -0
- package/src/engineObject.js +3 -2
- package/src/engineRelease.js +13 -1
- package/src/engineSettings.js +38 -0
package/src/engineEditor.js
CHANGED
|
@@ -57,6 +57,14 @@ class LevelEditor
|
|
|
57
57
|
* section has Play from mouse, which starts play there, Escape at the mouse and Play at the view center
|
|
58
58
|
* @type {EditorPlayFromCallback|undefined} */
|
|
59
59
|
this.onPlayFrom = undefined;
|
|
60
|
+
/** @property {Array<number>|undefined} - The tiles the palette shows, in its order, for a sheet that also holds
|
|
61
|
+
* sprites and art that are not level tiles; undefined shows every tile of the sheet
|
|
62
|
+
* @type {Array<number>|undefined} */
|
|
63
|
+
this.paletteTiles = undefined;
|
|
64
|
+
/** @property {boolean|undefined} - Which level editor opens: true the 3D one, false the 2D one, undefined the
|
|
65
|
+
* 3D one when a level was loaded with level3DLoad and there is a Render3DPlugin
|
|
66
|
+
* @type {boolean|undefined} */
|
|
67
|
+
this.use3D = undefined;
|
|
60
68
|
}
|
|
61
69
|
|
|
62
70
|
/** True while the editor is open, the game is paused under it
|
|
@@ -253,7 +261,7 @@ function editorMapRestore(map)
|
|
|
253
261
|
if (!saved) return map;
|
|
254
262
|
// an autosave from before the map's shape was in the hash matches on its tiles and objects, and one from before
|
|
255
263
|
// objects were matches on its tiles; one of a resized map is resized to first
|
|
256
|
-
const sameFile = saved.hash === record.hash || !saved.width &&
|
|
264
|
+
const sameFile = saved.hash === record.hash || saved.savedHash === record.hash || !saved.width &&
|
|
257
265
|
(saved.hash === editorMapHash(data, objects) || !saved.objects && saved.hash === editorMapHash(data));
|
|
258
266
|
if ((saved.width ?? map.width) === map.width && (saved.height ?? map.height) === map.height &&
|
|
259
267
|
editorSameData(saved.layers, data) && editorSameData(saved.objects ?? [], objects))
|
|
@@ -406,15 +414,17 @@ async function editorRememberedFile(record)
|
|
|
406
414
|
}
|
|
407
415
|
const editorFileKey = (record)=> (globalThis.location?.pathname ?? '') + ' ' + record.key;
|
|
408
416
|
|
|
409
|
-
// a map as a file Save wrote is the file from then on: Reset to file goes back to it,
|
|
410
|
-
//
|
|
411
|
-
//
|
|
417
|
+
// a map as a file Save wrote is the file from then on: Reset to file goes back to it, and a reload of it has nothing
|
|
418
|
+
// to apply; a download can not say it replaced the file, so it does not, and neither does a file of another name, a
|
|
419
|
+
// copy, since the game still loads the one it came from; the browser gives a picked file's name and not its folder,
|
|
420
|
+
// so a file of the same name may be a copy too, and the autosave stays, with the hash of the file the game loads and
|
|
421
|
+
// of the file written, until a reload shows which one the game loads
|
|
412
422
|
function editorSetBaseline(record, written)
|
|
413
423
|
{
|
|
414
424
|
if (record.synthetic) return; // a layer made in code has no file to load it from
|
|
415
425
|
const data = editorTileLayerData(written.layers);
|
|
416
426
|
const objects = editorObjectGroups(written.layers).map((group)=> group.objects ?? []);
|
|
417
|
-
Object.assign(record, {original: data, originalObjects: objects,
|
|
427
|
+
Object.assign(record, {original: data, originalObjects: objects, savedHash: editorMapHash(data, objects,
|
|
418
428
|
editorMapLayout(written)), originalSize: {width: written.width, height: written.height}});
|
|
419
429
|
record.pending || editorAutosave(record); // edits waiting to be applied keep their autosave
|
|
420
430
|
}
|
|
@@ -527,11 +537,12 @@ function editorAutosave(record)
|
|
|
527
537
|
while (kept.length > original.length && !kept.at(-1).length)
|
|
528
538
|
kept.pop(); // an Objects layer the editor made, empty again, is not an edit
|
|
529
539
|
const size = record.originalSize, sameSize = map.width === size.width && map.height === size.height;
|
|
530
|
-
|
|
540
|
+
// the map as it was loaded has nothing to keep; one a Save wrote is kept until a reload shows the file has it
|
|
541
|
+
if (sameSize && editorSameData(data, record.original) && editorSameData(kept, original) && !record.savedHash)
|
|
531
542
|
delete saves[record.key];
|
|
532
543
|
else
|
|
533
|
-
saves[record.key] = {hash: record.hash, width: map.width, height: map.height,
|
|
534
|
-
nextobjectid: map.nextobjectid};
|
|
544
|
+
saves[record.key] = {hash: record.hash, savedHash: record.savedHash, width: map.width, height: map.height,
|
|
545
|
+
layers: data, objects, nextobjectid: map.nextobjectid};
|
|
535
546
|
editorWriteSaves(saves);
|
|
536
547
|
}
|
|
537
548
|
|
|
@@ -1364,8 +1375,8 @@ function editorBrushTile()
|
|
|
1364
1375
|
// the brush takes the tile in a cell, an empty cell gives the Erase brush
|
|
1365
1376
|
function editorPick(layer, pos) { editorBrush = editorStampTile(editorGidAt(layer, pos) || 0); }
|
|
1366
1377
|
|
|
1367
|
-
// a palette slot into the brush: slot 0 is the Erase brush, slot n
|
|
1368
|
-
// an object layer slot n is the nth object type
|
|
1378
|
+
// a palette slot into the brush: slot 0 is the Erase brush, slot n the palette's nth tile, keeping a one tile
|
|
1379
|
+
// brush's turn; on an object layer slot n is the nth object type
|
|
1369
1380
|
function editorPalettePick(slot)
|
|
1370
1381
|
{
|
|
1371
1382
|
if (editorObjectLayer)
|
|
@@ -1376,7 +1387,8 @@ function editorPalettePick(slot)
|
|
|
1376
1387
|
return;
|
|
1377
1388
|
}
|
|
1378
1389
|
const t = editorBrushTile();
|
|
1379
|
-
|
|
1390
|
+
const tile = slot && (editorPaletteTiles(editorLayer)[slot - 1]?.tile ?? slot - 1); // every tile, in order
|
|
1391
|
+
editorBrush = editorStampTile(slot ? editorTileToGid(tile, t?.direction, t?.mirror) : 0);
|
|
1380
1392
|
}
|
|
1381
1393
|
|
|
1382
1394
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -1795,11 +1807,18 @@ function editorPanelInit()
|
|
|
1795
1807
|
// the palette's cell size in pixels and how many to a row
|
|
1796
1808
|
const editorPaletteCell = 30, editorPaletteColumns = 8;
|
|
1797
1809
|
|
|
1798
|
-
// a layer's
|
|
1799
|
-
// ones at the end, a tile of one
|
|
1810
|
+
// the tiles a layer's palette shows, each its index and the tile info it draws with: the game's
|
|
1811
|
+
// levelEditor.paletteTiles, or every tile up to the image's edge without the blank ones at the end, a tile of one
|
|
1812
|
+
// flat color; found once for each layer and list
|
|
1800
1813
|
function editorPaletteTiles(layer)
|
|
1801
1814
|
{
|
|
1802
|
-
const live = layer?.live, image = live?.tileInfo?.textureInfo?.image;
|
|
1815
|
+
const live = layer?.live, image = live?.tileInfo?.textureInfo?.image, list = levelEditor.paletteTiles;
|
|
1816
|
+
if (list && live)
|
|
1817
|
+
{
|
|
1818
|
+
if (layer.palette?.list !== list)
|
|
1819
|
+
layer.palette = {list, tiles: list.map((tile)=> ({tile, tileInfo: editorTileInfo(live, tile)}))};
|
|
1820
|
+
return layer.palette.tiles;
|
|
1821
|
+
}
|
|
1803
1822
|
if (!image) return [];
|
|
1804
1823
|
if (layer.palette?.image === image) return layer.palette.tiles;
|
|
1805
1824
|
|
|
@@ -1808,7 +1827,7 @@ function editorPaletteTiles(layer)
|
|
|
1808
1827
|
{
|
|
1809
1828
|
const t = editorTileInfo(live, i);
|
|
1810
1829
|
if (t.pos.x + t.size.x > image.width || t.pos.y + t.size.y > image.height) break;
|
|
1811
|
-
tiles.push(t);
|
|
1830
|
+
tiles.push({tile: i, tileInfo: t});
|
|
1812
1831
|
}
|
|
1813
1832
|
try
|
|
1814
1833
|
{
|
|
@@ -1817,7 +1836,8 @@ function editorPaletteTiles(layer)
|
|
|
1817
1836
|
context.drawImage(image, 0, 0);
|
|
1818
1837
|
const blank = (t)=>
|
|
1819
1838
|
{
|
|
1820
|
-
const pixels = new Uint32Array(context.getImageData(
|
|
1839
|
+
const {pos, size} = t.tileInfo, pixels = new Uint32Array(context.getImageData(pos.x, pos.y, size.x,
|
|
1840
|
+
size.y).data.buffer);
|
|
1821
1841
|
return pixels.every((p)=> p === pixels[0]);
|
|
1822
1842
|
};
|
|
1823
1843
|
while (tiles.length > 1 && blank(tiles.at(-1)))
|
|
@@ -1877,15 +1897,16 @@ function editorPaletteDraw(canvas, layer)
|
|
|
1877
1897
|
context.moveTo(8, 8), context.lineTo(cell - 8, cell - 8);
|
|
1878
1898
|
context.moveTo(cell - 8, 8), context.lineTo(8, cell - 8);
|
|
1879
1899
|
context.stroke();
|
|
1880
|
-
tiles.forEach((
|
|
1900
|
+
tiles.forEach(({tileInfo: {pos, size}}, i)=>
|
|
1881
1901
|
{
|
|
1882
1902
|
const slot = i + 1, x = slot % columns * cell, y = (slot / columns | 0) * cell;
|
|
1883
|
-
context.drawImage(image,
|
|
1903
|
+
context.drawImage(image, pos.x, pos.y, size.x, size.y, x + 2, y + 2, cell - 4, cell - 4);
|
|
1884
1904
|
});
|
|
1885
1905
|
|
|
1886
|
-
// the brush's slot outlined, when it is one tile or Erase
|
|
1906
|
+
// the brush's slot outlined, when it is one tile the palette shows or Erase
|
|
1887
1907
|
const t = editorBrushTile(), erase = !t && editorBrush.width === 1 && editorBrush.height === 1 &&
|
|
1888
|
-
editorBrush.grids[0][0] === 0,
|
|
1908
|
+
editorBrush.grids[0][0] === 0, shown = t ? tiles.findIndex((p)=> p.tile === t.tile) : -1;
|
|
1909
|
+
const selected = erase ? 0 : shown >= 0 ? shown + 1 : -1;
|
|
1889
1910
|
if (selected < 0) return;
|
|
1890
1911
|
context.strokeStyle = '#4af';
|
|
1891
1912
|
context.strokeRect(selected % columns * cell + 1, (selected / columns | 0) * cell + 1, cell - 2, cell - 2);
|
package/src/engineExport.js
CHANGED
|
@@ -26,6 +26,7 @@ export
|
|
|
26
26
|
engineObjectsCallback,
|
|
27
27
|
engineObjectsRaycast,
|
|
28
28
|
engineAddPlugin,
|
|
29
|
+
engineAddLoad,
|
|
29
30
|
|
|
30
31
|
// Globals
|
|
31
32
|
debug,
|
|
@@ -70,8 +71,10 @@ export
|
|
|
70
71
|
canvasPixelRatio,
|
|
71
72
|
fontDefault,
|
|
72
73
|
showSplashScreen,
|
|
74
|
+
loadingScreen,
|
|
73
75
|
headlessMode,
|
|
74
76
|
engineManualStep,
|
|
77
|
+
engineVariableStep,
|
|
75
78
|
tileDefaultSize,
|
|
76
79
|
tileDefaultPadding,
|
|
77
80
|
tileDefaultBleed,
|
|
@@ -129,8 +132,10 @@ export
|
|
|
129
132
|
getCanvasPixelRatio,
|
|
130
133
|
setFontDefault,
|
|
131
134
|
setShowSplashScreen,
|
|
135
|
+
setLoadingScreen,
|
|
132
136
|
setHeadlessMode,
|
|
133
137
|
setEngineManualStep,
|
|
138
|
+
setEngineVariableStep,
|
|
134
139
|
setGLEnable,
|
|
135
140
|
setDrawScreenSpace,
|
|
136
141
|
setTileDefaultSize,
|
|
@@ -268,6 +273,7 @@ export
|
|
|
268
273
|
TextureInfo,
|
|
269
274
|
loadTexture,
|
|
270
275
|
SpriteAnimation,
|
|
276
|
+
SpriteAnimator,
|
|
271
277
|
Shader,
|
|
272
278
|
mainCanvas,
|
|
273
279
|
mainContext,
|
package/src/engineInput.js
CHANGED
|
@@ -192,7 +192,7 @@ function keyIsDown(key, device=0)
|
|
|
192
192
|
ASSERT(isStringLike(key), 'key must be a number or string');
|
|
193
193
|
ASSERT(typeof key !== 'string' || key.length > 1, "keys are codes like 'KeyW' or 'Space', not characters");
|
|
194
194
|
ASSERT(device > 0 || typeof key !== 'number' || key < 5, 'use code string for keyboard');
|
|
195
|
-
return !!(inputData[device]?.[key] & 1);
|
|
195
|
+
return !!(inputData[device]?.[key] & 1) && !inputCaptureHides(device);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
/** Returns true if device key was pressed this frame
|
|
@@ -205,7 +205,7 @@ function keyWasPressed(key, device=0)
|
|
|
205
205
|
ASSERT(isStringLike(key), 'key must be a number or string');
|
|
206
206
|
ASSERT(typeof key !== 'string' || key.length > 1, "keys are codes like 'KeyW' or 'Space', not characters");
|
|
207
207
|
ASSERT(device > 0 || typeof key !== 'number' || key < 5, 'use code string for keyboard');
|
|
208
|
-
return !!(inputData[device]?.[key] & 2);
|
|
208
|
+
return !!(inputData[device]?.[key] & 2) && !inputCaptureHides(device);
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
/** Returns true if device key was released this frame
|
|
@@ -218,7 +218,7 @@ function keyWasReleased(key, device=0)
|
|
|
218
218
|
ASSERT(isStringLike(key), 'key must be a number or string');
|
|
219
219
|
ASSERT(typeof key !== 'string' || key.length > 1, "keys are codes like 'KeyW' or 'Space', not characters");
|
|
220
220
|
ASSERT(device > 0 || typeof key !== 'number' || key < 5, 'use code string for keyboard');
|
|
221
|
-
return !!(inputData[device]?.[key] & 4);
|
|
221
|
+
return !!(inputData[device]?.[key] & 4) && !inputCaptureHides(device);
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
/** Returns input vector from arrow keys or WASD if enabled
|
|
@@ -421,7 +421,10 @@ function pointerLockRequest()
|
|
|
421
421
|
/** Request to unlock the pointer
|
|
422
422
|
* @memberof Input */
|
|
423
423
|
function pointerLockExit()
|
|
424
|
-
{
|
|
424
|
+
{
|
|
425
|
+
inputLockExit(); // debug builds: the free camera and the 3D editor tell this from Escape
|
|
426
|
+
document.exitPointerLock?.();
|
|
427
|
+
}
|
|
425
428
|
|
|
426
429
|
/** Check if pointer is locked (true if locked)
|
|
427
430
|
* @return {boolean}
|
|
@@ -738,6 +741,7 @@ function inputInit()
|
|
|
738
741
|
|
|
739
742
|
function inputUpdate()
|
|
740
743
|
{
|
|
744
|
+
inputCaptureMouse(); // debug builds: the free camera or the 3D editor may have the mouse
|
|
741
745
|
if (headlessMode) return;
|
|
742
746
|
|
|
743
747
|
// clear input when lost focus (prevent stuck keys)
|
package/src/engineLogo.js
CHANGED
|
@@ -7,6 +7,25 @@
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
9
|
///////////////////////////////////////////////////////////////////////////////
|
|
10
|
+
// the default loading screen: Loading over a bar across the middle, filled by the part of the loads done
|
|
11
|
+
function drawLoadingScreen(progress)
|
|
12
|
+
{
|
|
13
|
+
const x = mainContext, w = mainCanvasSize.x, h = mainCanvasSize.y;
|
|
14
|
+
const barWidth = min(w * .6, 400), barHeight = 12, left = (w - barWidth) / 2, top = h / 2;
|
|
15
|
+
x.save();
|
|
16
|
+
x.fillStyle = '#000';
|
|
17
|
+
x.fillRect(0, 0, w, h);
|
|
18
|
+
x.fillStyle = x.strokeStyle = '#fff';
|
|
19
|
+
x.font = '28px ' + fontDefault;
|
|
20
|
+
x.textAlign = 'center';
|
|
21
|
+
x.textBaseline = 'bottom';
|
|
22
|
+
x.fillText('Loading', w / 2, top - 16);
|
|
23
|
+
x.lineWidth = 2;
|
|
24
|
+
x.strokeRect(left, top, barWidth, barHeight);
|
|
25
|
+
x.fillRect(left, top, barWidth * clamp(progress), barHeight);
|
|
26
|
+
x.restore();
|
|
27
|
+
}
|
|
28
|
+
|
|
10
29
|
function drawEngineLogo(t)
|
|
11
30
|
{
|
|
12
31
|
const blackAndWhite = 0;
|
package/src/engineObject.js
CHANGED
|
@@ -188,9 +188,10 @@ class EngineObject
|
|
|
188
188
|
// bail if a collision callback destroyed us mid-frame
|
|
189
189
|
if (this.destroyed) return;
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
// limit max speed to prevent missing collisions, only for what collides: with solids, or with tiles while it
|
|
192
|
+
// has a mass, which tile collision needs; anything else moves as fast as it is told
|
|
193
|
+
if (this.clampSpeed && enablePhysicsSolver && (this.collideSolidObjects || this.collideLevel && this.mass))
|
|
192
194
|
{
|
|
193
|
-
// limit max speed to prevent missing collisions
|
|
194
195
|
this.velocity.x = clamp(this.velocity.x, -objectMaxSpeed, objectMaxSpeed);
|
|
195
196
|
this.velocity.y = clamp(this.velocity.y, -objectMaxSpeed, objectMaxSpeed);
|
|
196
197
|
}
|
package/src/engineRelease.js
CHANGED
|
@@ -52,16 +52,28 @@ function tweak(){}
|
|
|
52
52
|
function tweakButton(){}
|
|
53
53
|
function tweakDivider(){}
|
|
54
54
|
function tweakEngineDefaults(){}
|
|
55
|
-
const levelEditor = {isOpen: false, open(){}, close(){}, onTile: undefined, onRestart: undefined, onPlayFrom: undefined
|
|
55
|
+
const levelEditor = {isOpen: false, open(){}, close(){}, onTile: undefined, onRestart: undefined, onPlayFrom: undefined,
|
|
56
|
+
paletteTiles: undefined, use3D: undefined};
|
|
56
57
|
function editorMapRestore(map){ return map; }
|
|
57
58
|
function editorMapLoaded(){}
|
|
58
59
|
function editorJSONFetched(){}
|
|
59
60
|
function editorPreRender(){}
|
|
60
61
|
function editorObjectMade(){}
|
|
61
62
|
|
|
63
|
+
// the input capture of the free camera and the 3D editor
|
|
64
|
+
function inputCaptureHides(){ return false; }
|
|
65
|
+
function inputCaptureMouse(){}
|
|
66
|
+
function inputLockExit(){}
|
|
67
|
+
|
|
62
68
|
// the 3D debug draws are debug only too
|
|
63
69
|
function debugBox3D(){}
|
|
64
70
|
function debugSphere3D(){}
|
|
65
71
|
function debugLine3D(){}
|
|
66
72
|
function debugPoint3D(){}
|
|
67
73
|
function render3DRenderDebug(){}
|
|
74
|
+
|
|
75
|
+
// the free camera and the 3D level editor are debug only
|
|
76
|
+
function editor3DCameraBegin(){}
|
|
77
|
+
function editor3DCameraEnd(){}
|
|
78
|
+
function editor3DLevelLoaded(){}
|
|
79
|
+
function editor3DObjectMade(){}
|
package/src/engineSettings.js
CHANGED
|
@@ -122,6 +122,13 @@ let fontDefault = 'arial';
|
|
|
122
122
|
* @memberof Settings */
|
|
123
123
|
let showSplashScreen = false;
|
|
124
124
|
|
|
125
|
+
/** The loading screen, drawn after the splash while the images, gameInit and what they load are loading, once that
|
|
126
|
+
* takes more than half a second: a function given the part done, 0 to 1, or undefined for none, which leaves the
|
|
127
|
+
* screen blank; the default says Loading over a bar
|
|
128
|
+
* @type {LoadingScreenCallback|undefined}
|
|
129
|
+
* @memberof Settings */
|
|
130
|
+
let loadingScreen = drawLoadingScreen;
|
|
131
|
+
|
|
125
132
|
/** Disables all rendering, audio, and input for servers, must be set before engineInit
|
|
126
133
|
* @type {boolean}
|
|
127
134
|
* @default
|
|
@@ -135,6 +142,15 @@ let headlessMode = false;
|
|
|
135
142
|
* @memberof Settings */
|
|
136
143
|
let engineManualStep = false;
|
|
137
144
|
|
|
145
|
+
/** Run one update per display frame with timeDelta the time it covers, in place of fixed updates at frameRate
|
|
146
|
+
* - Per-frame values are not scaled: velocity, gravity, damping and particle speeds act once per update, so a
|
|
147
|
+
* game that turns this on scales its own movement by timeDelta
|
|
148
|
+
* - Values in seconds follow real time as they are: time, timers, particle emit rate and life, animation, Box2D
|
|
149
|
+
* @type {boolean}
|
|
150
|
+
* @default
|
|
151
|
+
* @memberof Settings */
|
|
152
|
+
let engineVariableStep = false;
|
|
153
|
+
|
|
138
154
|
///////////////////////////////////////////////////////////////////////////////
|
|
139
155
|
// WebGL settings
|
|
140
156
|
|
|
@@ -530,6 +546,11 @@ function setFontDefault(font) { fontDefault = font; }
|
|
|
530
546
|
* @memberof Settings */
|
|
531
547
|
function setShowSplashScreen(show) { showSplashScreen = show; }
|
|
532
548
|
|
|
549
|
+
/** Set the loading screen, drawn after the splash while the game loads, once that takes more than half a second
|
|
550
|
+
* @param {LoadingScreenCallback} [callback] - Draws on mainContext given the part done, 0 to 1; undefined for none
|
|
551
|
+
* @memberof Settings */
|
|
552
|
+
function setLoadingScreen(callback) { loadingScreen = callback; }
|
|
553
|
+
|
|
533
554
|
/** Set to disable rendering, audio, and input for servers, must be set before engineInit
|
|
534
555
|
* @param {boolean} headless
|
|
535
556
|
* @memberof Settings */
|
|
@@ -555,6 +576,23 @@ function setEngineManualStep(enable=true)
|
|
|
555
576
|
}
|
|
556
577
|
}
|
|
557
578
|
|
|
579
|
+
/** Set if the engine runs one update per display frame with timeDelta the time it covers
|
|
580
|
+
* Can be set before engineInit or while running; turned off it goes back to fixed updates at frameRate
|
|
581
|
+
* @param {boolean} [enable]
|
|
582
|
+
* @memberof Settings */
|
|
583
|
+
function setEngineVariableStep(enable=true)
|
|
584
|
+
{
|
|
585
|
+
if (engineVariableStep && !enable)
|
|
586
|
+
{
|
|
587
|
+
// fixed time goes on one fixed step after the last update, if one ran, and timeDelta is the fixed step again
|
|
588
|
+
timeFixedStart = frame ? time + 1 / frameRate : time;
|
|
589
|
+
frameFixedStart = frame;
|
|
590
|
+
timeDelta = 1 / frameRate;
|
|
591
|
+
frameTimeBufferMS = engineManualStep ? -.5e3 / frameRate : 0;
|
|
592
|
+
}
|
|
593
|
+
engineVariableStep = enable;
|
|
594
|
+
}
|
|
595
|
+
|
|
558
596
|
/** Set whether the draw and debug functions draw in screen space when a call leaves screenSpace out
|
|
559
597
|
* @param {boolean} screenSpace
|
|
560
598
|
* @memberof Settings */
|