littlejsengine 1.16.2 → 1.17.1
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 +200 -166
- package/dist/littlejs.esm.js +1231 -1086
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +888 -735
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +884 -731
- package/examples/box2d/gameObjects.js +1 -1
- package/examples/breakout/game.js +5 -6
- package/examples/electron/index.html +2 -2
- package/examples/electron/tiles.png +0 -0
- package/examples/htmlMenu/tiles.png +0 -0
- package/examples/index.html +1 -1
- package/examples/logo.png +0 -0
- package/examples/module/tiles.png +0 -0
- package/examples/platformer/gameEffects.js +23 -22
- package/examples/platformer/gameLevel.js +24 -25
- package/examples/shorts/base.html +1 -1
- package/examples/shorts/clock.js +3 -3
- package/examples/shorts/fontImage.js +4 -3
- package/examples/shorts/parallax.js +1 -1
- package/examples/shorts/sequencer.js +1 -1
- package/examples/shorts/shapes.js +1 -1
- package/examples/shorts/texture.js +10 -6
- package/examples/shorts/tiles.png +0 -0
- package/examples/shorts/tiltedView.js +2 -0
- package/examples/starter/index.html +2 -2
- package/examples/starter/tiles.png +0 -0
- package/examples/typescript/tiles.png +0 -0
- package/examples/uiSystem/game.js +1 -1
- package/examples/uiSystem/tiles.png +0 -0
- package/package.json +1 -1
- package/plugins/postProcess.js +47 -28
- package/plugins/uiSystem.js +15 -15
- package/reference.md +1 -1
- package/src/engine.js +174 -174
- package/src/engineAudio.js +4 -6
- package/src/engineDebug.js +4 -4
- package/src/engineDraw.js +179 -122
- package/src/engineExport.js +326 -334
- package/src/engineFont.png +0 -0
- package/src/engineInput.js +14 -20
- package/src/engineMath.js +15 -104
- package/src/engineObject.js +26 -25
- package/src/engineParticles.js +2 -2
- package/src/engineTileLayer.js +196 -170
- package/src/engineUtilities.js +100 -4
- package/src/engineWebGL.js +123 -72
package/src/engineInput.js
CHANGED
|
@@ -55,6 +55,10 @@ let inputPreventDefault = true;
|
|
|
55
55
|
* @memberof Input */
|
|
56
56
|
let gamepadPrimary = 0;
|
|
57
57
|
|
|
58
|
+
/** True if a touch device has been detected
|
|
59
|
+
* @memberof Input */
|
|
60
|
+
const isTouchDevice = !headlessMode && window.ontouchstart !== undefined;
|
|
61
|
+
|
|
58
62
|
/** Prevents input continuing to the default browser handling
|
|
59
63
|
* This is useful to disable for html menus so the browser can handle input normally
|
|
60
64
|
* @param {boolean} preventDefault
|
|
@@ -253,10 +257,6 @@ function gamepadStickCount(gamepad=gamepadPrimary)
|
|
|
253
257
|
return gamepadStickData[gamepad]?.length ?? 0;
|
|
254
258
|
}
|
|
255
259
|
|
|
256
|
-
/** True if a touch device has been detected
|
|
257
|
-
* @memberof Input */
|
|
258
|
-
const isTouchDevice = !headlessMode && window.ontouchstart !== undefined;
|
|
259
|
-
|
|
260
260
|
///////////////////////////////////////////////////////////////////////////////
|
|
261
261
|
|
|
262
262
|
/** Pulse the vibration hardware if it exists
|
|
@@ -265,7 +265,7 @@ const isTouchDevice = !headlessMode && window.ontouchstart !== undefined;
|
|
|
265
265
|
function vibrate(pattern=100)
|
|
266
266
|
{
|
|
267
267
|
ASSERT(isNumber(pattern) || isArray(pattern), 'pattern must be a number or array');
|
|
268
|
-
vibrateEnable && !headlessMode && navigator
|
|
268
|
+
vibrateEnable && !headlessMode && navigator?.vibrate?.(pattern);
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
/** Cancel any ongoing vibration
|
|
@@ -383,8 +383,8 @@ function inputInit()
|
|
|
383
383
|
}
|
|
384
384
|
function onMouseUp(e)
|
|
385
385
|
{
|
|
386
|
-
if (isTouchDevice && touchInputEnable)
|
|
387
|
-
|
|
386
|
+
if (isTouchDevice && touchInputEnable) return;
|
|
387
|
+
|
|
388
388
|
inputData[0][e.button] = (inputData[0][e.button]&2) | 4;
|
|
389
389
|
}
|
|
390
390
|
function onMouseMove(e)
|
|
@@ -570,8 +570,7 @@ function inputUpdate()
|
|
|
570
570
|
// update touch gamepad if enabled
|
|
571
571
|
if (touchGamepadEnable && isTouchDevice)
|
|
572
572
|
{
|
|
573
|
-
if (!touchGamepadTimer.isSet())
|
|
574
|
-
return;
|
|
573
|
+
if (!touchGamepadTimer.isSet()) return;
|
|
575
574
|
|
|
576
575
|
// read virtual analog stick
|
|
577
576
|
gamepadPrimary = 0; // touch gamepad uses index 0
|
|
@@ -609,12 +608,10 @@ function inputUpdate()
|
|
|
609
608
|
}
|
|
610
609
|
|
|
611
610
|
// return if gamepads are disabled or not supported
|
|
612
|
-
if (!gamepadsEnable || !navigator || !navigator.getGamepads)
|
|
613
|
-
return;
|
|
611
|
+
if (!gamepadsEnable || !navigator || !navigator.getGamepads) return;
|
|
614
612
|
|
|
615
613
|
// only poll gamepads when focused or in debug mode
|
|
616
|
-
if (!debug && !document.hasFocus())
|
|
617
|
-
return;
|
|
614
|
+
if (!debug && !document.hasFocus()) return;
|
|
618
615
|
|
|
619
616
|
// poll gamepads
|
|
620
617
|
const maxGamepads = 8;
|
|
@@ -651,8 +648,7 @@ function inputUpdate()
|
|
|
651
648
|
data[j] = button.pressed ? wasDown ? 1 : 3 : wasDown ? 4 : 0;
|
|
652
649
|
|
|
653
650
|
// check for any input on this gamepad, analog must be full press
|
|
654
|
-
if (button.pressed)
|
|
655
|
-
if (!button.value || button.value > .9)
|
|
651
|
+
if (button.pressed && (!button.value || button.value > .9))
|
|
656
652
|
hadInput = true;
|
|
657
653
|
}
|
|
658
654
|
|
|
@@ -681,7 +677,7 @@ function inputUpdate()
|
|
|
681
677
|
}
|
|
682
678
|
|
|
683
679
|
// copy dpad to left analog stick when pressed
|
|
684
|
-
if (gamepadDirectionEmulateStick &&
|
|
680
|
+
if (gamepadDirectionEmulateStick && (dpad.x || dpad.y))
|
|
685
681
|
sticks[0] = dpad.clampLength();
|
|
686
682
|
}
|
|
687
683
|
|
|
@@ -710,13 +706,11 @@ function inputRender()
|
|
|
710
706
|
function touchGamepadRender()
|
|
711
707
|
{
|
|
712
708
|
if (!touchInputEnable || !isTouchDevice || headlessMode) return;
|
|
713
|
-
if (!touchGamepadEnable || !touchGamepadTimer.isSet())
|
|
714
|
-
return;
|
|
709
|
+
if (!touchGamepadEnable || !touchGamepadTimer.isSet()) return;
|
|
715
710
|
|
|
716
711
|
// fade off when not touching or paused
|
|
717
712
|
const alpha = percent(touchGamepadTimer.get(), 4, 3);
|
|
718
|
-
if (!alpha || paused)
|
|
719
|
-
return;
|
|
713
|
+
if (!alpha || paused) return;
|
|
720
714
|
|
|
721
715
|
// setup the canvas
|
|
722
716
|
const context = mainContext;
|
package/src/engineMath.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* LittleJS
|
|
2
|
+
* LittleJS Math Classes and Functions
|
|
3
3
|
* - General purpose math library
|
|
4
|
-
* - Vector2 - fast, simple, easy 2D vector class
|
|
5
|
-
* - Color - holds a rgba color with some math functions
|
|
6
|
-
* - Timer - tracks time automatically
|
|
7
4
|
* - RandomGenerator - seeded random number generator
|
|
5
|
+
* - Vector2 - fast, simple, easy 2D vector class
|
|
6
|
+
* - Color - holds a rgba color with math functions
|
|
8
7
|
* @namespace Math
|
|
9
8
|
*/
|
|
10
9
|
|
|
@@ -194,11 +193,11 @@ function nearestPowerOfTwo(value) { return 2**ceil(log2(value)); }
|
|
|
194
193
|
|
|
195
194
|
/** Returns true if two axis aligned bounding boxes are overlapping
|
|
196
195
|
* this can be used for simple collision detection between objects
|
|
197
|
-
* @param {Vector2} posA
|
|
198
|
-
* @param {Vector2} sizeA
|
|
199
|
-
* @param {Vector2} posB
|
|
200
|
-
* @param {Vector2} [sizeB=(
|
|
201
|
-
* @return {boolean}
|
|
196
|
+
* @param {Vector2} posA - Center of box A
|
|
197
|
+
* @param {Vector2} sizeA - Size of box A
|
|
198
|
+
* @param {Vector2} posB - Center of box B
|
|
199
|
+
* @param {Vector2} [sizeB=vec2()] - Size of box B, uses a point if undefined
|
|
200
|
+
* @return {boolean} - True if overlapping
|
|
202
201
|
* @memberof Math */
|
|
203
202
|
function isOverlapping(posA, sizeA, posB, sizeB=vec2())
|
|
204
203
|
{
|
|
@@ -272,7 +271,7 @@ function isNumber(n) { return typeof n === 'number' && !isNaN(n); }
|
|
|
272
271
|
* @param {any} s
|
|
273
272
|
* @return {boolean}
|
|
274
273
|
* @memberof Math */
|
|
275
|
-
function isString(s) { return s
|
|
274
|
+
function isString(s) { return s != null && typeof s?.toString() === 'string'; }
|
|
276
275
|
|
|
277
276
|
/**
|
|
278
277
|
* Check if object is an array
|
|
@@ -416,8 +415,8 @@ function randInCircle(radius=1, minRadius=0)
|
|
|
416
415
|
{ return radius > 0 ? randVec2(radius * rand(minRadius / radius, 1)**.5) : new Vector2; }
|
|
417
416
|
|
|
418
417
|
/** Returns a random color between the two passed in colors, combine components if linear
|
|
419
|
-
* @param {Color} [colorA=
|
|
420
|
-
* @param {Color} [colorB=
|
|
418
|
+
* @param {Color} [colorA=WHITE]
|
|
419
|
+
* @param {Color} [colorB=BLACK]
|
|
421
420
|
* @param {boolean} [linear]
|
|
422
421
|
* @return {Color}
|
|
423
422
|
* @memberof Random */
|
|
@@ -496,8 +495,8 @@ class RandomGenerator
|
|
|
496
495
|
{ return vec2(this.float(valueA, valueB), this.float(valueA, valueB)); }
|
|
497
496
|
|
|
498
497
|
/** Returns a random color between the two passed in colors, combine components if linear
|
|
499
|
-
* @param {Color} [colorA=
|
|
500
|
-
* @param {Color} [colorB=
|
|
498
|
+
* @param {Color} [colorA=WHITE]
|
|
499
|
+
* @param {Color} [colorB=BLACK]
|
|
501
500
|
* @param {boolean} [linear]
|
|
502
501
|
* @return {Color} */
|
|
503
502
|
randColor(colorA=new Color, colorB=new Color(0,0,0,1), linear=false)
|
|
@@ -541,7 +540,7 @@ class RandomGenerator
|
|
|
541
540
|
* a = vec2(5); // set a to (5, 5)
|
|
542
541
|
* b = vec2(); // set b to (0, 0)
|
|
543
542
|
* @memberof Math */
|
|
544
|
-
function vec2(x=0, y) { return new Vector2(x, y
|
|
543
|
+
function vec2(x=0, y) { return new Vector2(x, y ?? x); }
|
|
545
544
|
|
|
546
545
|
/**
|
|
547
546
|
* Check if object is a valid Vector2
|
|
@@ -749,10 +748,6 @@ class Vector2
|
|
|
749
748
|
* @return {number} */
|
|
750
749
|
area() { return abs(this.x * this.y); }
|
|
751
750
|
|
|
752
|
-
/** Returns true if this vector is (0,0)
|
|
753
|
-
* @return {boolean} */
|
|
754
|
-
isZero() { return !this.x && !this.y; }
|
|
755
|
-
|
|
756
751
|
/** Returns a new vector that is p percent between this and the vector passed in
|
|
757
752
|
* @param {Vector2} v - other vector
|
|
758
753
|
* @param {number} percent
|
|
@@ -1114,88 +1109,4 @@ const PURPLE = debugProtectConstant(rgb(.5,0,1));
|
|
|
1114
1109
|
/** Color - Magenta #ff00ff
|
|
1115
1110
|
* @type {Color}
|
|
1116
1111
|
* @memberof Math */
|
|
1117
|
-
const MAGENTA = debugProtectConstant(rgb(1,0,1));
|
|
1118
|
-
|
|
1119
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1120
|
-
|
|
1121
|
-
/**
|
|
1122
|
-
* Timer object tracks how long has passed since it was set
|
|
1123
|
-
* @memberof Engine
|
|
1124
|
-
* @example
|
|
1125
|
-
* let a = new Timer; // creates a timer that is not set
|
|
1126
|
-
* a.set(3); // sets the timer to 3 seconds
|
|
1127
|
-
*
|
|
1128
|
-
* let b = new Timer(1); // creates a timer with 1 second left
|
|
1129
|
-
* b.unset(); // unset the timer
|
|
1130
|
-
*/
|
|
1131
|
-
class Timer
|
|
1132
|
-
{
|
|
1133
|
-
/** Create a timer object set time passed in
|
|
1134
|
-
* @param {number} [timeLeft] - How much time left before the timer
|
|
1135
|
-
* @param {boolean} [useRealTime] - Should the timer keep running even when the game is paused? (useful for UI) */
|
|
1136
|
-
constructor(timeLeft, useRealTime=false)
|
|
1137
|
-
{
|
|
1138
|
-
ASSERT(timeLeft === undefined || isNumber(timeLeft), 'Constructed Timer is invalid.', timeLeft);
|
|
1139
|
-
this.useRealTime = useRealTime;
|
|
1140
|
-
const globalTime = this.getGlobalTime();
|
|
1141
|
-
this.time = timeLeft === undefined ? undefined : globalTime + timeLeft;
|
|
1142
|
-
this.setTime = timeLeft;
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
/** Set the timer with seconds passed in
|
|
1146
|
-
* @param {number} [timeLeft] - How much time left before the timer is elapsed in seconds */
|
|
1147
|
-
set(timeLeft=0)
|
|
1148
|
-
{
|
|
1149
|
-
ASSERT(isNumber(timeLeft), 'Timer is invalid.', timeLeft);
|
|
1150
|
-
const globalTime = this.getGlobalTime();
|
|
1151
|
-
this.time = globalTime + timeLeft;
|
|
1152
|
-
this.setTime = timeLeft;
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
/** Set if the timer should keep running even when the game is paused
|
|
1156
|
-
* @param {boolean} [useRealTime] */
|
|
1157
|
-
setUseRealTime(useRealTime=true)
|
|
1158
|
-
{
|
|
1159
|
-
ASSERT(!this.isSet(), 'Cannot change global time setting while timer is set.');
|
|
1160
|
-
this.useRealTime = useRealTime;
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
/** Unset the timer */
|
|
1164
|
-
unset() { this.time = undefined; }
|
|
1165
|
-
|
|
1166
|
-
/** Returns true if set
|
|
1167
|
-
* @return {boolean} */
|
|
1168
|
-
isSet() { return this.time !== undefined; }
|
|
1169
|
-
|
|
1170
|
-
/** Returns true if set and has not elapsed
|
|
1171
|
-
* @return {boolean} */
|
|
1172
|
-
active() { return this.getGlobalTime() < this.time; }
|
|
1173
|
-
|
|
1174
|
-
/** Returns true if set and elapsed
|
|
1175
|
-
* @return {boolean} */
|
|
1176
|
-
elapsed() { return this.getGlobalTime() >= this.time; }
|
|
1177
|
-
|
|
1178
|
-
/** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
|
|
1179
|
-
* @return {number} */
|
|
1180
|
-
get() { return this.isSet()? this.getGlobalTime() - this.time : 0; }
|
|
1181
|
-
|
|
1182
|
-
/** Get percentage elapsed based on time it was set to, returns 0 if not set
|
|
1183
|
-
* @return {number} */
|
|
1184
|
-
getPercent() { return this.isSet()? 1-percent(this.time - this.getGlobalTime(), 0, this.setTime) : 0; }
|
|
1185
|
-
|
|
1186
|
-
/** Get the time this timer was set to, returns 0 if not set
|
|
1187
|
-
* @return {number} */
|
|
1188
|
-
getSetTime() { return this.isSet() ? this.setTime : 0; }
|
|
1189
|
-
|
|
1190
|
-
/** Get the current global time this timer is based on
|
|
1191
|
-
* @return {number} */
|
|
1192
|
-
getGlobalTime() { return this.useRealTime ? timeReal : time; }
|
|
1193
|
-
|
|
1194
|
-
/** Returns this timer expressed as a string
|
|
1195
|
-
* @return {string} */
|
|
1196
|
-
toString() { return this.isSet() ? abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ) : 'unset'; }
|
|
1197
|
-
|
|
1198
|
-
/** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
|
|
1199
|
-
* @return {number} */
|
|
1200
|
-
valueOf() { return this.get(); }
|
|
1201
|
-
}
|
|
1112
|
+
const MAGENTA = debugProtectConstant(rgb(1,0,1));
|
package/src/engineObject.js
CHANGED
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
class EngineObject
|
|
34
34
|
{
|
|
35
35
|
/** Create an engine object and adds it to the list of objects
|
|
36
|
-
* @param {Vector2} [pos=(
|
|
37
|
-
* @param {Vector2} [size=(1
|
|
38
|
-
* @param {TileInfo} [tileInfo]
|
|
39
|
-
* @param {number} [angle]
|
|
36
|
+
* @param {Vector2} [pos=vec2()] - World space position of the object
|
|
37
|
+
* @param {Vector2} [size=vec2(1)] - World space size of the object
|
|
38
|
+
* @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
|
|
39
|
+
* @param {number} [angle] - Angle the object is rotated by
|
|
40
40
|
* @param {Color} [color=WHITE] - Color to apply to tile when rendered
|
|
41
41
|
* @param {number} [renderOrder] - Objects sorted by renderOrder before being rendered
|
|
42
42
|
*/
|
|
@@ -164,15 +164,16 @@ class EngineObject
|
|
|
164
164
|
// physics sanity checks
|
|
165
165
|
ASSERT(this.angleDamping >= 0 && this.angleDamping <= 1);
|
|
166
166
|
ASSERT(this.damping >= 0 && this.damping <= 1);
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
|
|
168
|
+
// don't do collision for static objects or if solver disabled
|
|
169
|
+
if (!enablePhysicsSolver || !this.mass) return;
|
|
169
170
|
|
|
170
171
|
const wasFalling = this.velocity.y < 0 && gravity.y < 0 || this.velocity.y > 0 && gravity.y > 0;
|
|
171
172
|
if (this.groundObject)
|
|
172
173
|
{
|
|
173
174
|
// apply friction in local space of ground object
|
|
174
175
|
const friction = max(this.friction, this.groundObject.friction);
|
|
175
|
-
const groundSpeed = this.groundObject.velocity
|
|
176
|
+
const groundSpeed = this.groundObject.velocity.x;
|
|
176
177
|
this.velocity.x = groundSpeed + (this.velocity.x - groundSpeed) * friction;
|
|
177
178
|
this.groundObject = undefined;
|
|
178
179
|
}
|
|
@@ -183,19 +184,19 @@ class EngineObject
|
|
|
183
184
|
const epsilon = .001; // necessary to push slightly outside of the collision
|
|
184
185
|
for (const o of engineObjectsCollide)
|
|
185
186
|
{
|
|
187
|
+
// skip destroyed, child objects, or self collision
|
|
188
|
+
if (o.destroyed || o.parent || o === this) continue;
|
|
189
|
+
|
|
186
190
|
// non solid objects don't collide with each other
|
|
187
|
-
if (
|
|
188
|
-
continue;
|
|
191
|
+
if (!this.isSolid && !o.isSolid) continue;
|
|
189
192
|
|
|
190
193
|
// check collision
|
|
191
|
-
if (!this.isOverlappingObject(o))
|
|
192
|
-
continue;
|
|
194
|
+
if (!this.isOverlappingObject(o)) continue;
|
|
193
195
|
|
|
194
196
|
// notify objects of collision and check if should be resolved
|
|
195
197
|
const collide1 = this.collideWithObject(o);
|
|
196
198
|
const collide2 = o.collideWithObject(this);
|
|
197
|
-
if (!collide1 || !collide2)
|
|
198
|
-
continue;
|
|
199
|
+
if (!collide1 || !collide2) continue;
|
|
199
200
|
|
|
200
201
|
if (isOverlapping(oldPos, this.size, o.pos, o.size))
|
|
201
202
|
{
|
|
@@ -297,7 +298,7 @@ class EngineObject
|
|
|
297
298
|
const delta = y - this.pos.y;
|
|
298
299
|
if (delta < maxMoveUp)
|
|
299
300
|
if (!tileCollisionTest(vec2(this.pos.x, y), this.size, this))
|
|
300
|
-
{
|
|
301
|
+
{
|
|
301
302
|
this.pos.y = y;
|
|
302
303
|
debugPhysics && debugRect(this.pos, this.size, '#ff0');
|
|
303
304
|
return;
|
|
@@ -357,10 +358,10 @@ class EngineObject
|
|
|
357
358
|
|
|
358
359
|
// disconnect from parent and destroy children
|
|
359
360
|
this.destroyed = 1;
|
|
360
|
-
this.parent
|
|
361
|
+
this.parent?.removeChild(this);
|
|
361
362
|
for (const child of this.children)
|
|
362
363
|
{
|
|
363
|
-
child.parent =
|
|
364
|
+
child.parent = undefined;
|
|
364
365
|
child.destroy();
|
|
365
366
|
}
|
|
366
367
|
}
|
|
@@ -381,15 +382,15 @@ class EngineObject
|
|
|
381
382
|
* @param {Vector2} vec - world space vector */
|
|
382
383
|
worldToLocalVector(vec) { return vec.rotate(-this.angle); }
|
|
383
384
|
|
|
384
|
-
/** Called to check if a tile collision should be resolved
|
|
385
|
+
/** Called to check if a tile collision should be resolved. Return true for physics to resolve the collision or false to ignore and resolve it manually.
|
|
385
386
|
* @param {number} tileData - the value of the tile at the position
|
|
386
|
-
* @param {Vector2} pos
|
|
387
|
-
* @return {boolean}
|
|
387
|
+
* @param {Vector2} pos - tile where the collision occurred
|
|
388
|
+
* @return {boolean} - true if the collision should be resolved by modifying it's position and velocity */
|
|
388
389
|
collideWithTile(tileData, pos) { return tileData > 0; }
|
|
389
390
|
|
|
390
|
-
/** Called to check if
|
|
391
|
+
/** Called by the engine to check if an object collision should be resolved. Return true for physics to resolve the collision or false to ignore and resolve it manually.
|
|
391
392
|
* @param {EngineObject} object - the object to test against
|
|
392
|
-
* @return {boolean}
|
|
393
|
+
* @return {boolean} - true if the collision should be resolved by modifying it's position and velocity
|
|
393
394
|
*/
|
|
394
395
|
collideWithObject(object) { return true; }
|
|
395
396
|
|
|
@@ -430,9 +431,9 @@ class EngineObject
|
|
|
430
431
|
* @return {number} -1 if this.mirror is true, or 1 if not mirrored */
|
|
431
432
|
getMirrorSign() { return this.mirror ? -1 : 1; }
|
|
432
433
|
|
|
433
|
-
/** Attaches a child to this with a local transform, returns child for chaining
|
|
434
|
+
/** Attaches a child to this with a local transform, returns child for chaining
|
|
434
435
|
* @param {EngineObject} child
|
|
435
|
-
* @param {Vector2} [localPos=(
|
|
436
|
+
* @param {Vector2} [localPos=vec2()]
|
|
436
437
|
* @param {number} [localAngle]
|
|
437
438
|
* @return {EngineObject} The child object added */
|
|
438
439
|
addChild(child, localPos=vec2(), localAngle=0)
|
|
@@ -456,7 +457,7 @@ class EngineObject
|
|
|
456
457
|
const index = this.children.indexOf(child);
|
|
457
458
|
ASSERT(index >= 0, 'child not found in children array');
|
|
458
459
|
index >= 0 && this.children.splice(index, 1);
|
|
459
|
-
child.parent =
|
|
460
|
+
child.parent = undefined;
|
|
460
461
|
}
|
|
461
462
|
|
|
462
463
|
/** Check if overlapping another engine object
|
|
@@ -468,7 +469,7 @@ class EngineObject
|
|
|
468
469
|
|
|
469
470
|
/** Check if overlapping a point or aligned bounding box
|
|
470
471
|
* @param {Vector2} pos - Center of box
|
|
471
|
-
* @param {Vector2} [size=(
|
|
472
|
+
* @param {Vector2} [size=vec2()] - Size of box, uses a point if undefined
|
|
472
473
|
* @return {boolean} */
|
|
473
474
|
isOverlapping(pos, size=vec2())
|
|
474
475
|
{ return isOverlapping(this.pos, this.size, pos, size); }
|
package/src/engineParticles.js
CHANGED
|
@@ -255,7 +255,7 @@ class ParticleEmitter extends EngineObject
|
|
|
255
255
|
particle.mirror = randBool();
|
|
256
256
|
|
|
257
257
|
// call particle create callback
|
|
258
|
-
this.particleCreateCallback
|
|
258
|
+
this.particleCreateCallback?.(particle);
|
|
259
259
|
|
|
260
260
|
// return the newly created particle
|
|
261
261
|
return particle;
|
|
@@ -340,7 +340,7 @@ class Particle extends EngineObject
|
|
|
340
340
|
const c = this.colorEnd;
|
|
341
341
|
this.color.set(c.r, c.g, c.b, c.a);
|
|
342
342
|
this.size.set(this.sizeEnd, this.sizeEnd);
|
|
343
|
-
this.destroyCallback
|
|
343
|
+
this.destroyCallback?.(this);
|
|
344
344
|
this.destroyed = 1;
|
|
345
345
|
}
|
|
346
346
|
}
|