littlejsengine 1.14.2 → 1.14.5
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 -3
- package/dist/littlejs.d.ts +59 -19
- package/dist/littlejs.esm.js +239 -90
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +233 -90
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +224 -81
- package/examples/box2d/game.js +4 -4
- package/examples/breakoutTutorial/README.md +1 -1
- package/examples/breakoutTutorial/game.js +1 -1
- package/examples/electron/build.js +1 -1
- package/examples/empty/game.js +1 -1
- package/examples/htmlMenu/index.html +7 -7
- package/examples/index.html +3 -3
- package/examples/platformer/gameEffects.js +1 -7
- package/examples/shorts/music.js +3 -3
- package/examples/shorts/shapes.js +12 -10
- package/examples/stress/index.html +14 -12
- package/examples/typescript/build.js +1 -1
- package/package.json +1 -1
- package/plugins/box2d.js +3 -3
- package/reference.md +9 -7
- package/src/engine.js +7 -3
- package/src/engineBuild.js +2 -2
- package/src/engineDebug.js +9 -9
- package/src/engineDraw.js +140 -18
- package/src/engineExport.js +6 -0
- package/src/engineObject.js +3 -3
- package/src/engineTileLayer.js +0 -1
- package/src/engineUtilities.js +4 -4
- package/src/engineWebGL.js +66 -48
- package/copyToGithub.bat +0 -28
package/src/engineExport.js
CHANGED
|
@@ -193,11 +193,14 @@ export
|
|
|
193
193
|
|
|
194
194
|
// Draw
|
|
195
195
|
textureInfos,
|
|
196
|
+
drawCount,
|
|
196
197
|
tile,
|
|
197
198
|
TileInfo,
|
|
198
199
|
TextureInfo,
|
|
199
200
|
mainCanvas,
|
|
200
201
|
mainContext,
|
|
202
|
+
drawCanvas,
|
|
203
|
+
drawContext,
|
|
201
204
|
overlayCanvas,
|
|
202
205
|
overlayContext,
|
|
203
206
|
mainCanvasSize,
|
|
@@ -205,6 +208,8 @@ export
|
|
|
205
208
|
worldToScreen,
|
|
206
209
|
drawTile,
|
|
207
210
|
drawRect,
|
|
211
|
+
drawRectGradient,
|
|
212
|
+
drawLineList,
|
|
208
213
|
drawLine,
|
|
209
214
|
drawPoly,
|
|
210
215
|
drawEllipse,
|
|
@@ -239,6 +244,7 @@ export
|
|
|
239
244
|
glDrawPointsTransform,
|
|
240
245
|
glDrawOutlineTransform,
|
|
241
246
|
glDrawPoints,
|
|
247
|
+
glDrawColoredPoints,
|
|
242
248
|
glAntialias,
|
|
243
249
|
glShader,
|
|
244
250
|
glPolyShader,
|
package/src/engineObject.js
CHANGED
|
@@ -42,11 +42,11 @@ class EngineObject
|
|
|
42
42
|
constructor(pos=vec2(), size=vec2(1), tileInfo, angle=0, color=new Color, renderOrder=0)
|
|
43
43
|
{
|
|
44
44
|
// check passed in params
|
|
45
|
-
ASSERT(isVector2(pos)
|
|
46
|
-
ASSERT(isVector2(size)
|
|
45
|
+
ASSERT(isVector2(pos), 'object pos should be a vec2');
|
|
46
|
+
ASSERT(isVector2(size), 'object size should be a vec2');
|
|
47
47
|
ASSERT(!tileInfo || tileInfo instanceof TileInfo, 'object tileInfo should be a TileInfo or undefined');
|
|
48
48
|
ASSERT(typeof angle === 'number' && isFinite(angle), 'object angle should be a number');
|
|
49
|
-
ASSERT(isColor(color)
|
|
49
|
+
ASSERT(isColor(color), 'object color should be a valid rgba color');
|
|
50
50
|
ASSERT(typeof renderOrder === 'number', 'object renderOrder should be a number');
|
|
51
51
|
|
|
52
52
|
/** @property {Vector2} - World space position of the object */
|
package/src/engineTileLayer.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* - Caches arrays of tiles to off screen canvas for fast rendering
|
|
4
4
|
* - Unlimited numbers of layers, allocates canvases as needed
|
|
5
5
|
* - Tile layers can be drawn to using their context with canvas2d
|
|
6
|
-
* - Drawn directly to the main canvas without using WebGL
|
|
7
6
|
* - Tile layers can also have collision with EngineObjects
|
|
8
7
|
* @namespace TileCollision
|
|
9
8
|
*/
|
package/src/engineUtilities.js
CHANGED
|
@@ -377,10 +377,10 @@ function vec2(x=0, y) { return new Vector2(x, y === undefined ? x : y); }
|
|
|
377
377
|
* @param {any} v
|
|
378
378
|
* @return {boolean}
|
|
379
379
|
* @memberof Utilities */
|
|
380
|
-
function isVector2(v) { return v instanceof Vector2; }
|
|
380
|
+
function isVector2(v) { return v instanceof Vector2 && v.isValid(); }
|
|
381
381
|
|
|
382
382
|
// vector2 asserts
|
|
383
|
-
function ASSERT_VECTOR2_VALID(v) { ASSERT(isVector2(v)
|
|
383
|
+
function ASSERT_VECTOR2_VALID(v) { ASSERT(isVector2(v), 'Vector2 is invalid.', v); }
|
|
384
384
|
function ASSERT_NUMBER_VALID(n) { ASSERT(isNumber(n), 'Number is invalid.', n); }
|
|
385
385
|
function ASSERT_VECTOR2_NORMAL(v)
|
|
386
386
|
{
|
|
@@ -638,10 +638,10 @@ function hsl(h, s, l, a) { return new Color().setHSLA(h, s, l, a); }
|
|
|
638
638
|
* @param {any} c
|
|
639
639
|
* @return {boolean}
|
|
640
640
|
* @memberof Utilities */
|
|
641
|
-
function isColor(c) { return c instanceof Color; }
|
|
641
|
+
function isColor(c) { return c instanceof Color && c.isValid(); }
|
|
642
642
|
|
|
643
643
|
// color asserts
|
|
644
|
-
function ASSERT_COLOR_VALID(c) { ASSERT(isColor(c)
|
|
644
|
+
function ASSERT_COLOR_VALID(c) { ASSERT(isColor(c), 'Color is invalid.', c); }
|
|
645
645
|
|
|
646
646
|
/**
|
|
647
647
|
* Color object (red, green, blue, alpha) with some helpful functions
|
package/src/engineWebGL.js
CHANGED
|
@@ -32,7 +32,7 @@ let glAntialias = true;
|
|
|
32
32
|
let glShader, glPolyShader, glPolyMode, glAdditive, glBatchAdditive, glActiveTexture, glArrayBuffer, glGeometryBuffer, glPositionData, glColorData, glBatchCount;
|
|
33
33
|
|
|
34
34
|
// WebGL internal constants
|
|
35
|
-
const gl_ARRAY_BUFFER_SIZE =
|
|
35
|
+
const gl_ARRAY_BUFFER_SIZE = 5e5;
|
|
36
36
|
const gl_INDICES_PER_INSTANCE = 11;
|
|
37
37
|
const gl_INSTANCE_BYTE_STRIDE = gl_INDICES_PER_INSTANCE * 4;
|
|
38
38
|
const gl_MAX_INSTANCES = gl_ARRAY_BUFFER_SIZE / gl_INSTANCE_BYTE_STRIDE | 0;
|
|
@@ -126,9 +126,9 @@ function glInit()
|
|
|
126
126
|
glContext.bufferData(glContext.ARRAY_BUFFER, geometry, glContext.STATIC_DRAW);
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
function glSetInstancedMode(
|
|
129
|
+
function glSetInstancedMode()
|
|
130
130
|
{
|
|
131
|
-
if (!glPolyMode
|
|
131
|
+
if (!glPolyMode)
|
|
132
132
|
return;
|
|
133
133
|
|
|
134
134
|
// setup instanced mode
|
|
@@ -209,7 +209,7 @@ function glPreRender()
|
|
|
209
209
|
1, 1, 1, 0,
|
|
210
210
|
p.x, p.y, 0, 1];
|
|
211
211
|
|
|
212
|
-
// set the same matrix for both shaders
|
|
212
|
+
// set the same transform matrix for both shaders
|
|
213
213
|
const initUniform = (program, uniform, value) =>
|
|
214
214
|
{
|
|
215
215
|
glContext.useProgram(program);
|
|
@@ -227,9 +227,12 @@ function glPreRender()
|
|
|
227
227
|
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture);
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
// start
|
|
231
|
-
glAdditive = glBatchAdditive =
|
|
232
|
-
|
|
230
|
+
// start with additive blending off
|
|
231
|
+
glAdditive = glBatchAdditive = false;
|
|
232
|
+
|
|
233
|
+
// force it to enter instanced mode
|
|
234
|
+
glPolyMode = true;
|
|
235
|
+
glSetInstancedMode();
|
|
233
236
|
}
|
|
234
237
|
|
|
235
238
|
/** Clear the canvas and setup the viewport
|
|
@@ -239,7 +242,9 @@ function glClearCanvas()
|
|
|
239
242
|
if (!glContext) return;
|
|
240
243
|
|
|
241
244
|
// clear and set to same size as main canvas
|
|
242
|
-
|
|
245
|
+
glCanvas.width = drawCanvas.width;
|
|
246
|
+
glCanvas.height = drawCanvas.height;
|
|
247
|
+
glContext.viewport(0, 0, glCanvas.width, glCanvas.height);
|
|
243
248
|
glContext.clear(glContext.COLOR_BUFFER_BIT);
|
|
244
249
|
}
|
|
245
250
|
|
|
@@ -374,15 +379,17 @@ function glFlush()
|
|
|
374
379
|
const destBlend = glBatchAdditive ? glContext.ONE : glContext.ONE_MINUS_SRC_ALPHA;
|
|
375
380
|
glContext.blendFuncSeparate(glContext.SRC_ALPHA, destBlend, glContext.ONE, destBlend);
|
|
376
381
|
glContext.enable(glContext.BLEND);
|
|
377
|
-
|
|
382
|
+
|
|
383
|
+
const byteLength = glBatchCount *
|
|
384
|
+
(glPolyMode ? gl_INDICES_PER_POLY_VERTEX : gl_INDICES_PER_INSTANCE);
|
|
385
|
+
glContext.bufferSubData(glContext.ARRAY_BUFFER, 0, glPositionData, 0, byteLength);
|
|
378
386
|
|
|
379
387
|
// draw the batch
|
|
380
388
|
if (glPolyMode)
|
|
381
389
|
glContext.drawArrays(glContext.TRIANGLE_STRIP, 0, glBatchCount);
|
|
382
390
|
else
|
|
383
391
|
glContext.drawArraysInstanced(glContext.TRIANGLE_STRIP, 0, 4, glBatchCount);
|
|
384
|
-
|
|
385
|
-
drawCount += glBatchCount;
|
|
392
|
+
drawCount += glBatchCount;
|
|
386
393
|
glBatchCount = 0;
|
|
387
394
|
}
|
|
388
395
|
glBatchAdditive = glAdditive;
|
|
@@ -446,7 +453,7 @@ function glDraw(x, y, sizeX, sizeY, angle=0, uv0X=0, uv0Y=0, uv1X=1, uv1Y=1, rgb
|
|
|
446
453
|
}
|
|
447
454
|
|
|
448
455
|
/** Transform and add a polygon to the gl draw list
|
|
449
|
-
* @param {Array} points - Array of Vector2 points
|
|
456
|
+
* @param {Array<Vector2>} points - Array of Vector2 points
|
|
450
457
|
* @param {number} rgba - Color of the polygon as a 32-bit integer
|
|
451
458
|
* @param {number} x
|
|
452
459
|
* @param {number} y
|
|
@@ -472,7 +479,7 @@ function glDrawPointsTransform(points, rgba, x, y, sx, sy, angle, tristrip=true)
|
|
|
472
479
|
}
|
|
473
480
|
|
|
474
481
|
/** Transform and add a polygon to the gl draw list
|
|
475
|
-
* @param {Array} points - Array of Vector2 points
|
|
482
|
+
* @param {Array<Vector2>} points - Array of Vector2 points
|
|
476
483
|
* @param {number} rgba - Color of the polygon as a 32-bit integer
|
|
477
484
|
* @param {number} lineWidth - Width of the outline
|
|
478
485
|
* @param {number} x
|
|
@@ -480,61 +487,73 @@ function glDrawPointsTransform(points, rgba, x, y, sx, sy, angle, tristrip=true)
|
|
|
480
487
|
* @param {number} sx
|
|
481
488
|
* @param {number} sy
|
|
482
489
|
* @param {number} angle
|
|
490
|
+
* @param {boolean} [wrap] - Should the outline connect the first and last points
|
|
483
491
|
* @memberof WebGL */
|
|
484
|
-
function glDrawOutlineTransform(points, rgba, lineWidth, x, y, sx, sy, angle)
|
|
492
|
+
function glDrawOutlineTransform(points, rgba, lineWidth, x, y, sx, sy, angle, wrap=true)
|
|
485
493
|
{
|
|
486
|
-
const outlinePoints = glMakeOutline(points, lineWidth);
|
|
494
|
+
const outlinePoints = glMakeOutline(points, lineWidth, wrap);
|
|
487
495
|
glDrawPointsTransform(outlinePoints, rgba, x, y, sx, sy, angle, false);
|
|
488
496
|
}
|
|
489
497
|
|
|
490
|
-
/** Add a
|
|
491
|
-
* @param {Array} points - Array of Vector2 points in
|
|
492
|
-
* @param {number} rgba - Color
|
|
498
|
+
/** Add a list of points to the gl draw list
|
|
499
|
+
* @param {Array<Vector2>} points - Array of Vector2 points in tri strip order
|
|
500
|
+
* @param {number} rgba - Color as a 32-bit integer
|
|
493
501
|
* @memberof WebGL */
|
|
494
502
|
function glDrawPoints(points, rgba)
|
|
495
503
|
{
|
|
496
504
|
if (!glEnable || points.length < 3)
|
|
497
505
|
return; // needs at least 3 points to have area
|
|
498
506
|
|
|
499
|
-
// add 2 degenerate verts if batching with existing polys to separate them
|
|
500
|
-
const needsBridge = glPolyMode && glBatchCount > 0;
|
|
501
|
-
const bridgeVerts = needsBridge ? 2 : 0;
|
|
502
|
-
const vertCount = points.length + bridgeVerts;
|
|
503
|
-
|
|
504
507
|
// flush if there is not enough room or if different blend mode
|
|
505
|
-
|
|
508
|
+
const vertCount = points.length + 2;
|
|
509
|
+
if (glBatchCount+vertCount >= gl_MAX_POLY_VERTEXES || glBatchAdditive !== glAdditive)
|
|
506
510
|
glFlush();
|
|
507
511
|
glSetPolyMode();
|
|
508
512
|
|
|
513
|
+
// setup triangle strip with degenerate verts at start and end
|
|
509
514
|
let offset = glBatchCount * gl_INDICES_PER_POLY_VERTEX;
|
|
510
|
-
|
|
511
|
-
// add degenerate bridge if needed (repeat last vertex of previous poly, then first of new poly)
|
|
512
|
-
if (needsBridge)
|
|
515
|
+
for(let i = vertCount; i--;)
|
|
513
516
|
{
|
|
514
|
-
|
|
515
|
-
const
|
|
516
|
-
glPositionData[offset++] =
|
|
517
|
-
glPositionData[offset++] =
|
|
518
|
-
glColorData[offset++] = glColorData[prevOffset + 2];
|
|
519
|
-
|
|
520
|
-
// repeat first vertex of new poly
|
|
521
|
-
glPositionData[offset++] = points[0].x;
|
|
522
|
-
glPositionData[offset++] = points[0].y;
|
|
517
|
+
const j = clamp(i-1, 0, vertCount-3);
|
|
518
|
+
const point = points[j];
|
|
519
|
+
glPositionData[offset++] = point.x;
|
|
520
|
+
glPositionData[offset++] = point.y;
|
|
523
521
|
glColorData[offset++] = rgba;
|
|
524
522
|
}
|
|
523
|
+
glBatchCount += vertCount;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/** Add a list of colored points to the gl draw list
|
|
527
|
+
* @param {Array<Vector2>} points - Array of Vector2 points in tri strip order
|
|
528
|
+
* @param {Array<number>} pointColors - Array of 32-bit integer colors
|
|
529
|
+
* @memberof WebGL */
|
|
530
|
+
function glDrawColoredPoints(points, pointColors)
|
|
531
|
+
{
|
|
532
|
+
if (!glEnable || points.length < 3)
|
|
533
|
+
return; // needs at least 3 points to have area
|
|
525
534
|
|
|
526
|
-
//
|
|
527
|
-
|
|
535
|
+
// flush if there is not enough room or if different blend mode
|
|
536
|
+
const vertCount = points.length + 2;
|
|
537
|
+
if (glBatchCount+vertCount >= gl_MAX_POLY_VERTEXES || glBatchAdditive !== glAdditive)
|
|
538
|
+
glFlush();
|
|
539
|
+
glSetPolyMode();
|
|
540
|
+
|
|
541
|
+
// setup triangle strip with degenerate verts at start and end
|
|
542
|
+
let offset = glBatchCount * gl_INDICES_PER_POLY_VERTEX;
|
|
543
|
+
for(let i = vertCount; i--;)
|
|
528
544
|
{
|
|
545
|
+
const j = clamp(i-1, 0, vertCount-3);
|
|
546
|
+
const point = points[j];
|
|
547
|
+
const color = pointColors[j];
|
|
529
548
|
glPositionData[offset++] = point.x;
|
|
530
549
|
glPositionData[offset++] = point.y;
|
|
531
|
-
glColorData[offset++] =
|
|
550
|
+
glColorData[offset++] = color;
|
|
532
551
|
}
|
|
533
552
|
glBatchCount += vertCount;
|
|
534
553
|
}
|
|
535
554
|
|
|
536
555
|
// WebGL internal function to convert polygon to outline triangle strip
|
|
537
|
-
function glMakeOutline(points, width)
|
|
556
|
+
function glMakeOutline(points, width, wrap=true)
|
|
538
557
|
{
|
|
539
558
|
if (points.length < 2)
|
|
540
559
|
return [];
|
|
@@ -543,12 +562,13 @@ function glMakeOutline(points, width)
|
|
|
543
562
|
const strip = [];
|
|
544
563
|
const n = points.length;
|
|
545
564
|
const e = 1e-6;
|
|
565
|
+
const miterLimit = width*100;
|
|
546
566
|
for (let i = 0; i < n; i++)
|
|
547
567
|
{
|
|
548
568
|
// for each vertex, calculate normal based on adjacent edges
|
|
549
|
-
const prev = points[(i - 1 + n) % n];
|
|
569
|
+
const prev = points[wrap ? (i - 1 + n) % n : max(i - 1, 0)];
|
|
550
570
|
const curr = points[i];
|
|
551
|
-
const next = points[(i + 1) % n];
|
|
571
|
+
const next = points[wrap ? (i + 1) % n : min(i + 1, n - 1)];
|
|
552
572
|
|
|
553
573
|
// direction from previous to current
|
|
554
574
|
const dx1 = curr.x - prev.x;
|
|
@@ -587,8 +607,8 @@ function glMakeOutline(points, width)
|
|
|
587
607
|
const dot = nx1 * nx + ny1 * ny;
|
|
588
608
|
if (dot > e)
|
|
589
609
|
{
|
|
590
|
-
// scale normal by miter length
|
|
591
|
-
const miterLength = 1 / dot;
|
|
610
|
+
// scale normal by miter length, clamped to miterLimit
|
|
611
|
+
const miterLength = min(1 / dot, miterLimit);
|
|
592
612
|
nx *= miterLength;
|
|
593
613
|
ny *= miterLength;
|
|
594
614
|
}
|
|
@@ -600,7 +620,7 @@ function glMakeOutline(points, width)
|
|
|
600
620
|
strip.push(inner);
|
|
601
621
|
strip.push(outer);
|
|
602
622
|
}
|
|
603
|
-
if (strip.length > 1)
|
|
623
|
+
if (strip.length > 1 && wrap)
|
|
604
624
|
{
|
|
605
625
|
// close the loop
|
|
606
626
|
strip.push(strip[0]);
|
|
@@ -635,10 +655,8 @@ function glPolyStrip(points)
|
|
|
635
655
|
if (signedArea(points) < 0)
|
|
636
656
|
points = points.reverse();
|
|
637
657
|
|
|
638
|
-
// tolerance constants
|
|
639
|
-
const e = 1e-10;
|
|
640
|
-
|
|
641
658
|
// check if point is inside triangle
|
|
659
|
+
const e = 1e-9;
|
|
642
660
|
const pointInTriangle = (p, a, b, c)=>
|
|
643
661
|
{
|
|
644
662
|
const c1 = cross(a, b, p);
|
package/copyToGithub.bat
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
@echo off
|
|
2
|
-
echo Copying LittleJS files to GitHub repository...
|
|
3
|
-
|
|
4
|
-
REM Set the GitHub repository path (adjust this to your actual GitHub repo location)
|
|
5
|
-
set GITHUB_PATH=C:\dev\GitHub\LittleJS
|
|
6
|
-
|
|
7
|
-
REM Check if GitHub path exists
|
|
8
|
-
if not exist "%GITHUB_PATH%" (
|
|
9
|
-
echo Error: GitHub repository path not found: %GITHUB_PATH%
|
|
10
|
-
echo Please update the GITHUB_PATH variable in this script
|
|
11
|
-
pause
|
|
12
|
-
exit /b 1
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
echo Copying folders and files...
|
|
16
|
-
|
|
17
|
-
REM Copy folders (using /E for subdirectories, /I to create destination, /Y to overwrite)
|
|
18
|
-
xcopy "dist" "%GITHUB_PATH%\dist\" /E /I /Y
|
|
19
|
-
xcopy "examples" "%GITHUB_PATH%\examples\" /E /I /Y
|
|
20
|
-
xcopy "plugins" "%GITHUB_PATH%\plugins\" /E /I /Y
|
|
21
|
-
xcopy "src" "%GITHUB_PATH%\src\" /E /I /Y
|
|
22
|
-
|
|
23
|
-
REM Copy individual files
|
|
24
|
-
copy "jsconfig.json" "%GITHUB_PATH%\" /Y
|
|
25
|
-
copy "package.json" "%GITHUB_PATH%\" /Y
|
|
26
|
-
copy "reference.md" "%GITHUB_PATH%\" /Y
|
|
27
|
-
|
|
28
|
-
echo Copy completed successfully!
|