littlejsengine 1.18.1 → 1.18.2
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/.claude/settings.local.json +7 -0
- package/.github/workflows/test.yml +17 -0
- package/AI.md +10 -0
- package/README.md +2 -2
- package/dist/littlejs.d.ts +36 -7
- package/dist/littlejs.esm.js +36 -15
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +32 -13
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +32 -13
- package/examples/shorts/base.html +1 -1
- package/examples/starter/index.html +2 -2
- package/package.json +3 -2
- package/src/engine.js +1 -1
- package/src/engineExport.js +4 -2
- package/src/engineInput.js +17 -4
- package/src/engineObject.js +1 -0
- package/src/engineSettings.js +13 -8
- package/test/math.test.mjs +774 -0
- package/test/setup.mjs +22 -0
- package/test/smoke.test.mjs +258 -0
- package/test/util.test.mjs +80 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v5
|
|
12
|
+
- uses: actions/setup-node@v5
|
|
13
|
+
with:
|
|
14
|
+
node-version: '22'
|
|
15
|
+
- run: npm install
|
|
16
|
+
- run: npm run build
|
|
17
|
+
- run: npm test
|
package/AI.md
CHANGED
|
@@ -155,6 +155,16 @@ drawEllipse(pos, size, color) // filled ellipse
|
|
|
155
155
|
npm run build
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
+
### Testing
|
|
159
|
+
```bash
|
|
160
|
+
npm test
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
- Tests target `dist/littlejs.esm.js` — rebuild with `npm run build` after changing source.
|
|
164
|
+
- [test/setup.mjs](test/setup.mjs) stubs minimal DOM and enables headless mode. Tests shouldn't call `engineInit`, `render()`, or assume `time` advances.
|
|
165
|
+
- Zero test dependencies — uses Node's built-in `node --test`. Match the style in [test/](test/) when adding new ones.
|
|
166
|
+
- CI runs build + test on every push/PR ([.github/workflows/test.yml](.github/workflows/test.yml)).
|
|
167
|
+
|
|
158
168
|
### Debug features
|
|
159
169
|
- Press `Esc` to toggle debug overlay
|
|
160
170
|
- Number keys toggle visualizations
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# LittleJS - The Tiny Fast JavaScript Game Engine
|
|
2
2
|
|
|
3
|
-
<div align='center'>
|
|
3
|
+
<div align='center' markdown='1'>
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
@@ -22,7 +22,7 @@ The code is very clean and well documented with many examples to get you started
|
|
|
22
22
|
|
|
23
23
|
*The Third Annual LittleJS Game Jam will take place From Oct 2 to Nov 2! Unleash your creativity and develop amazing games using the LittleJS game engine. 🕹️🎮 [Sign up today and get more info about the jam on itch.io!](https://itch.io/jam/littlejs-jam)*
|
|
24
24
|
|
|
25
|
-
<div align='center'>
|
|
25
|
+
<div align='center' markdown='1'>
|
|
26
26
|
|
|
27
27
|
## [Demos](https://killedbyapixel.github.io/LittleJS/examples) | [Docs](https://killedbyapixel.github.io/LittleJS/docs) | [Trailer](https://youtu.be/chuBzGjv7Ms) | [Discord](https://discord.gg/zb7hcGkyZe) | [FAQ](https://github.com/KilledByAPixel/LittleJS/blob/main/FAQ.md)
|
|
28
28
|
|
package/dist/littlejs.d.ts
CHANGED
|
@@ -480,17 +480,21 @@ declare module "littlejsengine" {
|
|
|
480
480
|
export let inputWASDEmulateDirection: boolean;
|
|
481
481
|
/** True if touch gamepad should appear on mobile devices
|
|
482
482
|
* - Supports left analog stick, 4 face buttons and start button (button 9)
|
|
483
|
+
* - setTouchGamepadButtonCount(1) to use face buttons as right analog stick
|
|
484
|
+
* - Analog stick buttons 10 and 11 are also activated when virtual sticks are touched
|
|
485
|
+
|
|
483
486
|
* @type {boolean}
|
|
484
487
|
* @default
|
|
485
488
|
* @memberof Settings */
|
|
486
489
|
export let touchGamepadEnable: boolean;
|
|
487
490
|
/** True if touch gamepad should have start button in the center
|
|
491
|
+
* - Prevents activating if overlappng with virtual stick or buttons if they are enabled
|
|
488
492
|
* - When the game is paused, any touch will press the button
|
|
489
|
-
* -
|
|
490
|
-
* @type {
|
|
493
|
+
* - Set size to enable the center button
|
|
494
|
+
* @type {number}
|
|
491
495
|
* @default
|
|
492
496
|
* @memberof Settings */
|
|
493
|
-
export let
|
|
497
|
+
export let touchGamepadCenterButtonSize: number;
|
|
494
498
|
/** True if touch gamepad should be analog stick or false to use if 8 way dpad
|
|
495
499
|
* @type {boolean}
|
|
496
500
|
* @default
|
|
@@ -687,11 +691,12 @@ declare module "littlejsengine" {
|
|
|
687
691
|
* @param {boolean} enable
|
|
688
692
|
* @memberof Settings */
|
|
689
693
|
export function setTouchGamepadEnable(enable: boolean): void;
|
|
690
|
-
/**
|
|
691
|
-
* -
|
|
692
|
-
*
|
|
694
|
+
/** Set if touch gamepad should have start button in the center
|
|
695
|
+
* - Set size to enable the center button
|
|
696
|
+
* - When the game is paused, any touch will press the button
|
|
697
|
+
* @param {number} size
|
|
693
698
|
* @memberof Settings */
|
|
694
|
-
export function
|
|
699
|
+
export function setTouchGamepadCenterButtonSize(size: number): void;
|
|
695
700
|
/** Set number of buttons on touch gamepad (0-4), if 1 also acts as right analog stick
|
|
696
701
|
* @param {number} count
|
|
697
702
|
* @memberof Settings */
|
|
@@ -893,6 +898,16 @@ declare module "littlejsengine" {
|
|
|
893
898
|
* @return {number}
|
|
894
899
|
* @memberof Math */
|
|
895
900
|
export function lerp(valueA: number, valueB: number, percent: number): number;
|
|
901
|
+
/** Gets percent between percentA and percentB and linearly interpolates between lerpA and lerpB
|
|
902
|
+
* A shortcut for lerp(lerpA, lerpB, percent(value, percentA, percentB))
|
|
903
|
+
* @param {number} value
|
|
904
|
+
* @param {number} percentA
|
|
905
|
+
* @param {number} percentB
|
|
906
|
+
* @param {number} lerpA
|
|
907
|
+
* @param {number} lerpB
|
|
908
|
+
* @return {number}
|
|
909
|
+
* @memberof Math */
|
|
910
|
+
export function percentLerp(value: number, percentA: number, percentB: number, lerpA: number, lerpB: number): number;
|
|
896
911
|
/** Applies smoothstep function to the percentage value
|
|
897
912
|
* @param {number} percent
|
|
898
913
|
* @return {number}
|
|
@@ -920,6 +935,20 @@ declare module "littlejsengine" {
|
|
|
920
935
|
* @return {boolean} - True if intersecting
|
|
921
936
|
* @memberof Math */
|
|
922
937
|
export function isIntersecting(start: Vector2, end: Vector2, pos: Vector2, size: Vector2): boolean;
|
|
938
|
+
/**
|
|
939
|
+
* @callback LineTestFunction - Checks if a position is colliding
|
|
940
|
+
* @param {Vector2} pos
|
|
941
|
+
* @memberof Draw
|
|
942
|
+
*/
|
|
943
|
+
/**
|
|
944
|
+
* Casts a ray and returns position of the first collision found, or undefined if none are found
|
|
945
|
+
* @param {Vector2} posStart
|
|
946
|
+
* @param {Vector2} posEnd
|
|
947
|
+
* @param {LineTestFunction} testFunction - Check if colliding
|
|
948
|
+
* @param {Vector2} [normal] - Optional vector to store the normal
|
|
949
|
+
* @return {Vector2|undefined} - Position of the collision or undefined if none found
|
|
950
|
+
* @memberof Math */
|
|
951
|
+
export function lineTest(posStart: Vector2, posEnd: Vector2, testFunction: LineTestFunction, normal?: Vector2): Vector2 | undefined;
|
|
923
952
|
/** Returns an oscillating wave between 0 and amplitude with frequency of 1 Hz by default
|
|
924
953
|
* @param {number} [frequency] - Frequency of the wave in Hz
|
|
925
954
|
* @param {number} [amplitude] - Amplitude (max height) of the wave
|
package/dist/littlejs.esm.js
CHANGED
|
@@ -35,7 +35,7 @@ const engineName = 'LittleJS';
|
|
|
35
35
|
* @type {string}
|
|
36
36
|
* @default
|
|
37
37
|
* @memberof Engine */
|
|
38
|
-
const engineVersion = '1.18.
|
|
38
|
+
const engineVersion = '1.18.2';
|
|
39
39
|
|
|
40
40
|
/** Frames per second to update
|
|
41
41
|
* @type {number}
|
|
@@ -3003,18 +3003,22 @@ let touchInputEnable = true;
|
|
|
3003
3003
|
|
|
3004
3004
|
/** True if touch gamepad should appear on mobile devices
|
|
3005
3005
|
* - Supports left analog stick, 4 face buttons and start button (button 9)
|
|
3006
|
+
* - setTouchGamepadButtonCount(1) to use face buttons as right analog stick
|
|
3007
|
+
* - Analog stick buttons 10 and 11 are also activated when virtual sticks are touched
|
|
3008
|
+
|
|
3006
3009
|
* @type {boolean}
|
|
3007
3010
|
* @default
|
|
3008
3011
|
* @memberof Settings */
|
|
3009
3012
|
let touchGamepadEnable = false;
|
|
3010
3013
|
|
|
3011
3014
|
/** True if touch gamepad should have start button in the center
|
|
3015
|
+
* - Prevents activating if overlappng with virtual stick or buttons if they are enabled
|
|
3012
3016
|
* - When the game is paused, any touch will press the button
|
|
3013
|
-
* -
|
|
3014
|
-
* @type {
|
|
3017
|
+
* - Set size to enable the center button
|
|
3018
|
+
* @type {number}
|
|
3015
3019
|
* @default
|
|
3016
3020
|
* @memberof Settings */
|
|
3017
|
-
let
|
|
3021
|
+
let touchGamepadCenterButtonSize = 300;
|
|
3018
3022
|
|
|
3019
3023
|
/** Number of buttons on touch gamepad (0-4), if 1 also acts as right analog stick
|
|
3020
3024
|
* @type {number}
|
|
@@ -3032,7 +3036,7 @@ let touchGamepadAnalog = true;
|
|
|
3032
3036
|
* @type {number}
|
|
3033
3037
|
* @default
|
|
3034
3038
|
* @memberof Settings */
|
|
3035
|
-
let touchGamepadSize =
|
|
3039
|
+
let touchGamepadSize = 100;
|
|
3036
3040
|
|
|
3037
3041
|
/** Transparency of touch gamepad overlay
|
|
3038
3042
|
* @type {number}
|
|
@@ -3300,11 +3304,12 @@ function setTouchInputEnable(enable) { touchInputEnable = enable; }
|
|
|
3300
3304
|
* @memberof Settings */
|
|
3301
3305
|
function setTouchGamepadEnable(enable) { touchGamepadEnable = enable; }
|
|
3302
3306
|
|
|
3303
|
-
/**
|
|
3304
|
-
* -
|
|
3305
|
-
*
|
|
3307
|
+
/** Set if touch gamepad should have start button in the center
|
|
3308
|
+
* - Set size to enable the center button
|
|
3309
|
+
* - When the game is paused, any touch will press the button
|
|
3310
|
+
* @param {number} size
|
|
3306
3311
|
* @memberof Settings */
|
|
3307
|
-
function
|
|
3312
|
+
function setTouchGamepadCenterButtonSize(size) { touchGamepadCenterButtonSize = size; }
|
|
3308
3313
|
|
|
3309
3314
|
/** Set number of buttons on touch gamepad (0-4), if 1 also acts as right analog stick
|
|
3310
3315
|
* @param {number} count
|
|
@@ -3842,6 +3847,7 @@ class EngineObject
|
|
|
3842
3847
|
child.parent = this;
|
|
3843
3848
|
child.localPos = localPos.copy();
|
|
3844
3849
|
child.localAngle = localAngle;
|
|
3850
|
+
child.updateTransforms();
|
|
3845
3851
|
return child;
|
|
3846
3852
|
}
|
|
3847
3853
|
|
|
@@ -5573,7 +5579,7 @@ function inputInit()
|
|
|
5573
5579
|
if (touching)
|
|
5574
5580
|
{
|
|
5575
5581
|
touchGamepadTimer.set();
|
|
5576
|
-
if (
|
|
5582
|
+
if (touchGamepadCenterButtonSize && !wasTouching && paused)
|
|
5577
5583
|
{
|
|
5578
5584
|
// touch anywhere to press start when paused
|
|
5579
5585
|
touchGamepadButtons[9] = 1;
|
|
@@ -5598,6 +5604,7 @@ function inputInit()
|
|
|
5598
5604
|
// virtual analog stick
|
|
5599
5605
|
const delta = touchPos.subtract(stickCenter);
|
|
5600
5606
|
touchGamepadSticks[0] = delta.scale(2/touchGamepadSize).clampLength();
|
|
5607
|
+
touchGamepadButtons[10] = 1; // also press a button when touching stick
|
|
5601
5608
|
}
|
|
5602
5609
|
else if (buttonCenter.distance(touchPos) < touchGamepadSize)
|
|
5603
5610
|
{
|
|
@@ -5606,6 +5613,7 @@ function inputInit()
|
|
|
5606
5613
|
// virtual right analog stick
|
|
5607
5614
|
const delta = touchPos.subtract(buttonCenter);
|
|
5608
5615
|
touchGamepadSticks[1] = delta.scale(2/touchGamepadSize).clampLength();
|
|
5616
|
+
touchGamepadButtons[11] = 1; // also press a button when touching right stick
|
|
5609
5617
|
}
|
|
5610
5618
|
// virtual face buttons
|
|
5611
5619
|
let button = buttonCenter.subtract(touchPos).direction();
|
|
@@ -5622,8 +5630,7 @@ function inputInit()
|
|
|
5622
5630
|
if (button < touchGamepadButtonCount)
|
|
5623
5631
|
touchGamepadButtons[button] = 1;
|
|
5624
5632
|
}
|
|
5625
|
-
else if (
|
|
5626
|
-
startCenter.distance(touchPos) < touchGamepadSize)
|
|
5633
|
+
else if (startCenter.distance(touchPos) < touchGamepadCenterButtonSize)
|
|
5627
5634
|
{
|
|
5628
5635
|
// virtual start button in center
|
|
5629
5636
|
touchGamepadButtons[9] = 1;
|
|
@@ -5672,6 +5679,18 @@ function inputUpdate()
|
|
|
5672
5679
|
// update touch gamepad if enabled
|
|
5673
5680
|
if (touchGamepadEnable && isTouchDevice)
|
|
5674
5681
|
{
|
|
5682
|
+
if (debugGamepads)
|
|
5683
|
+
{
|
|
5684
|
+
const stickCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
5685
|
+
const buttonCenter = touchGamepadButtonCenter();
|
|
5686
|
+
const startCenter = mainCanvasSize.scale(.5);
|
|
5687
|
+
|
|
5688
|
+
debugCircle(stickCenter, 2*touchGamepadSize, 'cyan', 0, false, true);
|
|
5689
|
+
debugCircle(buttonCenter, 2*touchGamepadSize, 'cyan', 0, false, true);
|
|
5690
|
+
if (touchGamepadCenterButtonSize)
|
|
5691
|
+
debugCircle(startCenter, 2*touchGamepadCenterButtonSize, 'cyan', 0, false, true);
|
|
5692
|
+
}
|
|
5693
|
+
|
|
5675
5694
|
if (!touchGamepadTimer.isSet()) return;
|
|
5676
5695
|
|
|
5677
5696
|
// read virtual analog stick
|
|
@@ -5699,7 +5718,7 @@ function inputUpdate()
|
|
|
5699
5718
|
|
|
5700
5719
|
// read virtual gamepad buttons
|
|
5701
5720
|
const data = inputData[1] ?? (inputData[1] = []);
|
|
5702
|
-
for (let i=
|
|
5721
|
+
for (let i=12; i--;)
|
|
5703
5722
|
{
|
|
5704
5723
|
const wasDown = gamepadIsDown(i,0);
|
|
5705
5724
|
data[i] = touchGamepadButtons[i] ? wasDown ? 1 : 3 : wasDown ? 4 : 0;
|
|
@@ -13125,7 +13144,7 @@ export
|
|
|
13125
13144
|
gamepadDirectionEmulateStick,
|
|
13126
13145
|
inputWASDEmulateDirection,
|
|
13127
13146
|
touchGamepadEnable,
|
|
13128
|
-
|
|
13147
|
+
touchGamepadCenterButtonSize,
|
|
13129
13148
|
touchGamepadAnalog,
|
|
13130
13149
|
touchGamepadSize,
|
|
13131
13150
|
touchGamepadAlpha,
|
|
@@ -13173,7 +13192,7 @@ export
|
|
|
13173
13192
|
setGamepadDirectionEmulateStick,
|
|
13174
13193
|
setInputWASDEmulateDirection,
|
|
13175
13194
|
setTouchGamepadEnable,
|
|
13176
|
-
|
|
13195
|
+
setTouchGamepadCenterButtonSize,
|
|
13177
13196
|
setTouchGamepadButtonCount,
|
|
13178
13197
|
setTouchGamepadAnalog,
|
|
13179
13198
|
setTouchGamepadSize,
|
|
@@ -13213,10 +13232,12 @@ export
|
|
|
13213
13232
|
distanceAngle,
|
|
13214
13233
|
lerpAngle,
|
|
13215
13234
|
lerp,
|
|
13235
|
+
percentLerp,
|
|
13216
13236
|
smoothStep,
|
|
13217
13237
|
nearestPowerOfTwo,
|
|
13218
13238
|
isOverlapping,
|
|
13219
13239
|
isIntersecting,
|
|
13240
|
+
lineTest,
|
|
13220
13241
|
oscillate,
|
|
13221
13242
|
|
|
13222
13243
|
// Utilities
|