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.
@@ -7,7 +7,7 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- LittleJS Engine -->
10
- <script src=../../dist/littlejs.js?1.18.2></script>
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.2></script>
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.18.2",
3
+ "version": "1.18.4",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
5
  "main": "dist/littlejs.esm.js",
6
6
  "types": "dist/littlejs.d.ts",
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
- this.body.SetTransform(box2d.vec2dTo(pos), angle);
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()), -angle); }
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
  }
@@ -60,4 +60,11 @@ export
60
60
  drawNineSliceScreen,
61
61
  drawThreeSlice,
62
62
  drawThreeSliceScreen,
63
+
64
+ // Tween System
65
+ Tween,
66
+ tweenProperty,
67
+ tweenStopAll,
68
+ tweenUpdate,
69
+ Ease,
63
70
  }