littlejsengine 1.11.2 → 1.11.5
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/.vscode/launch.json +14 -0
- package/README.md +16 -18
- package/dist/littlejs.d.ts +41 -30
- package/dist/littlejs.esm.js +165 -143
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +161 -142
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +157 -135
- package/examples/box2d/gameObjects.js +4 -4
- package/examples/box2d/scenes.js +2 -2
- package/examples/breakout/game.js +1 -1
- package/examples/breakout/gameObjects.js +28 -29
- package/examples/breakout/index.html +1 -1
- package/examples/breakoutTutorial/game.js +1 -1
- package/examples/index.html +1 -7
- package/examples/logo.png +0 -0
- package/examples/module/game.js +1 -1
- package/examples/platformer/game.js +2 -2
- package/examples/platformer/gameCharacter.js +5 -5
- package/examples/platformer/gameEffects.js +4 -4
- package/examples/platformer/gameObjects.js +2 -2
- package/examples/puzzle/game.js +3 -3
- package/examples/starter/game.js +11 -45
- package/examples/starter/tiles.png +0 -0
- package/jsconfig.json +1 -0
- package/package.json +1 -1
- package/plugins/box2d.js +10 -10
- package/plugins/newgrounds.js +1 -1
- package/plugins/postProcess.js +8 -8
- package/shortExamples/base.html +36 -0
- package/shortExamples/code/blending.js +12 -0
- package/shortExamples/code/helloWorld.js +7 -0
- package/shortExamples/code/particles.js +28 -0
- package/shortExamples/code/playSound.js +36 -0
- package/shortExamples/code/pong.js +40 -0
- package/shortExamples/code/shapes.js +24 -0
- package/shortExamples/code/spriteAtlas.js +27 -0
- package/shortExamples/code/systemFont.js +14 -0
- package/shortExamples/code/texture.js +12 -0
- package/shortExamples/code/tileLayer.js +50 -0
- package/shortExamples/index.html +242 -0
- package/shortExamples/tiles.png +0 -0
- package/src/engine.js +17 -3
- package/src/engineAudio.js +4 -4
- package/src/engineBuild.js +2 -1
- package/src/engineDebug.js +4 -7
- package/src/engineDraw.js +50 -25
- package/src/engineExport.js +4 -1
- package/src/engineInput.js +1 -1
- package/src/engineObject.js +8 -8
- package/src/engineParticles.js +7 -7
- package/src/engineSettings.js +5 -5
- package/src/engineTileLayer.js +6 -2
- package/src/engineUtilities.js +5 -5
- package/src/engineWebGL.js +52 -74
- package/examples/electron/build.js +0 -107
- package/examples/electron/electron.js +0 -43
- package/examples/electron/game.js +0 -131
- package/examples/electron/index.html +0 -13
- package/examples/electron/package.json +0 -22
- package/examples/electron/tiles.png +0 -0
- package/examples/js13k/build.bat +0 -2
- package/examples/js13k/build.js +0 -131
- package/examples/js13k/game.js +0 -118
- package/examples/js13k/index.html +0 -21
- package/examples/js13k/tiles.png +0 -0
- package/examples/typescript/build.bat +0 -5
- package/examples/typescript/build.js +0 -33
- package/examples/typescript/game.js +0 -102
- package/examples/typescript/game.ts +0 -134
- package/examples/typescript/index.html +0 -10
- package/examples/typescript/tiles.png +0 -0
- package/examples/typescript/tsconfig.json +0 -8
package/dist/littlejs.release.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
// LittleJS - MIT License - Copyright 2021 Frank Force
|
|
1
|
+
// LittleJS Engine - MIT License - Copyright 2021 Frank Force
|
|
2
|
+
// https://github.com/KilledByAPixel/LittleJS
|
|
2
3
|
|
|
3
4
|
'use strict';
|
|
4
5
|
|
|
@@ -54,7 +55,7 @@ function debugSaveDataURL(){}
|
|
|
54
55
|
* @memberof Utilities */
|
|
55
56
|
const PI = Math.PI;
|
|
56
57
|
|
|
57
|
-
/** Returns
|
|
58
|
+
/** Returns absolute value of value passed in
|
|
58
59
|
* @param {Number} value
|
|
59
60
|
* @return {Number}
|
|
60
61
|
* @memberof Utilities */
|
|
@@ -87,7 +88,7 @@ function sign(value) { return Math.sign(value); }
|
|
|
87
88
|
* @memberof Utilities */
|
|
88
89
|
function mod(dividend, divisor=1) { return ((dividend % divisor) + divisor) % divisor; }
|
|
89
90
|
|
|
90
|
-
/** Clamps the value
|
|
91
|
+
/** Clamps the value between max and min
|
|
91
92
|
* @param {Number} value
|
|
92
93
|
* @param {Number} [min]
|
|
93
94
|
* @param {Number} [max]
|
|
@@ -523,7 +524,7 @@ class Vector2
|
|
|
523
524
|
return new Vector2(this.x*c - this.y*s, this.x*s + this.y*c);
|
|
524
525
|
}
|
|
525
526
|
|
|
526
|
-
/** Set the integer direction of this vector,
|
|
527
|
+
/** Set the integer direction of this vector, corresponding to multiples of 90 degree rotation (0-3)
|
|
527
528
|
* @param {Number} [direction]
|
|
528
529
|
* @param {Number} [length] */
|
|
529
530
|
setDirection(direction, length=1)
|
|
@@ -534,7 +535,7 @@ class Vector2
|
|
|
534
535
|
direction%2 ? 0 : direction ? -length : length);
|
|
535
536
|
}
|
|
536
537
|
|
|
537
|
-
/** Returns the integer direction of this vector,
|
|
538
|
+
/** Returns the integer direction of this vector, corresponding to multiples of 90 degree rotation (0-3)
|
|
538
539
|
* @return {Number} */
|
|
539
540
|
direction()
|
|
540
541
|
{ return abs(this.x) > abs(this.y) ? this.x < 0 ? 3 : 1 : this.y < 0 ? 2 : 0; }
|
|
@@ -919,7 +920,7 @@ const MAGENTA = rgb(1,0,1);
|
|
|
919
920
|
* a.set(3); // sets the timer to 3 seconds
|
|
920
921
|
*
|
|
921
922
|
* let b = new Timer(1); // creates a timer with 1 second left
|
|
922
|
-
* b.unset(); //
|
|
923
|
+
* b.unset(); // unset the timer
|
|
923
924
|
*/
|
|
924
925
|
class Timer
|
|
925
926
|
{
|
|
@@ -1070,7 +1071,7 @@ let tileFixBleedScale = 0;
|
|
|
1070
1071
|
* @memberof Settings */
|
|
1071
1072
|
let enablePhysicsSolver = true;
|
|
1072
1073
|
|
|
1073
|
-
/** Default object mass for collision
|
|
1074
|
+
/** Default object mass for collision calculations (how heavy objects are)
|
|
1074
1075
|
* @type {Number}
|
|
1075
1076
|
* @default
|
|
1076
1077
|
* @memberof Settings */
|
|
@@ -1281,7 +1282,7 @@ function setFontDefault(font) { fontDefault = font; }
|
|
|
1281
1282
|
* @memberof Settings */
|
|
1282
1283
|
function setShowSplashScreen(show) { showSplashScreen = show; }
|
|
1283
1284
|
|
|
1284
|
-
/** Set to
|
|
1285
|
+
/** Set to disable rendering, audio, and input for servers
|
|
1285
1286
|
* @param {Boolean} headless
|
|
1286
1287
|
* @memberof Settings */
|
|
1287
1288
|
function setHeadlessMode(headless) { headlessMode = headless; }
|
|
@@ -1311,7 +1312,7 @@ function setTileFixBleedScale(scale) { tileFixBleedScale = scale; }
|
|
|
1311
1312
|
* @memberof Settings */
|
|
1312
1313
|
function setEnablePhysicsSolver(enable) { enablePhysicsSolver = enable; }
|
|
1313
1314
|
|
|
1314
|
-
/** Set default object mass for
|
|
1315
|
+
/** Set default object mass for collision calculations
|
|
1315
1316
|
* @param {Number} mass
|
|
1316
1317
|
* @memberof Settings */
|
|
1317
1318
|
function setObjectDefaultMass(mass) { objectDefaultMass = mass; }
|
|
@@ -1381,7 +1382,7 @@ function setTouchGamepadEnable(enable) { touchGamepadEnable = enable; }
|
|
|
1381
1382
|
* @memberof Settings */
|
|
1382
1383
|
function setTouchGamepadAnalog(analog) { touchGamepadAnalog = analog; }
|
|
1383
1384
|
|
|
1384
|
-
/** Set size of
|
|
1385
|
+
/** Set size of virtual gamepad for touch devices in pixels
|
|
1385
1386
|
* @param {Number} size
|
|
1386
1387
|
* @memberof Settings */
|
|
1387
1388
|
function setTouchGamepadSize(size) { touchGamepadSize = size; }
|
|
@@ -1408,7 +1409,7 @@ function setSoundVolume(volume)
|
|
|
1408
1409
|
{
|
|
1409
1410
|
soundVolume = volume;
|
|
1410
1411
|
if (soundEnable && !headlessMode && audioGainNode)
|
|
1411
|
-
audioGainNode.gain.value = volume; // update gain
|
|
1412
|
+
audioGainNode.gain.value = volume; // update gain immediately
|
|
1412
1413
|
}
|
|
1413
1414
|
|
|
1414
1415
|
/** Set default range where sound no longer plays
|
|
@@ -1612,7 +1613,7 @@ class EngineObject
|
|
|
1612
1613
|
const oldPos = this.pos.copy();
|
|
1613
1614
|
this.velocity.x *= this.damping;
|
|
1614
1615
|
this.velocity.y *= this.damping;
|
|
1615
|
-
if (this.mass) //
|
|
1616
|
+
if (this.mass) // don't apply gravity to static objects
|
|
1616
1617
|
this.velocity.y += gravity * this.gravityScale;
|
|
1617
1618
|
this.pos.x += this.velocity.x;
|
|
1618
1619
|
this.pos.y += this.velocity.y;
|
|
@@ -1621,7 +1622,7 @@ class EngineObject
|
|
|
1621
1622
|
// physics sanity checks
|
|
1622
1623
|
ASSERT(this.angleDamping >= 0 && this.angleDamping <= 1);
|
|
1623
1624
|
ASSERT(this.damping >= 0 && this.damping <= 1);
|
|
1624
|
-
if (!enablePhysicsSolver || !this.mass) //
|
|
1625
|
+
if (!enablePhysicsSolver || !this.mass) // don't do collision for static objects
|
|
1625
1626
|
return;
|
|
1626
1627
|
|
|
1627
1628
|
const wasMovingDown = this.velocity.y < 0;
|
|
@@ -1640,7 +1641,7 @@ class EngineObject
|
|
|
1640
1641
|
const epsilon = .001; // necessary to push slightly outside of the collision
|
|
1641
1642
|
for (const o of engineObjectsCollide)
|
|
1642
1643
|
{
|
|
1643
|
-
// non solid objects don't collide with
|
|
1644
|
+
// non solid objects don't collide with each other
|
|
1644
1645
|
if (!this.isSolid && !o.isSolid || o.destroyed || o.parent || o == this)
|
|
1645
1646
|
continue;
|
|
1646
1647
|
|
|
@@ -1700,7 +1701,7 @@ class EngineObject
|
|
|
1700
1701
|
const elastic1 = o.velocity.y * (o.mass - this.mass) / (this.mass + o.mass)
|
|
1701
1702
|
+ this.velocity.y * 2 * this.mass / (this.mass + o.mass);
|
|
1702
1703
|
|
|
1703
|
-
// lerp
|
|
1704
|
+
// lerp between elastic or inelastic based on elasticity
|
|
1704
1705
|
this.velocity.y = lerp(elasticity, inelastic, elastic0);
|
|
1705
1706
|
o.velocity.y = lerp(elasticity, inelastic, elastic1);
|
|
1706
1707
|
}
|
|
@@ -1720,7 +1721,7 @@ class EngineObject
|
|
|
1720
1721
|
const elastic1 = o.velocity.x * (o.mass - this.mass) / (this.mass + o.mass)
|
|
1721
1722
|
+ this.velocity.x * 2 * this.mass / (this.mass + o.mass);
|
|
1722
1723
|
|
|
1723
|
-
// lerp
|
|
1724
|
+
// lerp between elastic or inelastic based on elasticity
|
|
1724
1725
|
this.velocity.x = lerp(elasticity, inelastic, elastic0);
|
|
1725
1726
|
o.velocity.x = lerp(elasticity, inelastic, elastic1);
|
|
1726
1727
|
}
|
|
@@ -1786,7 +1787,7 @@ class EngineObject
|
|
|
1786
1787
|
if (this.destroyed)
|
|
1787
1788
|
return;
|
|
1788
1789
|
|
|
1789
|
-
// disconnect from parent and destroy
|
|
1790
|
+
// disconnect from parent and destroy children
|
|
1790
1791
|
this.destroyed = 1;
|
|
1791
1792
|
this.parent && this.parent.removeChild(this);
|
|
1792
1793
|
for (const child of this.children)
|
|
@@ -1811,7 +1812,7 @@ class EngineObject
|
|
|
1811
1812
|
|
|
1812
1813
|
/** Called to check if a tile collision should be resolved
|
|
1813
1814
|
* @param {Number} tileData - the value of the tile at the position
|
|
1814
|
-
* @param {Vector2} pos - tile where the collision
|
|
1815
|
+
* @param {Vector2} pos - tile where the collision occurred
|
|
1815
1816
|
* @return {Boolean} - true if the collision should be resolved */
|
|
1816
1817
|
collideWithTile(tileData, pos) { return tileData > 0; }
|
|
1817
1818
|
|
|
@@ -1874,7 +1875,7 @@ class EngineObject
|
|
|
1874
1875
|
this.collideRaycast = collideRaycast;
|
|
1875
1876
|
}
|
|
1876
1877
|
|
|
1877
|
-
/** Returns string
|
|
1878
|
+
/** Returns string containing info about this object for debugging
|
|
1878
1879
|
* @return {String} */
|
|
1879
1880
|
toString()
|
|
1880
1881
|
{
|
|
@@ -1960,7 +1961,7 @@ let overlayContext;
|
|
|
1960
1961
|
let mainCanvasSize = vec2();
|
|
1961
1962
|
|
|
1962
1963
|
/** Array containing texture info for batch rendering system
|
|
1963
|
-
* @type {Array}
|
|
1964
|
+
* @type {Array<TextureInfo>}
|
|
1964
1965
|
* @memberof Draw */
|
|
1965
1966
|
let textureInfos = [];
|
|
1966
1967
|
|
|
@@ -1999,11 +2000,13 @@ function tile(pos=vec2(), size=tileSizeDefault, textureIndex=0, padding=0)
|
|
|
1999
2000
|
|
|
2000
2001
|
// use pos as a tile index
|
|
2001
2002
|
const textureInfo = textureInfos[textureIndex];
|
|
2002
|
-
ASSERT(textureInfo, 'Texture not loaded');
|
|
2003
|
+
ASSERT(!!textureInfo, 'Texture not loaded');
|
|
2003
2004
|
const sizePadded = size.add(vec2(padding*2));
|
|
2004
|
-
const cols = textureInfo.size.x / sizePadded.x |0;
|
|
2005
2005
|
if (typeof pos === 'number')
|
|
2006
|
-
|
|
2006
|
+
{
|
|
2007
|
+
const cols = textureInfo.size.x / sizePadded.x |0;
|
|
2008
|
+
pos = cols>0 ? vec2(pos%cols, pos/cols|0) : vec2();
|
|
2009
|
+
}
|
|
2007
2010
|
pos = vec2(pos.x*sizePadded.x+padding, pos.y*sizePadded.y+padding);
|
|
2008
2011
|
|
|
2009
2012
|
// return a tile info object
|
|
@@ -2309,24 +2312,6 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, conte
|
|
|
2309
2312
|
context.restore();
|
|
2310
2313
|
}
|
|
2311
2314
|
|
|
2312
|
-
/** Enable normal or additive blend mode
|
|
2313
|
-
* @param {Boolean} [additive]
|
|
2314
|
-
* @param {Boolean} [useWebGL=glEnable]
|
|
2315
|
-
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
|
|
2316
|
-
* @memberof Draw */
|
|
2317
|
-
function setBlendMode(additive, useWebGL=glEnable, context)
|
|
2318
|
-
{
|
|
2319
|
-
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
2320
|
-
if (useWebGL)
|
|
2321
|
-
glAdditive = additive;
|
|
2322
|
-
else
|
|
2323
|
-
{
|
|
2324
|
-
if (!context)
|
|
2325
|
-
context = mainContext;
|
|
2326
|
-
context.globalCompositeOperation = additive ? 'lighter' : 'source-over';
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2329
|
-
|
|
2330
2315
|
/** Draw text on main canvas in world space
|
|
2331
2316
|
* Automatically splits new lines into rows
|
|
2332
2317
|
* @param {String} text
|
|
@@ -2394,6 +2379,38 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
|
|
|
2394
2379
|
});
|
|
2395
2380
|
}
|
|
2396
2381
|
|
|
2382
|
+
/** Enable normal or additive blend mode
|
|
2383
|
+
* @param {Boolean} [additive]
|
|
2384
|
+
* @param {Boolean} [useWebGL=glEnable]
|
|
2385
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
|
|
2386
|
+
* @memberof Draw */
|
|
2387
|
+
function setBlendMode(additive, useWebGL=glEnable, context)
|
|
2388
|
+
{
|
|
2389
|
+
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
2390
|
+
if (useWebGL)
|
|
2391
|
+
glAdditive = additive;
|
|
2392
|
+
else
|
|
2393
|
+
{
|
|
2394
|
+
if (!context)
|
|
2395
|
+
context = mainContext;
|
|
2396
|
+
context.globalCompositeOperation = additive ? 'lighter' : 'source-over';
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
/** Combines all LittleJS canvases onto the main canvas and clears them
|
|
2401
|
+
* This is necessary for things like saving a screenshot
|
|
2402
|
+
* @memberof Draw */
|
|
2403
|
+
function combineCanvases()
|
|
2404
|
+
{
|
|
2405
|
+
// combine canvases
|
|
2406
|
+
glCopyToContext(mainContext, true);
|
|
2407
|
+
mainContext.drawImage(overlayCanvas, 0, 0);
|
|
2408
|
+
|
|
2409
|
+
// clear canvases
|
|
2410
|
+
glClearCanvas();
|
|
2411
|
+
overlayCanvas.width |= 0;
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2397
2414
|
///////////////////////////////////////////////////////////////////////////////
|
|
2398
2415
|
|
|
2399
2416
|
let engineFontImage;
|
|
@@ -2405,7 +2422,7 @@ let engineFontImage;
|
|
|
2405
2422
|
* - You can also use fonts from the main tile sheet
|
|
2406
2423
|
* @example
|
|
2407
2424
|
* // use built in font
|
|
2408
|
-
* const font = new
|
|
2425
|
+
* const font = new FontImage;
|
|
2409
2426
|
*
|
|
2410
2427
|
* // draw text
|
|
2411
2428
|
* font.drawTextScreen("LittleJS\nHello World!", vec2(200, 50));
|
|
@@ -2480,14 +2497,14 @@ class FontImage
|
|
|
2480
2497
|
}
|
|
2481
2498
|
|
|
2482
2499
|
///////////////////////////////////////////////////////////////////////////////
|
|
2483
|
-
//
|
|
2500
|
+
// Display functions
|
|
2484
2501
|
|
|
2485
2502
|
/** Returns true if fullscreen mode is active
|
|
2486
2503
|
* @return {Boolean}
|
|
2487
2504
|
* @memberof Draw */
|
|
2488
2505
|
function isFullscreen() { return !!document.fullscreenElement; }
|
|
2489
2506
|
|
|
2490
|
-
/** Toggle
|
|
2507
|
+
/** Toggle fullscreen mode
|
|
2491
2508
|
* @memberof Draw */
|
|
2492
2509
|
function toggleFullscreen()
|
|
2493
2510
|
{
|
|
@@ -2499,6 +2516,15 @@ function toggleFullscreen()
|
|
|
2499
2516
|
}
|
|
2500
2517
|
else if (rootElement.requestFullscreen)
|
|
2501
2518
|
rootElement.requestFullscreen();
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
/** Set the cursor style
|
|
2522
|
+
* @param {String} cursorStyle - CSS cursor style (auto, none, crosshair, etc)
|
|
2523
|
+
* @memberof Draw */
|
|
2524
|
+
function setCursor(cursorStyle = 'auto')
|
|
2525
|
+
{
|
|
2526
|
+
const rootElement = mainCanvas.parentElement;
|
|
2527
|
+
rootElement.style.cursor = cursorStyle;
|
|
2502
2528
|
}
|
|
2503
2529
|
/**
|
|
2504
2530
|
* LittleJS Input System
|
|
@@ -2843,7 +2869,7 @@ function vibrateStop() { vibrate(0); }
|
|
|
2843
2869
|
|
|
2844
2870
|
/** True if a touch device has been detected
|
|
2845
2871
|
* @memberof Input */
|
|
2846
|
-
const isTouchDevice = window.ontouchstart !== undefined;
|
|
2872
|
+
const isTouchDevice = !headlessMode && window.ontouchstart !== undefined;
|
|
2847
2873
|
|
|
2848
2874
|
// touch gamepad internal variables
|
|
2849
2875
|
let touchGamepadTimer = new Timer, touchGamepadButtons, touchGamepadStick;
|
|
@@ -3041,7 +3067,7 @@ function audioInit()
|
|
|
3041
3067
|
{
|
|
3042
3068
|
if (!soundEnable || headlessMode) return;
|
|
3043
3069
|
|
|
3044
|
-
// (createGain is more widely
|
|
3070
|
+
// (createGain is more widely supported then GainNode constructor)
|
|
3045
3071
|
audioGainNode = audioContext.createGain();
|
|
3046
3072
|
audioGainNode.connect(audioContext.destination);
|
|
3047
3073
|
audioGainNode.gain.value = soundVolume; // set starting value
|
|
@@ -3391,7 +3417,7 @@ const zzfxR = 44100;
|
|
|
3391
3417
|
* @param {Number} [sustain] - Sustain time, how long sound holds (seconds)
|
|
3392
3418
|
* @param {Number} [release] - Release time, how fast sound fades out (seconds)
|
|
3393
3419
|
* @param {Number} [shape] - Shape of the sound wave
|
|
3394
|
-
* @param {Number} [shapeCurve] -
|
|
3420
|
+
* @param {Number} [shapeCurve] - Squareness of wave (0=square, 1=normal, 2=pointy)
|
|
3395
3421
|
* @param {Number} [slide] - How much to slide frequency (kHz/s)
|
|
3396
3422
|
* @param {Number} [deltaSlide] - How much to change slide (kHz/s/s)
|
|
3397
3423
|
* @param {Number} [pitchJump] - Frequency of pitch jump (Hz)
|
|
@@ -3403,7 +3429,7 @@ const zzfxR = 44100;
|
|
|
3403
3429
|
* @param {Number} [delay] - Overlap sound with itself for reverb and flanger effects (seconds)
|
|
3404
3430
|
* @param {Number} [sustainVolume] - Volume level for sustain (percent)
|
|
3405
3431
|
* @param {Number} [decay] - Decay time, how long to reach sustain after attack (seconds)
|
|
3406
|
-
* @param {Number} [tremolo] - Trembling effect, rate controlled by repeat time (
|
|
3432
|
+
* @param {Number} [tremolo] - Trembling effect, rate controlled by repeat time (percent)
|
|
3407
3433
|
* @param {Number} [filter] - Filter cutoff frequency, positive for HPF, negative for LPF (Hz)
|
|
3408
3434
|
* @return {Array} - Array of audio samples
|
|
3409
3435
|
* @memberof Audio
|
|
@@ -3507,7 +3533,7 @@ function zzfxG
|
|
|
3507
3533
|
// ZzFX Music Renderer v2.0.3 by Keith Clark and Frank Force
|
|
3508
3534
|
|
|
3509
3535
|
/** Generate samples for a ZzFM song with given parameters
|
|
3510
|
-
* @param {Array} instruments - Array of ZzFX sound
|
|
3536
|
+
* @param {Array} instruments - Array of ZzFX sound parameters
|
|
3511
3537
|
* @param {Array} patterns - Array of pattern data
|
|
3512
3538
|
* @param {Array} sequence - Array of pattern indexes
|
|
3513
3539
|
* @param {Number} [BPM] - Playback speed of the song in BPM
|
|
@@ -3848,6 +3874,10 @@ class TileLayer extends EngineObject
|
|
|
3848
3874
|
|
|
3849
3875
|
// draw the entire cached level onto the canvas
|
|
3850
3876
|
const pos = worldToScreen(this.pos.add(vec2(0,this.size.y*this.scale.y)));
|
|
3877
|
+
|
|
3878
|
+
// fix canvas jitter in some browsers if position is not an integer
|
|
3879
|
+
pos.x |= 0; pos.y |= 0;
|
|
3880
|
+
|
|
3851
3881
|
(this.isOverlay ? overlayContext : mainContext).drawImage
|
|
3852
3882
|
(
|
|
3853
3883
|
this.canvas, pos.x, pos.y,
|
|
@@ -3910,7 +3940,7 @@ class TileLayer extends EngineObject
|
|
|
3910
3940
|
|
|
3911
3941
|
/** Draw the tile at a given position in the tile grid
|
|
3912
3942
|
* This can be used to clear out tiles when they are destroyed
|
|
3913
|
-
* Tiles can also be redrawn if
|
|
3943
|
+
* Tiles can also be redrawn if inside a redrawStart/End block
|
|
3914
3944
|
* @param {Vector2} layerPos
|
|
3915
3945
|
* @param {Boolean} [clear] - should the old tile be cleared out
|
|
3916
3946
|
*/
|
|
@@ -3935,7 +3965,7 @@ class TileLayer extends EngineObject
|
|
|
3935
3965
|
}
|
|
3936
3966
|
}
|
|
3937
3967
|
|
|
3938
|
-
/** Draw directly to the 2D canvas in world space (
|
|
3968
|
+
/** Draw directly to the 2D canvas in world space (bypass webgl)
|
|
3939
3969
|
* @param {Vector2} pos
|
|
3940
3970
|
* @param {Vector2} size
|
|
3941
3971
|
* @param {Number} angle
|
|
@@ -4005,7 +4035,7 @@ class TileLayer extends EngineObject
|
|
|
4005
4035
|
* let pos = vec2(2,3);
|
|
4006
4036
|
* let particleEmitter = new ParticleEmitter
|
|
4007
4037
|
* (
|
|
4008
|
-
* pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate,
|
|
4038
|
+
* pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emitCone
|
|
4009
4039
|
* tile(0, 16), // tileInfo
|
|
4010
4040
|
* rgb(1,1,1), rgb(0,0,0), // colorStartA, colorStartB
|
|
4011
4041
|
* rgb(1,1,1,0), rgb(0,0,0,0), // colorEndA, colorEndB
|
|
@@ -4040,7 +4070,7 @@ class ParticleEmitter extends EngineObject
|
|
|
4040
4070
|
* @param {Number} [fadeRate] - How quick to fade particles at start/end in percent of life
|
|
4041
4071
|
* @param {Number} [randomness] - Apply extra randomness percent
|
|
4042
4072
|
* @param {Boolean} [collideTiles] - Do particles collide against tiles
|
|
4043
|
-
* @param {Boolean} [additive] - Should particles use
|
|
4073
|
+
* @param {Boolean} [additive] - Should particles use additive blend
|
|
4044
4074
|
* @param {Boolean} [randomColorLinear] - Should color be randomized linearly or across each component
|
|
4045
4075
|
* @param {Number} [renderOrder] - Render order for particles (additive is above other stuff by default)
|
|
4046
4076
|
* @param {Boolean} [localSpace] - Should it be in local space of emitter (world space is default)
|
|
@@ -4125,11 +4155,11 @@ class ParticleEmitter extends EngineObject
|
|
|
4125
4155
|
this.randomness = randomness;
|
|
4126
4156
|
/** @property {Boolean} - Do particles collide against tiles */
|
|
4127
4157
|
this.collideTiles = collideTiles;
|
|
4128
|
-
/** @property {Boolean} - Should particles use
|
|
4158
|
+
/** @property {Boolean} - Should particles use additive blend */
|
|
4129
4159
|
this.additive = additive;
|
|
4130
4160
|
/** @property {Boolean} - Should it be in local space of emitter */
|
|
4131
4161
|
this.localSpace = localSpace;
|
|
4132
|
-
/** @property {Number} - If non zero the
|
|
4162
|
+
/** @property {Number} - If non zero the particle is drawn as a trail, stretched in the direction of velocity */
|
|
4133
4163
|
this.trailScale = 0;
|
|
4134
4164
|
/** @property {Function} - Callback when particle is destroyed */
|
|
4135
4165
|
this.particleDestroyCallback = undefined;
|
|
@@ -4178,7 +4208,7 @@ class ParticleEmitter extends EngineObject
|
|
|
4178
4208
|
angle += this.angle;
|
|
4179
4209
|
}
|
|
4180
4210
|
|
|
4181
|
-
// randomness scales each
|
|
4211
|
+
// randomness scales each parameter by a percentage
|
|
4182
4212
|
const randomness = this.randomness;
|
|
4183
4213
|
const randomizeScale = (v)=> v + v*rand(randomness, -randomness);
|
|
4184
4214
|
|
|
@@ -4207,7 +4237,7 @@ class ParticleEmitter extends EngineObject
|
|
|
4207
4237
|
particle.renderOrder = this.renderOrder;
|
|
4208
4238
|
particle.mirror = !!randInt(2);
|
|
4209
4239
|
|
|
4210
|
-
// call particle create
|
|
4240
|
+
// call particle create callback
|
|
4211
4241
|
this.particleCreateCallback && this.particleCreateCallback(particle);
|
|
4212
4242
|
|
|
4213
4243
|
// return the newly created particle
|
|
@@ -4276,7 +4306,7 @@ class Particle extends EngineObject
|
|
|
4276
4306
|
render()
|
|
4277
4307
|
{
|
|
4278
4308
|
// modulate size and color
|
|
4279
|
-
const p = min((time - this.spawnTime) / this.lifeTime, 1);
|
|
4309
|
+
const p = this.lifeTime > 0 ? min((time - this.spawnTime) / this.lifeTime, 1) : 1;
|
|
4280
4310
|
const radius = this.sizeStart + p * this.sizeEndDelta;
|
|
4281
4311
|
const size = vec2(radius);
|
|
4282
4312
|
const fadeRate = this.fadeRate/2;
|
|
@@ -4527,7 +4557,7 @@ let glCanvas;
|
|
|
4527
4557
|
* @memberof WebGL */
|
|
4528
4558
|
let glContext;
|
|
4529
4559
|
|
|
4530
|
-
/**
|
|
4560
|
+
/** Should webgl be setup with anti-aliasing? must be set before calling engineInit
|
|
4531
4561
|
* @type {Boolean}
|
|
4532
4562
|
* @memberof WebGL */
|
|
4533
4563
|
let glAntialias = true;
|
|
@@ -4535,9 +4565,15 @@ let glAntialias = true;
|
|
|
4535
4565
|
// WebGL internal variables not exposed to documentation
|
|
4536
4566
|
let glShader, glActiveTexture, glArrayBuffer, glGeometryBuffer, glPositionData, glColorData, glInstanceCount, glAdditive, glBatchAdditive;
|
|
4537
4567
|
|
|
4568
|
+
// WebGL internal constants
|
|
4569
|
+
const gl_MAX_INSTANCES = 1e4;
|
|
4570
|
+
const gl_INDICES_PER_INSTANCE = 11;
|
|
4571
|
+
const gl_INSTANCE_BYTE_STRIDE = gl_INDICES_PER_INSTANCE * 4;
|
|
4572
|
+
const gl_INSTANCE_BUFFER_SIZE = gl_MAX_INSTANCES * gl_INSTANCE_BYTE_STRIDE;
|
|
4573
|
+
|
|
4538
4574
|
///////////////////////////////////////////////////////////////////////////////
|
|
4539
4575
|
|
|
4540
|
-
//
|
|
4576
|
+
// Initialize WebGL, called automatically by the engine
|
|
4541
4577
|
function glInit()
|
|
4542
4578
|
{
|
|
4543
4579
|
if (!glEnable || headlessMode) return;
|
|
@@ -4587,8 +4623,8 @@ function glInit()
|
|
|
4587
4623
|
|
|
4588
4624
|
// create the geometry buffer, triangle strip square
|
|
4589
4625
|
const geometry = new Float32Array([glInstanceCount=0,0,1,0,0,1,1,1]);
|
|
4590
|
-
glContext.bindBuffer(
|
|
4591
|
-
glContext.bufferData(
|
|
4626
|
+
glContext.bindBuffer(glContext.ARRAY_BUFFER, glGeometryBuffer);
|
|
4627
|
+
glContext.bufferData(glContext.ARRAY_BUFFER, geometry, glContext.STATIC_DRAW);
|
|
4592
4628
|
}
|
|
4593
4629
|
|
|
4594
4630
|
// Setup render each frame, called automatically by engine
|
|
@@ -4596,15 +4632,12 @@ function glPreRender()
|
|
|
4596
4632
|
{
|
|
4597
4633
|
if (!glEnable || headlessMode) return;
|
|
4598
4634
|
|
|
4599
|
-
//
|
|
4600
|
-
|
|
4601
|
-
glContext.clear(gl_COLOR_BUFFER_BIT);
|
|
4602
|
-
|
|
4603
|
-
// set up the shader
|
|
4635
|
+
// set up the shader and canvas
|
|
4636
|
+
glClearCanvas();
|
|
4604
4637
|
glContext.useProgram(glShader);
|
|
4605
|
-
glContext.activeTexture(
|
|
4638
|
+
glContext.activeTexture(glContext.TEXTURE0);
|
|
4606
4639
|
if (textureInfos[0])
|
|
4607
|
-
glContext.bindTexture(
|
|
4640
|
+
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture = textureInfos[0].glTexture);
|
|
4608
4641
|
|
|
4609
4642
|
// set vertex attributes
|
|
4610
4643
|
let offset = glAdditive = glBatchAdditive = 0;
|
|
@@ -4619,15 +4652,15 @@ function glPreRender()
|
|
|
4619
4652
|
glContext.vertexAttribDivisor(location, divisor);
|
|
4620
4653
|
offset += size*typeSize;
|
|
4621
4654
|
}
|
|
4622
|
-
glContext.bindBuffer(
|
|
4623
|
-
initVertexAttribArray('g',
|
|
4624
|
-
glContext.bindBuffer(
|
|
4625
|
-
glContext.bufferData(
|
|
4626
|
-
initVertexAttribArray('p',
|
|
4627
|
-
initVertexAttribArray('u',
|
|
4628
|
-
initVertexAttribArray('c',
|
|
4629
|
-
initVertexAttribArray('a',
|
|
4630
|
-
initVertexAttribArray('r',
|
|
4655
|
+
glContext.bindBuffer(glContext.ARRAY_BUFFER, glGeometryBuffer);
|
|
4656
|
+
initVertexAttribArray('g', glContext.FLOAT, 0, 2); // geometry
|
|
4657
|
+
glContext.bindBuffer(glContext.ARRAY_BUFFER, glArrayBuffer);
|
|
4658
|
+
glContext.bufferData(glContext.ARRAY_BUFFER, gl_INSTANCE_BUFFER_SIZE, glContext.DYNAMIC_DRAW);
|
|
4659
|
+
initVertexAttribArray('p', glContext.FLOAT, 4, 4); // position & size
|
|
4660
|
+
initVertexAttribArray('u', glContext.FLOAT, 4, 4); // texture coords
|
|
4661
|
+
initVertexAttribArray('c', glContext.UNSIGNED_BYTE, 1, 4); // color
|
|
4662
|
+
initVertexAttribArray('a', glContext.UNSIGNED_BYTE, 1, 4); // additiveColor
|
|
4663
|
+
initVertexAttribArray('r', glContext.FLOAT, 4, 1); // rotation
|
|
4631
4664
|
|
|
4632
4665
|
// build the transform matrix
|
|
4633
4666
|
const s = vec2(2*cameraScale).divide(mainCanvasSize);
|
|
@@ -4642,6 +4675,15 @@ function glPreRender()
|
|
|
4642
4675
|
);
|
|
4643
4676
|
}
|
|
4644
4677
|
|
|
4678
|
+
/** Clear the canvas and setup the viewport
|
|
4679
|
+
* @memberof WebGL */
|
|
4680
|
+
function glClearCanvas()
|
|
4681
|
+
{
|
|
4682
|
+
// clear and set to same size as main canvas
|
|
4683
|
+
glContext.viewport(0, 0, glCanvas.width=mainCanvas.width, glCanvas.height=mainCanvas.height);
|
|
4684
|
+
glContext.clear(glContext.COLOR_BUFFER_BIT);
|
|
4685
|
+
}
|
|
4686
|
+
|
|
4645
4687
|
/** Set the WebGl texture, called automatically if using multiple textures
|
|
4646
4688
|
* - This may also flush the gl buffer resulting in more draw calls and worse performance
|
|
4647
4689
|
* @param {WebGLTexture} texture
|
|
@@ -4653,7 +4695,7 @@ function glSetTexture(texture)
|
|
|
4653
4695
|
return;
|
|
4654
4696
|
|
|
4655
4697
|
glFlush();
|
|
4656
|
-
glContext.bindTexture(
|
|
4698
|
+
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture = texture);
|
|
4657
4699
|
}
|
|
4658
4700
|
|
|
4659
4701
|
/** Compile WebGL shader of the given type, will throw errors if in debug mode
|
|
@@ -4669,7 +4711,7 @@ function glCompileShader(source, type)
|
|
|
4669
4711
|
glContext.compileShader(shader);
|
|
4670
4712
|
|
|
4671
4713
|
// check for errors
|
|
4672
|
-
if (debug && !glContext.getShaderParameter(shader,
|
|
4714
|
+
if (debug && !glContext.getShaderParameter(shader, glContext.COMPILE_STATUS))
|
|
4673
4715
|
throw glContext.getShaderInfoLog(shader);
|
|
4674
4716
|
return shader;
|
|
4675
4717
|
}
|
|
@@ -4683,12 +4725,12 @@ function glCreateProgram(vsSource, fsSource)
|
|
|
4683
4725
|
{
|
|
4684
4726
|
// build the program
|
|
4685
4727
|
const program = glContext.createProgram();
|
|
4686
|
-
glContext.attachShader(program, glCompileShader(vsSource,
|
|
4687
|
-
glContext.attachShader(program, glCompileShader(fsSource,
|
|
4728
|
+
glContext.attachShader(program, glCompileShader(vsSource, glContext.VERTEX_SHADER));
|
|
4729
|
+
glContext.attachShader(program, glCompileShader(fsSource, glContext.FRAGMENT_SHADER));
|
|
4688
4730
|
glContext.linkProgram(program);
|
|
4689
4731
|
|
|
4690
4732
|
// check for errors
|
|
4691
|
-
if (debug && !glContext.getProgramParameter(program,
|
|
4733
|
+
if (debug && !glContext.getProgramParameter(program, glContext.LINK_STATUS))
|
|
4692
4734
|
throw glContext.getProgramInfoLog(program);
|
|
4693
4735
|
return program;
|
|
4694
4736
|
}
|
|
@@ -4701,20 +4743,20 @@ function glCreateTexture(image)
|
|
|
4701
4743
|
{
|
|
4702
4744
|
// build the texture
|
|
4703
4745
|
const texture = glContext.createTexture();
|
|
4704
|
-
glContext.bindTexture(
|
|
4746
|
+
glContext.bindTexture(glContext.TEXTURE_2D, texture);
|
|
4705
4747
|
if (image && image.width)
|
|
4706
|
-
glContext.texImage2D(
|
|
4748
|
+
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, image);
|
|
4707
4749
|
else
|
|
4708
4750
|
{
|
|
4709
4751
|
// create a white texture
|
|
4710
4752
|
const whitePixel = new Uint8Array([255, 255, 255, 255]);
|
|
4711
|
-
glContext.texImage2D(
|
|
4753
|
+
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, 1, 1, 0, glContext.RGBA, glContext.UNSIGNED_BYTE, whitePixel);
|
|
4712
4754
|
}
|
|
4713
4755
|
|
|
4714
4756
|
// use point filtering for pixelated rendering
|
|
4715
|
-
const filter = tilesPixelated ?
|
|
4716
|
-
glContext.texParameteri(
|
|
4717
|
-
glContext.texParameteri(
|
|
4757
|
+
const filter = tilesPixelated ? glContext.NEAREST : glContext.LINEAR;
|
|
4758
|
+
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MIN_FILTER, filter);
|
|
4759
|
+
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER, filter);
|
|
4718
4760
|
return texture;
|
|
4719
4761
|
}
|
|
4720
4762
|
|
|
@@ -4724,20 +4766,20 @@ function glFlush()
|
|
|
4724
4766
|
{
|
|
4725
4767
|
if (!glInstanceCount) return;
|
|
4726
4768
|
|
|
4727
|
-
const destBlend = glBatchAdditive ?
|
|
4728
|
-
glContext.blendFuncSeparate(
|
|
4729
|
-
glContext.enable(
|
|
4769
|
+
const destBlend = glBatchAdditive ? glContext.ONE : glContext.ONE_MINUS_SRC_ALPHA;
|
|
4770
|
+
glContext.blendFuncSeparate(glContext.SRC_ALPHA, destBlend, glContext.ONE, destBlend);
|
|
4771
|
+
glContext.enable(glContext.BLEND);
|
|
4730
4772
|
|
|
4731
4773
|
// draw all the sprites in the batch and reset the buffer
|
|
4732
|
-
glContext.bufferSubData(
|
|
4733
|
-
glContext.drawArraysInstanced(
|
|
4774
|
+
glContext.bufferSubData(glContext.ARRAY_BUFFER, 0, glPositionData);
|
|
4775
|
+
glContext.drawArraysInstanced(glContext.TRIANGLE_STRIP, 0, 4, glInstanceCount);
|
|
4734
4776
|
if (showWatermark)
|
|
4735
4777
|
drawCount += glInstanceCount;
|
|
4736
4778
|
glInstanceCount = 0;
|
|
4737
4779
|
glBatchAdditive = glAdditive;
|
|
4738
4780
|
}
|
|
4739
4781
|
|
|
4740
|
-
/** Draw any sprites still in the buffer
|
|
4782
|
+
/** Draw any sprites still in the buffer and copy to main canvas
|
|
4741
4783
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} context
|
|
4742
4784
|
* @param {Boolean} [forceDraw]
|
|
4743
4785
|
* @memberof WebGL */
|
|
@@ -4752,7 +4794,7 @@ function glCopyToContext(context, forceDraw=false)
|
|
|
4752
4794
|
context.drawImage(glCanvas, 0, 0);
|
|
4753
4795
|
}
|
|
4754
4796
|
|
|
4755
|
-
/** Set
|
|
4797
|
+
/** Set anti-aliasing for webgl canvas
|
|
4756
4798
|
* @param {Boolean} [antialias]
|
|
4757
4799
|
* @memberof WebGL */
|
|
4758
4800
|
function glSetAntialias(antialias=true)
|
|
@@ -4782,7 +4824,7 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
|
|
|
4782
4824
|
if (glInstanceCount >= gl_MAX_INSTANCES || glBatchAdditive != glAdditive)
|
|
4783
4825
|
glFlush();
|
|
4784
4826
|
|
|
4785
|
-
let offset = glInstanceCount *
|
|
4827
|
+
let offset = glInstanceCount++ * gl_INDICES_PER_INSTANCE;
|
|
4786
4828
|
glPositionData[offset++] = x;
|
|
4787
4829
|
glPositionData[offset++] = y;
|
|
4788
4830
|
glPositionData[offset++] = sizeX;
|
|
@@ -4794,41 +4836,7 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
|
|
|
4794
4836
|
glColorData[offset++] = rgba;
|
|
4795
4837
|
glColorData[offset++] = rgbaAdditive;
|
|
4796
4838
|
glPositionData[offset++] = angle;
|
|
4797
|
-
|
|
4798
|
-
}
|
|
4799
|
-
|
|
4800
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
4801
|
-
// store gl constants as integers so their name doesn't use space in minifed
|
|
4802
|
-
const
|
|
4803
|
-
gl_ONE = 1,
|
|
4804
|
-
gl_TRIANGLE_STRIP = 5,
|
|
4805
|
-
gl_SRC_ALPHA = 770,
|
|
4806
|
-
gl_ONE_MINUS_SRC_ALPHA = 771,
|
|
4807
|
-
gl_BLEND = 3042,
|
|
4808
|
-
gl_TEXTURE_2D = 3553,
|
|
4809
|
-
gl_UNSIGNED_BYTE = 5121,
|
|
4810
|
-
gl_FLOAT = 5126,
|
|
4811
|
-
gl_RGBA = 6408,
|
|
4812
|
-
gl_NEAREST = 9728,
|
|
4813
|
-
gl_LINEAR = 9729,
|
|
4814
|
-
gl_TEXTURE_MAG_FILTER = 10240,
|
|
4815
|
-
gl_TEXTURE_MIN_FILTER = 10241,
|
|
4816
|
-
gl_COLOR_BUFFER_BIT = 16384,
|
|
4817
|
-
gl_TEXTURE0 = 33984,
|
|
4818
|
-
gl_ARRAY_BUFFER = 34962,
|
|
4819
|
-
gl_STATIC_DRAW = 35044,
|
|
4820
|
-
gl_DYNAMIC_DRAW = 35048,
|
|
4821
|
-
gl_FRAGMENT_SHADER = 35632,
|
|
4822
|
-
gl_VERTEX_SHADER = 35633,
|
|
4823
|
-
gl_COMPILE_STATUS = 35713,
|
|
4824
|
-
gl_LINK_STATUS = 35714,
|
|
4825
|
-
gl_UNPACK_FLIP_Y_WEBGL = 37440,
|
|
4826
|
-
|
|
4827
|
-
// constants for batch rendering
|
|
4828
|
-
gl_INDICIES_PER_INSTANCE = 11,
|
|
4829
|
-
gl_MAX_INSTANCES = 1e4,
|
|
4830
|
-
gl_INSTANCE_BYTE_STRIDE = gl_INDICIES_PER_INSTANCE * 4, // 11 * 4
|
|
4831
|
-
gl_INSTANCE_BUFFER_SIZE = gl_MAX_INSTANCES * gl_INSTANCE_BYTE_STRIDE;
|
|
4839
|
+
}
|
|
4832
4840
|
/**
|
|
4833
4841
|
* LittleJS - The Tiny Fast JavaScript Game Engine
|
|
4834
4842
|
* MIT License - Copyright 2021 Frank Force
|
|
@@ -4861,7 +4869,7 @@ const engineName = 'LittleJS';
|
|
|
4861
4869
|
* @type {String}
|
|
4862
4870
|
* @default
|
|
4863
4871
|
* @memberof Engine */
|
|
4864
|
-
const engineVersion = '1.11.
|
|
4872
|
+
const engineVersion = '1.11.5';
|
|
4865
4873
|
|
|
4866
4874
|
/** Frames per second to update
|
|
4867
4875
|
* @type {Number}
|
|
@@ -4944,8 +4952,21 @@ function engineAddPlugin(updateFunction, renderFunction)
|
|
|
4944
4952
|
* @memberof Engine */
|
|
4945
4953
|
function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
|
|
4946
4954
|
{
|
|
4955
|
+
ASSERT(!mainContext, 'engine already initialized');
|
|
4947
4956
|
ASSERT(Array.isArray(imageSources), 'pass in images as array');
|
|
4948
4957
|
|
|
4958
|
+
// allow passing in empty functions
|
|
4959
|
+
if (!gameInit)
|
|
4960
|
+
gameInit = ()=>{};
|
|
4961
|
+
if (!gameUpdate)
|
|
4962
|
+
gameUpdate = ()=>{};
|
|
4963
|
+
if (!gameUpdatePost)
|
|
4964
|
+
gameUpdatePost = ()=>{};
|
|
4965
|
+
if (!gameRender)
|
|
4966
|
+
gameRender = ()=>{};
|
|
4967
|
+
if (!gameRenderPost)
|
|
4968
|
+
gameRenderPost = ()=>{};
|
|
4969
|
+
|
|
4949
4970
|
// Called automatically by engine to setup render system
|
|
4950
4971
|
function enginePreRender()
|
|
4951
4972
|
{
|
|
@@ -5110,7 +5131,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
5110
5131
|
(canvasPixelated ? 'image-rendering:pixelated;' : '') + // pixel art
|
|
5111
5132
|
'user-select:none;' + // prevent hold to select
|
|
5112
5133
|
'-webkit-user-select:none;' + // compatibility for ios
|
|
5113
|
-
(!touchInputEnable ? '' : // no touch css
|
|
5134
|
+
(!touchInputEnable ? '' : // no touch css settings
|
|
5114
5135
|
'touch-action:none;' + // prevent mobile pinch to resize
|
|
5115
5136
|
'-webkit-touch-callout:none');// compatibility for ios
|
|
5116
5137
|
rootElement.style.cssText = styleRoot;
|
|
@@ -5139,6 +5160,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
5139
5160
|
new Promise(resolve =>
|
|
5140
5161
|
{
|
|
5141
5162
|
const image = new Image;
|
|
5163
|
+
image.crossOrigin = 'anonymous';
|
|
5142
5164
|
image.onerror = image.onload = ()=>
|
|
5143
5165
|
{
|
|
5144
5166
|
textureInfos[textureIndex] = new TextureInfo(image);
|
|
@@ -5183,7 +5205,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
5183
5205
|
* @memberof Engine */
|
|
5184
5206
|
function engineObjectsUpdate()
|
|
5185
5207
|
{
|
|
5186
|
-
// get list of solid objects for physics
|
|
5208
|
+
// get list of solid objects for physics optimization
|
|
5187
5209
|
engineObjectsCollide = engineObjects.filter(o=>o.collideSolidObjects);
|
|
5188
5210
|
|
|
5189
5211
|
// recursive object update
|