littlejsengine 1.16.2 → 1.17.5
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/dist/littlejs.d.ts +291 -246
- package/dist/littlejs.esm.js +1520 -1271
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +1178 -920
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +1170 -912
- package/examples/box2d/gameObjects.js +4 -4
- package/examples/breakout/game.js +5 -6
- package/examples/electron/index.html +2 -2
- package/examples/electron/tiles.png +0 -0
- package/examples/htmlMenu/tiles.png +0 -0
- package/examples/index.html +9 -8
- package/examples/logo.png +0 -0
- package/examples/module/build.bat +7 -0
- package/examples/module/build.js +121 -0
- package/examples/module/tiles.png +0 -0
- package/examples/platformer/game.js +1 -1
- package/examples/platformer/gameEffects.js +25 -29
- package/examples/platformer/gameLevel.js +27 -28
- package/examples/puzzle/game.js +2 -2
- package/examples/shorts/base.html +4 -1
- package/examples/shorts/box2dPool.js +2 -2
- package/examples/shorts/box2dTileLayer.js +48 -0
- package/examples/shorts/clock.js +3 -3
- package/examples/shorts/fontImage.js +4 -3
- package/examples/shorts/music.js +2 -2
- package/examples/shorts/musicPlayer.js +2 -2
- package/examples/shorts/parallax.js +1 -1
- package/examples/shorts/sequencer.js +1 -1
- package/examples/shorts/shapes.js +1 -1
- package/examples/shorts/texture.js +10 -6
- package/examples/shorts/tiles.png +0 -0
- package/examples/shorts/tiltedView.js +2 -0
- package/examples/starter/index.html +2 -2
- package/examples/starter/tiles.png +0 -0
- package/examples/typescript/tiles.png +0 -0
- package/examples/uiSystem/game.js +1 -1
- package/examples/uiSystem/tiles.png +0 -0
- package/package.json +5 -5
- package/plugins/box2d.js +167 -63
- package/plugins/postProcess.js +47 -28
- package/plugins/uiSystem.js +18 -18
- package/plugins/zzfxm.js +2 -2
- package/reference.md +4 -3
- package/src/engine.js +182 -181
- package/src/engineAudio.js +47 -63
- package/src/engineDebug.js +8 -8
- package/src/engineDraw.js +184 -124
- package/src/engineExport.js +325 -334
- package/src/engineFont.png +0 -0
- package/src/engineInput.js +18 -24
- package/src/engineMath.js +24 -113
- package/src/engineObject.js +27 -26
- package/src/engineParticles.js +2 -2
- package/src/engineTileLayer.js +229 -192
- package/src/engineUtilities.js +100 -4
- package/src/engineWebGL.js +124 -73
package/src/engineAudio.js
CHANGED
|
@@ -44,29 +44,46 @@ function audioInit()
|
|
|
44
44
|
///////////////////////////////////////////////////////////////////////////////
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
* Sound Object - Stores a sound for later
|
|
47
|
+
* Sound Object - Stores a sound for later
|
|
48
|
+
* - this can be used to load and play wave, mp3, and ogg files
|
|
49
|
+
* - it can also create sounds using the ZzFX sound generator
|
|
50
|
+
* - can attenuate and apply stereo panning to sounds
|
|
51
|
+
* - sound instance control with pause/resume capability
|
|
48
52
|
*
|
|
49
53
|
* <a href=https://killedbyapixel.github.io/ZzFX/>Create sounds using the ZzFX Sound Designer.</a>
|
|
50
54
|
* @memberof Audio
|
|
51
55
|
* @example
|
|
52
|
-
* //
|
|
56
|
+
* // load an audio asset file
|
|
57
|
+
* const sound_example = new Sound('sound.mp3');
|
|
58
|
+
*
|
|
59
|
+
* // create a zzfx sound
|
|
53
60
|
* const sound_example = new Sound([.5,.5]);
|
|
54
61
|
*
|
|
55
|
-
* // play
|
|
62
|
+
* // play a sound
|
|
56
63
|
* sound_example.play();
|
|
57
64
|
*/
|
|
58
65
|
class Sound
|
|
59
66
|
{
|
|
60
|
-
/**
|
|
61
|
-
*
|
|
67
|
+
/**
|
|
68
|
+
* @callback SoundLoadCallback - Function called when sound is loaded
|
|
69
|
+
* @param {Sound} sound
|
|
70
|
+
* @memberof Audio
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
/** Create a sound object and cache the audio for later use
|
|
74
|
+
* @param {string|Array} [asset] - Filename of audio file or zzfx array
|
|
75
|
+
* @param {number} [randomness] - How much to randomize frequency each time sound plays, for zzfx sounds the zzfx default is used if undefined
|
|
62
76
|
* @param {number} [range=soundDefaultRange] - World space max range of sound
|
|
63
77
|
* @param {number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
|
|
78
|
+
* @param {SoundLoadCallback} [onloadCallback] - callback function to call when sound is loaded
|
|
64
79
|
*/
|
|
65
|
-
constructor(
|
|
80
|
+
constructor(asset, randomness, range=soundDefaultRange, taper=soundDefaultTaper, onloadCallback)
|
|
66
81
|
{
|
|
67
82
|
if (!soundEnable || headlessMode) return;
|
|
68
83
|
|
|
69
|
-
ASSERT(!
|
|
84
|
+
ASSERT(!asset || isArray(asset) || isString(asset), 'asset must be a file name or zzfx array');
|
|
85
|
+
ASSERT(randomness === undefined || isNumber(randomness), 'randomness must be a number');
|
|
86
|
+
ASSERT(randomness === undefined || randomness >= 0 && randomness <=1, 'randomness must be between 0 and 1');
|
|
70
87
|
ASSERT(isNumber(range), 'range must be a number');
|
|
71
88
|
ASSERT(isNumber(taper), 'taper must be a number');
|
|
72
89
|
|
|
@@ -75,24 +92,35 @@ class Sound
|
|
|
75
92
|
/** @property {number} - At what percentage of range should it start tapering */
|
|
76
93
|
this.taper = taper;
|
|
77
94
|
/** @property {number} - How much to randomize frequency each time sound plays */
|
|
78
|
-
this.randomness = 0;
|
|
95
|
+
this.randomness = randomness ?? 0;
|
|
79
96
|
/** @property {number} - Sample rate for this sound */
|
|
80
97
|
this.sampleRate = audioDefaultSampleRate;
|
|
81
98
|
/** @property {number} - Percentage of this sound currently loaded */
|
|
82
99
|
this.loadedPercent = 0;
|
|
100
|
+
/** @property {SoundLoadCallback} - function to call when sound is loaded */
|
|
101
|
+
this.onloadCallback = onloadCallback;
|
|
83
102
|
|
|
84
|
-
|
|
85
|
-
if (zzfxSound)
|
|
103
|
+
if (Array.isArray(asset))
|
|
86
104
|
{
|
|
105
|
+
// generate zzfx sound
|
|
106
|
+
const zzfxSound = asset;
|
|
107
|
+
|
|
87
108
|
// remove randomness so it can be applied on playback
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
109
|
+
const defaultRandomness = randomness ?? .05;
|
|
110
|
+
const randomnessIndex = 1;
|
|
111
|
+
this.randomness = zzfxSound[randomnessIndex] ?? defaultRandomness;
|
|
91
112
|
zzfxSound[randomnessIndex] = 0;
|
|
92
113
|
|
|
93
114
|
// generate the zzfx samples
|
|
94
115
|
this.sampleChannels = [zzfxG(...zzfxSound)];
|
|
95
116
|
this.loadedPercent = 1;
|
|
117
|
+
onloadCallback?.(this);
|
|
118
|
+
}
|
|
119
|
+
else if (typeof asset === 'string')
|
|
120
|
+
{
|
|
121
|
+
// load the audio file
|
|
122
|
+
const filename = asset;
|
|
123
|
+
this.loadSound(filename);
|
|
96
124
|
}
|
|
97
125
|
}
|
|
98
126
|
|
|
@@ -144,7 +172,7 @@ class Sound
|
|
|
144
172
|
* @param {number} [volume] - Volume to play the music at
|
|
145
173
|
* @param {boolean} [loop] - Should the music loop?
|
|
146
174
|
* @param {boolean} [paused] - Should the music start paused
|
|
147
|
-
* @return {SoundInstance} - The
|
|
175
|
+
* @return {SoundInstance} - The sound instance
|
|
148
176
|
*/
|
|
149
177
|
playMusic(volume=1, loop=true, paused=false)
|
|
150
178
|
{ return this.play(undefined, volume, 1, 0, loop, paused); }
|
|
@@ -154,7 +182,7 @@ class Sound
|
|
|
154
182
|
* @param {number} [semitoneOffset=0] - How many semitones to offset pitch
|
|
155
183
|
* @param {Vector2} [pos] - World space position to play the sound if any
|
|
156
184
|
* @param {number} [volume=1] - How much to scale volume by
|
|
157
|
-
* @return {SoundInstance} - The
|
|
185
|
+
* @return {SoundInstance} - The sound instance
|
|
158
186
|
*/
|
|
159
187
|
playNote(semitoneOffset=0, pos, volume)
|
|
160
188
|
{
|
|
@@ -167,57 +195,14 @@ class Sound
|
|
|
167
195
|
* @return {number} - How long the sound is in seconds (undefined if loading)
|
|
168
196
|
*/
|
|
169
197
|
getDuration()
|
|
170
|
-
{ return this.sampleChannels
|
|
198
|
+
{ return this.sampleChannels?.[0]?.length / this.sampleRate || 0; }
|
|
171
199
|
|
|
172
200
|
/** Check if sound is loaded, for sounds fetched from a url
|
|
173
201
|
* @return {boolean} - True if sound is loaded and ready to play
|
|
174
202
|
*/
|
|
175
203
|
isLoaded() { return this.loadedPercent === 1; }
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Sound Wave Object - Loads and stores an audio file for later use
|
|
182
|
-
* - this can be used to load and play wave, mp3, and ogg files
|
|
183
|
-
* @extends Sound
|
|
184
|
-
* @memberof Audio
|
|
185
|
-
* @example
|
|
186
|
-
* // load an audio asset file
|
|
187
|
-
* const sound_example = new SoundWave('sound.mp3');
|
|
188
|
-
*
|
|
189
|
-
* // play the sound
|
|
190
|
-
* sound_example.play();
|
|
191
|
-
*/
|
|
192
|
-
class SoundWave extends Sound
|
|
193
|
-
{
|
|
194
|
-
/**
|
|
195
|
-
* @callback SoundLoadCallback - Function called when sound is loaded
|
|
196
|
-
* @param {SoundWave} sound
|
|
197
|
-
* @memberof Audio
|
|
198
|
-
*/
|
|
199
204
|
|
|
200
|
-
/**
|
|
201
|
-
* @param {string} filename - Filename of audio file to load
|
|
202
|
-
* @param {number} [randomness] - How much to randomize frequency each time sound plays
|
|
203
|
-
* @param {number} [range=soundDefaultRange] - World space max range of sound
|
|
204
|
-
* @param {number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
|
|
205
|
-
* @param {SoundLoadCallback} [onloadCallback] - callback function to call when sound is loaded
|
|
206
|
-
*/
|
|
207
|
-
constructor(filename, randomness=0, range, taper, onloadCallback)
|
|
208
|
-
{
|
|
209
|
-
super(undefined, range, taper);
|
|
210
|
-
if (!soundEnable || headlessMode) return;
|
|
211
|
-
ASSERT(!filename || isString(filename), 'filename must be a string');
|
|
212
|
-
ASSERT(isNumber(randomness), 'randomness must be a number');
|
|
213
|
-
|
|
214
|
-
/** @property {SoundLoadCallback} - callback function to call when sound is loaded */
|
|
215
|
-
this.onloadCallback = onloadCallback;
|
|
216
|
-
this.randomness = randomness;
|
|
217
|
-
filename && this.loadSound(filename);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/** Loads a sound from a URL and decodes it into sample data. Must be used with await!
|
|
205
|
+
/** Loads a sound from a URL and decodes it into sample data.
|
|
221
206
|
* @param {string} filename
|
|
222
207
|
* @return {Promise<void>} */
|
|
223
208
|
async loadSound(filename)
|
|
@@ -259,8 +244,7 @@ class SoundWave extends Sound
|
|
|
259
244
|
this.sampleRate = audioBuffer.sampleRate;
|
|
260
245
|
this.sampleChannels = sampleChannels;
|
|
261
246
|
this.loadedPercent = 1;
|
|
262
|
-
|
|
263
|
-
this.onloadCallback(this);
|
|
247
|
+
this.onloadCallback?.(this);
|
|
264
248
|
}
|
|
265
249
|
}
|
|
266
250
|
|
|
@@ -463,7 +447,7 @@ function speak(text, language='', volume=1, rate=1, pitch=1)
|
|
|
463
447
|
|
|
464
448
|
/** Stop all queued speech
|
|
465
449
|
* @memberof Audio */
|
|
466
|
-
function speakStop() {speechSynthesis
|
|
450
|
+
function speakStop() {speechSynthesis?.cancel();}
|
|
467
451
|
|
|
468
452
|
/** Get frequency of a note on a musical scale
|
|
469
453
|
* @param {number} semitoneOffset - How many semitones away from the root note
|
package/src/engineDebug.js
CHANGED
|
@@ -49,7 +49,7 @@ let debugPrimitives = [], debugPhysics = false, debugRaycast = false, debugParti
|
|
|
49
49
|
/** Asserts if the expression is false, does nothing in release builds
|
|
50
50
|
* Halts execution if the assert fails and throws an error
|
|
51
51
|
* @param {boolean} assert
|
|
52
|
-
* @param {...Object}
|
|
52
|
+
* @param {...Object} output - error message output
|
|
53
53
|
* @memberof Debug */
|
|
54
54
|
function ASSERT(assert, ...output)
|
|
55
55
|
{
|
|
@@ -59,13 +59,13 @@ function ASSERT(assert, ...output)
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/** Log to console if debug is enabled, does nothing in release builds
|
|
62
|
-
* @param {...Object}
|
|
62
|
+
* @param {...Object} output - message output
|
|
63
63
|
* @memberof Debug */
|
|
64
64
|
function LOG(...output) { console.log(...output); }
|
|
65
65
|
|
|
66
66
|
/** Draw a debug rectangle in world space
|
|
67
67
|
* @param {Vector2} pos
|
|
68
|
-
* @param {Vector2} [size=
|
|
68
|
+
* @param {Vector2} [size=vec2(0)]
|
|
69
69
|
* @param {Color|string} [color]
|
|
70
70
|
* @param {number} [time]
|
|
71
71
|
* @param {number} [angle]
|
|
@@ -389,7 +389,7 @@ function debugRender()
|
|
|
389
389
|
if (tileCollisionTest(mousePos))
|
|
390
390
|
{
|
|
391
391
|
// show floored tile pick for tile collision
|
|
392
|
-
drawRect(mousePos.floor().add(vec2(.5)), vec2(1), rgb(1,1,0,.5));
|
|
392
|
+
drawRect(mousePos.floor().add(vec2(.5)), vec2(1), rgb(1,1,0,.5), 0, false);
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
395
|
|
|
@@ -468,8 +468,8 @@ function debugRender()
|
|
|
468
468
|
if (debugObject)
|
|
469
469
|
{
|
|
470
470
|
const raycastHitPos = tileCollisionRaycast(debugObject.pos, mousePos);
|
|
471
|
-
raycastHitPos && drawRect(raycastHitPos.floor().add(vec2(.5)), vec2(1), rgb(0,1,1,.3));
|
|
472
|
-
drawLine(mousePos, debugObject.pos, .1, raycastHitPos ? rgb(1,0,0,.5) : rgb(0,1,0,.5));
|
|
471
|
+
raycastHitPos && drawRect(raycastHitPos.floor().add(vec2(.5)), vec2(1), rgb(0,1,1,.3), 0, false);
|
|
472
|
+
drawLine(mousePos, debugObject.pos, .1, raycastHitPos ? rgb(1,0,0,.5) : rgb(0,1,0,.5), undefined, undefined, false);
|
|
473
473
|
|
|
474
474
|
let debugText = 'mouse pos = ' + mousePos;
|
|
475
475
|
if (tileCollisionLayers.length)
|
|
@@ -706,8 +706,8 @@ function debugProtectConstant(obj)
|
|
|
706
706
|
props.forEach(prop =>
|
|
707
707
|
{
|
|
708
708
|
Object.defineProperty(obj, prop, {
|
|
709
|
-
get: ()
|
|
710
|
-
set: (value)
|
|
709
|
+
get: ()=> values[prop],
|
|
710
|
+
set: (value)=>
|
|
711
711
|
{
|
|
712
712
|
ASSERT(false, `Cannot modify engine constant. Attempted to set constant (${obj}) property '${prop}' to '${value}'.`);
|
|
713
713
|
},
|