littlejsengine 1.18.2 → 1.18.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/AI.md +1 -0
- package/LICENSE +5 -27
- package/dist/littlejs.d.ts +201 -3
- package/dist/littlejs.esm.js +713 -18
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +701 -18
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +701 -18
- package/examples/index.html +62 -800
- package/examples/shorts/base.html +1 -1
- package/examples/shorts/textureWrapped.js +12 -0
- package/examples/shorts/tween.js +24 -0
- package/examples/shorts.js +743 -0
- package/examples/starter/index.html +2 -2
- package/examples/tweenSystem/game.js +171 -0
- package/examples/tweenSystem/index.html +10 -0
- package/examples/tweenSystem/tiles.png +0 -0
- package/package.json +1 -1
- package/plugins/box2d.js +4 -2
- package/plugins/pluginExport.js +7 -0
- package/plugins/tween.js +509 -0
- package/plugins/uiSystem.js +1 -1
- package/reference.md +1 -0
- package/src/engine.js +9 -6
- package/src/engineBuild.mjs +1 -0
- package/src/engineDraw.js +133 -2
- package/src/engineExport.js +5 -0
- package/src/engineInput.js +26 -0
- package/src/engineSettings.js +17 -0
- package/src/engineWebGL.js +3 -7
- package/test/smoke.test.mjs +16 -0
- package/test/tween.test.mjs +576 -0
- package/.claude/settings.local.json +0 -7
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../dist/littlejs.js?1.18.
|
|
10
|
+
<script src=../../dist/littlejs.js?1.18.4></script>
|
|
11
11
|
|
|
12
12
|
<!-- LittleJS Engine Source
|
|
13
13
|
<script src=../../src/engine.js></script>
|
|
@@ -32,4 +32,4 @@
|
|
|
32
32
|
-->
|
|
33
33
|
|
|
34
34
|
<!-- Add your game scripts here -->
|
|
35
|
-
<script src=game.js?1.18.
|
|
35
|
+
<script src=game.js?1.18.4></script>
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/*
|
|
2
|
+
LittleJS Tween System Example
|
|
3
|
+
- Demonstrates every public feature of the tween plugin
|
|
4
|
+
- 1) Property tween, 2) Callback tween, 3) Chaining, 4) Loop+PingPong,
|
|
5
|
+
5) Easing showcase, 6) Real-time tween that survives pause
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
import * as LJS from '../../dist/littlejs.esm.js';
|
|
11
|
+
const { vec2, hsl, drawRect, drawText } = LJS;
|
|
12
|
+
const { Tween, tweenProperty, Ease } = LJS;
|
|
13
|
+
|
|
14
|
+
LJS.setCanvasFixedSize(vec2(1920, 1080));
|
|
15
|
+
LJS.setCanvasPixelated(false);
|
|
16
|
+
|
|
17
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
18
|
+
// Layout — world-space row positions
|
|
19
|
+
|
|
20
|
+
const ROW_PROPERTY = 9;
|
|
21
|
+
const ROW_COUNTDOWN = 7.2;
|
|
22
|
+
const ROW_CHAIN = 5.4;
|
|
23
|
+
const ROW_LOOP = 3.6;
|
|
24
|
+
const ROW_PINGPONG = 1.8;
|
|
25
|
+
const ROW_EASE_TOP = 0;
|
|
26
|
+
const EASE_SPACING = 1.2;
|
|
27
|
+
const ROW_REALTIME = -10.0;
|
|
28
|
+
const ROW_VECTOR2 = -11.7;
|
|
29
|
+
const ROW_COLOR = -13.2;
|
|
30
|
+
const LABEL_X = -9;
|
|
31
|
+
|
|
32
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
33
|
+
// State
|
|
34
|
+
|
|
35
|
+
const moverObj = { pos: vec2(-5, ROW_PROPERTY) };
|
|
36
|
+
const chainObj = { pos: vec2(-5, ROW_CHAIN), size: 1 };
|
|
37
|
+
const loopObj = { pos: vec2(-5, ROW_LOOP) };
|
|
38
|
+
const pingPongObj = { pos: vec2(-5, ROW_PINGPONG) };
|
|
39
|
+
const realObj = { pos: vec2(-5, ROW_REALTIME) };
|
|
40
|
+
const vec2Obj = { pos: vec2(-5, ROW_VECTOR2 + 0.4) };
|
|
41
|
+
const colorObj = { pos: vec2(0, ROW_COLOR), color: hsl(0, 0.8, 0.6) };
|
|
42
|
+
let countdownValue = 10;
|
|
43
|
+
|
|
44
|
+
const easingDemos =
|
|
45
|
+
[
|
|
46
|
+
['LINEAR', Ease.LINEAR],
|
|
47
|
+
['OUT(SINE)', Ease.OUT(Ease.SINE)],
|
|
48
|
+
['OUT(POWER(2))', Ease.OUT(Ease.POWER(2))],
|
|
49
|
+
['OUT(BACK)', Ease.OUT(Ease.BACK)],
|
|
50
|
+
['OUT(ELASTIC)', Ease.OUT(Ease.ELASTIC)],
|
|
51
|
+
['OUT(BOUNCE)', Ease.OUT(Ease.BOUNCE)],
|
|
52
|
+
['IN_OUT(POW(3))', Ease.IN_OUT(Ease.POWER(3))],
|
|
53
|
+
['BEZIER', Ease.BEZIER(0.25, 0.1, 0.25, 1)],
|
|
54
|
+
];
|
|
55
|
+
const easingObjs = easingDemos.map((_, i) => ({
|
|
56
|
+
pos: vec2(-5, ROW_EASE_TOP - i * EASE_SPACING)
|
|
57
|
+
}));
|
|
58
|
+
|
|
59
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
60
|
+
function gameInit()
|
|
61
|
+
{
|
|
62
|
+
LJS.setCanvasClearColor(hsl(0, 0, 0.1));
|
|
63
|
+
|
|
64
|
+
// 1) Basic property tween, ping-pong forever
|
|
65
|
+
tweenProperty(moverObj.pos, 'x', -5, 5, 2).pingPong();
|
|
66
|
+
|
|
67
|
+
// 2) Callback tween — countdown 10 → 0 looping forever
|
|
68
|
+
new Tween((v) => { countdownValue = v; }, 10, 0, 5).loop();
|
|
69
|
+
|
|
70
|
+
// 3) Chaining: slide right, then shrink, then restart the chain
|
|
71
|
+
startChain();
|
|
72
|
+
|
|
73
|
+
// 4) Loop forever and PingPong forever on adjacent rows
|
|
74
|
+
tweenProperty(loopObj.pos, 'x', -5, 5, 1.5).loop();
|
|
75
|
+
tweenProperty(pingPongObj.pos, 'x', -5, 5, 1.5).pingPong();
|
|
76
|
+
|
|
77
|
+
// 5) Easing showcase — each row uses a different curve, all ping-pong
|
|
78
|
+
for (let i = 0; i < easingDemos.length; i++)
|
|
79
|
+
{
|
|
80
|
+
const [, easeFn] = easingDemos[i];
|
|
81
|
+
tweenProperty(easingObjs[i].pos, 'x', -5, 5, 2)
|
|
82
|
+
.setEase(easeFn)
|
|
83
|
+
.pingPong();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 6) Real-time tween — keeps moving while game is paused
|
|
87
|
+
tweenProperty(realObj.pos, 'x', -5, 5, 2, { useRealTime: true }).pingPong();
|
|
88
|
+
|
|
89
|
+
// 7) Vector2 tween — moves diagonally (interpolates both x and y)
|
|
90
|
+
tweenProperty(vec2Obj, 'pos',
|
|
91
|
+
vec2(-5, ROW_VECTOR2 + 0.4),
|
|
92
|
+
vec2( 5, ROW_VECTOR2 - 0.4),
|
|
93
|
+
2).pingPong();
|
|
94
|
+
|
|
95
|
+
// 8) Color tween — pulses between two colors using Color.lerp()
|
|
96
|
+
tweenProperty(colorObj, 'color', hsl(0, 0.8, 0.6), hsl(0.6, 0.8, 0.6), 2).pingPong();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function startChain()
|
|
100
|
+
{
|
|
101
|
+
chainObj.pos.x = -5;
|
|
102
|
+
chainObj.size = 1;
|
|
103
|
+
new Tween((v) => { chainObj.pos.x = v; }, -5, 5, 1.5)
|
|
104
|
+
.then(() =>
|
|
105
|
+
{
|
|
106
|
+
new Tween((v) => { chainObj.size = v; }, 1, 0.2, 0.8)
|
|
107
|
+
.then(startChain);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
112
|
+
function gameUpdate() { }
|
|
113
|
+
|
|
114
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
115
|
+
function gameUpdatePost()
|
|
116
|
+
{
|
|
117
|
+
// Press P to toggle pause; the real-time row keeps moving regardless.
|
|
118
|
+
if (LJS.keyWasPressed('KeyP')) LJS.setPaused(!LJS.getPaused());
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
122
|
+
function gameRender()
|
|
123
|
+
{
|
|
124
|
+
drawRect(moverObj.pos, vec2(0.8), hsl(0.60, 0.8, 0.6));
|
|
125
|
+
drawRect(chainObj.pos, vec2(chainObj.size), hsl(0.05, 0.8, 0.6));
|
|
126
|
+
drawRect(loopObj.pos, vec2(0.8), hsl(0.30, 0.8, 0.6));
|
|
127
|
+
drawRect(pingPongObj.pos, vec2(0.8), hsl(0.50, 0.8, 0.6));
|
|
128
|
+
for (let i = 0; i < easingObjs.length; i++)
|
|
129
|
+
drawRect(easingObjs[i].pos, vec2(0.6), hsl(i / easingObjs.length, 0.8, 0.6));
|
|
130
|
+
drawRect(realObj.pos, vec2(0.8), hsl(0.85, 0.8, 0.6));
|
|
131
|
+
drawRect(vec2Obj.pos, vec2(0.8), hsl(0.15, 0.8, 0.6));
|
|
132
|
+
drawRect(colorObj.pos, vec2(0.8), colorObj.color);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
136
|
+
function gameRenderPost()
|
|
137
|
+
{
|
|
138
|
+
const labelColor = hsl(0, 0, 1);
|
|
139
|
+
const subColor = hsl(0, 0, 0.75);
|
|
140
|
+
|
|
141
|
+
// Title and subtitle (world space, centered)
|
|
142
|
+
drawText('LittleJS Tween System Example', vec2(0, 13), 1.4, labelColor);
|
|
143
|
+
drawText('Press P to pause — the bottom row uses useRealTime and keeps moving',
|
|
144
|
+
vec2(0, 11.5), 0.5, subColor);
|
|
145
|
+
|
|
146
|
+
// Row labels (centered at LABEL_X, sitting just left of the animating objects)
|
|
147
|
+
drawText('property', vec2(LABEL_X, ROW_PROPERTY), 0.6, labelColor);
|
|
148
|
+
drawText('callback', vec2(LABEL_X, ROW_COUNTDOWN), 0.6, labelColor);
|
|
149
|
+
drawText('chain', vec2(LABEL_X, ROW_CHAIN), 0.6, labelColor);
|
|
150
|
+
drawText('loop()', vec2(LABEL_X, ROW_LOOP), 0.6, labelColor);
|
|
151
|
+
drawText('pingPong()', vec2(LABEL_X, ROW_PINGPONG), 0.6, labelColor);
|
|
152
|
+
for (let i = 0; i < easingDemos.length; i++)
|
|
153
|
+
{
|
|
154
|
+
const [label] = easingDemos[i];
|
|
155
|
+
drawText(label, vec2(LABEL_X, ROW_EASE_TOP - i * EASE_SPACING), 0.5, labelColor);
|
|
156
|
+
}
|
|
157
|
+
drawText('useRealTime', vec2(LABEL_X, ROW_REALTIME), 0.6, labelColor);
|
|
158
|
+
drawText('Vector2', vec2(LABEL_X, ROW_VECTOR2), 0.6, labelColor);
|
|
159
|
+
drawText('Color', vec2(LABEL_X, ROW_COLOR), 0.6, labelColor);
|
|
160
|
+
|
|
161
|
+
// Live countdown value sitting on the callback row, between label and the easing rows
|
|
162
|
+
const countdownText = Math.ceil(countdownValue).toString();
|
|
163
|
+
drawText(countdownText, vec2(0, ROW_COUNTDOWN), 1.2, hsl(0, 0.8, 0.6));
|
|
164
|
+
|
|
165
|
+
// Pause indicator
|
|
166
|
+
if (LJS.getPaused())
|
|
167
|
+
drawText('PAUSED', vec2(0, -5), 2.5, hsl(0, 1, 0.7));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
171
|
+
LJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<!DOCTYPE html><head>
|
|
2
|
+
<title>LittleJS Tween System Example</title>
|
|
3
|
+
<meta charset=utf-8>
|
|
4
|
+
<meta name=apple-mobile-web-app-capable content=yes>
|
|
5
|
+
<meta name=mobile-web-app-capable content=yes>
|
|
6
|
+
<link rel=icon type=image/png href=../favicon.png>
|
|
7
|
+
</head><body>
|
|
8
|
+
|
|
9
|
+
<!-- Add your game scripts here -->
|
|
10
|
+
<script src=game.js type=module></script>
|
|
Binary file
|
package/package.json
CHANGED
package/plugins/box2d.js
CHANGED
|
@@ -401,7 +401,8 @@ class Box2dObject extends EngineObject
|
|
|
401
401
|
{
|
|
402
402
|
this.pos = pos;
|
|
403
403
|
this.angle = angle;
|
|
404
|
-
|
|
404
|
+
// box2d uses reverse angle
|
|
405
|
+
this.body.SetTransform(box2d.vec2dTo(pos), -angle);
|
|
405
406
|
}
|
|
406
407
|
|
|
407
408
|
/** Sets the position
|
|
@@ -412,7 +413,7 @@ class Box2dObject extends EngineObject
|
|
|
412
413
|
/** Sets the angle
|
|
413
414
|
* @param {number} angle */
|
|
414
415
|
setAngle(angle)
|
|
415
|
-
{ this.setTransform(box2d.vec2From(this.body.GetPosition()),
|
|
416
|
+
{ this.setTransform(box2d.vec2From(this.body.GetPosition()), angle); }
|
|
416
417
|
|
|
417
418
|
/** Sets the linear velocity
|
|
418
419
|
* @param {Vector2} velocity */
|
|
@@ -1957,6 +1958,7 @@ async function box2dInit()
|
|
|
1957
1958
|
{
|
|
1958
1959
|
if (o.body)
|
|
1959
1960
|
{
|
|
1961
|
+
// box2d uses reverse angle
|
|
1960
1962
|
o.pos = box2d.vec2From(o.body.GetPosition());
|
|
1961
1963
|
o.angle = -o.body.GetAngle();
|
|
1962
1964
|
}
|