littlejsengine 1.14.2 → 1.14.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 +2 -2
- package/dist/littlejs.d.ts +57 -17
- package/dist/littlejs.esm.js +233 -84
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +227 -84
- 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/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 +8 -6
- package/src/engine.js +7 -3
- package/src/engineBuild.js +2 -2
- package/src/engineDebug.js +3 -3
- 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
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
</head><body>
|
|
31
31
|
|
|
32
32
|
<!-- setup html menu system -->
|
|
33
|
-
<div class=
|
|
34
|
-
<div id=
|
|
35
|
-
<b style=
|
|
33
|
+
<div class=topDiv>
|
|
34
|
+
<div id=menu class=menuDiv>
|
|
35
|
+
<b style=font-size:50px>Test Menu</b>
|
|
36
36
|
This is an example menu using html elements.
|
|
37
|
-
<input id=
|
|
38
|
-
<input id=
|
|
39
|
-
<button id=
|
|
40
|
-
<button id=
|
|
37
|
+
<input id=input_test value='Test Input'>
|
|
38
|
+
<input id=input_rangeTest type=range>
|
|
39
|
+
<button id=button_test>Test Button</button>
|
|
40
|
+
<button id=button_exitMenu>Exit Menu</button>
|
|
41
41
|
</div>
|
|
42
42
|
</div>
|
|
43
43
|
|
package/examples/index.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<link rel=icon type=image/png href=favicon.png>
|
|
4
4
|
<link rel=stylesheet href=style.css?9>
|
|
5
5
|
<meta charset=utf-8>
|
|
6
|
-
<meta name=
|
|
6
|
+
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
|
7
7
|
</head><body>
|
|
8
8
|
<div id=container1>
|
|
9
9
|
<div id=container3>
|
|
@@ -35,7 +35,7 @@ Theme:
|
|
|
35
35
|
<div id=iframeContainer></div>
|
|
36
36
|
</div>
|
|
37
37
|
<div>
|
|
38
|
-
<input id=inputSearch placeholder='Search examples...' oninput=filterExamples() onkeydown='if(event.key
|
|
38
|
+
<input id=inputSearch placeholder='Search examples...' oninput=filterExamples() onkeydown='if(event.key===`Escape`)filterExamples(1)'>
|
|
39
39
|
<button id=buttonRestart onclick=restartCode()>Restart</button>
|
|
40
40
|
<button id=buttonPause>Pause</button>
|
|
41
41
|
<span id=container4>
|
|
@@ -318,7 +318,7 @@ function filterExamples(reset=0)
|
|
|
318
318
|
if (!selectExample.options.length)
|
|
319
319
|
{
|
|
320
320
|
// show a message if no matches
|
|
321
|
-
const o = new Option(
|
|
321
|
+
const o = new Option(`No examples found matching '${searchTerm}'`);
|
|
322
322
|
o.disabled = true;
|
|
323
323
|
selectExample.add(o);
|
|
324
324
|
}
|
|
@@ -184,13 +184,7 @@ export class Sky extends LJS.EngineObject
|
|
|
184
184
|
{
|
|
185
185
|
// fill background with a gradient
|
|
186
186
|
const canvas = LJS.mainCanvas;
|
|
187
|
-
|
|
188
|
-
for (let y=0; y<canvas.height; y+=gradientDelta)
|
|
189
|
-
{
|
|
190
|
-
// draw horizontal lines to create a gradient
|
|
191
|
-
const color = this.skyColor.lerp(this.horizonColor, y/canvas.height);
|
|
192
|
-
LJS.drawRect(vec2(0,y), vec2(canvas.width*2, gradientDelta*2), color, 0, undefined, true)
|
|
193
|
-
}
|
|
187
|
+
LJS.drawRectGradient(LJS.cameraPos, LJS.getCameraSize(), this.skyColor, this.horizonColor);
|
|
194
188
|
|
|
195
189
|
// draw stars
|
|
196
190
|
LJS.setBlendMode(true);
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
function gameRender()
|
|
2
2
|
{
|
|
3
|
-
// polygon shapes
|
|
4
|
-
for (let j=3; j<7; ++j)
|
|
5
|
-
drawRegularPoly(vec2(j*4-18,0), vec2(1), j, hsl(j/4+time/9,1,.5), .2, WHITE, time);
|
|
6
|
-
|
|
7
3
|
// circles and ellipses
|
|
8
|
-
drawCircle(vec2(0,5), 1+wave(.5),
|
|
9
|
-
drawEllipse(vec2(-
|
|
10
|
-
drawEllipse(vec2(
|
|
4
|
+
drawCircle(vec2(0,5), 1+wave(.5), RED);
|
|
5
|
+
drawEllipse(vec2(-6,5), vec2(1,1), YELLOW, .5);
|
|
6
|
+
drawEllipse(vec2(6,5), vec2(1,2), CLEAR_BLACK, .3, .5, CYAN)
|
|
7
|
+
|
|
8
|
+
// polygon shapes
|
|
9
|
+
drawRectGradient(vec2(-6,0), vec2(5,4), RED, BLUE)
|
|
10
|
+
drawRegularPoly(vec2(0,0), vec2(2), 3, PURPLE, .2, WHITE, time);
|
|
11
|
+
const starPath = [vec2(0,2), vec2(2,-2), vec2(-3,.5), vec2(3,.5), vec2(-2,-2), vec2(0,2)];
|
|
12
|
+
drawLineList(starPath, .2, MAGENTA, true, vec2(6, 0));
|
|
11
13
|
|
|
12
14
|
// rects and lines
|
|
13
|
-
drawRect(vec2(0,-5), vec2(4,3),
|
|
14
|
-
drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1
|
|
15
|
-
|
|
15
|
+
drawRect(vec2(0,-5), vec2(4,3), ORANGE, time);
|
|
16
|
+
drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1,.5));
|
|
17
|
+
drawLineList([vec2(5,-3), vec2(-5,-3), vec2(5,-7), vec2(-5,-7)], .2, GREEN);
|
|
16
18
|
}
|
|
@@ -21,7 +21,7 @@ import * as LJS from '../../dist/littlejs.esm.min.js';
|
|
|
21
21
|
const {vec2, rgb} = LJS;
|
|
22
22
|
|
|
23
23
|
// keep our own list of simple sprites and track fps
|
|
24
|
-
let sprites, tileLayer, timeMS, fpsDisplay, statsDisplay, spriteColor, spriteAdditiveColor, musicInstance;
|
|
24
|
+
let sprites, tileLayer, timeMS, fpsDisplay, statsDisplay, spriteColor, spriteAdditiveColor, musicInstance, hasClicked;
|
|
25
25
|
|
|
26
26
|
///////////////////////////////////////////////////////////////////////////////
|
|
27
27
|
|
|
@@ -59,21 +59,14 @@ function gameInit()
|
|
|
59
59
|
///////////////////////////////////////////////////////////////////////////////
|
|
60
60
|
function gameUpdate()
|
|
61
61
|
{
|
|
62
|
-
if (LJS.mouseWasPressed(0))
|
|
63
|
-
{
|
|
64
|
-
if (!musicInstance)
|
|
65
|
-
musicInstance = music.play();
|
|
66
|
-
else if (!musicInstance.isPlaying())
|
|
67
|
-
musicInstance.start();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
62
|
// mouse click = change color
|
|
71
63
|
if (LJS.mouseWasPressed(0) || LJS.mouseIsDown(2))
|
|
72
64
|
{
|
|
65
|
+
hasClicked = true;
|
|
73
66
|
spriteColor = LJS.randColor();
|
|
74
67
|
spriteAdditiveColor = LJS.randColor(rgb(.5,.5,.5, 0), rgb(0,0,0,0));
|
|
75
68
|
}
|
|
76
|
-
|
|
69
|
+
|
|
77
70
|
// right click = drop test object
|
|
78
71
|
if (LJS.mouseIsDown(2))
|
|
79
72
|
new TestObject(LJS.mousePos);
|
|
@@ -92,9 +85,18 @@ function gameUpdate()
|
|
|
92
85
|
additiveColor:spriteAdditiveColor.rgbaInt()
|
|
93
86
|
});
|
|
94
87
|
}
|
|
95
|
-
|
|
88
|
+
|
|
96
89
|
// mouse wheel = zoom
|
|
97
90
|
LJS.setCameraScale(LJS.clamp(LJS.cameraScale*(1-LJS.mouseWheel/10), 1, 1e3));
|
|
91
|
+
|
|
92
|
+
// mouse click = play music
|
|
93
|
+
if (hasClicked)
|
|
94
|
+
{
|
|
95
|
+
if (!musicInstance)
|
|
96
|
+
musicInstance = music.play();
|
|
97
|
+
else if (!musicInstance.isPlaying())
|
|
98
|
+
musicInstance.start();
|
|
99
|
+
}
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -167,5 +169,5 @@ LJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost,
|
|
|
167
169
|
|
|
168
170
|
///////////////////////////////////////////////////////////////////////////////
|
|
169
171
|
// music - Depp Loop
|
|
170
|
-
const music = new LJS.ZzFXMusic([[[.6,0,
|
|
172
|
+
const music = new LJS.ZzFXMusic([[[.6,0,77,,,1,1,.5,,,,,.1,,,.05,,.5,.4,.2],[,0,43,.01,,.2,2,,,,,,,,,,.01],[,0,170,.003,,.008,,.97,-35,53,,,,,,.1],[.8,0,270,,,.12,3,1.65,-2,,,,,4.5,,.02],[,0,86,,,.1,,.7,,,,.5,,6.7,1,.05],[,0,41,,.05,.4,2,0,,,9,.01,,,,.08,.02],[,0,2200,,,.04,3,2,,,800,.02,,4.8,,.01,.1],[.3,0,16,,,.3,3]],[[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,22,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,24,,,,,,,,,,,,,,,,,,,,,,,,22,,22,,22,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,24,,,,,,,,27,,,,,,,,,,,,,,,,27,,,,24,,,,24,,,,,,,,27,,,,,,,,,,,,,,,,24,,24,,24,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[6,1,,,34,34,34,,,,,,34,34,,,,,34,,,,34,34,,,,,34,,,,34,,,,34,34,34,,,,,,34,,,,,,34,34,,,34,34,,,,,,,,,34,34],[4,1,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,23,23,35,23,23,36,23,23,35,23,23,36,23,23,35,35,23,23,35,23,23,35,23,23,36,23,23,35,23,23,36,36],[5,-1,21,,,19,,,21,,,,,,,,,,21,,,19,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,],[3,1,24,,,24,,,24,,,,,,,,,,24,,,24,,,24,,,,24.75,24.5,24.26,24.01,24.01,24.01,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[4,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,24.75,24.5,24.26,24.01,24.01,24.01,24.01,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,,21,23,,35,,23,,21,23,,35,,35,,23,,21,23,,35,,21,23,,35,,21,23,,,],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,36,34,,33,34,34,36,31,36,34,,31,34,32,,33,36,34,,31,34,34,36,33,36,33,,31,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,21,,19,21,,33,,21,,19,21,,33,,33,,21,,19,21,,33,,21,,19,21,,33,,33,,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29],[2,1,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,],[6,1,,,36,,,,,,36,,36,,,,,,,,36,,,,,,36,,36,,,,,,,,36,,,,,,,,,,,,,,,,36,,,,,,36,,36,,,,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,25,,,25,,,,,,,,25,,,,,,,,25,25,25,25]],[[1,-1,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,19,19,31,19,19,31,19,19,31,19,19,31,19,19,31,31],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,36,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,19,,19,19,31,19,19,31,19,,19,19,31,19,19,31],[2,1,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,,,,,,34,,34,,,,,,,,34,,,,,,34,,34,,,,,,]]],[0,1,1,2,3,4,4]]);
|
|
171
173
|
</script>
|
|
@@ -23,7 +23,7 @@ fs.rmSync(BUILD_FOLDER, { recursive: true, force: true });
|
|
|
23
23
|
console.log(`Compiling TypeScript...`);
|
|
24
24
|
// Compile all TypeScript files at once
|
|
25
25
|
const tsFiles = tsSourceFiles.join(' ');
|
|
26
|
-
child_process.execSync(`npx tsc ${tsFiles} --outDir
|
|
26
|
+
child_process.execSync(`npx tsc ${tsFiles} --outDir './${BUILD_FOLDER}' --target es2020 --module es2020`, {stdio: 'inherit'});
|
|
27
27
|
console.log(`TypeScript built in ${((Date.now() - startTime)/1e3).toFixed(2)} seconds!`);
|
|
28
28
|
|
|
29
29
|
console.log(`Moving js files back to root...`);
|
package/package.json
CHANGED
package/plugins/box2d.js
CHANGED
|
@@ -1608,7 +1608,7 @@ class Box2dPlugin
|
|
|
1608
1608
|
case box2d.instance.b2Shape.e_circle:
|
|
1609
1609
|
{
|
|
1610
1610
|
const radius = shape.get_m_radius();
|
|
1611
|
-
drawCircle(pos, radius, color, lineWidth, lineColor);
|
|
1611
|
+
drawCircle(pos, radius*2, color, lineWidth, lineColor);
|
|
1612
1612
|
break;
|
|
1613
1613
|
}
|
|
1614
1614
|
case box2d.instance.b2Shape.e_edge:
|
|
@@ -1759,14 +1759,14 @@ async function box2dInit()
|
|
|
1759
1759
|
{
|
|
1760
1760
|
color = getDebugColor(color);
|
|
1761
1761
|
center = box2d.vec2FromPointer(center);
|
|
1762
|
-
drawCircle(center, radius, CLEAR_WHITE, debugLineWidth, color, false, false, overlayContext);
|
|
1762
|
+
drawCircle(center, radius*2, CLEAR_WHITE, debugLineWidth, color, false, false, overlayContext);
|
|
1763
1763
|
};
|
|
1764
1764
|
debugDraw.DrawSolidCircle = function(center, radius, axis, color)
|
|
1765
1765
|
{
|
|
1766
1766
|
color = getDebugColor(color);
|
|
1767
1767
|
center = box2d.vec2FromPointer(center);
|
|
1768
1768
|
axis = box2d.vec2FromPointer(axis).scale(radius);
|
|
1769
|
-
drawCircle(center, radius, color, debugLineWidth, color, false, false, overlayContext);
|
|
1769
|
+
drawCircle(center, radius*2, color, debugLineWidth, color, false, false, overlayContext);
|
|
1770
1770
|
drawLine(vec2(), axis, debugLineWidth, color, center, 0, false, false, overlayContext);
|
|
1771
1771
|
};
|
|
1772
1772
|
debugDraw.DrawTransform = function(transform)
|
package/reference.md
CHANGED
|
@@ -13,7 +13,7 @@ To start LittleJS, you need to create a few functions and pass them to engineIni
|
|
|
13
13
|
|
|
14
14
|
```javascript
|
|
15
15
|
// Start up LittleJS engine with your callback functions
|
|
16
|
-
engineInit(
|
|
16
|
+
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## LittleJS Utilities Classes and Functions
|
|
@@ -135,11 +135,13 @@ Timer.valueOf() // Get how long since elapsed, 0 if not set
|
|
|
135
135
|
// Drawing functions
|
|
136
136
|
drawTile(pos, size, tileInfo, color=WHITE, angle=0, mirror, additiveColor)
|
|
137
137
|
drawRect(pos, size, color=WHITE, angle=0)
|
|
138
|
-
|
|
138
|
+
drawRectGradient(pos, size, colorTop=WHITE, colorBottom=BLACK, angle=0)
|
|
139
|
+
drawLine(posA, posB, width=.1, color=WHITE, pos=(0,0), angle=0)
|
|
140
|
+
drawLineList(points, width=.1, color, wrap=false, pos=(0,0), angle=0)
|
|
139
141
|
drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos, angle=0)
|
|
140
|
-
drawRegularPoly(pos, size=(1,1), sides=3, color=WHITE)
|
|
141
|
-
drawEllipse(pos, size, color=WHITE, angle=0, lineWidth=0, lineColor=BLACK)
|
|
142
|
-
drawCircle(pos,
|
|
142
|
+
drawRegularPoly(pos, size=(1,1), sides=3, color=WHITE, lineWidth=0, lineColor=BLACK, angle=0)
|
|
143
|
+
drawEllipse(pos, size=(1,1), color=WHITE, angle=0, lineWidth=0, lineColor=BLACK)
|
|
144
|
+
drawCircle(pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
|
|
143
145
|
drawCanvas2D(pos, size, angle=0, mirror, drawFunction, screenSpace, context)
|
|
144
146
|
|
|
145
147
|
// Text functions
|
|
@@ -426,7 +428,7 @@ ASSERT(assert, output) // Asserts if the expression is false
|
|
|
426
428
|
debugRect(pos, size, color='#fff', time=0, angle=0, fill) // Draw debug rectangle
|
|
427
429
|
debugCircle(pos, radius, color='#fff', time=0, fill) // Draw debug circle
|
|
428
430
|
debugPoint(pos, color, time, angle) // Draw debug point
|
|
429
|
-
debugLine(posA, posB, color,
|
|
431
|
+
debugLine(posA, posB, color, width=.1, time) // Draw debug line
|
|
430
432
|
debugText(text, pos, size=1, color='#fff', time=0, angle=0) // Draw debug text
|
|
431
433
|
debugAABB(pA, sA, pB, sB, color) // Draw a debug axis aligned box
|
|
432
434
|
debugClear() // Clear all debug primitives
|
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.14.
|
|
33
|
+
const engineVersion = '1.14.4';
|
|
34
34
|
|
|
35
35
|
/** Frames per second to update
|
|
36
36
|
* @type {number}
|
|
@@ -246,8 +246,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
246
246
|
overlayContext.fillStyle = '#fff';
|
|
247
247
|
overlayContext.fillText(text, mainCanvas.width-2, 2);
|
|
248
248
|
}
|
|
249
|
-
|
|
250
|
-
drawCount = 0;
|
|
249
|
+
drawCount = 0;
|
|
251
250
|
}
|
|
252
251
|
requestAnimationFrame(engineUpdate);
|
|
253
252
|
}
|
|
@@ -281,6 +280,11 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
281
280
|
|
|
282
281
|
// save canvas size
|
|
283
282
|
mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
|
|
283
|
+
|
|
284
|
+
// set default line join and cap
|
|
285
|
+
const lineJoin = 'round', lineCap = 'round';
|
|
286
|
+
mainContext.lineJoin = overlayContext.lineJoin = lineJoin;
|
|
287
|
+
mainContext.lineCap = overlayContext.lineCap = lineCap;
|
|
284
288
|
}
|
|
285
289
|
|
|
286
290
|
// wait for gameInit to load
|
package/src/engineBuild.js
CHANGED
|
@@ -144,7 +144,7 @@ function Build(message, outputFile, files=[], buildSteps=[], isPrimaryBuild)
|
|
|
144
144
|
{
|
|
145
145
|
// add license and strict mode to top
|
|
146
146
|
buffer += license;
|
|
147
|
-
buffer +=
|
|
147
|
+
buffer += `'use strict';\n\n`;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
for (const file of files)
|
|
@@ -212,7 +212,7 @@ function typeScriptBuildStep(filename)
|
|
|
212
212
|
const tsFilename = `${BUILD_FOLDER}/${ENGINE_NAME}.d.ts`
|
|
213
213
|
child_process.execSync(`npx tsc ${filename} --declaration --allowJs --emitDeclarationOnly --outFile ${tsFilename}`);
|
|
214
214
|
|
|
215
|
-
// Make declare module part use the package name
|
|
215
|
+
// Make declare module part use the package name littlejsengine
|
|
216
216
|
let fileContent = fs.readFileSync(tsFilename, 'utf8');
|
|
217
217
|
fileContent = fileContent.replace(`${ENGINE_NAME}\.esm`, 'littlejsengine')
|
|
218
218
|
fs.writeFileSync(tsFilename, fileContent);
|
package/src/engineDebug.js
CHANGED
|
@@ -121,13 +121,13 @@ function debugPoint(pos, color, time, angle)
|
|
|
121
121
|
* @param {Vector2} posA
|
|
122
122
|
* @param {Vector2} posB
|
|
123
123
|
* @param {string} [color]
|
|
124
|
-
* @param {number} [
|
|
124
|
+
* @param {number} [width]
|
|
125
125
|
* @param {number} [time]
|
|
126
126
|
* @memberof Debug */
|
|
127
|
-
function debugLine(posA, posB, color,
|
|
127
|
+
function debugLine(posA, posB, color, width=.1, time)
|
|
128
128
|
{
|
|
129
129
|
const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
|
|
130
|
-
const size = vec2(
|
|
130
|
+
const size = vec2(width, halfDelta.length()*2);
|
|
131
131
|
debugRect(posA.add(halfDelta), size, color, time, halfDelta.angle(), true);
|
|
132
132
|
}
|
|
133
133
|
|
package/src/engineDraw.js
CHANGED
|
@@ -72,7 +72,9 @@ let mainCanvasSize = vec2();
|
|
|
72
72
|
* @memberof Draw */
|
|
73
73
|
let textureInfos = [];
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
/** Keeps track of how many draw calls there were each frame for debugging
|
|
76
|
+
* @type {number}
|
|
77
|
+
* @memberof Draw */
|
|
76
78
|
let drawCount;
|
|
77
79
|
|
|
78
80
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -227,8 +229,8 @@ class TextureInfo
|
|
|
227
229
|
function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
228
230
|
angle=0, mirror, additiveColor, useWebGL=glEnable, screenSpace, context)
|
|
229
231
|
{
|
|
230
|
-
ASSERT(isVector2(pos)
|
|
231
|
-
ASSERT(isVector2(size)
|
|
232
|
+
ASSERT(isVector2(pos), 'drawTile pos should be a vec2');
|
|
233
|
+
ASSERT(isVector2(size), 'drawTile size should be a vec2');
|
|
232
234
|
ASSERT(isColor(color) && (!additiveColor || isColor(additiveColor)), 'drawTile color is invalid');
|
|
233
235
|
ASSERT(isNumber(angle), 'drawTile angle should be a number');
|
|
234
236
|
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
@@ -276,7 +278,7 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
276
278
|
else
|
|
277
279
|
{
|
|
278
280
|
// normal canvas 2D rendering method (slower)
|
|
279
|
-
|
|
281
|
+
++drawCount;
|
|
280
282
|
size = new Vector2(size.x, -size.y); // fix upside down sprites
|
|
281
283
|
drawCanvas2D(pos, size, angle, mirror, (context)=>
|
|
282
284
|
{
|
|
@@ -312,10 +314,124 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
|
312
314
|
drawTile(pos, size, undefined, color, angle, false, undefined, useWebGL, screenSpace, context);
|
|
313
315
|
}
|
|
314
316
|
|
|
317
|
+
/** Draw a rect centered on pos with a gradient from top to bottom
|
|
318
|
+
* @param {Vector2} pos
|
|
319
|
+
* @param {Vector2} [size=(1,1)]
|
|
320
|
+
* @param {Color} [colorTop=(1,1,1,1)]
|
|
321
|
+
* @param {Color} [colorBottom=(0,0,0,1)]
|
|
322
|
+
* @param {number} [angle]
|
|
323
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
324
|
+
* @param {boolean} [screenSpace]
|
|
325
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
326
|
+
* @memberof Draw */
|
|
327
|
+
function drawRectGradient(pos, size, colorTop=WHITE, colorBottom=BLACK, angle=0, useWebGL=glEnable, screenSpace=false, context)
|
|
328
|
+
{
|
|
329
|
+
ASSERT(isVector2(pos), 'drawRectGradient pos should be a vec2');
|
|
330
|
+
ASSERT(isVector2(size), 'drawRectGradient size should be a vec2');
|
|
331
|
+
ASSERT(isColor(colorTop) && isColor(colorBottom), 'drawRectGradient color is invalid');
|
|
332
|
+
ASSERT(isNumber(angle), 'drawRectGradient angle should be a number');
|
|
333
|
+
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
334
|
+
if (useWebGL)
|
|
335
|
+
{
|
|
336
|
+
if (screenSpace)
|
|
337
|
+
{
|
|
338
|
+
// convert to world space
|
|
339
|
+
pos = screenToWorld(pos);
|
|
340
|
+
size = size.scale(1/cameraScale);
|
|
341
|
+
}
|
|
342
|
+
// build 4 corner points for the rectangle
|
|
343
|
+
const points = [], colors = [];
|
|
344
|
+
const halfSizeX = size.x/2, halfSizeY = size.y/2;
|
|
345
|
+
const colorTopInt = colorTop.rgbaInt();
|
|
346
|
+
const colorBottomInt = colorBottom.rgbaInt();
|
|
347
|
+
const c = Math.cos(-angle), s = Math.sin(-angle);
|
|
348
|
+
for (let i=4; i--;)
|
|
349
|
+
{
|
|
350
|
+
const x = i & 1 ? halfSizeX : -halfSizeX;
|
|
351
|
+
const y = i & 2 ? halfSizeY : -halfSizeY;
|
|
352
|
+
const rx = x * c - y * s;
|
|
353
|
+
const ry = x * s + y * c;
|
|
354
|
+
const color = i & 2 ? colorTopInt : colorBottomInt;
|
|
355
|
+
points.push(vec2(pos.x + rx, pos.y + ry));
|
|
356
|
+
colors.push(color);
|
|
357
|
+
}
|
|
358
|
+
glDrawColoredPoints(points, colors);
|
|
359
|
+
}
|
|
360
|
+
else
|
|
361
|
+
{
|
|
362
|
+
// normal canvas 2D rendering method (slower)
|
|
363
|
+
++drawCount;
|
|
364
|
+
size = new Vector2(size.x, -size.y); // fix upside down sprites
|
|
365
|
+
drawCanvas2D(pos, size, angle, false, (context)=>
|
|
366
|
+
{
|
|
367
|
+
// if no tile info, use untextured rect
|
|
368
|
+
const gradient = context.createLinearGradient(0, -.5, 0, .5);
|
|
369
|
+
gradient.addColorStop(0, colorTop.toString());
|
|
370
|
+
gradient.addColorStop(1, colorBottom.toString());
|
|
371
|
+
context.fillStyle = gradient;
|
|
372
|
+
context.fillRect(-.5, -.5, 1, 1);
|
|
373
|
+
}, screenSpace, context);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/** Draw connected lines between a series of points
|
|
378
|
+
* @param {Array<Vector2>} points
|
|
379
|
+
* @param {number} [width]
|
|
380
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
381
|
+
* @param {boolean} [wrap] - Should the last point connect to the first?
|
|
382
|
+
* @param {Vector2} [pos=(0,0)] - Offset to apply
|
|
383
|
+
* @param {number} [angle] - Angle to rotate by
|
|
384
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
385
|
+
* @param {boolean} [screenSpace]
|
|
386
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
387
|
+
* @memberof Draw */
|
|
388
|
+
function drawLineList(points, width=.1, color, wrap=false, pos=vec2(), angle=0, useWebGL=glEnable, screenSpace, context)
|
|
389
|
+
{
|
|
390
|
+
ASSERT(Array.isArray(points), 'drawLineList points should be an array');
|
|
391
|
+
ASSERT(isNumber(width), 'drawLineList width should be a number');
|
|
392
|
+
ASSERT(isColor(color), 'drawLineList color is invalid');
|
|
393
|
+
ASSERT(isVector2(pos), 'drawLineList pos should be a vec2');
|
|
394
|
+
ASSERT(isNumber(angle), 'drawLineList angle should be a number');
|
|
395
|
+
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
396
|
+
if (useWebGL)
|
|
397
|
+
{
|
|
398
|
+
let scale = 1;
|
|
399
|
+
if (screenSpace)
|
|
400
|
+
{
|
|
401
|
+
// convert to world space
|
|
402
|
+
pos = screenToWorld(pos);
|
|
403
|
+
scale = 1/cameraScale;
|
|
404
|
+
}
|
|
405
|
+
glDrawOutlineTransform(points, color.rgbaInt(), width, pos.x, pos.y, scale, scale, angle, wrap);
|
|
406
|
+
}
|
|
407
|
+
else
|
|
408
|
+
{
|
|
409
|
+
// normal canvas 2D rendering method (slower)
|
|
410
|
+
++drawCount;
|
|
411
|
+
drawCanvas2D(pos, vec2(1), angle, false, (context)=>
|
|
412
|
+
{
|
|
413
|
+
context.strokeStyle = color.toString();
|
|
414
|
+
context.lineWidth = width;
|
|
415
|
+
context.beginPath();
|
|
416
|
+
for (let i=0; i<points.length; ++i)
|
|
417
|
+
{
|
|
418
|
+
const point = points[i];
|
|
419
|
+
if (i)
|
|
420
|
+
context.lineTo(point.x, point.y);
|
|
421
|
+
else
|
|
422
|
+
context.moveTo(point.x, point.y);
|
|
423
|
+
}
|
|
424
|
+
if (wrap)
|
|
425
|
+
context.closePath();
|
|
426
|
+
context.stroke();
|
|
427
|
+
}, screenSpace, context);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
315
431
|
/** Draw colored line between two points
|
|
316
432
|
* @param {Vector2} posA
|
|
317
433
|
* @param {Vector2} posB
|
|
318
|
-
* @param {number} [
|
|
434
|
+
* @param {number} [width]
|
|
319
435
|
* @param {Color} [color=(1,1,1,1)]
|
|
320
436
|
* @param {Vector2} [pos=(0,0)] - Offset to apply
|
|
321
437
|
* @param {number} [angle] - Angle to rotate by
|
|
@@ -323,10 +439,10 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
|
323
439
|
* @param {boolean} [screenSpace]
|
|
324
440
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
325
441
|
* @memberof Draw */
|
|
326
|
-
function drawLine(posA, posB,
|
|
442
|
+
function drawLine(posA, posB, width=.1, color, pos=vec2(), angle=0, useWebGL, screenSpace, context)
|
|
327
443
|
{
|
|
328
444
|
const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
|
|
329
|
-
const size = vec2(
|
|
445
|
+
const size = vec2(width, halfDelta.length()*2);
|
|
330
446
|
pos = pos.add(posA.add(halfDelta));
|
|
331
447
|
angle += halfDelta.angle();
|
|
332
448
|
drawRect(pos, size, color, angle, useWebGL, screenSpace, context);
|
|
@@ -346,12 +462,16 @@ function drawLine(posA, posB, thickness=.1, color, pos=vec2(), angle=0, useWebGL
|
|
|
346
462
|
* @memberof Draw */
|
|
347
463
|
function drawRegularPoly(pos, size=vec2(1), sides=3, color=WHITE, lineWidth=0, lineColor=BLACK, angle=0, useWebGL=glEnable, screenSpace=false, context)
|
|
348
464
|
{
|
|
465
|
+
ASSERT(isVector2(size), 'drawRegularPoly size should be a vec2');
|
|
466
|
+
ASSERT(isNumber(sides), 'drawRegularPoly sides should be a number');
|
|
467
|
+
|
|
349
468
|
// build regular polygon points
|
|
350
469
|
const points = [];
|
|
470
|
+
const sizeX = size.x/2, sizeY = size.y/2;
|
|
351
471
|
for (let i=sides; i--;)
|
|
352
472
|
{
|
|
353
473
|
const a = (i/sides)*PI*2;
|
|
354
|
-
points.push(vec2(Math.sin(a)*
|
|
474
|
+
points.push(vec2(Math.sin(a)*sizeX, Math.cos(a)*sizeY));
|
|
355
475
|
}
|
|
356
476
|
drawPoly(points, color, lineWidth, lineColor, pos, angle, useWebGL, screenSpace, context);
|
|
357
477
|
}
|
|
@@ -369,7 +489,7 @@ function drawRegularPoly(pos, size=vec2(1), sides=3, color=WHITE, lineWidth=0, l
|
|
|
369
489
|
* @memberof Draw */
|
|
370
490
|
function drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos=vec2(), angle=0, useWebGL=glEnable, screenSpace=false, context=undefined)
|
|
371
491
|
{
|
|
372
|
-
ASSERT(isVector2(pos)
|
|
492
|
+
ASSERT(isVector2(pos), 'drawPoly pos should be a vec2');
|
|
373
493
|
ASSERT(Array.isArray(points), 'drawPoly points should be an array');
|
|
374
494
|
ASSERT(isColor(color) && isColor(lineColor), 'drawPoly color is invalid');
|
|
375
495
|
ASSERT(isNumber(lineWidth), 'drawPoly lineWidth should be a number');
|
|
@@ -410,7 +530,7 @@ function drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos=vec2(),
|
|
|
410
530
|
|
|
411
531
|
/** Draw colored ellipse using passed in point
|
|
412
532
|
* @param {Vector2} pos
|
|
413
|
-
* @param {Vector2} [size=(1,1)]
|
|
533
|
+
* @param {Vector2} [size=(1,1)] - Width and height diameter
|
|
414
534
|
* @param {Color} [color=(1,1,1,1)]
|
|
415
535
|
* @param {number} [angle]
|
|
416
536
|
* @param {number} [lineWidth]
|
|
@@ -421,8 +541,8 @@ function drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos=vec2(),
|
|
|
421
541
|
* @memberof Draw */
|
|
422
542
|
function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineColor=BLACK, useWebGL=glEnable, screenSpace=false, context)
|
|
423
543
|
{
|
|
424
|
-
ASSERT(isVector2(pos)
|
|
425
|
-
ASSERT(isVector2(size)
|
|
544
|
+
ASSERT(isVector2(pos), 'drawEllipse pos should be a vec2');
|
|
545
|
+
ASSERT(isVector2(size), 'drawEllipse size should be a vec2');
|
|
426
546
|
ASSERT(isColor(color) && isColor(lineColor), 'drawEllipse color is invalid');
|
|
427
547
|
ASSERT(isNumber(angle), 'drawEllipse angle should be a number');
|
|
428
548
|
ASSERT(isNumber(lineWidth), 'drawEllipse lineWidth should be a number');
|
|
@@ -440,7 +560,7 @@ function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineC
|
|
|
440
560
|
{
|
|
441
561
|
context.fillStyle = color.toString();
|
|
442
562
|
context.beginPath();
|
|
443
|
-
context.ellipse(0, 0, size.x, size.y, 0, 0, 9);
|
|
563
|
+
context.ellipse(0, 0, size.x/2, size.y/2, 0, 0, 9);
|
|
444
564
|
context.fill();
|
|
445
565
|
if (lineWidth)
|
|
446
566
|
{
|
|
@@ -454,7 +574,7 @@ function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineC
|
|
|
454
574
|
|
|
455
575
|
/** Draw colored circle using passed in point
|
|
456
576
|
* @param {Vector2} pos
|
|
457
|
-
* @param {number} [
|
|
577
|
+
* @param {number} [size=1] - Diameter
|
|
458
578
|
* @param {Color} [color=(1,1,1,1)]
|
|
459
579
|
* @param {number} [lineWidth=0]
|
|
460
580
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
@@ -462,8 +582,11 @@ function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineC
|
|
|
462
582
|
* @param {boolean} [screenSpace]
|
|
463
583
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
464
584
|
* @memberof Draw */
|
|
465
|
-
function drawCircle(pos,
|
|
466
|
-
{
|
|
585
|
+
function drawCircle(pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK, useWebGL=glEnable, screenSpace=false, context)
|
|
586
|
+
{
|
|
587
|
+
ASSERT(isNumber(size), 'drawCircle size should be a number');
|
|
588
|
+
drawEllipse(pos, vec2(size), color, 0, lineWidth, lineColor, useWebGL, screenSpace, context);
|
|
589
|
+
}
|
|
467
590
|
|
|
468
591
|
/** Draw directly to a 2d canvas context in world space
|
|
469
592
|
* @param {Vector2} pos
|
|
@@ -549,7 +672,6 @@ function drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=B
|
|
|
549
672
|
context.textAlign = textAlign;
|
|
550
673
|
context.font = size + 'px '+ font;
|
|
551
674
|
context.textBaseline = 'middle';
|
|
552
|
-
context.lineJoin = 'round';
|
|
553
675
|
|
|
554
676
|
const lines = (text+'').split('\n');
|
|
555
677
|
let posY = pos.y;
|
|
@@ -749,7 +871,7 @@ let engineFontImage;
|
|
|
749
871
|
* const font = new FontImage;
|
|
750
872
|
*
|
|
751
873
|
* // draw text
|
|
752
|
-
* font.drawTextScreen(
|
|
874
|
+
* font.drawTextScreen('LittleJS\nHello World!', vec2(200, 50));
|
|
753
875
|
*/
|
|
754
876
|
class FontImage
|
|
755
877
|
{
|
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
|
*/
|