littlejsengine 1.9.9 → 1.9.11
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 -0
- package/dist/littlejs.d.ts +27 -5
- package/dist/littlejs.esm.js +62 -36
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +56 -34
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +39 -32
- package/examples/box2d/game.js +28 -9
- package/examples/box2d/gameObjects.js +485 -0
- package/examples/box2d/index.html +5 -4
- package/examples/box2d/scenes.js +28 -247
- package/examples/box2d/tiles.png +0 -0
- package/examples/breakout/index.html +3 -3
- package/examples/breakoutTutorial/index.html +2 -2
- package/examples/electron/index.html +2 -2
- package/examples/js13k/index.html +13 -13
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +1 -1
- package/examples/platformer/gameCharacter.js +1 -0
- package/examples/platformer/gameEffects.js +0 -2
- package/examples/platformer/gameObjects.js +1 -1
- package/examples/platformer/index.html +8 -8
- package/examples/puzzle/index.html +2 -2
- package/examples/starter/game.js +1 -1
- package/examples/starter/index.html +13 -13
- package/examples/stress/index.html +1 -1
- package/examples/typescript/index.html +1 -1
- package/package.json +1 -1
- package/plugins/box2d.js +114 -41
- package/src/engine.js +1 -1
- package/src/engineAudio.js +16 -16
- package/src/engineDebug.js +17 -2
- package/src/engineExport.js +5 -2
- package/src/engineInput.js +7 -3
- package/src/engineObject.js +15 -12
package/dist/littlejs.release.js
CHANGED
|
@@ -1549,9 +1549,9 @@ class EngineObject
|
|
|
1549
1549
|
|
|
1550
1550
|
// apply physics
|
|
1551
1551
|
const oldPos = this.pos.copy();
|
|
1552
|
-
this.velocity.y += gravity * this.gravityScale;
|
|
1553
1552
|
this.pos.x += this.velocity.x *= this.damping;
|
|
1554
|
-
this.pos.y += this.velocity.y
|
|
1553
|
+
this.pos.y += this.velocity.y = this.damping * this.velocity.y
|
|
1554
|
+
+ gravity * this.gravityScale;
|
|
1555
1555
|
this.angle += this.angleVelocity *= this.angleDamping;
|
|
1556
1556
|
|
|
1557
1557
|
// physics sanity checks
|
|
@@ -1680,19 +1680,22 @@ class EngineObject
|
|
|
1680
1680
|
const isBlockedX = tileCollisionTest(vec2(this.pos.x, oldPos.y), this.size, this);
|
|
1681
1681
|
if (isBlockedY || !isBlockedX)
|
|
1682
1682
|
{
|
|
1683
|
-
// set if landed on ground
|
|
1684
|
-
this.groundObject = wasMovingDown;
|
|
1685
|
-
|
|
1686
1683
|
// bounce velocity
|
|
1687
1684
|
this.velocity.y *= -this.elasticity;
|
|
1688
1685
|
|
|
1689
|
-
//
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1686
|
+
// set if landed on ground
|
|
1687
|
+
if (this.groundObject = wasMovingDown)
|
|
1688
|
+
{
|
|
1689
|
+
// adjust position to slightly above nearest tile boundary
|
|
1690
|
+
// this prevents gap between object and ground
|
|
1691
|
+
const epsilon = .0001;
|
|
1692
|
+
this.pos.y = (oldPos.y-this.size.y/2|0)+this.size.y/2+epsilon;
|
|
1693
|
+
}
|
|
1694
|
+
else
|
|
1695
|
+
{
|
|
1696
|
+
// move to previous position
|
|
1697
|
+
this.pos.y = oldPos.y;
|
|
1698
|
+
}
|
|
1696
1699
|
}
|
|
1697
1700
|
if (isBlockedX)
|
|
1698
1701
|
{
|
|
@@ -2542,6 +2545,10 @@ function inputInit()
|
|
|
2542
2545
|
// mouse event handlers
|
|
2543
2546
|
onmousedown = (e)=>
|
|
2544
2547
|
{
|
|
2548
|
+
// fix stalled audio requiring user interaction
|
|
2549
|
+
if (soundEnable && !headlessMode && audioContext && audioContext.state != 'running')
|
|
2550
|
+
audioContext.resume();
|
|
2551
|
+
|
|
2545
2552
|
isUsingGamepad = false;
|
|
2546
2553
|
inputData[0][e.button] = 3;
|
|
2547
2554
|
mousePosScreen = mouseToScreen(e);
|
|
@@ -2553,7 +2560,7 @@ function inputInit()
|
|
|
2553
2560
|
oncontextmenu = (e)=> false; // prevent right click menu
|
|
2554
2561
|
|
|
2555
2562
|
// init touch input
|
|
2556
|
-
if (isTouchDevice && touchInputEnable
|
|
2563
|
+
if (isTouchDevice && touchInputEnable)
|
|
2557
2564
|
touchInputInit();
|
|
2558
2565
|
}
|
|
2559
2566
|
|
|
@@ -2710,8 +2717,8 @@ function touchInputInit()
|
|
|
2710
2717
|
function handleTouchDefault(e)
|
|
2711
2718
|
{
|
|
2712
2719
|
// fix stalled audio requiring user interaction
|
|
2713
|
-
if (soundEnable && audioContext && audioContext.state != 'running')
|
|
2714
|
-
|
|
2720
|
+
if (soundEnable && !headlessMode && audioContext && audioContext.state != 'running')
|
|
2721
|
+
audioContext.resume();
|
|
2715
2722
|
|
|
2716
2723
|
// check if touching and pass to mouse events
|
|
2717
2724
|
const touching = e.touches.length;
|
|
@@ -2924,6 +2931,7 @@ class Sound
|
|
|
2924
2931
|
// generate zzfx sound now for fast playback
|
|
2925
2932
|
const defaultRandomness = .05;
|
|
2926
2933
|
this.randomness = zzfxSound[1] || defaultRandomness;
|
|
2934
|
+
zzfxSound[1] = 0; // generate without randomness
|
|
2927
2935
|
this.sampleChannels = [zzfxG(...zzfxSound)];
|
|
2928
2936
|
this.sampleRate = zzfxR;
|
|
2929
2937
|
}
|
|
@@ -3156,10 +3164,6 @@ function getNoteFrequency(semitoneOffset, rootFrequency=220)
|
|
|
3156
3164
|
|
|
3157
3165
|
///////////////////////////////////////////////////////////////////////////////
|
|
3158
3166
|
|
|
3159
|
-
// internal tracking if audio was suspended when last sound was played
|
|
3160
|
-
// allows first suspended sound to play when audio is resumed
|
|
3161
|
-
let audioSuspended = false;
|
|
3162
|
-
|
|
3163
3167
|
/** Play cached audio samples with given settings
|
|
3164
3168
|
* @param {Array} sampleChannels - Array of arrays of samples to play (for stereo playback)
|
|
3165
3169
|
* @param {Number} [volume] - How much to scale volume by
|
|
@@ -3175,20 +3179,21 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=false, sample
|
|
|
3175
3179
|
if (!soundEnable || headlessMode) return;
|
|
3176
3180
|
|
|
3177
3181
|
// prevent sounds from building up if they can't be played
|
|
3178
|
-
|
|
3179
|
-
if (audioSuspended = audioContext.state != 'running')
|
|
3182
|
+
if (audioContext.state != 'running')
|
|
3180
3183
|
{
|
|
3181
3184
|
// fix stalled audio
|
|
3182
|
-
audioContext.resume()
|
|
3185
|
+
audioContext.resume().then(()=>
|
|
3186
|
+
playSamples(sampleChannels, volume, rate, pan, loop, sampleRate, gainNode));
|
|
3183
3187
|
|
|
3184
3188
|
// prevent suspended sounds from building up
|
|
3185
|
-
|
|
3186
|
-
return;
|
|
3189
|
+
return;
|
|
3187
3190
|
}
|
|
3188
3191
|
|
|
3189
3192
|
// create buffer and source
|
|
3190
|
-
const
|
|
3191
|
-
|
|
3193
|
+
const channelCount = sampleChannels.length;
|
|
3194
|
+
const sampleLength = sampleChannels[0].length;
|
|
3195
|
+
const buffer = audioContext.createBuffer(channelCount, sampleLength, sampleRate);
|
|
3196
|
+
const source = audioContext.createBufferSource();
|
|
3192
3197
|
|
|
3193
3198
|
// copy samples to buffer and setup source
|
|
3194
3199
|
sampleChannels.forEach((c,i)=> buffer.getChannelData(i).set(c));
|
|
@@ -3202,7 +3207,8 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=false, sample
|
|
|
3202
3207
|
gainNode.connect(audioGainNode);
|
|
3203
3208
|
|
|
3204
3209
|
// connect source to stereo panner and gain
|
|
3205
|
-
|
|
3210
|
+
const pannerNode = new StereoPannerNode(audioContext, {'pan':clamp(pan, -1, 1)});
|
|
3211
|
+
source.connect(pannerNode).connect(gainNode);
|
|
3206
3212
|
|
|
3207
3213
|
// play and return sound
|
|
3208
3214
|
source.start();
|
|
@@ -3218,7 +3224,7 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=false, sample
|
|
|
3218
3224
|
* @param {Array} zzfxSound - Array of ZzFX parameters, ex. [.5,.5]
|
|
3219
3225
|
* @return {AudioBufferSourceNode} - The audio node of the sound played
|
|
3220
3226
|
* @memberof Audio */
|
|
3221
|
-
function zzfx(...zzfxSound) { return
|
|
3227
|
+
function zzfx(...zzfxSound) { return playSamples([zzfxG(...zzfxSound)]); }
|
|
3222
3228
|
|
|
3223
3229
|
/** Sample rate used for all ZzFX sounds
|
|
3224
3230
|
* @default 44100
|
|
@@ -3227,7 +3233,7 @@ const zzfxR = 44100;
|
|
|
3227
3233
|
|
|
3228
3234
|
/** Generate samples for a ZzFX sound
|
|
3229
3235
|
* @param {Number} [volume] - Volume scale (percent)
|
|
3230
|
-
* @param {Number} [randomness] -
|
|
3236
|
+
* @param {Number} [randomness] - How much to randomize frequency (percent Hz)
|
|
3231
3237
|
* @param {Number} [frequency] - Frequency of sound (Hz)
|
|
3232
3238
|
* @param {Number} [attack] - Attack time, how fast sound starts (seconds)
|
|
3233
3239
|
* @param {Number} [sustain] - Sustain time, how long sound holds (seconds)
|
|
@@ -3253,7 +3259,7 @@ const zzfxR = 44100;
|
|
|
3253
3259
|
function zzfxG
|
|
3254
3260
|
(
|
|
3255
3261
|
// parameters
|
|
3256
|
-
volume = 1, randomness =
|
|
3262
|
+
volume = 1, randomness = .05, frequency = 220, attack = 0, sustain = 0,
|
|
3257
3263
|
release = .1, shape = 0, shapeCurve = 1, slide = 0, deltaSlide = 0,
|
|
3258
3264
|
pitchJump = 0, pitchJumpTime = 0, repeatTime = 0, noise = 0, modulation = 0,
|
|
3259
3265
|
bitCrush = 0, delay = 0, sustainVolume = 1, decay = 0, tremolo = 0, filter = 0
|
|
@@ -3264,7 +3270,8 @@ function zzfxG
|
|
|
3264
3270
|
// init parameters
|
|
3265
3271
|
let PI2 = PI*2, sampleRate = zzfxR,
|
|
3266
3272
|
startSlide = slide *= 500 * PI2 / sampleRate / sampleRate,
|
|
3267
|
-
startFrequency = frequency *=
|
|
3273
|
+
startFrequency = frequency *=
|
|
3274
|
+
rand(1 + randomness, 1-randomness) * PI2 / sampleRate,
|
|
3268
3275
|
b = [], t = 0, tm = 0, i = 0, j = 1, r = 0, c = 0, s = 0, f, length,
|
|
3269
3276
|
|
|
3270
3277
|
// biquad LP/HP filter
|
|
@@ -4664,7 +4671,7 @@ const engineName = 'LittleJS';
|
|
|
4664
4671
|
* @type {String}
|
|
4665
4672
|
* @default
|
|
4666
4673
|
* @memberof Engine */
|
|
4667
|
-
const engineVersion = '1.9.
|
|
4674
|
+
const engineVersion = '1.9.11';
|
|
4668
4675
|
|
|
4669
4676
|
/** Frames per second to update
|
|
4670
4677
|
* @type {Number}
|
package/examples/box2d/game.js
CHANGED
|
@@ -16,12 +16,13 @@ setShowSplashScreen(true);
|
|
|
16
16
|
//box2dDebug = 1; // enable box2d debug draw
|
|
17
17
|
|
|
18
18
|
// game variables
|
|
19
|
-
const maxScenes =
|
|
19
|
+
const maxScenes = 11;
|
|
20
20
|
let scene = 0;
|
|
21
21
|
let sceneName;
|
|
22
22
|
let groundObject;
|
|
23
23
|
let mouseJoint;
|
|
24
|
-
let
|
|
24
|
+
let car;
|
|
25
|
+
let repeatSpawnTimer = new Timer;
|
|
25
26
|
|
|
26
27
|
///////////////////////////////////////////////////////////////////////////////
|
|
27
28
|
function gameInit()
|
|
@@ -54,13 +55,25 @@ function gameUpdate()
|
|
|
54
55
|
mouseJoint = 0;
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
|
-
if (
|
|
58
|
-
|
|
58
|
+
if (mouseIsDown(1) || mouseIsDown('KeyZ'))
|
|
59
|
+
{
|
|
60
|
+
const isSet = repeatSpawnTimer.isSet();
|
|
61
|
+
if (!isSet || repeatSpawnTimer.elapsed())
|
|
62
|
+
{
|
|
63
|
+
// spawn continuously after a delay
|
|
64
|
+
isSet || repeatSpawnTimer.set(.5);
|
|
65
|
+
spawnRandomObject(mousePos);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else
|
|
69
|
+
repeatSpawnTimer.unset();
|
|
59
70
|
if (mouseWasPressed(2) || keyWasPressed('KeyX'))
|
|
60
71
|
explosion(mousePos);
|
|
61
72
|
if (mouseJoint)
|
|
62
73
|
mouseJoint.SetTarget(mousePos.getBox2d());
|
|
63
74
|
|
|
75
|
+
if (keyWasPressed('KeyR'))
|
|
76
|
+
loadScene(scene); // reset scene
|
|
64
77
|
if (keyWasPressed('ArrowUp') || keyWasPressed('ArrowDown'))
|
|
65
78
|
{
|
|
66
79
|
// change scene
|
|
@@ -69,13 +82,11 @@ function gameUpdate()
|
|
|
69
82
|
loadScene(scene);
|
|
70
83
|
}
|
|
71
84
|
|
|
72
|
-
if (
|
|
85
|
+
if (car)
|
|
73
86
|
{
|
|
74
87
|
// update car control
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
s = control ? clamp(s + control, -40, 40) : s * .8;
|
|
78
|
-
carWheelJoint.SetMotorSpeed(s);
|
|
88
|
+
const input = keyIsDown('ArrowLeft') - keyIsDown('ArrowRight');
|
|
89
|
+
car.applyMotorInput(input);
|
|
79
90
|
}
|
|
80
91
|
}
|
|
81
92
|
|
|
@@ -110,6 +121,14 @@ function gameRender()
|
|
|
110
121
|
///////////////////////////////////////////////////////////////////////////////
|
|
111
122
|
function gameRenderPost()
|
|
112
123
|
{
|
|
124
|
+
if (mouseJoint)
|
|
125
|
+
{
|
|
126
|
+
// draw mouse joint
|
|
127
|
+
const ab = vec2(mouseJoint.GetAnchorB());
|
|
128
|
+
drawTile(ab, vec2(.3), tile(0), BLACK);
|
|
129
|
+
drawLine(mousePos, ab, .1, BLACK);
|
|
130
|
+
}
|
|
131
|
+
|
|
113
132
|
// draw to overlay canvas for hud rendering
|
|
114
133
|
const pos = vec2(mainCanvasSize.x/2, 50);
|
|
115
134
|
drawText('LittleJS Box2D Demo', 80, 80);
|