littlejsengine 1.1.26 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/engine/engine.all.js +248 -324
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.release.js +223 -105
- package/engine/engine.js +34 -11
- package/engine/engineAudio.js +2 -2
- package/engine/engineBuild.bat +9 -1
- package/engine/engineBuildSetup.bat +2 -1
- package/engine/engineDebug.js +26 -220
- package/engine/engineDraw.js +98 -9
- package/engine/engineInput.js +13 -6
- package/engine/engineObject.js +13 -10
- package/engine/engineTileLayer.js +11 -9
- package/engine/engineUtilities.js +12 -12
- package/engine/engineWebGL.js +40 -46
- package/engine/index.d.ts +1612 -0
- package/examples/breakout/game.js +9 -7
- package/examples/breakout/gameObjects.js +1 -1
- package/examples/breakout/index.html +3 -3
- package/examples/platformer/game.js +1 -1
- package/examples/platformer/gameEffects.js +1 -1
- package/examples/platformer/gameLevel.js +3 -3
- package/examples/platformer/gameObjects.js +1 -1
- package/examples/platformer/gamePlayer.js +11 -6
- package/examples/platformer/index.html +6 -6
- package/examples/platformer/tiles.png +0 -0
- package/examples/puzzle/game.js +1 -1
- package/examples/puzzle/index.html +2 -2
- package/examples/stress/index.html +3 -3
- package/game.js +0 -3
- package/index.html +13 -13
- package/package.json +1 -1
package/engine/engineObject.js
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
class EngineObject
|
|
33
33
|
{
|
|
34
34
|
/** Create an engine object and adds it to the list of objects
|
|
35
|
-
* @param {Vector2} [position=new Vector2(
|
|
35
|
+
* @param {Vector2} [position=new Vector2()] - World space position of the object
|
|
36
36
|
* @param {Vector2} [size=objectDefaultSize] - World space size of the object
|
|
37
37
|
* @param {Number} [tileIndex=-1] - Tile to use to render object, untextured if -1
|
|
38
38
|
* @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
|
|
@@ -77,12 +77,15 @@ class EngineObject
|
|
|
77
77
|
this.gravityScale = 1;
|
|
78
78
|
/** @property {Number} [renderOrder=0] - Objects are sorted by render order */
|
|
79
79
|
this.renderOrder = renderOrder;
|
|
80
|
+
/** @property {Vector2} [velocity=new Vector2()] - Velocity of the object */
|
|
81
|
+
this.velocity = new Vector2();
|
|
82
|
+
/** @property {Number} [angleVelocity=0] - Angular velocity of the object */
|
|
83
|
+
this.angleVelocity = 0;
|
|
80
84
|
|
|
81
85
|
// init other internal object stuff
|
|
82
86
|
this.spawnTime = time;
|
|
83
|
-
this.velocity = vec2(this.collideSolidObjects = this.angleVelocity = 0);
|
|
84
|
-
this.collideTiles = 1;
|
|
85
87
|
this.children = [];
|
|
88
|
+
this.collideTiles = 1;
|
|
86
89
|
|
|
87
90
|
// add to list of objects
|
|
88
91
|
engineObjects.push(this);
|
|
@@ -101,8 +104,8 @@ class EngineObject
|
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
// limit max speed to prevent missing collisions
|
|
104
|
-
this.velocity.x = clamp(this.velocity.x, objectMaxSpeed,
|
|
105
|
-
this.velocity.y = clamp(this.velocity.y, objectMaxSpeed,
|
|
107
|
+
this.velocity.x = clamp(this.velocity.x, -objectMaxSpeed, objectMaxSpeed);
|
|
108
|
+
this.velocity.y = clamp(this.velocity.y, -objectMaxSpeed, objectMaxSpeed);
|
|
106
109
|
|
|
107
110
|
// apply physics
|
|
108
111
|
const oldPos = this.pos.copy();
|
|
@@ -192,8 +195,8 @@ class EngineObject
|
|
|
192
195
|
|
|
193
196
|
// lerp betwen elastic or inelastic based on elasticity
|
|
194
197
|
const elasticity = max(this.elasticity, o.elasticity);
|
|
195
|
-
this.velocity.y = lerp(elasticity,
|
|
196
|
-
o.velocity.y = lerp(elasticity,
|
|
198
|
+
this.velocity.y = lerp(elasticity, inelastic, elastic0);
|
|
199
|
+
o.velocity.y = lerp(elasticity, inelastic, elastic1);
|
|
197
200
|
}
|
|
198
201
|
}
|
|
199
202
|
if (!smallStepUp && (isBlockedX || !isBlockedY)) // resolve x collision
|
|
@@ -213,8 +216,8 @@ class EngineObject
|
|
|
213
216
|
|
|
214
217
|
// lerp betwen elastic or inelastic based on elasticity
|
|
215
218
|
const elasticity = max(this.elasticity, o.elasticity);
|
|
216
|
-
this.velocity.x = lerp(elasticity,
|
|
217
|
-
o.velocity.x = lerp(elasticity,
|
|
219
|
+
this.velocity.x = lerp(elasticity, inelastic, elastic0);
|
|
220
|
+
o.velocity.x = lerp(elasticity, inelastic, elastic1);
|
|
218
221
|
}
|
|
219
222
|
else // bounce if other object is fixed
|
|
220
223
|
this.velocity.x *= -this.elasticity;
|
|
@@ -244,7 +247,7 @@ class EngineObject
|
|
|
244
247
|
|
|
245
248
|
// adjust next velocity to settle on ground
|
|
246
249
|
const o = (oldPos.y - this.size.y/2|0) - (oldPos.y - this.size.y/2);
|
|
247
|
-
if (o < 0 && o >
|
|
250
|
+
if (o < 0 && o > this.damping * this.velocity.y + gravity * this.gravityScale)
|
|
248
251
|
this.velocity.y = this.damping ? (o - gravity * this.gravityScale) / this.damping : 0;
|
|
249
252
|
|
|
250
253
|
// move to previous position
|
|
@@ -154,11 +154,11 @@ class TileLayerData
|
|
|
154
154
|
class TileLayer extends EngineObject
|
|
155
155
|
{
|
|
156
156
|
/** Create a tile layer object
|
|
157
|
-
* @param {Vector2} [position=new Vector2(
|
|
158
|
-
* @param {Vector2} [size=objectDefaultSize]
|
|
159
|
-
* @param {Vector2} [tileSize=tileSizeDefault]
|
|
160
|
-
* @param {Vector2} [scale=new Vector2(1,1)]
|
|
161
|
-
* @param {Number} [renderOrder=0]
|
|
157
|
+
* @param {Vector2} [position=new Vector2()] - World space position
|
|
158
|
+
* @param {Vector2} [size=objectDefaultSize] - World space size
|
|
159
|
+
* @param {Vector2} [tileSize=tileSizeDefault] - Size of tiles in source pixels
|
|
160
|
+
* @param {Vector2} [scale=new Vector2(1,1)] - How much to scale this layer when rendered
|
|
161
|
+
* @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
|
|
162
162
|
*/
|
|
163
163
|
constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1), renderOrder=0)
|
|
164
164
|
{
|
|
@@ -218,17 +218,19 @@ class TileLayer extends EngineObject
|
|
|
218
218
|
);
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
/** Draw all the tile data to an offscreen canvas
|
|
221
|
+
/** Draw all the tile data to an offscreen canvas
|
|
222
|
+
* - This may be slow in some browsers
|
|
223
|
+
*/
|
|
222
224
|
redraw()
|
|
223
225
|
{
|
|
224
|
-
this.redrawStart();
|
|
226
|
+
this.redrawStart(1);
|
|
225
227
|
this.drawAllTileData();
|
|
226
228
|
this.redrawEnd();
|
|
227
229
|
}
|
|
228
230
|
|
|
229
231
|
/** Call to start the redraw process
|
|
230
|
-
* @param {Boolean} [clear=
|
|
231
|
-
redrawStart(clear =
|
|
232
|
+
* @param {Boolean} [clear=0] - Should it clear the canvas before drawing */
|
|
233
|
+
redrawStart(clear = 0)
|
|
232
234
|
{
|
|
233
235
|
if (clear)
|
|
234
236
|
{
|
|
@@ -49,27 +49,27 @@ const mod = (a, b=1)=> ((a % b) + b) % b;
|
|
|
49
49
|
|
|
50
50
|
/** Clamps the value beween max and min
|
|
51
51
|
* @param {Number} value
|
|
52
|
-
* @param {Number} [max=1]
|
|
53
52
|
* @param {Number} [min=0]
|
|
53
|
+
* @param {Number} [max=1]
|
|
54
54
|
* @return {Number}
|
|
55
55
|
* @memberof Utilities */
|
|
56
|
-
const clamp = (v,
|
|
56
|
+
const clamp = (v, min=0, max=1)=> v < min ? min : v > max ? max : v;
|
|
57
57
|
|
|
58
58
|
/** Returns what percentage the value is between max and min
|
|
59
59
|
* @param {Number} value
|
|
60
|
-
* @param {Number} [max=1]
|
|
61
60
|
* @param {Number} [min=0]
|
|
61
|
+
* @param {Number} [max=1]
|
|
62
62
|
* @return {Number}
|
|
63
63
|
* @memberof Utilities */
|
|
64
|
-
const percent = (v,
|
|
64
|
+
const percent = (v, min=0, max=1)=> max-min ? clamp((v-min) / (max-min)) : 0;
|
|
65
65
|
|
|
66
66
|
/** Linearly interpolates the percent value between max and min
|
|
67
67
|
* @param {Number} percent
|
|
68
|
-
* @param {Number} [max=1]
|
|
69
68
|
* @param {Number} [min=0]
|
|
69
|
+
* @param {Number} [max=1]
|
|
70
70
|
* @return {Number}
|
|
71
71
|
* @memberof Utilities */
|
|
72
|
-
const lerp = (p,
|
|
72
|
+
const lerp = (p, min=0, max=1)=> min + clamp(p) * (max-min);
|
|
73
73
|
|
|
74
74
|
/** Applies smoothstep function to the percentage value
|
|
75
75
|
* @param {Number} value
|
|
@@ -84,11 +84,11 @@ const smoothStep = (p)=> p * p * (3 - 2 * p);
|
|
|
84
84
|
const nearestPowerOfTwo = (v)=> 2**Math.ceil(Math.log2(v));
|
|
85
85
|
|
|
86
86
|
/** Returns true if two axis aligned bounding boxes are overlapping
|
|
87
|
-
* @param {Vector2} pointA
|
|
88
|
-
* @param {Vector2} sizeA
|
|
89
|
-
* @param {Vector2} pointB
|
|
90
|
-
* @param {Vector2} sizeB
|
|
91
|
-
* @return {Boolean}
|
|
87
|
+
* @param {Vector2} pointA - Center of box A
|
|
88
|
+
* @param {Vector2} sizeA - Size of box A
|
|
89
|
+
* @param {Vector2} pointB - Center of box B
|
|
90
|
+
* @param {Vector2} [sizeB] - Size of box B
|
|
91
|
+
* @return {Boolean} - True if overlapping
|
|
92
92
|
* @memberof Utilities */
|
|
93
93
|
const isOverlapping = (pA, sA, pB, sB)=> abs(pA.x - pB.x)*2 < sA.x + sB.x & abs(pA.y - pB.y)*2 < sA.y + sB.y;
|
|
94
94
|
|
|
@@ -477,5 +477,5 @@ class Timer
|
|
|
477
477
|
|
|
478
478
|
/** Get percentage elapsed based on time it was set to, returns 0 if not set
|
|
479
479
|
* @return {Number} */
|
|
480
|
-
getPercent() { return this.isSet()? percent(this.time - time,
|
|
480
|
+
getPercent() { return this.isSet()? percent(this.time - time, this.setTime, 0) : 0; }
|
|
481
481
|
}
|
package/engine/engineWebGL.js
CHANGED
|
@@ -38,8 +38,8 @@ function glInit()
|
|
|
38
38
|
|
|
39
39
|
// create the canvas and tile texture
|
|
40
40
|
glCanvas = document.createElement('canvas');
|
|
41
|
-
glContext = glCanvas.getContext('webgl');
|
|
42
|
-
glCanvas.style =
|
|
41
|
+
glContext = glCanvas.getContext('webgl', {antialias: false});
|
|
42
|
+
glCanvas.style = styleCanvas;
|
|
43
43
|
glTileTexture = glCreateTexture(tileImage);
|
|
44
44
|
|
|
45
45
|
// some browsers are much faster without copying the gl buffer so we just overlay it instead
|
|
@@ -49,14 +49,13 @@ function glInit()
|
|
|
49
49
|
glShader = glCreateProgram(
|
|
50
50
|
'precision highp float;'+ // use highp for better accuracy, lowp for better perf
|
|
51
51
|
'uniform mat4 m;'+ // transform matrix
|
|
52
|
-
'attribute
|
|
53
|
-
'attribute
|
|
54
|
-
'attribute vec4 c,b;'+ // color, additiveColor
|
|
52
|
+
'attribute vec2 p,t;'+ // position, uv
|
|
53
|
+
'attribute vec4 c,a;'+ // color, additiveColor
|
|
55
54
|
'varying vec2 v;'+ // return uv
|
|
56
55
|
'varying vec4 d,e;'+ // return color, additiveColor
|
|
57
56
|
'void main(){'+ // shader entry point
|
|
58
|
-
'gl_Position=m*vec4(
|
|
59
|
-
'v=t;d=c;e=
|
|
57
|
+
'gl_Position=m*vec4(p,1,1);'+// transform position
|
|
58
|
+
'v=t;d=c;e=a;'+ // pass stuff to fragment shader
|
|
60
59
|
'}' // end of shader
|
|
61
60
|
,
|
|
62
61
|
'precision highp float;'+ // use highp for better accuracy, lowp for better perf
|
|
@@ -83,12 +82,10 @@ function glInit()
|
|
|
83
82
|
glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
|
|
84
83
|
offset += size*typeSize;
|
|
85
84
|
}
|
|
86
|
-
initVertexAttribArray('a', gl_FLOAT, 4, 1); // angle
|
|
87
85
|
initVertexAttribArray('p', gl_FLOAT, 4, 2); // position
|
|
88
|
-
initVertexAttribArray('s', gl_FLOAT, 4, 2); // size
|
|
89
86
|
initVertexAttribArray('t', gl_FLOAT, 4, 2); // texture coords
|
|
90
87
|
initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
|
|
91
|
-
initVertexAttribArray('
|
|
88
|
+
initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
|
|
92
89
|
}
|
|
93
90
|
|
|
94
91
|
/** Set the WebGl blend mode, normally you should call setBlendMode instead
|
|
@@ -203,6 +200,7 @@ function glPreRender(width, height, cameraX, cameraY, cameraScale)
|
|
|
203
200
|
|
|
204
201
|
// clear and set to same size as main canvas
|
|
205
202
|
glContext.viewport(0, 0, glCanvas.width = width, glCanvas.height = height);
|
|
203
|
+
glContext.clear(gl_COLOR_BUFFER_BIT);
|
|
206
204
|
|
|
207
205
|
// set up the shader
|
|
208
206
|
glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = glTileTexture);
|
|
@@ -249,12 +247,10 @@ function glCopyToContext(context, forceDraw)
|
|
|
249
247
|
if (!glEnable || !glBatchCount) return;
|
|
250
248
|
|
|
251
249
|
glFlush();
|
|
250
|
+
|
|
251
|
+
// do not draw in overlay mode because the canvas is visible
|
|
252
252
|
if (!glOverlay || forceDraw)
|
|
253
|
-
{
|
|
254
|
-
// do not draw/clear in overlay mode because the canvas is visible
|
|
255
253
|
context.drawImage(glCanvas, 0, 0);
|
|
256
|
-
glContext.clear(gl_COLOR_BUFFER_BIT);
|
|
257
|
-
}
|
|
258
254
|
}
|
|
259
255
|
|
|
260
256
|
/** Add a sprite to the gl draw list, used by all gl draw functions
|
|
@@ -277,51 +273,49 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba=0xffffff
|
|
|
277
273
|
// flush if there is no room for more verts or if different blend mode
|
|
278
274
|
if (glBatchCount == gl_MAX_BATCH || glBatchAdditive != glAdditive)
|
|
279
275
|
glFlush();
|
|
276
|
+
|
|
277
|
+
// prepare to create the verts from size and angle
|
|
278
|
+
const c = Math.cos(angle)/2, s = Math.sin(angle)/2;
|
|
279
|
+
const cX = c*sizeX, cY = c*sizeY, sX = s*sizeX, sY = s*sizeY;
|
|
280
280
|
|
|
281
281
|
// setup 2 triangles to form a quad
|
|
282
282
|
let offset = glBatchCount++ * gl_VERTICES_PER_QUAD * gl_INDICIES_PER_VERT;
|
|
283
283
|
|
|
284
284
|
// vertex 0
|
|
285
|
-
glPositionData[offset++] =
|
|
286
|
-
glPositionData[offset++] =
|
|
287
|
-
glPositionData[offset++] =
|
|
288
|
-
|
|
289
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
285
|
+
glPositionData[offset++] = x - cX - sY;
|
|
286
|
+
glPositionData[offset++] = y - cY + sX;
|
|
287
|
+
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv1Y;
|
|
288
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
290
289
|
|
|
291
290
|
// vertex 1
|
|
292
|
-
glPositionData[offset++] =
|
|
293
|
-
glPositionData[offset++] =
|
|
294
|
-
glPositionData[offset++] =
|
|
295
|
-
|
|
296
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
291
|
+
glPositionData[offset++] = x + cX + sY;
|
|
292
|
+
glPositionData[offset++] = y + cY - sX;
|
|
293
|
+
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv0Y;
|
|
294
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
297
295
|
|
|
298
296
|
// vertex 2
|
|
299
|
-
glPositionData[offset++] =
|
|
300
|
-
glPositionData[offset++] =
|
|
301
|
-
glPositionData[offset++] =
|
|
302
|
-
|
|
303
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
297
|
+
glPositionData[offset++] = x - cX + sY;
|
|
298
|
+
glPositionData[offset++] = y + cY + sX;
|
|
299
|
+
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv0Y;
|
|
300
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
304
301
|
|
|
305
302
|
// vertex 0
|
|
306
|
-
glPositionData[offset++] =
|
|
307
|
-
glPositionData[offset++] =
|
|
308
|
-
glPositionData[offset++] =
|
|
309
|
-
|
|
310
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
303
|
+
glPositionData[offset++] = x - cX - sY;
|
|
304
|
+
glPositionData[offset++] = y - cY + sX;
|
|
305
|
+
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv1Y;
|
|
306
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
311
307
|
|
|
312
308
|
// vertex 3
|
|
313
|
-
glPositionData[offset++] =
|
|
314
|
-
glPositionData[offset++] =
|
|
315
|
-
glPositionData[offset++] =
|
|
316
|
-
|
|
317
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
309
|
+
glPositionData[offset++] = x + cX - sY;
|
|
310
|
+
glPositionData[offset++] = y - cY - sX;
|
|
311
|
+
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv1Y;
|
|
312
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
318
313
|
|
|
319
314
|
// vertex 1
|
|
320
|
-
glPositionData[offset++] =
|
|
321
|
-
glPositionData[offset++] =
|
|
322
|
-
glPositionData[offset++] =
|
|
323
|
-
|
|
324
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
315
|
+
glPositionData[offset++] = x + cX + sY;
|
|
316
|
+
glPositionData[offset++] = y + cY - sX;
|
|
317
|
+
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv0Y;
|
|
318
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
325
319
|
}
|
|
326
320
|
|
|
327
321
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -353,6 +347,6 @@ gl_LINK_STATUS = 35714,
|
|
|
353
347
|
|
|
354
348
|
// constants for batch rendering
|
|
355
349
|
gl_VERTICES_PER_QUAD = 6,
|
|
356
|
-
gl_INDICIES_PER_VERT =
|
|
350
|
+
gl_INDICIES_PER_VERT = 6,
|
|
357
351
|
gl_MAX_BATCH = 1<<16,
|
|
358
|
-
gl_VERTEX_BYTE_STRIDE =
|
|
352
|
+
gl_VERTEX_BYTE_STRIDE = (4 * 2) * 2 + (4) * 2; // vec2 * 2 + (char * 4) * 2
|