littlejsengine 1.18.4 → 1.18.7
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/COPYRIGHT.txt +38 -0
- package/FAQ.md +633 -0
- package/README.md +19 -1
- package/dist/littlejs.d.ts +349 -54
- package/dist/littlejs.esm.js +1469 -448
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +1438 -436
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +1438 -436
- package/package.json +8 -1
- package/plugins/box2d.js +32 -7
- package/{src/engineMedals.js → plugins/medalSystem.js} +248 -196
- package/plugins/pathFinder.js +758 -0
- package/plugins/pluginExport.js +19 -0
- package/plugins/tween.js +1 -1
- package/plugins/tweenSystem.js +509 -0
- package/plugins/uiSystem.js +150 -11
- package/src/engine.js +2 -141
- package/src/engineAudio.js +8 -5
- package/src/engineBuild.mjs +4 -2
- package/src/engineDebug.js +1 -1
- package/src/engineDraw.js +21 -3
- package/src/engineExport.js +12 -12
- package/src/engineInput.js +1 -1
- package/src/engineLogo.js +146 -0
- package/src/engineMath.js +10 -3
- package/src/engineObject.js +11 -5
- package/src/engineParticles.js +6 -3
- package/src/engineRelease.js +1 -1
- package/src/engineSettings.js +0 -47
- package/src/engineUtilities.js +7 -2
- package/src/engineWebGL.js +34 -7
- package/src/jsconfig.json +3 -1
- package/.github/workflows/test.yml +0 -17
- package/AI.md +0 -173
- package/CLAUDE.md +0 -1
- package/examples/box2d/game.js +0 -192
- package/examples/box2d/gameObjects.js +0 -564
- package/examples/box2d/index.html +0 -9
- package/examples/box2d/scenes.js +0 -194
- package/examples/box2d/tiles.png +0 -0
- package/examples/breakout/game.js +0 -175
- package/examples/breakout/gameObjects.js +0 -147
- package/examples/breakout/index.html +0 -8
- package/examples/breakout/tiles.png +0 -0
- package/examples/breakoutTutorial/README.md +0 -521
- package/examples/breakoutTutorial/game.js +0 -191
- package/examples/breakoutTutorial/images/1.png +0 -0
- package/examples/breakoutTutorial/images/10.png +0 -0
- package/examples/breakoutTutorial/images/11.png +0 -0
- package/examples/breakoutTutorial/images/2.png +0 -0
- package/examples/breakoutTutorial/images/3.png +0 -0
- package/examples/breakoutTutorial/images/4.png +0 -0
- package/examples/breakoutTutorial/images/5.png +0 -0
- package/examples/breakoutTutorial/images/6.png +0 -0
- package/examples/breakoutTutorial/images/7.png +0 -0
- package/examples/breakoutTutorial/images/8.png +0 -0
- package/examples/breakoutTutorial/images/9.png +0 -0
- package/examples/breakoutTutorial/index.html +0 -8
- package/examples/electron/build.mjs +0 -127
- package/examples/electron/electron.js +0 -35
- package/examples/electron/game.js +0 -54
- package/examples/electron/index.html +0 -13
- package/examples/electron/package.json +0 -5
- package/examples/electron/tiles.png +0 -0
- package/examples/empty/game.js +0 -51
- package/examples/empty/index.html +0 -5
- package/examples/empty/tiles.png +0 -0
- package/examples/favicon.png +0 -0
- package/examples/games.jpg +0 -0
- package/examples/htmlMenu/game.js +0 -82
- package/examples/htmlMenu/index.html +0 -45
- package/examples/htmlMenu/tiles.png +0 -0
- package/examples/index.html +0 -62
- package/examples/logo.png +0 -0
- package/examples/logo2.png +0 -0
- package/examples/module/build.mjs +0 -124
- package/examples/module/game.js +0 -132
- package/examples/module/index.html +0 -10
- package/examples/module/tiles.png +0 -0
- package/examples/particles/index.html +0 -426
- package/examples/particles/tiles.png +0 -0
- package/examples/platformer/data/gameLevelData.tmx +0 -143
- package/examples/platformer/data/gameLevelData.tsx +0 -4
- package/examples/platformer/game.js +0 -147
- package/examples/platformer/gameCharacter.js +0 -309
- package/examples/platformer/gameEffects.js +0 -278
- package/examples/platformer/gameLevel.js +0 -205
- package/examples/platformer/gameLevelData.json +0 -171
- package/examples/platformer/gameObjects.js +0 -378
- package/examples/platformer/gamePlayer.js +0 -35
- package/examples/platformer/index.html +0 -9
- package/examples/platformer/tiles.png +0 -0
- package/examples/platformer/tilesLevel.png +0 -0
- package/examples/puzzle/game.js +0 -331
- package/examples/puzzle/index.html +0 -8
- package/examples/puzzle/tiles.png +0 -0
- package/examples/screenshot.jpg +0 -0
- package/examples/shorts/animation.js +0 -18
- package/examples/shorts/base.html +0 -54
- package/examples/shorts/blending.js +0 -14
- package/examples/shorts/box2d.js +0 -51
- package/examples/shorts/box2dCar.js +0 -59
- package/examples/shorts/box2dPool.js +0 -107
- package/examples/shorts/box2dTileLayer.js +0 -48
- package/examples/shorts/cameraDrag.js +0 -22
- package/examples/shorts/clock.js +0 -21
- package/examples/shorts/colors.js +0 -25
- package/examples/shorts/debugDraw.js +0 -37
- package/examples/shorts/empty.js +0 -30
- package/examples/shorts/flappyGame.js +0 -55
- package/examples/shorts/fontImage.js +0 -17
- package/examples/shorts/fps.js +0 -90
- package/examples/shorts/helloWorld.js +0 -11
- package/examples/shorts/hillGlideGame.js +0 -63
- package/examples/shorts/input.js +0 -64
- package/examples/shorts/landerGame.js +0 -57
- package/examples/shorts/maze.js +0 -48
- package/examples/shorts/medals.js +0 -51
- package/examples/shorts/music.js +0 -78
- package/examples/shorts/musicPlayer.js +0 -137
- package/examples/shorts/nineSlice.js +0 -40
- package/examples/shorts/parallax.js +0 -72
- package/examples/shorts/particles.js +0 -28
- package/examples/shorts/piano.js +0 -44
- package/examples/shorts/platformer.js +0 -45
- package/examples/shorts/pongGame.js +0 -41
- package/examples/shorts/postProcess.js +0 -62
- package/examples/shorts/sequencer.js +0 -124
- package/examples/shorts/shader.js +0 -29
- package/examples/shorts/shapes.js +0 -21
- package/examples/shorts/slidingPuzzle.js +0 -52
- package/examples/shorts/song.mp3 +0 -0
- package/examples/shorts/sound.js +0 -36
- package/examples/shorts/spaceGame.js +0 -58
- package/examples/shorts/spriteAtlas.js +0 -31
- package/examples/shorts/starfield.js +0 -15
- package/examples/shorts/texture.js +0 -16
- package/examples/shorts/textureWrapped.js +0 -12
- package/examples/shorts/tileLayer.js +0 -48
- package/examples/shorts/tileRaycast.js +0 -39
- package/examples/shorts/tiles.png +0 -0
- package/examples/shorts/tiltedView.js +0 -63
- package/examples/shorts/timers.js +0 -53
- package/examples/shorts/topDown.js +0 -38
- package/examples/shorts/tween.js +0 -24
- package/examples/shorts/uiSystem.js +0 -61
- package/examples/shorts/video.webm +0 -0
- package/examples/shorts/videoPlayer.js +0 -34
- package/examples/shorts.js +0 -743
- package/examples/starter/build.bat +0 -7
- package/examples/starter/build.mjs +0 -126
- package/examples/starter/game.js +0 -137
- package/examples/starter/index.html +0 -35
- package/examples/starter/tiles.png +0 -0
- package/examples/stress/index.html +0 -173
- package/examples/style.css +0 -150
- package/examples/tweenSystem/game.js +0 -171
- package/examples/tweenSystem/index.html +0 -10
- package/examples/tweenSystem/tiles.png +0 -0
- package/examples/typescript/build.mjs +0 -60
- package/examples/typescript/game.js +0 -100
- package/examples/typescript/game.ts +0 -132
- package/examples/typescript/index.html +0 -10
- package/examples/typescript/tiles.png +0 -0
- package/examples/typescript/tsconfig.json +0 -17
- package/examples/uiSystem/game.js +0 -139
- package/examples/uiSystem/index.html +0 -10
- package/examples/uiSystem/tiles.png +0 -0
- package/jsconfig.json +0 -12
- package/plugins/desktop.ini +0 -2
- package/reference.md +0 -448
- package/test/math.test.mjs +0 -774
- package/test/setup.mjs +0 -22
- package/test/smoke.test.mjs +0 -274
- package/test/tween.test.mjs +0 -576
- package/test/util.test.mjs +0 -80
package/test/setup.mjs
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// Minimal globalThis stubs so dist/littlejs.esm.js can import under Node.
|
|
2
|
-
// The bundle has two top-level side effects that need host objects:
|
|
3
|
-
// 1. `const isTouchDevice = !headlessMode && window.ontouchstart !== undefined;`
|
|
4
|
-
// 2. `let audioContext = new AudioContext;`
|
|
5
|
-
// Anything beyond these is on-demand inside functions we don't invoke from tests.
|
|
6
|
-
|
|
7
|
-
globalThis.window = {};
|
|
8
|
-
|
|
9
|
-
globalThis.AudioContext = class AudioContext
|
|
10
|
-
{
|
|
11
|
-
constructor() { this.currentTime = 0; this.destination = {}; this.state = 'running'; }
|
|
12
|
-
createGain() { return { connect(){}, gain: { value: 0 } }; }
|
|
13
|
-
createBuffer() { return {}; }
|
|
14
|
-
createBufferSource() { return { connect(){}, start(){}, stop(){} }; }
|
|
15
|
-
resume() { return Promise.resolve(); }
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
// Enable headless mode on the shared bundle instance. ES module caching
|
|
19
|
-
// means every test file that imports the bundle gets this same instance,
|
|
20
|
-
// so tile() / audio paths / input setup all take their headless branches.
|
|
21
|
-
const { setHeadlessMode } = await import('../dist/littlejs.esm.js');
|
|
22
|
-
setHeadlessMode(true);
|
package/test/smoke.test.mjs
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
import { test } from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
import {
|
|
4
|
-
EngineObject, ParticleEmitter, TileLayerData, TileInfo,
|
|
5
|
-
TileLayer, CanvasLayer, Medal,
|
|
6
|
-
Timer, tile, vec2, rgb,
|
|
7
|
-
} from '../dist/littlejs.esm.js';
|
|
8
|
-
|
|
9
|
-
const near = (a, b, eps=1e-9) => Math.abs(a - b) <= eps;
|
|
10
|
-
|
|
11
|
-
// Tier 2-lite: verify core engine primitives can be constructed without
|
|
12
|
-
// crashing or tripping ASSERTs (debug bundle keeps them live). We do NOT
|
|
13
|
-
// boot the engine via engineInit and we do NOT call render() (which would
|
|
14
|
-
// require a canvas context). update() on the base EngineObject is safe
|
|
15
|
-
// because the default is a no-op.
|
|
16
|
-
|
|
17
|
-
test('bundle exposes core engine symbols', () =>
|
|
18
|
-
{
|
|
19
|
-
// If the bundle failed to load under our stubs, this file wouldn't
|
|
20
|
-
// have imported at all — so reaching here proves import succeeded.
|
|
21
|
-
// These checks also guard against an export regression stripping
|
|
22
|
-
// core names from the public surface.
|
|
23
|
-
assert.equal(typeof EngineObject, 'function');
|
|
24
|
-
assert.equal(typeof Timer, 'function');
|
|
25
|
-
assert.equal(typeof tile, 'function');
|
|
26
|
-
assert.equal(typeof vec2, 'function');
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test('EngineObject constructs and base update is safe', () =>
|
|
30
|
-
{
|
|
31
|
-
const o = new EngineObject(vec2(0, 0), vec2(1, 1));
|
|
32
|
-
assert.equal(o.pos.x, 0);
|
|
33
|
-
assert.equal(o.pos.y, 0);
|
|
34
|
-
assert.equal(o.size.x, 1);
|
|
35
|
-
assert.equal(o.size.y, 1);
|
|
36
|
-
// base class update is an empty method — calling it should not throw
|
|
37
|
-
assert.doesNotThrow(() => o.update());
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test('EngineObject with color and angle constructs', () =>
|
|
41
|
-
{
|
|
42
|
-
const o = new EngineObject(vec2(5, -3), vec2(2, 2), undefined, Math.PI/4, rgb(1, 0, 0));
|
|
43
|
-
assert.equal(o.pos.x, 5);
|
|
44
|
-
assert.equal(o.angle, Math.PI/4);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test('tile() returns a TileInfo', () =>
|
|
48
|
-
{
|
|
49
|
-
const t = tile(0, 16);
|
|
50
|
-
assert(t instanceof TileInfo);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test('ParticleEmitter constructs with defaults', () =>
|
|
54
|
-
{
|
|
55
|
-
// minimum reasonable args: pos, angle, emitSize, emitTime, emitRate
|
|
56
|
-
const e = new ParticleEmitter(vec2(0, 0), 0, 0, 0, 0);
|
|
57
|
-
assert(e instanceof ParticleEmitter);
|
|
58
|
-
assert(e instanceof EngineObject);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test('TileLayerData constructs', () =>
|
|
62
|
-
{
|
|
63
|
-
// TileLayerData(tile, direction, mirror, color) — minimal form
|
|
64
|
-
assert.doesNotThrow(() => new TileLayerData(0));
|
|
65
|
-
assert.doesNotThrow(() => new TileLayerData(5, 1, false));
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
test('Timer lifecycle (unset -> set -> elapsed check)', () =>
|
|
69
|
-
{
|
|
70
|
-
const t = new Timer();
|
|
71
|
-
assert.equal(t.isSet(), false);
|
|
72
|
-
assert.equal(t.get(), 0); // returns 0 when unset
|
|
73
|
-
assert.equal(t.getSetTime(), 0);
|
|
74
|
-
t.set(1);
|
|
75
|
-
assert.equal(t.isSet(), true);
|
|
76
|
-
assert.equal(t.getSetTime(), 1);
|
|
77
|
-
t.unset();
|
|
78
|
-
assert.equal(t.isSet(), false);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test('Timer constructed with duration is set', () =>
|
|
82
|
-
{
|
|
83
|
-
const t = new Timer(5);
|
|
84
|
-
assert.equal(t.isSet(), true);
|
|
85
|
-
assert.equal(t.getSetTime(), 5);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// The engine's `time` global stays at 0 because the main loop never runs
|
|
89
|
-
// in headless mode without engineInit. That lets us check time-derived
|
|
90
|
-
// Timer methods against known reference points.
|
|
91
|
-
|
|
92
|
-
test('Timer active / elapsed / get for a fresh positive-duration timer', () =>
|
|
93
|
-
{
|
|
94
|
-
const t = new Timer(1);
|
|
95
|
-
assert.equal(t.active(), true); // time(0) < setAt(1)
|
|
96
|
-
assert.equal(t.elapsed(), false);
|
|
97
|
-
assert(near(t.get(), -1)); // negative = still active
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test('Timer active / elapsed / get for an already-elapsed timer', () =>
|
|
101
|
-
{
|
|
102
|
-
// negative duration -> timer's internal target is in the past
|
|
103
|
-
const t = new Timer(-2);
|
|
104
|
-
assert.equal(t.active(), false);
|
|
105
|
-
assert.equal(t.elapsed(), true);
|
|
106
|
-
assert(near(t.get(), 2)); // positive = how long since elapsed
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
test('Timer with zero duration is immediately elapsed', () =>
|
|
110
|
-
{
|
|
111
|
-
const t = new Timer(0);
|
|
112
|
-
assert.equal(t.active(), false);
|
|
113
|
-
assert.equal(t.elapsed(), true);
|
|
114
|
-
assert(near(t.get(), 0));
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
test('Timer getPercent for fresh positive-duration timer is 0', () =>
|
|
118
|
-
{
|
|
119
|
-
// at time=0 with a timer set for duration 1, no time has elapsed yet
|
|
120
|
-
assert(near(new Timer(1).getPercent(), 0));
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test('Timer unset returns 0 from get/getPercent/getSetTime', () =>
|
|
124
|
-
{
|
|
125
|
-
const t = new Timer();
|
|
126
|
-
assert.equal(t.isSet(), false);
|
|
127
|
-
assert.equal(t.get(), 0);
|
|
128
|
-
assert.equal(t.getPercent(), 0);
|
|
129
|
-
assert.equal(t.getSetTime(), 0);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
133
|
-
// EngineObject methods
|
|
134
|
-
|
|
135
|
-
test('EngineObject.setCollision applies each flag to the right slot', () =>
|
|
136
|
-
{
|
|
137
|
-
// Asymmetric patterns: each of the four (collideSolidObjects, isSolid,
|
|
138
|
-
// collideTiles, collideRaycast) slots gets a different value from its
|
|
139
|
-
// neighbors, so any pairwise swap of assignments would show up.
|
|
140
|
-
const o = new EngineObject(vec2(0, 0), vec2(1, 1));
|
|
141
|
-
// pattern A: [T, F, T, F]
|
|
142
|
-
o.setCollision(true, false, true, false);
|
|
143
|
-
assert.equal(o.collideSolidObjects, true);
|
|
144
|
-
assert.equal(o.isSolid, false);
|
|
145
|
-
assert.equal(o.collideTiles, true);
|
|
146
|
-
assert.equal(o.collideRaycast, false);
|
|
147
|
-
// pattern B: [T, T, F, T] — flips everything from A (ASSERT requires collideSolidObjects||!isSolid)
|
|
148
|
-
o.setCollision(true, true, false, true);
|
|
149
|
-
assert.equal(o.collideSolidObjects, true);
|
|
150
|
-
assert.equal(o.isSolid, true);
|
|
151
|
-
assert.equal(o.collideTiles, false);
|
|
152
|
-
assert.equal(o.collideRaycast, true);
|
|
153
|
-
// defaults: all true
|
|
154
|
-
o.setCollision();
|
|
155
|
-
assert.equal(o.collideSolidObjects, true);
|
|
156
|
-
assert.equal(o.isSolid, true);
|
|
157
|
-
assert.equal(o.collideTiles, true);
|
|
158
|
-
assert.equal(o.collideRaycast, true);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
test('EngineObject.addChild / removeChild maintain bidirectional links', () =>
|
|
162
|
-
{
|
|
163
|
-
const parent = new EngineObject(vec2(0, 0), vec2(1, 1));
|
|
164
|
-
const child = new EngineObject(vec2(0, 0), vec2(1, 1));
|
|
165
|
-
const localPos = vec2(2, 3);
|
|
166
|
-
parent.addChild(child, localPos, 0.5);
|
|
167
|
-
assert.equal(child.parent, parent);
|
|
168
|
-
assert.deepEqual(parent.children, [child]);
|
|
169
|
-
assert.equal(child.localAngle, 0.5);
|
|
170
|
-
// localPos is stored as a copy — mutating the original doesn't affect the child
|
|
171
|
-
assert.equal(child.localPos.x, 2);
|
|
172
|
-
assert.equal(child.localPos.y, 3);
|
|
173
|
-
localPos.x = 999;
|
|
174
|
-
assert.equal(child.localPos.x, 2);
|
|
175
|
-
// removeChild clears parent and splices children
|
|
176
|
-
parent.removeChild(child);
|
|
177
|
-
assert.equal(child.parent, undefined);
|
|
178
|
-
assert.deepEqual(parent.children, []);
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
test('EngineObject.destroy is idempotent and cascades to children', () =>
|
|
182
|
-
{
|
|
183
|
-
const parent = new EngineObject(vec2(0, 0), vec2(1, 1));
|
|
184
|
-
const childA = new EngineObject(vec2(0, 0), vec2(1, 1));
|
|
185
|
-
const childB = new EngineObject(vec2(0, 0), vec2(1, 1));
|
|
186
|
-
parent.addChild(childA);
|
|
187
|
-
parent.addChild(childB);
|
|
188
|
-
parent.destroy();
|
|
189
|
-
assert.equal(parent.destroyed, true);
|
|
190
|
-
// children cascade-destroyed
|
|
191
|
-
assert.equal(childA.destroyed, true);
|
|
192
|
-
assert.equal(childB.destroyed, true);
|
|
193
|
-
// children have parent cleared
|
|
194
|
-
assert.equal(childA.parent, undefined);
|
|
195
|
-
assert.equal(childB.parent, undefined);
|
|
196
|
-
// idempotent — second call is a no-op (no throw)
|
|
197
|
-
assert.doesNotThrow(() => parent.destroy());
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
test('EngineObject.destroy disconnects from parent', () =>
|
|
201
|
-
{
|
|
202
|
-
const parent = new EngineObject(vec2(0, 0), vec2(1, 1));
|
|
203
|
-
const child = new EngineObject(vec2(0, 0), vec2(1, 1));
|
|
204
|
-
parent.addChild(child);
|
|
205
|
-
child.destroy();
|
|
206
|
-
assert.equal(child.destroyed, true);
|
|
207
|
-
assert.equal(child.parent, undefined);
|
|
208
|
-
assert.deepEqual(parent.children, []); // parent's children array spliced
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
test('EngineObject.getAliveTime is 0 right after construction (time=0 in headless)', () =>
|
|
212
|
-
{
|
|
213
|
-
const o = new EngineObject(vec2(0, 0), vec2(1, 1));
|
|
214
|
-
assert(near(o.getAliveTime(), 0));
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
218
|
-
// Medal
|
|
219
|
-
|
|
220
|
-
test('Medal construction sets fields and registers in medals[]', () =>
|
|
221
|
-
{
|
|
222
|
-
const m = new Medal(100, 'Test Medal', 'A test medal', '🏆');
|
|
223
|
-
assert.equal(m.id, 100);
|
|
224
|
-
assert.equal(m.name, 'Test Medal');
|
|
225
|
-
assert.equal(m.description, 'A test medal');
|
|
226
|
-
assert.equal(m.icon, '🏆');
|
|
227
|
-
assert.equal(m.unlocked, false);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
test('Medal description and icon default when omitted', () =>
|
|
231
|
-
{
|
|
232
|
-
const m = new Medal(101, 'Defaults Medal');
|
|
233
|
-
assert.equal(m.description, '');
|
|
234
|
-
assert.equal(m.icon, '🏆'); // default trophy
|
|
235
|
-
assert.equal(m.unlocked, false);
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
239
|
-
// CanvasLayer / TileLayer
|
|
240
|
-
|
|
241
|
-
test('CanvasLayer extends EngineObject and has no canvas in headless', () =>
|
|
242
|
-
{
|
|
243
|
-
const cl = new CanvasLayer(vec2(0, 0), vec2(10, 10), 0, 0, vec2(64), false);
|
|
244
|
-
assert(cl instanceof EngineObject);
|
|
245
|
-
assert(cl instanceof CanvasLayer);
|
|
246
|
-
assert.equal(cl.canvas, undefined); // headless: no OffscreenCanvas created
|
|
247
|
-
assert.equal(cl.mass, 0); // physics disabled by default
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
test('TileLayer extends CanvasLayer and stubs render methods in headless', () =>
|
|
251
|
-
{
|
|
252
|
-
const tl = new TileLayer(vec2(0, 0), vec2(4, 3), tile(0, 16), 0, false);
|
|
253
|
-
assert(tl instanceof CanvasLayer);
|
|
254
|
-
assert(tl instanceof TileLayer);
|
|
255
|
-
// in headless the render-family methods are replaced with no-op arrow functions
|
|
256
|
-
assert.doesNotThrow(() => tl.render());
|
|
257
|
-
assert.doesNotThrow(() => tl.redraw());
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
test('drawTextureWrapped is exported', async () =>
|
|
261
|
-
{
|
|
262
|
-
const mod = await import('../dist/littlejs.esm.js');
|
|
263
|
-
assert.equal(typeof mod.drawTextureWrapped, 'function');
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
test('drawTextureWrapped is callable in headless mode', async () =>
|
|
267
|
-
{
|
|
268
|
-
const mod = await import('../dist/littlejs.esm.js');
|
|
269
|
-
const { drawTextureWrapped, vec2 } = mod;
|
|
270
|
-
// headlessMode short-circuits before texture lookup, so this just
|
|
271
|
-
// exercises argument-type ASSERTs (which are stripped in release)
|
|
272
|
-
assert.doesNotThrow(() =>
|
|
273
|
-
drawTextureWrapped(vec2(), vec2(1, 1), vec2(2, 2)));
|
|
274
|
-
});
|