littlejsengine 1.12.6 → 1.13.4
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/README.md +15 -12
- package/dist/littlejs.d.ts +466 -236
- package/dist/littlejs.esm.js +6126 -5370
- package/dist/littlejs.esm.min.js +4 -1
- package/dist/littlejs.js +6093 -5359
- package/dist/littlejs.min.js +4 -1
- package/dist/littlejs.release.js +5614 -4907
- package/examples/box2d/game.js +2 -2
- package/examples/box2d/gameObjects.js +8 -7
- package/examples/box2d/index.html +1 -1
- package/examples/box2d/scenes.js +8 -8
- package/examples/breakout/game.js +1 -1
- package/examples/breakout/gameObjects.js +2 -2
- package/examples/breakout/index.html +1 -1
- package/examples/breakoutTutorial/README.md +46 -43
- package/examples/breakoutTutorial/game.js +3 -3
- package/examples/breakoutTutorial/index.html +1 -1
- package/examples/electron/build.bat +7 -0
- package/examples/electron/build.js +124 -0
- package/examples/electron/electron.js +35 -0
- package/examples/electron/game.js +140 -0
- package/examples/electron/index.html +13 -0
- package/examples/electron/package.json +12 -0
- package/examples/electron/tiles.png +0 -0
- package/examples/empty/game.js +1 -0
- package/examples/empty/index.html +1 -1
- package/examples/htmlMenu/game.js +1 -1
- package/examples/htmlMenu/index.html +1 -1
- package/examples/index.html +486 -182
- package/examples/module/game.js +6 -3
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +12 -3
- package/examples/platformer/game.js +4 -4
- package/examples/platformer/gameCharacter.js +6 -6
- package/examples/platformer/gameEffects.js +74 -57
- package/examples/platformer/gameLevel.js +61 -70
- package/examples/platformer/gameObjects.js +4 -4
- package/examples/platformer/index.html +1 -1
- package/examples/puzzle/index.html +1 -1
- package/examples/shorts/base.html +23 -3
- package/examples/shorts/blending.js +9 -5
- package/examples/shorts/box2d.js +1 -1
- package/examples/shorts/box2dCar.js +9 -13
- package/examples/shorts/clock.js +1 -1
- package/examples/shorts/colors.js +2 -2
- package/examples/shorts/flappyGame.js +52 -0
- package/examples/shorts/helloWorld.js +6 -3
- package/examples/shorts/hillGlideGame.js +56 -0
- package/examples/shorts/landerGame.js +32 -0
- package/examples/shorts/maze.js +47 -0
- package/examples/shorts/medals.js +42 -0
- package/examples/shorts/nineSlice.js +21 -0
- package/examples/shorts/piano.js +52 -0
- package/examples/shorts/platformer.js +24 -20
- package/examples/shorts/{pong.js → pongGame.js} +1 -1
- package/examples/shorts/raycasting.js +71 -0
- package/examples/shorts/shapes.js +9 -9
- package/examples/shorts/slidingPuzzle.js +42 -0
- package/examples/shorts/spaceGame.js +56 -0
- package/examples/shorts/starfield.js +15 -0
- package/examples/shorts/systemFont.js +1 -1
- package/examples/shorts/tileLayer.js +3 -5
- package/examples/shorts/tiles.png +0 -0
- package/examples/shorts/tiltedView.js +8 -7
- package/examples/shorts/topDown.js +18 -26
- package/examples/shorts/uiSystem.js +5 -7
- package/examples/starter/build.bat +6 -1
- package/examples/starter/build.js +9 -8
- package/examples/starter/game.js +7 -4
- package/examples/starter/index.html +23 -13
- package/examples/stress/index.html +7 -8
- package/examples/style.css +139 -0
- package/examples/typescript/build.js +2 -3
- package/examples/typescript/game.js +4 -4
- package/examples/typescript/game.ts +6 -3
- package/examples/typescript/index.html +1 -1
- package/examples/uiSystem/game.js +10 -25
- package/examples/uiSystem/index.html +1 -1
- package/package.json +2 -2
- package/plugins/box2d.js +22 -97
- package/plugins/drawUtilities.js +132 -0
- package/plugins/newgrounds.js +1 -1
- package/plugins/pluginExport.js +7 -1
- package/plugins/postProcess.js +9 -2
- package/plugins/uiSystem.js +155 -67
- package/plugins/zzfxm.js +1 -1
- package/reference.md +10 -10
- package/src/engine.js +56 -30
- package/src/engineAudio.js +15 -6
- package/src/engineBuild.bat +6 -1
- package/src/engineBuild.js +20 -5
- package/src/engineDebug.js +55 -28
- package/src/engineDraw.js +321 -177
- package/src/engineExport.js +27 -9
- package/src/engineInput.js +110 -38
- package/src/engineMedals.js +4 -4
- package/src/engineObject.js +71 -70
- package/src/engineParticles.js +33 -9
- package/src/engineSettings.js +69 -23
- package/src/engineTileLayer.js +312 -153
- package/src/engineUtilities.js +187 -135
- package/src/engineWebGL.js +70 -39
package/src/engineObject.js
CHANGED
|
@@ -41,9 +41,13 @@ class EngineObject
|
|
|
41
41
|
*/
|
|
42
42
|
constructor(pos=vec2(), size=vec2(1), tileInfo, angle=0, color=new Color, renderOrder=0)
|
|
43
43
|
{
|
|
44
|
-
//
|
|
45
|
-
ASSERT(isVector2(pos) &&
|
|
46
|
-
ASSERT(
|
|
44
|
+
// check passed in params
|
|
45
|
+
ASSERT(isVector2(pos) && pos.isValid(), 'object pos should be a vec2');
|
|
46
|
+
ASSERT(isVector2(size) && size.isValid(), 'object size should be a vec2');
|
|
47
|
+
ASSERT(!tileInfo || tileInfo instanceof TileInfo, 'object tileInfo should be a TileInfo or undefined');
|
|
48
|
+
ASSERT(typeof angle == 'number' && isFinite(angle), 'object angle should be a number');
|
|
49
|
+
ASSERT(isColor(color) && color.isValid(), 'object color should be a valid rgba color');
|
|
50
|
+
ASSERT(typeof renderOrder == 'number', 'object renderOrder should be a number');
|
|
47
51
|
|
|
48
52
|
/** @property {Vector2} - World space position of the object */
|
|
49
53
|
this.pos = pos.copy();
|
|
@@ -53,49 +57,49 @@ class EngineObject
|
|
|
53
57
|
this.drawSize = undefined;
|
|
54
58
|
/** @property {TileInfo} - Tile info to render object (undefined is untextured) */
|
|
55
59
|
this.tileInfo = tileInfo;
|
|
56
|
-
/** @property {number}
|
|
60
|
+
/** @property {number} - Angle to rotate the object */
|
|
57
61
|
this.angle = angle;
|
|
58
|
-
/** @property {Color}
|
|
62
|
+
/** @property {Color} - Color to apply when rendered */
|
|
59
63
|
this.color = color;
|
|
60
|
-
/** @property {Color}
|
|
64
|
+
/** @property {Color} - Additive color to apply when rendered */
|
|
61
65
|
this.additiveColor = undefined;
|
|
62
66
|
/** @property {boolean} - Should it flip along y axis when rendered */
|
|
63
67
|
this.mirror = false;
|
|
64
68
|
|
|
65
69
|
// physical properties
|
|
66
|
-
/** @property {number} [mass=objectDefaultMass]
|
|
67
|
-
this.mass
|
|
68
|
-
/** @property {number} [damping=objectDefaultDamping]
|
|
69
|
-
this.damping
|
|
70
|
+
/** @property {number} [mass=objectDefaultMass] - How heavy the object is, static if 0 */
|
|
71
|
+
this.mass = objectDefaultMass;
|
|
72
|
+
/** @property {number} [damping=objectDefaultDamping] - How much to slow down velocity each frame (0-1) */
|
|
73
|
+
this.damping = objectDefaultDamping;
|
|
70
74
|
/** @property {number} [angleDamping=objectDefaultAngleDamping] - How much to slow down rotation each frame (0-1) */
|
|
71
75
|
this.angleDamping = objectDefaultAngleDamping;
|
|
72
|
-
/** @property {number} [
|
|
73
|
-
this.
|
|
74
|
-
/** @property {number} [friction=objectDefaultFriction]
|
|
75
|
-
this.friction
|
|
76
|
-
/** @property {number}
|
|
76
|
+
/** @property {number} [restitution=objectDefaultRestitution] - How bouncy the object is when colliding (0-1) */
|
|
77
|
+
this.restitution = objectDefaultRestitution;
|
|
78
|
+
/** @property {number} [friction=objectDefaultFriction] - How much friction to apply when sliding (0-1) */
|
|
79
|
+
this.friction = objectDefaultFriction;
|
|
80
|
+
/** @property {number} - How much to scale gravity by for this object */
|
|
77
81
|
this.gravityScale = 1;
|
|
78
|
-
/** @property {number}
|
|
82
|
+
/** @property {number} - Objects are sorted by render order */
|
|
79
83
|
this.renderOrder = renderOrder;
|
|
80
84
|
/** @property {Vector2} - Velocity of the object */
|
|
81
85
|
this.velocity = vec2();
|
|
82
|
-
/** @property {number}
|
|
86
|
+
/** @property {number} - Angular velocity of the object */
|
|
83
87
|
this.angleVelocity = 0;
|
|
84
|
-
/** @property {number}
|
|
88
|
+
/** @property {number} - Track when object was created */
|
|
85
89
|
this.spawnTime = time;
|
|
86
|
-
/** @property {Array<EngineObject>}
|
|
90
|
+
/** @property {Array<EngineObject>} - List of children of this object */
|
|
87
91
|
this.children = [];
|
|
88
|
-
/** @property {boolean}
|
|
89
|
-
this.
|
|
92
|
+
/** @property {boolean} - Limit object speed along x and y axis */
|
|
93
|
+
this.clampSpeed = true;
|
|
90
94
|
/** @property {EngineObject} - Object we are standing on, if any */
|
|
91
95
|
this.groundObject = undefined;
|
|
92
96
|
|
|
93
97
|
// parent child system
|
|
94
98
|
/** @property {EngineObject} - Parent of object if in local space */
|
|
95
99
|
this.parent = undefined;
|
|
96
|
-
/** @property {Vector2}
|
|
100
|
+
/** @property {Vector2} - Local position if child */
|
|
97
101
|
this.localPos = vec2();
|
|
98
|
-
/** @property {number}
|
|
102
|
+
/** @property {number} - Local angle if child */
|
|
99
103
|
this.localAngle = 0;
|
|
100
104
|
|
|
101
105
|
// collision flags
|
|
@@ -136,29 +140,20 @@ class EngineObject
|
|
|
136
140
|
if (this.parent)
|
|
137
141
|
return;
|
|
138
142
|
|
|
139
|
-
|
|
140
|
-
if (this.clampSpeedLinear)
|
|
143
|
+
if (this.clampSpeed)
|
|
141
144
|
{
|
|
145
|
+
// limit max speed to prevent missing collisions
|
|
142
146
|
this.velocity.x = clamp(this.velocity.x, -objectMaxSpeed, objectMaxSpeed);
|
|
143
147
|
this.velocity.y = clamp(this.velocity.y, -objectMaxSpeed, objectMaxSpeed);
|
|
144
148
|
}
|
|
145
|
-
else
|
|
146
|
-
{
|
|
147
|
-
const length2 = this.velocity.lengthSquared();
|
|
148
|
-
if (length2 > objectMaxSpeed*objectMaxSpeed)
|
|
149
|
-
{
|
|
150
|
-
const s = objectMaxSpeed / length2**.5;
|
|
151
|
-
this.velocity.x *= s;
|
|
152
|
-
this.velocity.y *= s;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
149
|
|
|
156
150
|
// apply physics
|
|
157
151
|
const oldPos = this.pos.copy();
|
|
158
152
|
this.velocity.x *= this.damping;
|
|
159
153
|
this.velocity.y *= this.damping;
|
|
160
|
-
if (this.mass)
|
|
154
|
+
if (this.mass)
|
|
161
155
|
{
|
|
156
|
+
// apply gravity only if it has mass
|
|
162
157
|
this.velocity.x += gravity.x * this.gravityScale;
|
|
163
158
|
this.velocity.y += gravity.y * this.gravityScale;
|
|
164
159
|
}
|
|
@@ -180,7 +175,6 @@ class EngineObject
|
|
|
180
175
|
const groundSpeed = this.groundObject.velocity ? this.groundObject.velocity.x : 0;
|
|
181
176
|
this.velocity.x = groundSpeed + (this.velocity.x - groundSpeed) * friction;
|
|
182
177
|
this.groundObject = undefined;
|
|
183
|
-
//debugOverlay && debugPhysics && debugPoint(this.pos.subtract(vec2(0,this.size.y/2)), '#0f0');
|
|
184
178
|
}
|
|
185
179
|
|
|
186
180
|
if (this.collideSolidObjects)
|
|
@@ -209,12 +203,12 @@ class EngineObject
|
|
|
209
203
|
const deltaPos = oldPos.subtract(o.pos);
|
|
210
204
|
const length = deltaPos.length();
|
|
211
205
|
const pushAwayAccel = .001; // push away if already overlapping
|
|
212
|
-
const velocity = length < .01 ?
|
|
206
|
+
const velocity = length < .01 ? randVec2(pushAwayAccel) : deltaPos.scale(pushAwayAccel/length);
|
|
213
207
|
this.velocity = this.velocity.add(velocity);
|
|
214
208
|
if (o.mass) // push away if not fixed
|
|
215
209
|
o.velocity = o.velocity.subtract(velocity);
|
|
216
210
|
|
|
217
|
-
|
|
211
|
+
debugPhysics && debugOverlap(this.pos, this.size, o.pos, o.size, '#f00');
|
|
218
212
|
continue;
|
|
219
213
|
}
|
|
220
214
|
|
|
@@ -223,7 +217,7 @@ class EngineObject
|
|
|
223
217
|
const smallStepUp = (oldPos.y - o.pos.y)*2 > sizeBoth.y + gravity.y; // prefer to push up if small delta
|
|
224
218
|
const isBlockedX = abs(oldPos.y - o.pos.y)*2 < sizeBoth.y;
|
|
225
219
|
const isBlockedY = abs(oldPos.x - o.pos.x)*2 < sizeBoth.x;
|
|
226
|
-
const
|
|
220
|
+
const restitution = max(this.restitution, o.restitution);
|
|
227
221
|
|
|
228
222
|
if (smallStepUp || isBlockedY || !isBlockedX) // resolve y collision
|
|
229
223
|
{
|
|
@@ -236,7 +230,7 @@ class EngineObject
|
|
|
236
230
|
this.groundObject = o;
|
|
237
231
|
|
|
238
232
|
// bounce if other object is fixed or grounded
|
|
239
|
-
this.velocity.y *= -
|
|
233
|
+
this.velocity.y *= -restitution;
|
|
240
234
|
}
|
|
241
235
|
else if (o.mass)
|
|
242
236
|
{
|
|
@@ -249,9 +243,9 @@ class EngineObject
|
|
|
249
243
|
const elastic1 = o.velocity.y * (o.mass - this.mass) / (this.mass + o.mass)
|
|
250
244
|
+ this.velocity.y * 2 * this.mass / (this.mass + o.mass);
|
|
251
245
|
|
|
252
|
-
// lerp between elastic or inelastic based on
|
|
253
|
-
this.velocity.y = lerp(
|
|
254
|
-
o.velocity.y = lerp(
|
|
246
|
+
// lerp between elastic or inelastic based on restitution
|
|
247
|
+
this.velocity.y = lerp(inelastic, elastic0, restitution);
|
|
248
|
+
o.velocity.y = lerp(inelastic, elastic1, restitution);
|
|
255
249
|
}
|
|
256
250
|
}
|
|
257
251
|
if (!smallStepUp && isBlockedX) // resolve x collision
|
|
@@ -269,14 +263,14 @@ class EngineObject
|
|
|
269
263
|
const elastic1 = o.velocity.x * (o.mass - this.mass) / (this.mass + o.mass)
|
|
270
264
|
+ this.velocity.x * 2 * this.mass / (this.mass + o.mass);
|
|
271
265
|
|
|
272
|
-
// lerp between elastic or inelastic based on
|
|
273
|
-
this.velocity.x = lerp(
|
|
274
|
-
o.velocity.x = lerp(
|
|
266
|
+
// lerp between elastic or inelastic based on restitution
|
|
267
|
+
this.velocity.x = lerp(inelastic, elastic0, restitution);
|
|
268
|
+
o.velocity.x = lerp(inelastic, elastic1, restitution);
|
|
275
269
|
}
|
|
276
270
|
else // bounce if other object is fixed
|
|
277
|
-
this.velocity.x *= -
|
|
271
|
+
this.velocity.x *= -restitution;
|
|
278
272
|
}
|
|
279
|
-
|
|
273
|
+
debugPhysics && debugOverlap(this.pos, this.size, o.pos, o.size, '#f0f');
|
|
280
274
|
}
|
|
281
275
|
}
|
|
282
276
|
if (this.collideTiles)
|
|
@@ -295,8 +289,8 @@ class EngineObject
|
|
|
295
289
|
if (blockedLayerY || !blockedLayerX)
|
|
296
290
|
{
|
|
297
291
|
// bounce velocity
|
|
298
|
-
const
|
|
299
|
-
this.velocity.y *= -
|
|
292
|
+
const restitution = max(this.restitution, hitLayer.restitution);
|
|
293
|
+
this.velocity.y *= -restitution;
|
|
300
294
|
|
|
301
295
|
if (wasMovingDown)
|
|
302
296
|
{
|
|
@@ -319,9 +313,9 @@ class EngineObject
|
|
|
319
313
|
{
|
|
320
314
|
// move to previous position and bounce
|
|
321
315
|
this.pos.x = oldPos.x;
|
|
322
|
-
this.velocity.x *= -this.
|
|
316
|
+
this.velocity.x *= -this.restitution;
|
|
323
317
|
}
|
|
324
|
-
|
|
318
|
+
debugPhysics && debugRect(this.pos, this.size, '#f00');
|
|
325
319
|
}
|
|
326
320
|
}
|
|
327
321
|
}
|
|
@@ -334,7 +328,7 @@ class EngineObject
|
|
|
334
328
|
drawTile(this.pos, this.drawSize || this.size, this.tileInfo, this.color, this.angle, this.mirror, this.additiveColor);
|
|
335
329
|
}
|
|
336
330
|
|
|
337
|
-
/** Destroy this object, destroy
|
|
331
|
+
/** Destroy this object, destroy its children, detach it's parent, and mark it for removal */
|
|
338
332
|
destroy()
|
|
339
333
|
{
|
|
340
334
|
if (this.destroyed)
|
|
@@ -344,7 +338,10 @@ class EngineObject
|
|
|
344
338
|
this.destroyed = 1;
|
|
345
339
|
this.parent && this.parent.removeChild(this);
|
|
346
340
|
for (const child of this.children)
|
|
347
|
-
|
|
341
|
+
{
|
|
342
|
+
child.parent = 0;
|
|
343
|
+
child.destroy();
|
|
344
|
+
}
|
|
348
345
|
}
|
|
349
346
|
|
|
350
347
|
/** Convert from local space to world space
|
|
@@ -367,25 +364,29 @@ class EngineObject
|
|
|
367
364
|
* @param {number} tileData - the value of the tile at the position
|
|
368
365
|
* @param {Vector2} pos - tile where the collision occurred
|
|
369
366
|
* @return {boolean} - true if the collision should be resolved */
|
|
370
|
-
collideWithTile(tileData, pos)
|
|
367
|
+
collideWithTile(tileData, pos) { return tileData > 0; }
|
|
371
368
|
|
|
372
369
|
/** Called to check if a object collision should be resolved
|
|
373
370
|
* @param {EngineObject} object - the object to test against
|
|
374
371
|
* @return {boolean} - true if the collision should be resolved
|
|
375
372
|
*/
|
|
376
|
-
collideWithObject(object)
|
|
373
|
+
collideWithObject(object) { return true; }
|
|
377
374
|
|
|
378
375
|
/** How long since the object was created
|
|
379
376
|
* @return {number} */
|
|
380
|
-
getAliveTime()
|
|
377
|
+
getAliveTime() { return time - this.spawnTime; }
|
|
381
378
|
|
|
382
379
|
/** Apply acceleration to this object (adjust velocity, not affected by mass)
|
|
383
380
|
* @param {Vector2} acceleration */
|
|
384
|
-
applyAcceleration(acceleration)
|
|
381
|
+
applyAcceleration(acceleration) { if (this.mass) this.velocity = this.velocity.add(acceleration); }
|
|
382
|
+
|
|
383
|
+
/** Apply angular acceleration to this object
|
|
384
|
+
* @param {number} acceleration */
|
|
385
|
+
applyAngularAcceleration(acceleration) { if (this.mass) this.angleVelocity += acceleration; }
|
|
385
386
|
|
|
386
387
|
/** Apply force to this object (adjust velocity, affected by mass)
|
|
387
388
|
* @param {Vector2} force */
|
|
388
|
-
applyForce(force)
|
|
389
|
+
applyForce(force) { this.applyAcceleration(force.scale(1/this.mass)); }
|
|
389
390
|
|
|
390
391
|
/** Get the direction of the mirror
|
|
391
392
|
* @return {number} -1 if this.mirror is true, or 1 if not mirrored */
|
|
@@ -452,15 +453,15 @@ class EngineObject
|
|
|
452
453
|
/** Render debug info for this object */
|
|
453
454
|
renderDebugInfo()
|
|
454
455
|
{
|
|
455
|
-
if (debug)
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
456
|
+
if (!debug)
|
|
457
|
+
return;
|
|
458
|
+
|
|
459
|
+
// show object info for debugging
|
|
460
|
+
const size = vec2(max(this.size.x, .2), max(this.size.y, .2));
|
|
461
|
+
const color = rgb(this.collideTiles?1:0, this.collideSolidObjects?1:0, this.isSolid?1:0, .5);
|
|
462
|
+
drawRect(this.pos, size, color, this.angle);
|
|
463
|
+
if (this.parent)
|
|
464
|
+
drawRect(this.pos, size.scale(.8), rgb(1,1,1,.5), this.angle);
|
|
465
|
+
this.parent && drawLine(this.pos, this.parent.pos, .1, rgb(1,1,1,.5));
|
|
465
466
|
}
|
|
466
467
|
}
|
package/src/engineParticles.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* (
|
|
15
15
|
* pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emitCone
|
|
16
16
|
* tile(0, 16), // tileInfo
|
|
17
|
-
* rgb(1,1,1),
|
|
17
|
+
* rgb(1,1,1,1), rgb(0,0,0,1), // colorStartA, colorStartB
|
|
18
18
|
* rgb(1,1,1,0), rgb(0,0,0,0), // colorEndA, colorEndB
|
|
19
19
|
* 2, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
|
|
20
20
|
* .99, 1, 1, PI, .05, // damping, angleDamping, gravityScale, particleCone, fadeRate,
|
|
@@ -169,7 +169,7 @@ class ParticleEmitter extends EngineObject
|
|
|
169
169
|
if (debugParticles)
|
|
170
170
|
{
|
|
171
171
|
// show emitter bounds
|
|
172
|
-
const emitSize = typeof this.emitSize
|
|
172
|
+
const emitSize = typeof this.emitSize == 'number' ? vec2(this.emitSize) : this.emitSize;
|
|
173
173
|
debugRect(this.pos, emitSize, '#0f0', 0, this.angle);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -179,9 +179,9 @@ class ParticleEmitter extends EngineObject
|
|
|
179
179
|
emitParticle()
|
|
180
180
|
{
|
|
181
181
|
// spawn a particle
|
|
182
|
-
let pos = typeof this.emitSize
|
|
183
|
-
randInCircle(this.emitSize/2)
|
|
184
|
-
: vec2(rand(-.5,.5), rand(-.5,.5))
|
|
182
|
+
let pos = typeof this.emitSize == 'number' ? // check if number was used
|
|
183
|
+
randInCircle(this.emitSize/2) // circle emitter
|
|
184
|
+
: vec2(rand(-.5,.5), rand(-.5,.5)) // box emitter
|
|
185
185
|
.multiply(this.emitSize).rotate(this.angle)
|
|
186
186
|
let angle = rand(this.particleConeAngle, -this.particleConeAngle);
|
|
187
187
|
if (!this.localSpace)
|
|
@@ -209,15 +209,22 @@ class ParticleEmitter extends EngineObject
|
|
|
209
209
|
const particle = new Particle(pos, this.tileInfo, angle, colorStart, colorEnd, particleTime, sizeStart, sizeEnd, this.fadeRate, this.additive, this.trailScale, this.localSpace && this, this.particleDestroyCallback);
|
|
210
210
|
particle.velocity = vec2().setAngle(velocityAngle, speed);
|
|
211
211
|
particle.angleVelocity = angleSpeed;
|
|
212
|
+
if (!this.localSpace)
|
|
213
|
+
{
|
|
214
|
+
// apply emitter velocity to particle
|
|
215
|
+
particle.velocity.x += this.velocity.x;
|
|
216
|
+
particle.velocity.y += this.velocity.y;
|
|
217
|
+
particle.angleVelocity += this.angleVelocity;
|
|
218
|
+
}
|
|
212
219
|
particle.fadeRate = this.fadeRate;
|
|
213
220
|
particle.damping = this.damping;
|
|
214
221
|
particle.angleDamping = this.angleDamping;
|
|
215
|
-
particle.
|
|
222
|
+
particle.restitution = this.restitution;
|
|
216
223
|
particle.friction = this.friction;
|
|
217
224
|
particle.gravityScale = this.gravityScale;
|
|
218
225
|
particle.collideTiles = this.collideTiles;
|
|
219
226
|
particle.renderOrder = this.renderOrder;
|
|
220
|
-
particle.mirror =
|
|
227
|
+
particle.mirror = randBool();
|
|
221
228
|
|
|
222
229
|
// call particle create callback
|
|
223
230
|
this.particleCreateCallback && this.particleCreateCallback(particle);
|
|
@@ -279,9 +286,26 @@ class Particle extends EngineObject
|
|
|
279
286
|
this.localSpaceEmitter = localSpaceEmitter;
|
|
280
287
|
/** @property {Function} - Called when particle dies */
|
|
281
288
|
this.destroyCallback = destroyCallback;
|
|
289
|
+
// particles do not clamp speed by default
|
|
290
|
+
this.clampSpeed = false;
|
|
291
|
+
}
|
|
282
292
|
|
|
283
|
-
|
|
284
|
-
|
|
293
|
+
/** Update the object physics, called automatically by engine once each frame */
|
|
294
|
+
update()
|
|
295
|
+
{
|
|
296
|
+
super.update();
|
|
297
|
+
|
|
298
|
+
if (this.collideTiles || this.collideSolidObjects)
|
|
299
|
+
{
|
|
300
|
+
// only apply max circular speed if particle can collide
|
|
301
|
+
const length2 = this.velocity.lengthSquared();
|
|
302
|
+
if (length2 > objectMaxSpeed*objectMaxSpeed)
|
|
303
|
+
{
|
|
304
|
+
const s = objectMaxSpeed / length2**.5;
|
|
305
|
+
this.velocity.x *= s;
|
|
306
|
+
this.velocity.y *= s;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
285
309
|
}
|
|
286
310
|
|
|
287
311
|
/** Render the particle, automatically called each frame, sorted by renderOrder */
|
package/src/engineSettings.js
CHANGED
|
@@ -15,6 +15,12 @@
|
|
|
15
15
|
* @memberof Settings */
|
|
16
16
|
let cameraPos = vec2();
|
|
17
17
|
|
|
18
|
+
/** Rotation angle of camera in world space
|
|
19
|
+
* @type {number}
|
|
20
|
+
* @default
|
|
21
|
+
* @memberof Settings */
|
|
22
|
+
let cameraAngle = 0;
|
|
23
|
+
|
|
18
24
|
/** Scale of camera in world space
|
|
19
25
|
* @type {number}
|
|
20
26
|
* @default
|
|
@@ -24,6 +30,13 @@ let cameraScale = 32;
|
|
|
24
30
|
///////////////////////////////////////////////////////////////////////////////
|
|
25
31
|
// Display settings
|
|
26
32
|
|
|
33
|
+
/** Enable applying color to tiles when using canvas2d
|
|
34
|
+
* - This is slower but should be the same as webgl rendering
|
|
35
|
+
* @type {boolean}
|
|
36
|
+
* @default
|
|
37
|
+
* @memberof Settings */
|
|
38
|
+
let canvasColorTiles = true;
|
|
39
|
+
|
|
27
40
|
/** The max size of the canvas, centered if window is larger
|
|
28
41
|
* @type {Vector2}
|
|
29
42
|
* @default Vector2(1920,1080)
|
|
@@ -37,14 +50,21 @@ let canvasMaxSize = vec2(1920, 1080);
|
|
|
37
50
|
* @memberof Settings */
|
|
38
51
|
let canvasFixedSize = vec2();
|
|
39
52
|
|
|
40
|
-
/** Use nearest
|
|
41
|
-
* - Must be set before startup to take effect
|
|
53
|
+
/** Use nearest canvas scaling for more pixelated look
|
|
42
54
|
* - If enabled sets css image-rendering:pixelated
|
|
43
55
|
* @type {boolean}
|
|
44
56
|
* @default
|
|
45
57
|
* @memberof Settings */
|
|
46
58
|
let canvasPixelated = true;
|
|
47
59
|
|
|
60
|
+
/** Use nearest canvas scaling for more pixelated look
|
|
61
|
+
* - If enabled sets css image-rendering:pixelated
|
|
62
|
+
* - This defaults to false because text looks better with smoothing
|
|
63
|
+
* @type {boolean}
|
|
64
|
+
* @default
|
|
65
|
+
* @memberof Settings */
|
|
66
|
+
let overlayCanvasPixelated = false;
|
|
67
|
+
|
|
48
68
|
/** Disables texture filtering for crisper pixel art
|
|
49
69
|
* @type {boolean}
|
|
50
70
|
* @default
|
|
@@ -80,13 +100,6 @@ let headlessMode = false;
|
|
|
80
100
|
* @memberof Settings */
|
|
81
101
|
let glEnable = true;
|
|
82
102
|
|
|
83
|
-
/** Fixes slow rendering in some browsers by not compositing the WebGL canvas
|
|
84
|
-
* - Must be set before startup to take effect
|
|
85
|
-
* @type {boolean}
|
|
86
|
-
* @default
|
|
87
|
-
* @memberof Settings */
|
|
88
|
-
let glOverlay = true;
|
|
89
|
-
|
|
90
103
|
///////////////////////////////////////////////////////////////////////////////
|
|
91
104
|
// Tile sheet settings
|
|
92
105
|
|
|
@@ -133,7 +146,7 @@ let objectDefaultAngleDamping = 1;
|
|
|
133
146
|
* @type {number}
|
|
134
147
|
* @default
|
|
135
148
|
* @memberof Settings */
|
|
136
|
-
let
|
|
149
|
+
let objectDefaultRestitution = 0;
|
|
137
150
|
|
|
138
151
|
/** How much to slow when touching (0-1)
|
|
139
152
|
* @type {number}
|
|
@@ -168,13 +181,13 @@ let particleEmitRateScale = 1;
|
|
|
168
181
|
* @memberof Settings */
|
|
169
182
|
let gamepadsEnable = true;
|
|
170
183
|
|
|
171
|
-
/** If true, the dpad input is also routed to the left analog stick (for better
|
|
184
|
+
/** If true, the dpad input is also routed to the left analog stick (for better accessibility)
|
|
172
185
|
* @type {boolean}
|
|
173
186
|
* @default
|
|
174
187
|
* @memberof Settings */
|
|
175
188
|
let gamepadDirectionEmulateStick = true;
|
|
176
189
|
|
|
177
|
-
/** If true the WASD keys are also routed to the direction keys (for better
|
|
190
|
+
/** If true the WASD keys are also routed to the direction keys (for better accessibility)
|
|
178
191
|
* @type {boolean}
|
|
179
192
|
* @default
|
|
180
193
|
* @memberof Settings */
|
|
@@ -282,11 +295,24 @@ let medalsPreventUnlock = false;
|
|
|
282
295
|
* @memberof Settings */
|
|
283
296
|
function setCameraPos(pos) { cameraPos = pos; }
|
|
284
297
|
|
|
298
|
+
/** Set angle of camera in world space
|
|
299
|
+
* @param {number} angle
|
|
300
|
+
* @memberof Settings */
|
|
301
|
+
function setCameraAngle(angle) { cameraAngle = angle; }
|
|
302
|
+
|
|
285
303
|
/** Set scale of camera in world space
|
|
286
304
|
* @param {number} scale
|
|
287
305
|
* @memberof Settings */
|
|
288
306
|
function setCameraScale(scale) { cameraScale = scale; }
|
|
289
307
|
|
|
308
|
+
/** Set if tiles should be colorized when using canvas2d
|
|
309
|
+
* This can be slower but results should look nearly identical to webgl rendering
|
|
310
|
+
* It can be enabled/disabled at any time
|
|
311
|
+
* Optimized for performance, and will use faster method if color is white or untextured
|
|
312
|
+
* @param {boolean} colorTiles
|
|
313
|
+
* @memberof Settings */
|
|
314
|
+
function setCanvasColorTiles(colorTiles) { canvasColorTiles = colorTiles; }
|
|
315
|
+
|
|
290
316
|
/** Set max size of the canvas
|
|
291
317
|
* @param {Vector2} size
|
|
292
318
|
* @memberof Settings */
|
|
@@ -297,10 +323,30 @@ function setCanvasMaxSize(size) { canvasMaxSize = size; }
|
|
|
297
323
|
* @memberof Settings */
|
|
298
324
|
function setCanvasFixedSize(size) { canvasFixedSize = size; }
|
|
299
325
|
|
|
300
|
-
/** Use nearest
|
|
326
|
+
/** Use nearest scaling algorithm for canvas for more pixelated look
|
|
327
|
+
* - If enabled sets css image-rendering:pixelated
|
|
301
328
|
* @param {boolean} pixelated
|
|
302
329
|
* @memberof Settings */
|
|
303
|
-
function setCanvasPixelated(pixelated)
|
|
330
|
+
function setCanvasPixelated(pixelated)
|
|
331
|
+
{
|
|
332
|
+
canvasPixelated = pixelated;
|
|
333
|
+
if (mainCanvas)
|
|
334
|
+
mainCanvas.style.imageRendering = pixelated ? 'pixelated' : '';
|
|
335
|
+
if (glCanvas)
|
|
336
|
+
glCanvas.style.imageRendering = pixelated ? 'pixelated' : '';
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** Use nearest scaling algorithm for canvas for more pixelated look
|
|
340
|
+
* - If enabled sets css image-rendering:pixelated
|
|
341
|
+
* - This defaults to false because text looks better with smoothing
|
|
342
|
+
* @param {boolean} pixelated
|
|
343
|
+
* @memberof Settings */
|
|
344
|
+
function setOverlayCanvasPixelated(pixelated)
|
|
345
|
+
{
|
|
346
|
+
overlayCanvasPixelated = pixelated;
|
|
347
|
+
if (overlayCanvas)
|
|
348
|
+
overlayCanvas.style.imageRendering = pixelated ? 'pixelated' : '';
|
|
349
|
+
}
|
|
304
350
|
|
|
305
351
|
/** Disables texture filtering for crisper pixel art
|
|
306
352
|
* @param {boolean} pixelated
|
|
@@ -325,12 +371,12 @@ function setHeadlessMode(headless) { headlessMode = headless; }
|
|
|
325
371
|
/** Set if webgl rendering is enabled
|
|
326
372
|
* @param {boolean} enable
|
|
327
373
|
* @memberof Settings */
|
|
328
|
-
function
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
374
|
+
function setGLEnable(enable)
|
|
375
|
+
{
|
|
376
|
+
glEnable = enable;
|
|
377
|
+
if (glCanvas) // hide glCanvas if webgl is disabled
|
|
378
|
+
glCanvas.style.visibility = enable ? 'visible' : 'hidden';
|
|
379
|
+
}
|
|
334
380
|
|
|
335
381
|
/** Set default size of tiles in pixels
|
|
336
382
|
* @param {Vector2} size
|
|
@@ -362,10 +408,10 @@ function setObjectDefaultDamping(damp) { objectDefaultDamping = damp; }
|
|
|
362
408
|
* @memberof Settings */
|
|
363
409
|
function setObjectDefaultAngleDamping(damp) { objectDefaultAngleDamping = damp; }
|
|
364
410
|
|
|
365
|
-
/** Set how much to bounce when a collision
|
|
366
|
-
* @param {number}
|
|
411
|
+
/** Set how much to bounce when a collision occurs
|
|
412
|
+
* @param {number} restitution
|
|
367
413
|
* @memberof Settings */
|
|
368
|
-
function
|
|
414
|
+
function setObjectDefaultRestitution(restitution) { objectDefaultRestitution = restitution; }
|
|
369
415
|
|
|
370
416
|
/** Set how much to slow when touching
|
|
371
417
|
* @param {number} friction
|