littlejsengine 1.6.6 → 1.7.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/README.md +76 -53
- package/build/littlejs.d.ts +154 -136
- package/build/littlejs.esm.js +461 -305
- package/build/littlejs.esm.min.js +1 -1
- package/build/littlejs.js +452 -291
- package/build/littlejs.min.js +1 -1
- package/build/littlejs.release.js +2317 -2168
- package/examples/breakout/game.js +5 -1
- package/examples/breakout/index.html +5 -5
- package/examples/breakoutTutorial/README.md +6 -6
- package/examples/breakoutTutorial/game.js +3 -0
- package/examples/breakoutTutorial/index.html +3 -3
- package/examples/electron/build.js +105 -0
- package/examples/electron/game.js +4 -2
- package/examples/electron/index.html +13 -2
- package/examples/electron/package.json +5 -3
- package/examples/empty/game.js +3 -1
- package/examples/empty/index.html +1 -1
- package/examples/js13k/build.bat +2 -0
- package/examples/js13k/build.js +110 -0
- package/examples/js13k/game.js +109 -0
- package/examples/js13k/index.html +18 -0
- package/examples/js13k/tiles.png +0 -0
- package/examples/module/game.js +9 -3
- package/examples/module/index.html +2 -2
- package/examples/particles/index.html +7 -13
- package/examples/platformer/game.js +5 -2
- package/examples/platformer/gameEffects.js +12 -12
- package/examples/platformer/gamePlayer.js +2 -2
- package/examples/platformer/index.html +8 -8
- package/examples/puzzle/game.js +5 -3
- package/examples/puzzle/index.html +4 -4
- package/examples/starter/build.bat +2 -78
- package/examples/starter/build.js +109 -0
- package/examples/starter/game.js +4 -1
- package/examples/starter/index.html +15 -18
- package/examples/stress/index.html +5 -7
- package/examples/typescript/build.bat +2 -14
- package/examples/typescript/build.js +31 -0
- package/examples/typescript/game.js +94 -89
- package/examples/typescript/game.ts +9 -3
- package/examples/typescript/index.html +2 -2
- package/package.json +2 -2
- package/src/engine.js +3 -3
- package/src/engineAudio.js +44 -16
- package/src/engineBuild.bat +2 -132
- package/src/engineBuild.js +156 -0
- package/src/engineDebug.js +25 -15
- package/src/engineDraw.js +62 -53
- package/src/engineExport.js +7 -12
- package/src/engineInput.js +27 -35
- package/src/engineObject.js +15 -13
- package/src/engineParticles.js +6 -6
- package/src/engineRelease.js +1 -3
- package/src/engineSettings.js +1 -0
- package/src/engineTileLayer.js +31 -18
- package/src/engineUtilities.js +161 -93
- package/src/engineWebGL.js +63 -27
- package/examples/electron/build.bat +0 -52
package/src/engineObject.js
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* LittleJS Object Base Object Class
|
|
9
|
-
* -
|
|
9
|
+
* - Top level object class used by the engine
|
|
10
10
|
* - Automatically adds self to object list
|
|
11
11
|
* - Will be updated and rendered each frame
|
|
12
12
|
* - Renders as a sprite from a tilesheet by default
|
|
13
13
|
* - Can have color and addtive color applied
|
|
14
|
-
* -
|
|
14
|
+
* - 2D Physics and collision system
|
|
15
15
|
* - Sorted by renderOrder
|
|
16
16
|
* - Objects can have children attached
|
|
17
17
|
* - Parents are updated before children, and set child transform
|
|
@@ -78,7 +78,7 @@ class EngineObject
|
|
|
78
78
|
/** @property {Number} [renderOrder=0] - Objects are sorted by render order */
|
|
79
79
|
this.renderOrder = renderOrder;
|
|
80
80
|
/** @property {Vector2} [velocity=Vector2()] - Velocity of the object */
|
|
81
|
-
this.velocity =
|
|
81
|
+
this.velocity = vec2();
|
|
82
82
|
/** @property {Number} [angleVelocity=0] - Angular velocity of the object */
|
|
83
83
|
this.angleVelocity = 0;
|
|
84
84
|
|
|
@@ -138,15 +138,17 @@ class EngineObject
|
|
|
138
138
|
for (const o of engineObjectsCollide)
|
|
139
139
|
{
|
|
140
140
|
// non solid objects don't collide with eachother
|
|
141
|
-
if (!this.isSolid
|
|
141
|
+
if (!this.isSolid && !o.isSolid || o.destroyed || o.parent || o == this)
|
|
142
142
|
continue;
|
|
143
143
|
|
|
144
144
|
// check collision
|
|
145
145
|
if (!isOverlapping(this.pos, this.size, o.pos, o.size))
|
|
146
146
|
continue;
|
|
147
147
|
|
|
148
|
-
//
|
|
149
|
-
|
|
148
|
+
// notify objects of collision and check if should be resolved
|
|
149
|
+
const collide1 = this.collideWithObject(o);
|
|
150
|
+
const collide2 = o.collideWithObject(this);
|
|
151
|
+
if (!collide1 || !collide2)
|
|
150
152
|
continue;
|
|
151
153
|
|
|
152
154
|
if (isOverlapping(oldPos, this.size, o.pos, o.size))
|
|
@@ -171,7 +173,7 @@ class EngineObject
|
|
|
171
173
|
const isBlockedY = abs(oldPos.x - o.pos.x)*2 < sizeBoth.x;
|
|
172
174
|
const elasticity = max(this.elasticity, o.elasticity);
|
|
173
175
|
|
|
174
|
-
if (smallStepUp
|
|
176
|
+
if (smallStepUp || isBlockedY || !isBlockedX) // resolve y collision
|
|
175
177
|
{
|
|
176
178
|
// push outside object collision
|
|
177
179
|
this.pos.y = o.pos.y + (sizeBoth.y/2 + epsilon) * sign(oldPos.y - o.pos.y);
|
|
@@ -200,7 +202,7 @@ class EngineObject
|
|
|
200
202
|
o.velocity.y = lerp(elasticity, inelastic, elastic1);
|
|
201
203
|
}
|
|
202
204
|
}
|
|
203
|
-
if (!smallStepUp
|
|
205
|
+
if (!smallStepUp && isBlockedX) // resolve x collision
|
|
204
206
|
{
|
|
205
207
|
// push outside collision
|
|
206
208
|
this.pos.x = o.pos.x + (sizeBoth.x/2 + epsilon) * sign(oldPos.x - o.pos.x);
|
|
@@ -235,9 +237,9 @@ class EngineObject
|
|
|
235
237
|
if (!tileCollisionTest(oldPos, this.size, this))
|
|
236
238
|
{
|
|
237
239
|
// test which side we bounced off (or both if a corner)
|
|
238
|
-
const isBlockedY = tileCollisionTest(
|
|
239
|
-
const isBlockedX = tileCollisionTest(
|
|
240
|
-
if (isBlockedY
|
|
240
|
+
const isBlockedY = tileCollisionTest(vec2(oldPos.x, this.pos.y), this.size, this);
|
|
241
|
+
const isBlockedX = tileCollisionTest(vec2(this.pos.x, oldPos.y), this.size, this);
|
|
242
|
+
if (isBlockedY || !isBlockedX)
|
|
241
243
|
{
|
|
242
244
|
// set if landed on ground
|
|
243
245
|
this.groundObject = wasMovingDown;
|
|
@@ -300,7 +302,7 @@ class EngineObject
|
|
|
300
302
|
* @param {EngineObject} object - the object to test against
|
|
301
303
|
* @return {Boolean} - true if the collision should be resolved
|
|
302
304
|
*/
|
|
303
|
-
collideWithObject(
|
|
305
|
+
collideWithObject(object) { return 1; }
|
|
304
306
|
|
|
305
307
|
/** How long since the object was created
|
|
306
308
|
* @return {Number} */
|
|
@@ -308,7 +310,7 @@ class EngineObject
|
|
|
308
310
|
|
|
309
311
|
/** Apply acceleration to this object (adjust velocity, not affected by mass)
|
|
310
312
|
* @param {Vector2} acceleration */
|
|
311
|
-
applyAcceleration(
|
|
313
|
+
applyAcceleration(acceleration) { if (this.mass) this.velocity = this.velocity.add(acceleration); }
|
|
312
314
|
|
|
313
315
|
/** Apply force to this object (adjust velocity, affected by mass)
|
|
314
316
|
* @param {Vector2} force */
|
package/src/engineParticles.js
CHANGED
|
@@ -85,7 +85,7 @@ class ParticleEmitter extends EngineObject
|
|
|
85
85
|
localSpace
|
|
86
86
|
)
|
|
87
87
|
{
|
|
88
|
-
super(pos,
|
|
88
|
+
super(pos, vec2(), tileIndex, tileSize, angle, undefined, renderOrder);
|
|
89
89
|
|
|
90
90
|
// emitter settings
|
|
91
91
|
/** @property {Number} - World space size of the emitter (float for circle diameter, vec2 for rect) */
|
|
@@ -152,7 +152,7 @@ class ParticleEmitter extends EngineObject
|
|
|
152
152
|
this.parent && super.update();
|
|
153
153
|
|
|
154
154
|
// update emitter
|
|
155
|
-
if (!this.emitTime
|
|
155
|
+
if (!this.emitTime || this.getAliveTime() <= this.emitTime)
|
|
156
156
|
{
|
|
157
157
|
// emit particles
|
|
158
158
|
if (this.emitRate * particleEmitRateScale)
|
|
@@ -174,7 +174,7 @@ class ParticleEmitter extends EngineObject
|
|
|
174
174
|
{
|
|
175
175
|
// spawn a particle
|
|
176
176
|
let pos = this.emitSize.x != undefined ? // check if vec2 was used for size
|
|
177
|
-
(
|
|
177
|
+
vec2(rand(-.5,.5), rand(-.5,.5))
|
|
178
178
|
.multiply(this.emitSize).rotate(this.angle) // box emitter
|
|
179
179
|
: randInCircle(this.emitSize/2); // circle emitter
|
|
180
180
|
let angle = rand(this.particleConeAngle, -this.particleConeAngle);
|
|
@@ -204,7 +204,7 @@ class ParticleEmitter extends EngineObject
|
|
|
204
204
|
// build particle settings
|
|
205
205
|
particle.colorStart = colorStart;
|
|
206
206
|
particle.colorEndDelta = colorEnd.subtract(colorStart);
|
|
207
|
-
particle.velocity = (
|
|
207
|
+
particle.velocity = vec2().setAngle(velocityAngle, speed);
|
|
208
208
|
particle.angleVelocity = angleSpeed;
|
|
209
209
|
particle.lifeTime = particleTime;
|
|
210
210
|
particle.sizeStart = sizeStart;
|
|
@@ -249,7 +249,7 @@ class Particle extends EngineObject
|
|
|
249
249
|
* @param {Number} [angle=0] - Angle to rotate the particle
|
|
250
250
|
*/
|
|
251
251
|
constructor(pos, tileIndex, tileSize, angle)
|
|
252
|
-
{ super(pos,
|
|
252
|
+
{ super(pos, vec2(), tileIndex, tileSize, angle); }
|
|
253
253
|
|
|
254
254
|
/** Render the particle, automatically called each frame, sorted by renderOrder */
|
|
255
255
|
render()
|
|
@@ -257,7 +257,7 @@ class Particle extends EngineObject
|
|
|
257
257
|
// modulate size and color
|
|
258
258
|
const p = min((time - this.spawnTime) / this.lifeTime, 1);
|
|
259
259
|
const radius = this.sizeStart + p * this.sizeEndDelta;
|
|
260
|
-
const size =
|
|
260
|
+
const size = vec2(radius);
|
|
261
261
|
const fadeRate = this.fadeRate/2;
|
|
262
262
|
const color = new Color(
|
|
263
263
|
this.colorStart.r + p * this.colorEndDelta.r,
|
package/src/engineRelease.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* LittleJS - Release
|
|
3
|
-
* MIT License - Copyright 2021 Frank Force
|
|
2
|
+
* LittleJS - Release Mode
|
|
4
3
|
* - This file is used for release builds in place of engineDebug.js
|
|
5
4
|
* - Debug functionality is disabled to reduce size and increase performance
|
|
6
5
|
*/
|
|
@@ -8,7 +7,6 @@
|
|
|
8
7
|
'use strict';
|
|
9
8
|
|
|
10
9
|
let showWatermark = 0;
|
|
11
|
-
let godMode = 0;
|
|
12
10
|
let debugKeyCode = 0;
|
|
13
11
|
const debug = 0;
|
|
14
12
|
const debugOverlay = 0;
|
package/src/engineSettings.js
CHANGED
package/src/engineTileLayer.js
CHANGED
|
@@ -67,12 +67,12 @@ function tileCollisionTest(pos, size=vec2(), object)
|
|
|
67
67
|
for (let x = minX; x < maxX; ++x)
|
|
68
68
|
{
|
|
69
69
|
const tileData = tileCollision[y*tileCollisionSize.x+x];
|
|
70
|
-
if (tileData && (!object || object.collideWithTile(tileData,
|
|
70
|
+
if (tileData && (!object || object.collideWithTile(tileData, vec2(x, y))))
|
|
71
71
|
return 1;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
/** Return the center of tile if any that is hit (
|
|
75
|
+
/** Return the center of tile if any that is hit (does not return the exact intersection)
|
|
76
76
|
* @param {Vector2} posStart
|
|
77
77
|
* @param {Vector2} posEnd
|
|
78
78
|
* @param {EngineObject} [object]
|
|
@@ -81,28 +81,41 @@ function tileCollisionTest(pos, size=vec2(), object)
|
|
|
81
81
|
function tileCollisionRaycast(posStart, posEnd, object)
|
|
82
82
|
{
|
|
83
83
|
// test if a ray collides with tiles from start to end
|
|
84
|
-
// todo: a way to get the exact hit point, it must still
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
const
|
|
84
|
+
// todo: a way to get the exact hit point, it must still be inside the hit tile
|
|
85
|
+
const delta = posEnd.subtract(posStart);
|
|
86
|
+
const totalLength = delta.length();
|
|
87
|
+
const normalizedDelta = delta.normalize();
|
|
88
|
+
const unit = vec2(abs(1/normalizedDelta.x), abs(1/normalizedDelta.y));
|
|
89
|
+
const flooredPosStart = posStart.floor();
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
// setup iteration variables
|
|
92
|
+
let pos = flooredPosStart;
|
|
93
|
+
let xi = unit.x * (delta.x < 0 ? posStart.x - pos.x : pos.x - posStart.x + 1);
|
|
94
|
+
let yi = unit.y * (delta.y < 0 ? posStart.y - pos.y : pos.y - posStart.y + 1);
|
|
95
|
+
|
|
96
|
+
while (1)
|
|
90
97
|
{
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
// check for tile collision
|
|
99
|
+
const tileData = getTileCollisionData(pos);
|
|
100
|
+
if (tileData && (!object || object.collideWithTile(tileData, pos)))
|
|
93
101
|
{
|
|
94
|
-
debugRaycast && debugLine(posStart, posEnd, '#f00'
|
|
95
|
-
debugRaycast && debugPoint(
|
|
96
|
-
return
|
|
102
|
+
debugRaycast && debugLine(posStart, posEnd, '#f00', .02);
|
|
103
|
+
debugRaycast && debugPoint(pos.add(vec2(.5)), '#ff0');
|
|
104
|
+
return pos.add(vec2(.5));
|
|
97
105
|
}
|
|
98
106
|
|
|
99
|
-
//
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
// check if past the end
|
|
108
|
+
if (xi > totalLength && yi > totalLength)
|
|
109
|
+
break;
|
|
110
|
+
|
|
111
|
+
// get coordinates of the next tile to check
|
|
112
|
+
if (xi > yi)
|
|
113
|
+
pos.y += sign(delta.y), yi += unit.y;
|
|
114
|
+
else
|
|
115
|
+
pos.x += sign(delta.x), xi += unit.x;
|
|
104
116
|
}
|
|
105
|
-
|
|
117
|
+
|
|
118
|
+
debugRaycast && debugLine(posStart, posEnd, '#00f', .02);
|
|
106
119
|
}
|
|
107
120
|
|
|
108
121
|
///////////////////////////////////////////////////////////////////////////////
|