littlejsengine 1.15.9 → 1.16.2
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 +154 -158
- package/dist/littlejs.esm.js +573 -570
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +553 -553
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +392 -396
- package/examples/box2d/game.js +1 -1
- package/examples/box2d/gameObjects.js +5 -5
- package/examples/breakout/game.js +3 -3
- package/examples/electron/game.js +1 -2
- package/examples/electron/index.html +2 -2
- package/examples/htmlMenu/game.js +0 -1
- package/examples/index.html +1 -1
- package/examples/logo.png +0 -0
- package/examples/logo2.png +0 -0
- package/examples/module/game.js +1 -2
- package/examples/particles/index.html +1 -1
- package/examples/platformer/game.js +4 -4
- package/examples/platformer/gameEffects.js +1 -1
- package/examples/puzzle/game.js +2 -2
- package/examples/shorts/base.html +4 -3
- package/examples/shorts/box2dPool.js +2 -2
- package/examples/shorts/empty.js +1 -1
- package/examples/shorts/{systemFont.js → fontImage.js} +3 -3
- package/examples/shorts/fps.js +1 -1
- package/examples/shorts/helloWorld.js +2 -2
- package/examples/shorts/nineSlice.js +2 -2
- package/examples/shorts/slidingPuzzle.js +1 -1
- package/examples/starter/game.js +1 -2
- package/examples/starter/index.html +3 -2
- package/examples/stress/index.html +1 -1
- package/examples/typescript/game.js +1 -2
- package/examples/typescript/game.ts +1 -2
- package/package.json +1 -1
- package/plugins/box2d.js +8 -8
- package/plugins/drawUtilities.js +6 -6
- package/plugins/postProcess.js +13 -20
- package/plugins/uiSystem.js +16 -4
- package/reference.md +9 -11
- package/src/engine.js +40 -54
- package/src/engineAudio.js +5 -7
- package/src/engineBuild.js +1 -0
- package/src/engineDebug.js +163 -161
- package/src/engineDraw.js +108 -130
- package/src/engineExport.js +20 -17
- package/src/engineInput.js +4 -7
- package/src/engineMath.js +1201 -0
- package/src/engineMedals.js +7 -7
- package/src/engineObject.js +5 -4
- package/src/engineRelease.js +2 -4
- package/src/engineSettings.js +22 -32
- package/src/engineTileLayer.js +9 -10
- package/src/engineUtilities.js +34 -1187
- package/src/engineWebGL.js +13 -15
package/reference.md
CHANGED
|
@@ -145,7 +145,6 @@ drawCanvas2D(pos, size, angle=0, mirror, drawFunction, screenSpace, context)
|
|
|
145
145
|
|
|
146
146
|
// Text functions
|
|
147
147
|
drawText(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
|
|
148
|
-
drawTextOverlay(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
|
|
149
148
|
drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
|
|
150
149
|
|
|
151
150
|
// Utility drawing functions
|
|
@@ -173,7 +172,6 @@ TextureInfo.glTexture // WebGL texture
|
|
|
173
172
|
FontImage(image, tileSize=(8,8), paddingSize=(0,1)) // Create an image font
|
|
174
173
|
FontImage.drawText(text, pos, scale, center) // Draw text in world space
|
|
175
174
|
FontImage.drawTextScreen(text, pos, scale, center) // Draw text in screen space
|
|
176
|
-
FontImage.drawTextOverlay(text, pos, scale, center) // Draw text to overlay canvas
|
|
177
175
|
|
|
178
176
|
// Camera settings
|
|
179
177
|
cameraPos = (0,0) // Position of camera in world space
|
|
@@ -193,8 +191,8 @@ showSplashScreen = false // Show the LittleJS splash screen on startup
|
|
|
193
191
|
glEnable = true // Enable fast WebGL rendering
|
|
194
192
|
|
|
195
193
|
// Tile sheet settings
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
tileDefaultSize = (16,16) // Default size of tiles in pixels
|
|
195
|
+
tileDefaultBleed = .3 // How much smaller to draw tiles to prevent bleeding
|
|
198
196
|
```
|
|
199
197
|
|
|
200
198
|
## LittleJS Audio System
|
|
@@ -430,18 +428,18 @@ debugCircle(pos, size, color='#fff', time=0, fill) // Draw debug circle
|
|
|
430
428
|
debugPoint(pos, color, time, angle) // Draw debug point
|
|
431
429
|
debugLine(posA, posB, color, width=.1, time) // Draw debug line
|
|
432
430
|
debugText(text, pos, size=1, color='#fff', time=0, angle=0) // Draw debug text
|
|
433
|
-
debugAABB(pA, sA, pB, sB, color)
|
|
434
|
-
debugClear()
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
431
|
+
debugAABB(pA, sA, pB, sB, color) // Draw a debug axis aligned box
|
|
432
|
+
debugClear() // Clear all debug primitives
|
|
433
|
+
saveCanvas(canvas, filename) // Save canvas to a file
|
|
434
|
+
saveText(text, filename) // Save text to a file
|
|
435
|
+
saveDataURL(dataURL, filename) // Save url to a file
|
|
438
436
|
|
|
439
437
|
// Debug settings
|
|
440
438
|
debug // Is debug enabled?
|
|
441
439
|
debugPointSize = .5 // Size to render debug points by default
|
|
442
440
|
debugKey = 'Escape' // Key code used to toggle debug mode
|
|
443
|
-
debugOverlay //
|
|
444
|
-
|
|
441
|
+
debugOverlay // Is the debug overlay is active?
|
|
442
|
+
debugWatermark // Should watermark with FPS appear in debug mode?
|
|
445
443
|
```
|
|
446
444
|
|
|
447
445
|
[LittleJS Engine](https://github.com/KilledByAPixel/LittleJS) Copyright 2021 Frank Force
|
package/src/engine.js
CHANGED
|
@@ -30,7 +30,7 @@ const engineName = 'LittleJS';
|
|
|
30
30
|
* @type {string}
|
|
31
31
|
* @default
|
|
32
32
|
* @memberof Engine */
|
|
33
|
-
const engineVersion = '1.
|
|
33
|
+
const engineVersion = '1.16.2';
|
|
34
34
|
|
|
35
35
|
/** Frames per second to update
|
|
36
36
|
* @type {number}
|
|
@@ -177,8 +177,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
177
177
|
mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
|
|
178
178
|
|
|
179
179
|
// disable smoothing for pixel art
|
|
180
|
-
|
|
181
|
-
mainContext.imageSmoothingEnabled = !tilesPixelated;
|
|
180
|
+
mainContext.imageSmoothingEnabled = !tilesPixelated;
|
|
182
181
|
|
|
183
182
|
// setup gl rendering if enabled
|
|
184
183
|
glPreRender();
|
|
@@ -190,7 +189,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
190
189
|
// update time keeping
|
|
191
190
|
let frameTimeDeltaMS = frameTimeMS - frameTimeLastMS;
|
|
192
191
|
frameTimeLastMS = frameTimeMS;
|
|
193
|
-
if (debug ||
|
|
192
|
+
if (debug || debugWatermark)
|
|
194
193
|
averageFPS = lerp(averageFPS, 1e3/(frameTimeDeltaMS||1), .05);
|
|
195
194
|
const debugSpeedUp = debug && keyIsDown('Equal'); // +
|
|
196
195
|
const debugSpeedDown = debug && keyIsDown('Minus'); // -
|
|
@@ -218,6 +217,8 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
218
217
|
debugUpdate();
|
|
219
218
|
gameUpdatePost();
|
|
220
219
|
inputUpdatePost();
|
|
220
|
+
if (debugVideoCaptureIsActive())
|
|
221
|
+
renderFrame();
|
|
221
222
|
}
|
|
222
223
|
else
|
|
223
224
|
{
|
|
@@ -268,33 +269,20 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
268
269
|
if (!wasUpdated)
|
|
269
270
|
updateCanvas();
|
|
270
271
|
|
|
271
|
-
// render
|
|
272
|
+
// render the game and objects
|
|
272
273
|
enginePreRender();
|
|
273
274
|
gameRender();
|
|
274
275
|
engineObjects.sort((a,b)=> a.renderOrder - b.renderOrder);
|
|
275
276
|
for (const o of engineObjects)
|
|
276
277
|
o.destroyed || o.render();
|
|
278
|
+
|
|
279
|
+
// post rendering
|
|
277
280
|
gameRenderPost();
|
|
278
281
|
pluginList.forEach(plugin=>plugin.render?.());
|
|
279
282
|
inputRender();
|
|
280
283
|
debugRender();
|
|
281
284
|
glFlush();
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if (showWatermark && !debugVideoCaptureIsActive())
|
|
285
|
-
{
|
|
286
|
-
// update fps display
|
|
287
|
-
overlayContext.textAlign = 'right';
|
|
288
|
-
overlayContext.textBaseline = 'top';
|
|
289
|
-
overlayContext.font = '1em monospace';
|
|
290
|
-
overlayContext.fillStyle = '#000';
|
|
291
|
-
const text = engineName + ' ' + 'v' + engineVersion + ' / '
|
|
292
|
-
+ drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
|
|
293
|
-
+ (glEnable ? ' GL' : ' 2D') ;
|
|
294
|
-
overlayContext.fillText(text, mainCanvas.width-3, 3);
|
|
295
|
-
overlayContext.fillStyle = '#fff';
|
|
296
|
-
overlayContext.fillText(text, mainCanvas.width-2, 2);
|
|
297
|
-
}
|
|
285
|
+
debugRenderPost();
|
|
298
286
|
drawCount = 0;
|
|
299
287
|
}
|
|
300
288
|
}
|
|
@@ -313,8 +301,8 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
313
301
|
const fixedAspect = canvasFixedSize.x / canvasFixedSize.y;
|
|
314
302
|
const w = innerAspect < fixedAspect ? '100%' : '';
|
|
315
303
|
const h = innerAspect < fixedAspect ? '' : '100%';
|
|
316
|
-
|
|
317
|
-
|
|
304
|
+
mainCanvas.style.width = w;
|
|
305
|
+
mainCanvas.style.height = h;
|
|
318
306
|
if (glCanvas)
|
|
319
307
|
{
|
|
320
308
|
glCanvas.style.width = w;
|
|
@@ -329,6 +317,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
329
317
|
|
|
330
318
|
// responsive aspect ratio with native resolution
|
|
331
319
|
const innerAspect = innerWidth / innerHeight;
|
|
320
|
+
ASSERT(canvasMinAspect <= canvasMaxAspect);
|
|
332
321
|
if (canvasMaxAspect && innerAspect > canvasMaxAspect)
|
|
333
322
|
{
|
|
334
323
|
// full height
|
|
@@ -343,12 +332,12 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
343
332
|
}
|
|
344
333
|
}
|
|
345
334
|
|
|
346
|
-
// clear main
|
|
347
|
-
|
|
348
|
-
|
|
335
|
+
// clear main canvas and set size
|
|
336
|
+
mainCanvas.width = mainCanvasSize.x;
|
|
337
|
+
mainCanvas.height = mainCanvasSize.y;
|
|
349
338
|
|
|
350
339
|
// apply the clear color to main canvas
|
|
351
|
-
if (canvasClearColor.a > 0)
|
|
340
|
+
if (canvasClearColor.a > 0 && !glEnable)
|
|
352
341
|
{
|
|
353
342
|
mainContext.fillStyle = canvasClearColor.toString();
|
|
354
343
|
mainContext.fillRect(0, 0, mainCanvasSize.x, mainCanvasSize.y);
|
|
@@ -356,19 +345,15 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
356
345
|
}
|
|
357
346
|
|
|
358
347
|
// set default line join and cap
|
|
359
|
-
|
|
360
|
-
mainContext.
|
|
361
|
-
mainContext.lineCap = overlayContext.lineCap = lineCap;
|
|
348
|
+
mainContext.lineJoin = 'round';
|
|
349
|
+
mainContext.lineCap = 'round';
|
|
362
350
|
}
|
|
351
|
+
|
|
352
|
+
// skip setup if headless
|
|
353
|
+
if (headlessMode) return startEngine();
|
|
363
354
|
|
|
364
|
-
//
|
|
365
|
-
|
|
366
|
-
{
|
|
367
|
-
await gameInit();
|
|
368
|
-
engineUpdate();
|
|
369
|
-
}
|
|
370
|
-
if (headlessMode)
|
|
371
|
-
return startEngine();
|
|
355
|
+
// setup webgl
|
|
356
|
+
glInit(rootElement);
|
|
372
357
|
|
|
373
358
|
// setup html
|
|
374
359
|
const styleRoot =
|
|
@@ -380,36 +365,30 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
380
365
|
'touch-action:none;' + // prevent mobile pinch to resize
|
|
381
366
|
'-webkit-touch-callout:none'; // compatibility for ios
|
|
382
367
|
rootElement.style.cssText = styleRoot;
|
|
383
|
-
|
|
384
|
-
rootElement.appendChild(mainCanvas);
|
|
368
|
+
mainCanvas = rootElement.appendChild(document.createElement('canvas'));
|
|
385
369
|
drawContext = mainContext = mainCanvas.getContext('2d');
|
|
386
370
|
|
|
387
371
|
// init stuff and start engine
|
|
388
372
|
inputInit();
|
|
389
373
|
audioInit();
|
|
390
374
|
debugInit();
|
|
391
|
-
glInit();
|
|
392
|
-
|
|
393
|
-
// create overlay canvas for hud to appear above gl canvas
|
|
394
|
-
overlayCanvas = document.createElement('canvas')
|
|
395
|
-
rootElement.appendChild(overlayCanvas);
|
|
396
|
-
overlayContext = overlayCanvas.getContext('2d');
|
|
397
375
|
|
|
398
376
|
// setup canvases
|
|
399
377
|
// transform way is still more reliable then flexbox or grid
|
|
400
378
|
const styleCanvas = 'position:absolute;'+ // allow canvases to overlap
|
|
401
379
|
'top:50%;left:50%;transform:translate(-50%,-50%)'; // center on screen
|
|
402
|
-
mainCanvas.style.cssText =
|
|
380
|
+
mainCanvas.style.cssText = styleCanvas;
|
|
403
381
|
if (glCanvas)
|
|
404
382
|
glCanvas.style.cssText = styleCanvas;
|
|
405
383
|
setCanvasPixelated(canvasPixelated);
|
|
406
|
-
setOverlayCanvasPixelated(overlayCanvasPixelated);
|
|
407
384
|
updateCanvas();
|
|
408
385
|
glPreRender();
|
|
409
386
|
|
|
410
|
-
// create offscreen
|
|
411
|
-
workCanvas = new OffscreenCanvas(
|
|
412
|
-
workContext = workCanvas.getContext('2d'
|
|
387
|
+
// create offscreen canvases for image processing
|
|
388
|
+
workCanvas = new OffscreenCanvas(64, 64);
|
|
389
|
+
workContext = workCanvas.getContext('2d');
|
|
390
|
+
workReadCanvas = new OffscreenCanvas(64, 64);
|
|
391
|
+
workReadContext = workReadCanvas.getContext('2d', { willReadFrequently: true });
|
|
413
392
|
|
|
414
393
|
// create promises for loading images
|
|
415
394
|
const promises = imageSources.map((src, textureIndex)=>
|
|
@@ -461,13 +440,20 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
461
440
|
await Promise.all(promises);
|
|
462
441
|
return startEngine();
|
|
463
442
|
|
|
443
|
+
async function startEngine()
|
|
444
|
+
{
|
|
445
|
+
// wait for gameInit to load
|
|
446
|
+
await gameInit();
|
|
447
|
+
engineUpdate();
|
|
448
|
+
}
|
|
449
|
+
|
|
464
450
|
///////////////////////////////////////////////////////////////////////////
|
|
465
451
|
// LittleJS Splash Screen
|
|
466
452
|
function drawEngineSplashScreen(t)
|
|
467
453
|
{
|
|
468
|
-
const x =
|
|
469
|
-
const w =
|
|
470
|
-
const h =
|
|
454
|
+
const x = mainContext;
|
|
455
|
+
const w = mainCanvas.width = innerWidth;
|
|
456
|
+
const h = mainCanvas.height = innerHeight;
|
|
471
457
|
|
|
472
458
|
{
|
|
473
459
|
// background
|
package/src/engineAudio.js
CHANGED
|
@@ -178,12 +178,12 @@ class Sound
|
|
|
178
178
|
///////////////////////////////////////////////////////////////////////////////
|
|
179
179
|
|
|
180
180
|
/**
|
|
181
|
-
* Sound Wave Object -
|
|
182
|
-
* - this can be used to play wave, mp3, and ogg files
|
|
181
|
+
* Sound Wave Object - Loads and stores an audio file for later use
|
|
182
|
+
* - this can be used to load and play wave, mp3, and ogg files
|
|
183
183
|
* @extends Sound
|
|
184
184
|
* @memberof Audio
|
|
185
185
|
* @example
|
|
186
|
-
* //
|
|
186
|
+
* // load an audio asset file
|
|
187
187
|
* const sound_example = new SoundWave('sound.mp3');
|
|
188
188
|
*
|
|
189
189
|
* // play the sound
|
|
@@ -383,8 +383,7 @@ class SoundInstance
|
|
|
383
383
|
/** Pause this sound instance */
|
|
384
384
|
pause()
|
|
385
385
|
{
|
|
386
|
-
if (this.isPaused())
|
|
387
|
-
return;
|
|
386
|
+
if (this.isPaused()) return;
|
|
388
387
|
|
|
389
388
|
// save current time and stop sound
|
|
390
389
|
this.pausedTime = this.getCurrentTime();
|
|
@@ -396,8 +395,7 @@ class SoundInstance
|
|
|
396
395
|
/** Unpauses this sound instance */
|
|
397
396
|
resume()
|
|
398
397
|
{
|
|
399
|
-
if (!this.isPaused())
|
|
400
|
-
return;
|
|
398
|
+
if (!this.isPaused()) return;
|
|
401
399
|
|
|
402
400
|
// restart sound from paused time
|
|
403
401
|
this.start(this.pausedTime);
|
package/src/engineBuild.js
CHANGED