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/engineWebGL.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LittleJS WebGL Interface
|
|
3
3
|
* - All webgl used by the engine is wrapped up here
|
|
4
|
+
* - Will fall back to 2D canvas rendering if webgl is not supported
|
|
4
5
|
* - For normal stuff you won't need to see or call anything in this file
|
|
5
6
|
* - For advanced stuff there are helper functions to create shaders, textures, etc
|
|
6
7
|
* - Can be disabled with glEnable to revert to 2D canvas rendering
|
|
7
8
|
* - Batches sprite rendering on GPU for incredibly fast performance
|
|
8
9
|
* - Sprite transform math is done in the shader where possible
|
|
9
|
-
* - Supports shadertoy style post processing shaders
|
|
10
|
+
* - Supports shadertoy style post processing shaders via plugin
|
|
10
11
|
* @namespace WebGL
|
|
11
12
|
*/
|
|
12
13
|
|
|
@@ -47,9 +48,17 @@ function glInit()
|
|
|
47
48
|
glCanvas = document.createElement('canvas');
|
|
48
49
|
glContext = glCanvas.getContext('webgl2', {antialias:glAntialias});
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
if (!glContext)
|
|
52
|
+
{
|
|
53
|
+
console.warn('WebGL2 not supported, falling back to 2D canvas rendering!');
|
|
54
|
+
glCanvas = glContext = undefined;
|
|
55
|
+
glEnable = false;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// create the webgl canvas
|
|
51
60
|
const rootElement = mainCanvas.parentElement;
|
|
52
|
-
|
|
61
|
+
rootElement.appendChild(glCanvas);
|
|
53
62
|
|
|
54
63
|
// setup vertex and fragment shaders
|
|
55
64
|
glShader = glCreateProgram(
|
|
@@ -92,10 +101,11 @@ function glInit()
|
|
|
92
101
|
glContext.bufferData(glContext.ARRAY_BUFFER, geometry, glContext.STATIC_DRAW);
|
|
93
102
|
}
|
|
94
103
|
|
|
95
|
-
// Setup render each frame, called automatically by engine
|
|
104
|
+
// Setup webgl render each frame, called automatically by engine
|
|
105
|
+
// Also used by tile layer rendering when redrawing tiles
|
|
96
106
|
function glPreRender()
|
|
97
107
|
{
|
|
98
|
-
if (!glEnable ||
|
|
108
|
+
if (!glEnable || !glContext) return;
|
|
99
109
|
|
|
100
110
|
// set up the shader and canvas
|
|
101
111
|
glClearCanvas();
|
|
@@ -126,41 +136,51 @@ function glPreRender()
|
|
|
126
136
|
initVertexAttribArray('c', glContext.UNSIGNED_BYTE, 1, 4); // color
|
|
127
137
|
initVertexAttribArray('a', glContext.UNSIGNED_BYTE, 1, 4); // additiveColor
|
|
128
138
|
initVertexAttribArray('r', glContext.FLOAT, 4, 1); // rotation
|
|
129
|
-
|
|
139
|
+
|
|
130
140
|
// build the transform matrix
|
|
131
141
|
const s = vec2(2*cameraScale).divide(mainCanvasSize);
|
|
132
|
-
const
|
|
142
|
+
const rotatedCam = cameraPos.rotate(-cameraAngle);
|
|
143
|
+
const p = vec2(-1).subtract(rotatedCam.multiply(s));
|
|
144
|
+
const ca = Math.cos(cameraAngle);
|
|
145
|
+
const sa = Math.sin(cameraAngle);
|
|
133
146
|
glContext.uniformMatrix4fv(glContext.getUniformLocation(glShader, 'm'), false,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
);
|
|
147
|
+
[
|
|
148
|
+
s.x * ca, s.y * sa, 0, 0,
|
|
149
|
+
-s.x * sa, s.y * ca, 0, 0,
|
|
150
|
+
1, 1, 1, 0,
|
|
151
|
+
p.x, p.y, 0, 1
|
|
152
|
+
]);
|
|
141
153
|
}
|
|
142
154
|
|
|
143
155
|
/** Clear the canvas and setup the viewport
|
|
144
156
|
* @memberof WebGL */
|
|
145
157
|
function glClearCanvas()
|
|
146
158
|
{
|
|
159
|
+
if (!glContext) return;
|
|
160
|
+
|
|
147
161
|
// clear and set to same size as main canvas
|
|
148
|
-
glContext.viewport(0, 0, glCanvas.width=
|
|
162
|
+
glContext.viewport(0, 0, glCanvas.width=drawCanvas.width, glCanvas.height=drawCanvas.height);
|
|
149
163
|
glContext.clear(glContext.COLOR_BUFFER_BIT);
|
|
150
164
|
}
|
|
151
165
|
|
|
152
166
|
/** Set the WebGl texture, called automatically if using multiple textures
|
|
153
167
|
* - This may also flush the gl buffer resulting in more draw calls and worse performance
|
|
154
168
|
* @param {WebGLTexture} texture
|
|
169
|
+
* @param {boolean} wrap - Should the texture wrap or clamp
|
|
155
170
|
* @memberof WebGL */
|
|
156
|
-
function glSetTexture(texture)
|
|
171
|
+
function glSetTexture(texture, wrap=false)
|
|
157
172
|
{
|
|
158
173
|
// must flush cache with the old texture to set a new one
|
|
159
|
-
if (
|
|
174
|
+
if (!glContext || texture == glActiveTexture)
|
|
160
175
|
return;
|
|
161
176
|
|
|
162
177
|
glFlush();
|
|
163
178
|
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture = texture);
|
|
179
|
+
|
|
180
|
+
// set wrap mode
|
|
181
|
+
const wrapMode = wrap ? glContext.REPEAT : glContext.CLAMP_TO_EDGE;
|
|
182
|
+
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_WRAP_S, wrapMode);
|
|
183
|
+
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_WRAP_T, wrapMode);
|
|
164
184
|
}
|
|
165
185
|
|
|
166
186
|
/** Compile WebGL shader of the given type, will throw errors if in debug mode
|
|
@@ -170,6 +190,8 @@ function glSetTexture(texture)
|
|
|
170
190
|
* @memberof WebGL */
|
|
171
191
|
function glCompileShader(source, type)
|
|
172
192
|
{
|
|
193
|
+
if (!glContext) return;
|
|
194
|
+
|
|
173
195
|
// build the shader
|
|
174
196
|
const shader = glContext.createShader(type);
|
|
175
197
|
glContext.shaderSource(shader, source);
|
|
@@ -188,6 +210,8 @@ function glCompileShader(source, type)
|
|
|
188
210
|
* @memberof WebGL */
|
|
189
211
|
function glCreateProgram(vsSource, fsSource)
|
|
190
212
|
{
|
|
213
|
+
if (!glContext) return;
|
|
214
|
+
|
|
191
215
|
// build the program
|
|
192
216
|
const program = glContext.createProgram();
|
|
193
217
|
glContext.attachShader(program, glCompileShader(vsSource, glContext.VERTEX_SHADER));
|
|
@@ -201,19 +225,19 @@ function glCreateProgram(vsSource, fsSource)
|
|
|
201
225
|
}
|
|
202
226
|
|
|
203
227
|
/** Create WebGL texture from an image and init the texture settings
|
|
204
|
-
* @param {HTMLImageElement} image
|
|
228
|
+
* @param {HTMLImageElement|HTMLCanvasElement|OffscreenCanvas} [image]
|
|
205
229
|
* @return {WebGLTexture}
|
|
206
230
|
* @memberof WebGL */
|
|
207
231
|
function glCreateTexture(image)
|
|
208
232
|
{
|
|
233
|
+
if (!glContext) return;
|
|
234
|
+
|
|
209
235
|
// build the texture
|
|
210
236
|
const texture = glContext.createTexture();
|
|
211
237
|
glContext.bindTexture(glContext.TEXTURE_2D, texture);
|
|
212
238
|
if (image && image.width)
|
|
213
239
|
{
|
|
214
240
|
glSetTextureData(texture, image);
|
|
215
|
-
|
|
216
|
-
const isPowerOfTwo = (value)=> !(value & (value - 1));
|
|
217
241
|
if (!tilesPixelated && isPowerOfTwo(image.width) && isPowerOfTwo(image.height))
|
|
218
242
|
{
|
|
219
243
|
// use mipmap filtering
|
|
@@ -237,12 +261,24 @@ function glCreateTexture(image)
|
|
|
237
261
|
return texture;
|
|
238
262
|
}
|
|
239
263
|
|
|
264
|
+
|
|
265
|
+
/** Deletes a WebGL texture
|
|
266
|
+
* @param {WebGLTexture} [texture]
|
|
267
|
+
* @memberof WebGL */
|
|
268
|
+
function glDeleteTexture(texture)
|
|
269
|
+
{
|
|
270
|
+
if (!glContext) return;
|
|
271
|
+
glContext.deleteTexture(texture);
|
|
272
|
+
}
|
|
273
|
+
|
|
240
274
|
/** Set WebGL texture data from an image
|
|
241
275
|
* @param {WebGLTexture} texture
|
|
242
|
-
* @param {HTMLImageElement} image
|
|
276
|
+
* @param {HTMLImageElement|HTMLCanvasElement|OffscreenCanvas} image
|
|
243
277
|
* @memberof WebGL */
|
|
244
278
|
function glSetTextureData(texture, image)
|
|
245
279
|
{
|
|
280
|
+
if (!glContext) return;
|
|
281
|
+
|
|
246
282
|
// build the texture
|
|
247
283
|
ASSERT(!!image && image.width > 0, 'Invalid image data.');
|
|
248
284
|
glContext.bindTexture(glContext.TEXTURE_2D, texture);
|
|
@@ -253,7 +289,7 @@ function glSetTextureData(texture, image)
|
|
|
253
289
|
* @memberof WebGL */
|
|
254
290
|
function glFlush()
|
|
255
291
|
{
|
|
256
|
-
if (!glInstanceCount) return;
|
|
292
|
+
if (!glEnable || !glContext || !glInstanceCount) return;
|
|
257
293
|
|
|
258
294
|
const destBlend = glBatchAdditive ? glContext.ONE : glContext.ONE_MINUS_SRC_ALPHA;
|
|
259
295
|
glContext.blendFuncSeparate(glContext.SRC_ALPHA, destBlend, glContext.ONE, destBlend);
|
|
@@ -262,25 +298,22 @@ function glFlush()
|
|
|
262
298
|
// draw all the sprites in the batch and reset the buffer
|
|
263
299
|
glContext.bufferSubData(glContext.ARRAY_BUFFER, 0, glPositionData);
|
|
264
300
|
glContext.drawArraysInstanced(glContext.TRIANGLE_STRIP, 0, 4, glInstanceCount);
|
|
265
|
-
if (showWatermark)
|
|
301
|
+
if (debug || showWatermark)
|
|
266
302
|
drawCount += glInstanceCount;
|
|
267
303
|
glInstanceCount = 0;
|
|
268
304
|
glBatchAdditive = glAdditive;
|
|
269
305
|
}
|
|
270
306
|
|
|
271
|
-
/**
|
|
307
|
+
/** Flush any sprites still in the buffer and copy to main canvas
|
|
272
308
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} context
|
|
273
|
-
* @param {boolean} [forceDraw]
|
|
274
309
|
* @memberof WebGL */
|
|
275
|
-
function glCopyToContext(context
|
|
310
|
+
function glCopyToContext(context)
|
|
276
311
|
{
|
|
277
|
-
if (!glEnable || !
|
|
312
|
+
if (!glEnable || !glContext)
|
|
313
|
+
return;
|
|
278
314
|
|
|
279
315
|
glFlush();
|
|
280
|
-
|
|
281
|
-
// do not draw in overlay mode because the canvas is visible
|
|
282
|
-
if (!glOverlay || forceDraw)
|
|
283
|
-
context.drawImage(glCanvas, 0, 0);
|
|
316
|
+
context.drawImage(glCanvas, 0, 0);
|
|
284
317
|
}
|
|
285
318
|
|
|
286
319
|
/** Set anti-aliasing for webgl canvas
|
|
@@ -297,18 +330,16 @@ function glSetAntialias(antialias=true)
|
|
|
297
330
|
* @param {Number} y
|
|
298
331
|
* @param {Number} sizeX
|
|
299
332
|
* @param {Number} sizeY
|
|
300
|
-
* @param {Number} angle
|
|
301
|
-
* @param {Number} uv0X
|
|
302
|
-
* @param {Number} uv0Y
|
|
303
|
-
* @param {Number} uv1X
|
|
304
|
-
* @param {Number} uv1Y
|
|
333
|
+
* @param {Number} [angle]
|
|
334
|
+
* @param {Number} [uv0X]
|
|
335
|
+
* @param {Number} [uv0Y]
|
|
336
|
+
* @param {Number} [uv1X]
|
|
337
|
+
* @param {Number} [uv1Y]
|
|
305
338
|
* @param {Number} [rgba=-1] - white is -1
|
|
306
339
|
* @param {Number} [rgbaAdditive=0] - black is 0
|
|
307
340
|
* @memberof WebGL */
|
|
308
|
-
function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba=-1, rgbaAdditive=0)
|
|
341
|
+
function glDraw(x, y, sizeX, sizeY, angle=0, uv0X=0, uv0Y=0, uv1X=1, uv1Y=1, rgba=-1, rgbaAdditive=0)
|
|
309
342
|
{
|
|
310
|
-
ASSERT(typeof rgba == 'number' && typeof rgbaAdditive == 'number', 'invalid color');
|
|
311
|
-
|
|
312
343
|
// flush if there is not enough room or if different blend mode
|
|
313
344
|
if (glInstanceCount >= gl_MAX_INSTANCES || glBatchAdditive != glAdditive)
|
|
314
345
|
glFlush();
|