littlejsengine 1.0.14 → 1.1.8
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/build.bat +5 -1
- package/docs/Audio.html +2268 -0
- package/docs/Color.html +2989 -0
- package/docs/Debug.html +2933 -0
- package/docs/Draw.html +4092 -0
- package/docs/EngineObject.html +4458 -0
- package/docs/Input.html +2482 -0
- package/docs/Medal.html +1007 -0
- package/docs/Medals.html +628 -0
- package/docs/Music.html +584 -0
- package/docs/Newgrounds.html +1399 -0
- package/docs/Particle.html +4535 -0
- package/docs/ParticleEmitter.html +7770 -0
- package/docs/Random.html +1774 -0
- package/docs/Settings.html +2679 -0
- package/docs/Sound.html +1249 -0
- package/docs/TileCollision.html +1409 -0
- package/docs/TileLayer.html +6948 -0
- package/docs/TileLayerData.html +1052 -0
- package/docs/Timer.html +1183 -0
- package/docs/Utilities.html +3281 -0
- package/docs/Vector2.html +4207 -0
- package/docs/WebGL.html +2327 -0
- package/docs/engine.js.html +429 -0
- package/docs/engineAudio.js.html +609 -0
- package/docs/engineDebug.js.html +725 -0
- package/docs/engineDraw.js.html +419 -0
- package/docs/engineInput.js.html +401 -0
- package/docs/engineMedals.js.html +461 -0
- package/docs/engineObject.js.html +518 -0
- package/docs/engineParticles.js.html +441 -0
- package/docs/engineSettings.js.html +349 -0
- package/docs/engineTileLayer.js.html +513 -0
- package/docs/engineUtilities.js.html +647 -0
- package/docs/engineWebGL.js.html +522 -0
- package/docs/fonts/MavenPro-Regular.ttf +0 -0
- package/docs/fonts/Montserrat-Regular.ttf +0 -0
- package/docs/fonts/Muli-Black.ttf +0 -0
- package/docs/fonts/OFL-hind.txt +93 -0
- package/docs/fonts/OFL-montserrat.txt +93 -0
- package/docs/global.html +1691 -0
- package/docs/index.css +6 -0
- package/docs/index.html +247 -0
- package/docs/scripts/fix-code-block.js +53 -0
- package/docs/scripts/fix-navbar.js +25 -0
- package/docs/scripts/linenumber.js +25 -0
- package/docs/scripts/misc.js +217 -0
- package/docs/scripts/resize.js +85 -0
- package/docs/scripts/search.js +83 -0
- package/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
- package/docs/scripts/third-party/fuse.js +9 -0
- package/docs/scripts/third-party/lang-css.js +2 -0
- package/docs/scripts/third-party/prettify.js +28 -0
- package/docs/static/favicon.png +0 -0
- package/docs/static/index.css +4 -0
- package/docs/styles/clean-jsdoc-theme-base.css +393 -0
- package/docs/styles/clean-jsdoc-theme-dark.css +324 -0
- package/docs/styles/clean-jsdoc-theme-light.css +319 -0
- package/docs/styles/reset.css +346 -0
- package/docs/styles/third-party/ionicons.min.css +11 -0
- package/docs/styles/third-party/prettify-jsdoc.css +111 -0
- package/docs/styles/third-party/prettify-tomorrow.css +5 -0
- package/engine/engine.all.js +1997 -744
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.release.js +1743 -569
- package/engine/engine.js +107 -39
- package/engine/engineAudio.js +152 -34
- package/engine/{build.bat → engineBuild.bat} +10 -10
- package/engine/{buildSetup.bat → engineBuildSetup.bat} +0 -0
- package/engine/engineDebug.js +105 -32
- package/engine/engineDraw.js +137 -32
- package/engine/engineInput.js +111 -37
- package/engine/{engineMedal.js → engineMedals.js} +129 -56
- package/engine/engineObject.js +117 -67
- package/engine/engineParticles.js +282 -0
- package/engine/engineRelease.js +3 -9
- package/engine/engineSettings.js +190 -0
- package/engine/engineTileLayer.js +147 -44
- package/engine/engineUtilities.js +488 -0
- package/engine/engineWebGL.js +113 -74
- package/examples/breakout/game.js +1 -1
- package/examples/breakout/gameObjects.js +3 -3
- package/examples/breakout/index.html +3 -3
- package/examples/platformer/game.js +5 -7
- package/examples/platformer/gameEffects.js +7 -7
- package/examples/platformer/gameLevel.js +2 -2
- package/examples/platformer/gameObjects.js +4 -5
- package/examples/platformer/gamePlayer.js +3 -3
- package/examples/platformer/index.html +6 -6
- package/examples/puzzle/game.js +1 -2
- package/examples/puzzle/index.html +2 -2
- package/examples/stress/index.html +2 -8
- package/game.js +5 -11
- package/index.html +13 -13
- package/package.json +4 -4
- package/tiles.png +0 -0
- package/engine/engineConfig.js +0 -64
- package/engine/engineParticle.js +0 -199
- package/engine/engineUtil.js +0 -147
package/engine/engine.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
/*
|
|
2
|
-
LittleJS - The Tiny JavaScript Game Engine That Can
|
|
3
|
-
MIT License - Copyright
|
|
2
|
+
LittleJS - The Tiny JavaScript Game Engine That Can!
|
|
3
|
+
MIT License - Copyright 2021 Frank Force
|
|
4
4
|
|
|
5
5
|
Engine Features
|
|
6
|
-
-
|
|
7
|
-
- Object oriented with base class engine object
|
|
8
|
-
- Engine handles core update loop
|
|
6
|
+
- Object oriented system with base class engine object
|
|
9
7
|
- Base class object handles update, physics, collision, rendering, etc
|
|
10
8
|
- Engine helper classes and functions like Vector2, Color, and Timer
|
|
11
9
|
- Super fast rendering system for tile sheets
|
|
@@ -13,30 +11,63 @@
|
|
|
13
11
|
- Input processing system with gamepad and touchscreen support
|
|
14
12
|
- Tile layer rendering and collision system
|
|
15
13
|
- Particle effect system
|
|
16
|
-
-
|
|
14
|
+
- Medal system tracks and displays achievements
|
|
17
15
|
- Debug tools and debug rendering system
|
|
18
16
|
- Call engineInit() to start it up!
|
|
19
17
|
*/
|
|
20
18
|
|
|
21
19
|
'use strict';
|
|
22
20
|
|
|
21
|
+
/** Name of engine */
|
|
23
22
|
const engineName = 'LittleJS';
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
|
|
24
|
+
/** Version of engine */
|
|
25
|
+
const engineVersion = '1.1.8';
|
|
26
|
+
|
|
27
|
+
/** Frames per second to update objects
|
|
28
|
+
* @default */
|
|
29
|
+
const FPS = 60;
|
|
30
|
+
|
|
31
|
+
/** How many seconds each frame lasts, engine uses a fixed time step
|
|
32
|
+
* @default 1/60 */
|
|
33
|
+
const timeDelta = 1/FPS;
|
|
34
|
+
|
|
35
|
+
/** Array containing all engine objects */
|
|
36
|
+
let engineObjects = [];
|
|
37
|
+
|
|
38
|
+
/** Array containing only objects that are set to collide with other objects (for optimization) */
|
|
39
|
+
let engineCollideObjects = [];
|
|
40
|
+
|
|
41
|
+
/** Current update frame, used to calculate time */
|
|
42
|
+
let frame = 0;
|
|
43
|
+
|
|
44
|
+
/** Current engine time since start in seconds, derived from frame */
|
|
45
|
+
let time = 0;
|
|
46
|
+
|
|
47
|
+
/** Actual clock time since start in seconds (not affected by pause or frame rate clamping) */
|
|
48
|
+
let timeReal = 0;
|
|
49
|
+
|
|
50
|
+
/** Is the game paused? Causes time and objects to not be updated. */
|
|
51
|
+
let paused = 0;
|
|
52
|
+
|
|
53
|
+
// Engine internal variables not exposed to documentation
|
|
54
|
+
let frameTimeLastMS = 0, frameTimeBufferMS = 0, debugFPS = 0,
|
|
55
|
+
shrinkTilesX, shrinkTilesY, drawCount, tileImageSize, tileImageSizeInverse;
|
|
56
|
+
|
|
57
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
58
|
+
|
|
59
|
+
/** Start up LittleJS engine with your callback functions
|
|
60
|
+
* @param {Function} gameInit - Called once after the engine starts up, setup the game
|
|
61
|
+
* @param {Function} gameUpdate - Called every frame at 60 frames per second, handle input and update the game state
|
|
62
|
+
* @param {Function} gameUpdatePost - Called after physics and objects are updated, setup camera and prepare for render
|
|
63
|
+
* @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
|
|
64
|
+
* @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
|
|
65
|
+
* @param {String} [tileImageSource] - Tile image to use, everything starts when the image is finished loading
|
|
66
|
+
*/
|
|
36
67
|
function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, tileImageSource)
|
|
37
68
|
{
|
|
38
|
-
// init engine when tiles load
|
|
39
|
-
tileImage.onload = ()=>
|
|
69
|
+
// init engine when tiles load or fail to load
|
|
70
|
+
tileImage.onerror = tileImage.onload = ()=>
|
|
40
71
|
{
|
|
41
72
|
// save tile image info
|
|
42
73
|
tileImageSizeInverse = vec2(1).divide(tileImageSize = vec2(tileImage.width, tileImage.height));
|
|
@@ -76,7 +107,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
76
107
|
debugFPS = lerp(.05, 1e3/(frameTimeDeltaMS||1), debugFPS);
|
|
77
108
|
if (debug)
|
|
78
109
|
frameTimeDeltaMS *= keyIsDown(107) ? 5 : keyIsDown(109) ? .2 : 1; // +/- to speed/slow time
|
|
79
|
-
|
|
110
|
+
timeReal += frameTimeDeltaMS / 1e3;
|
|
80
111
|
frameTimeBufferMS = min(frameTimeBufferMS + !paused * frameTimeDeltaMS, 50); // clamp incase of slow framerate
|
|
81
112
|
|
|
82
113
|
if (paused)
|
|
@@ -104,7 +135,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
104
135
|
// update game and objects
|
|
105
136
|
inputUpdate();
|
|
106
137
|
gameUpdate();
|
|
107
|
-
|
|
138
|
+
engineObjectsUpdate();
|
|
108
139
|
|
|
109
140
|
// do post update
|
|
110
141
|
debugUpdate();
|
|
@@ -116,31 +147,28 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
116
147
|
frameTimeBufferMS += deltaSmooth;
|
|
117
148
|
}
|
|
118
149
|
|
|
119
|
-
if (
|
|
150
|
+
if (fixedSize.x)
|
|
120
151
|
{
|
|
121
152
|
// clear set fixed size
|
|
122
|
-
mainCanvas.width =
|
|
123
|
-
mainCanvas.height =
|
|
153
|
+
mainCanvas.width = fixedSize.x;
|
|
154
|
+
mainCanvas.height = fixedSize.y;
|
|
124
155
|
|
|
125
|
-
if
|
|
156
|
+
// fit to window by adding space on top or bottom if necessary
|
|
157
|
+
const aspect = innerWidth / innerHeight;
|
|
158
|
+
const fixedAspect = mainCanvas.width / mainCanvas.height;
|
|
159
|
+
mainCanvas.style.width = overlayCanvas.style.width = aspect < fixedAspect ? '100%' : '';
|
|
160
|
+
mainCanvas.style.height = overlayCanvas.style.height = aspect < fixedAspect ? '' : '100%';
|
|
161
|
+
if (glCanvas)
|
|
126
162
|
{
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const fixedAspect = fixedWidth / fixedHeight;
|
|
130
|
-
mainCanvas.style.width = overlayCanvas.style.width = aspect < fixedAspect ? '100%' : '';
|
|
131
|
-
mainCanvas.style.height = overlayCanvas.style.height = aspect < fixedAspect ? '' : '100%';
|
|
132
|
-
if (glCanvas)
|
|
133
|
-
{
|
|
134
|
-
glCanvas.style.width = mainCanvas.style.width;
|
|
135
|
-
glCanvas.style.height = mainCanvas.style.height;
|
|
136
|
-
}
|
|
163
|
+
glCanvas.style.width = mainCanvas.style.width;
|
|
164
|
+
glCanvas.style.height = mainCanvas.style.height;
|
|
137
165
|
}
|
|
138
166
|
}
|
|
139
167
|
else
|
|
140
168
|
{
|
|
141
169
|
// clear and set size to same as window
|
|
142
|
-
mainCanvas.width = min(innerWidth,
|
|
143
|
-
mainCanvas.height = min(innerHeight,
|
|
170
|
+
mainCanvas.width = min(innerWidth, maxSize.x);
|
|
171
|
+
mainCanvas.height = min(innerHeight, maxSize.y);
|
|
144
172
|
}
|
|
145
173
|
|
|
146
174
|
// save canvas size and clear overlay canvas
|
|
@@ -178,7 +206,11 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
178
206
|
tileImageSource ? tileImage.src = tileImageSource : tileImage.onload();
|
|
179
207
|
}
|
|
180
208
|
|
|
181
|
-
|
|
209
|
+
|
|
210
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
211
|
+
|
|
212
|
+
/** Calls update on each engine object (recursively if child), removes destroyed objects, and updated time */
|
|
213
|
+
function engineObjectsUpdate()
|
|
182
214
|
{
|
|
183
215
|
// recursive object update
|
|
184
216
|
const updateObject = (o)=>
|
|
@@ -199,4 +231,40 @@ function engineUpdateObjects()
|
|
|
199
231
|
|
|
200
232
|
// increment frame and update time
|
|
201
233
|
time = ++frame / FPS;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Detroy and remove all objects that are not persistent or descendants of a persistent object */
|
|
237
|
+
function engineObjectsDestroy()
|
|
238
|
+
{
|
|
239
|
+
for (const o of engineObjects)
|
|
240
|
+
o.persistent || o.parent || o.destroy();
|
|
241
|
+
engineObjects = engineObjects.filter(o=>!o.destroyed);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/** Triggers a callback for each object within a given area
|
|
245
|
+
* @param {Vector2} [pos] - Center of test area
|
|
246
|
+
* @param {Number} [size] - Radius of circle if float, rectangle size if Vector2
|
|
247
|
+
* @param {Function} [callbackFunction] - Calls this function on every object that passes the test
|
|
248
|
+
* @param {Array} [objects=engineObjects] - List of objects to check */
|
|
249
|
+
function engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
|
|
250
|
+
{
|
|
251
|
+
if (!pos)
|
|
252
|
+
{
|
|
253
|
+
// all objects
|
|
254
|
+
for (const o of objects)
|
|
255
|
+
callbackFunction(o);
|
|
256
|
+
}
|
|
257
|
+
else if (size.x != undefined)
|
|
258
|
+
{
|
|
259
|
+
// aabb test
|
|
260
|
+
for (const o of objects)
|
|
261
|
+
isOverlapping(pos, size, o.pos, o.size) && callbackFunction(o);
|
|
262
|
+
}
|
|
263
|
+
else
|
|
264
|
+
{
|
|
265
|
+
// circle test
|
|
266
|
+
const sizeSquared = size*size;
|
|
267
|
+
for (const o of objects)
|
|
268
|
+
pos.distanceSquared(o.pos) < sizeSquared && callbackFunction(o);
|
|
269
|
+
}
|
|
202
270
|
}
|
package/engine/engineAudio.js
CHANGED
|
@@ -1,24 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
/**
|
|
2
|
+
* LittleJS Audio System
|
|
3
|
+
* <br> - ZzFX Sound Effects and ZzFXM Music
|
|
4
|
+
* <br> - Caches sounds and music for fast playback
|
|
5
|
+
* <br> - Can attenuate and apply stereo panning to sounds
|
|
6
|
+
* <br> - Ability to play mp3, ogg, and wave files
|
|
7
|
+
* <br> - Speech synthesis wrapper functions
|
|
8
|
+
* @namespace Audio
|
|
9
|
+
*/
|
|
9
10
|
|
|
10
11
|
'use strict';
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Sound Object - Stores a zzfx sound for later use and can be played positionally
|
|
15
|
+
* @example
|
|
16
|
+
* // create a sound
|
|
17
|
+
* const sound_example = new Sound([.5,.5]);
|
|
18
|
+
*
|
|
19
|
+
* // play the sound
|
|
20
|
+
* sound_example.play();
|
|
21
|
+
*/
|
|
12
22
|
class Sound
|
|
13
23
|
{
|
|
14
|
-
|
|
24
|
+
/** Create a sound object and cache the zzfx samples for later use
|
|
25
|
+
* @param {Array} zzfxSound - Array of zzfx parameters, ex. [.5,.5]
|
|
26
|
+
* @param {Number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
|
|
27
|
+
* @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering off
|
|
28
|
+
*/
|
|
29
|
+
constructor(zzfxSound, range=soundDefaultRange, taper=soundDefaultTaper)
|
|
15
30
|
{
|
|
16
31
|
if (!soundEnable) return;
|
|
17
32
|
|
|
33
|
+
/** @property {Number} - World space max range of sound, will not play if camera is farther away */
|
|
18
34
|
this.range = range;
|
|
35
|
+
|
|
36
|
+
/** @property {Number} - At what percentage of range should it start tapering off */
|
|
19
37
|
this.taper = taper;
|
|
20
38
|
|
|
21
|
-
// get randomness from sound
|
|
39
|
+
// get randomness from sound parameters
|
|
22
40
|
this.randomness = zzfxSound[1] || 0;
|
|
23
41
|
zzfxSound[1] = 0;
|
|
24
42
|
|
|
@@ -26,7 +44,14 @@ class Sound
|
|
|
26
44
|
this.cachedSamples = zzfxG(...zzfxSound);
|
|
27
45
|
}
|
|
28
46
|
|
|
29
|
-
|
|
47
|
+
/** Play the sound
|
|
48
|
+
* @param {Vector2} [pos] - World space position to play the sound, sound is not attenuated if null
|
|
49
|
+
* @param {Number} [volume=1] - How much to scale volume by (in addition to range fade)
|
|
50
|
+
* @param {Number} [pitch=1] - How much to scale pitch by (also adjusted by this.randomness)
|
|
51
|
+
* @param {Number} [randomnessScale=1] - How much to scale randomness
|
|
52
|
+
* @return {AudioBufferSourceNode} - The audio, can be used to stop sound later
|
|
53
|
+
*/
|
|
54
|
+
play(pos, volume=1, pitch=1, randomnessScale=1)
|
|
30
55
|
{
|
|
31
56
|
if (!soundEnable) return;
|
|
32
57
|
|
|
@@ -42,7 +67,7 @@ class Sound
|
|
|
42
67
|
return; // out of range
|
|
43
68
|
|
|
44
69
|
// attenuate volume by distance
|
|
45
|
-
|
|
70
|
+
volume *= percent(lengthSquared**.5, range*this.taper, range);
|
|
46
71
|
}
|
|
47
72
|
|
|
48
73
|
// get pan from screen space coords
|
|
@@ -50,13 +75,57 @@ class Sound
|
|
|
50
75
|
}
|
|
51
76
|
|
|
52
77
|
// play the sound
|
|
53
|
-
const playbackRate =
|
|
54
|
-
return playSamples([this.cachedSamples],
|
|
78
|
+
const playbackRate = pitch + pitch * this.randomness*randomnessScale*rand(-1,1);
|
|
79
|
+
return playSamples([this.cachedSamples], volume, playbackRate, pan);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Play the sound as a note with a semitone offset
|
|
83
|
+
* @param {Number} semitoneOffset - How many semitones to offset pitch
|
|
84
|
+
* @param {Vector2} [pos] - World space position to play the sound, sound is not attenuated if null
|
|
85
|
+
* @param {Number} [volume=1] - How much to scale volume by (in addition to range fade)
|
|
86
|
+
* @return {AudioBufferSourceNode} - The audio, can be used to stop sound later
|
|
87
|
+
*/
|
|
88
|
+
playNote(semitoneOffset, pos, volume=1)
|
|
89
|
+
{
|
|
90
|
+
if (!soundEnable) return;
|
|
91
|
+
|
|
92
|
+
return this.play(pos, volume, 2**(semitoneOffset/12), 0);
|
|
55
93
|
}
|
|
56
94
|
}
|
|
57
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Music Object - Stores a zzfx music track for later use
|
|
98
|
+
* @example
|
|
99
|
+
* // create some music
|
|
100
|
+
* const music_example = new Music(
|
|
101
|
+
* [
|
|
102
|
+
* [ // instruments
|
|
103
|
+
* [,0,400] // simple note
|
|
104
|
+
* ],
|
|
105
|
+
* [ // patterns
|
|
106
|
+
* [ // pattern 1
|
|
107
|
+
* [ // channel 0
|
|
108
|
+
* 0, -1, // instrument 0, left speaker
|
|
109
|
+
* 1, 0, 9, 1 // channel notes
|
|
110
|
+
* ],
|
|
111
|
+
* [ // channel 1
|
|
112
|
+
* 0, 1, // instrument 1, right speaker
|
|
113
|
+
* 0, 12, 17, -1 // channel notes
|
|
114
|
+
* ]
|
|
115
|
+
* ],
|
|
116
|
+
* ],
|
|
117
|
+
* [0, 0, 0, 0], // sequence, play pattern 0 four times
|
|
118
|
+
* 90 // BPM
|
|
119
|
+
* ]);
|
|
120
|
+
*
|
|
121
|
+
* // play the music
|
|
122
|
+
* music_example.play();
|
|
123
|
+
*/
|
|
58
124
|
class Music
|
|
59
125
|
{
|
|
126
|
+
/** Create a music object and cache the zzfx music samples for later use
|
|
127
|
+
* @param {Array} zzfxMusic - Array of zzfx music parameters
|
|
128
|
+
*/
|
|
60
129
|
constructor(zzfxMusic)
|
|
61
130
|
{
|
|
62
131
|
if (!soundEnable) return;
|
|
@@ -64,29 +133,44 @@ class Music
|
|
|
64
133
|
this.cachedSamples = zzfxM(...zzfxMusic);
|
|
65
134
|
}
|
|
66
135
|
|
|
67
|
-
|
|
136
|
+
/** Play the music
|
|
137
|
+
* @param {Number} [volume=1] - How much to scale volume by
|
|
138
|
+
* @param {Boolean} [loop=1] - True if the music should loop when it reaches the end
|
|
139
|
+
* @return {AudioBufferSourceNode} - The audio node, can be used to stop sound later
|
|
140
|
+
*/
|
|
141
|
+
play(volume = 1, loop = 1)
|
|
68
142
|
{
|
|
69
143
|
if (!soundEnable) return;
|
|
70
144
|
|
|
71
|
-
return playSamples(this.cachedSamples,
|
|
145
|
+
return playSamples(this.cachedSamples, volume, 1, 0, loop);
|
|
72
146
|
}
|
|
73
147
|
}
|
|
74
148
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
149
|
+
/** Play an mp3 or wav audio from a local file or url
|
|
150
|
+
* @param {String} url - Location of sound file to play
|
|
151
|
+
* @param {Number} [volume=1] - How much to scale volume by
|
|
152
|
+
* @param {Boolean} [loop=1] - True if the music should loop when it reaches the end
|
|
153
|
+
* @return {HTMLAudioElement} - The audio element for this sound
|
|
154
|
+
* @memberof Audio */
|
|
155
|
+
function playAudioFile(url, volume=1, loop=1)
|
|
79
156
|
{
|
|
80
157
|
if (!soundEnable) return;
|
|
81
158
|
|
|
82
159
|
const audio = new Audio(url);
|
|
83
|
-
audio.volume =
|
|
160
|
+
audio.volume = soundVolume * volume;
|
|
84
161
|
audio.loop = loop;
|
|
85
162
|
audio.play();
|
|
86
163
|
return audio;
|
|
87
164
|
}
|
|
88
165
|
|
|
89
|
-
|
|
166
|
+
/** Speak text with passed in settings
|
|
167
|
+
* @param {String} text - The text to speak
|
|
168
|
+
* @param {String} [language] - The language/accent to use (examples: en, it, ru, ja, zh)
|
|
169
|
+
* @param {Number} [volume=1] - How much to scale volume by
|
|
170
|
+
* @param {Number} [rate=1] - How quickly to speak
|
|
171
|
+
* @param {Number} [pitch=1] - How much to change the pitch by
|
|
172
|
+
* @return {SpeechSynthesisUtterance} - The utterance that was spoken
|
|
173
|
+
* @memberof Audio */
|
|
90
174
|
function speak(text, language='', volume=1, rate=1, pitch=1)
|
|
91
175
|
{
|
|
92
176
|
if (!soundEnable || !speechSynthesis) return;
|
|
@@ -98,22 +182,39 @@ function speak(text, language='', volume=1, rate=1, pitch=1)
|
|
|
98
182
|
// build utterance and speak
|
|
99
183
|
const utterance = new SpeechSynthesisUtterance(text);
|
|
100
184
|
utterance.lang = language;
|
|
101
|
-
utterance.volume = volume*
|
|
185
|
+
utterance.volume = 2*volume*soundVolume;
|
|
102
186
|
utterance.rate = rate;
|
|
103
187
|
utterance.pitch = pitch;
|
|
104
188
|
speechSynthesis.speak(utterance);
|
|
105
189
|
return utterance;
|
|
106
190
|
}
|
|
107
191
|
|
|
108
|
-
|
|
192
|
+
/** Stop all queued speech
|
|
193
|
+
* @memberof Audio */
|
|
109
194
|
const stopSpeech = ()=> speechSynthesis && speechSynthesis.cancel();
|
|
110
195
|
|
|
111
|
-
|
|
196
|
+
/** Get frequency of a note on a musical scale
|
|
197
|
+
* @param {Number} semitoneOffset - How many semitones away from the root note
|
|
198
|
+
* @param {Number} [rootNoteFrequency=220] - Frequency at semitone offset 0
|
|
199
|
+
* @return {Number} - The frequency of the note
|
|
200
|
+
* @memberof Audio */
|
|
201
|
+
const getNoteFrequency = (semitoneOffset, rootFrequency=220)=> rootFrequency * 2**(semitoneOffset/12);
|
|
112
202
|
|
|
113
|
-
|
|
203
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
114
204
|
|
|
115
|
-
|
|
116
|
-
|
|
205
|
+
/** Audio context used by the engine
|
|
206
|
+
* @memberof Audio */
|
|
207
|
+
let audioContext;
|
|
208
|
+
|
|
209
|
+
/** Play cached audio samples with given settings
|
|
210
|
+
* @param {Array} sampleChannels - Array of arrays of samples to play (for stereo playback)
|
|
211
|
+
* @param {Number} [volume=1] - How much to scale volume by
|
|
212
|
+
* @param {Number} [rate=1] - The playback rate to use
|
|
213
|
+
* @param {Number} [pan=0] - How much to apply stereo panning
|
|
214
|
+
* @param {Boolean} [loop=0] - True if the sound should loop when it reaches the end
|
|
215
|
+
* @return {AudioBufferSourceNode} - The audio node of the sound played
|
|
216
|
+
* @memberof Audio */
|
|
217
|
+
function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0)
|
|
117
218
|
{
|
|
118
219
|
if (!soundEnable) return;
|
|
119
220
|
|
|
@@ -128,13 +229,13 @@ function playSamples(sampleChannels, volume=1, playbackRate=1, pan=0, loop=0)
|
|
|
128
229
|
// copy samples to buffer and setup source
|
|
129
230
|
sampleChannels.forEach((c,i)=> buffer.getChannelData(i).set(c));
|
|
130
231
|
source.buffer = buffer;
|
|
131
|
-
source.playbackRate.value =
|
|
232
|
+
source.playbackRate.value = rate;
|
|
132
233
|
source.loop = loop;
|
|
133
234
|
|
|
134
235
|
// create pan and gain nodes
|
|
135
236
|
source
|
|
136
237
|
.connect(new StereoPannerNode(audioContext, {'pan':clamp(pan, 1, -1)}))
|
|
137
|
-
.connect(new GainNode(audioContext, {'gain':
|
|
238
|
+
.connect(new GainNode(audioContext, {'gain':soundVolume*volume}))
|
|
138
239
|
.connect(audioContext.destination);
|
|
139
240
|
|
|
140
241
|
// play and return sound
|
|
@@ -145,10 +246,20 @@ function playSamples(sampleChannels, volume=1, playbackRate=1, pan=0, loop=0)
|
|
|
145
246
|
///////////////////////////////////////////////////////////////////////////////
|
|
146
247
|
// ZzFXMicro - Zuper Zmall Zound Zynth - v1.1.8 by Frank Force
|
|
147
248
|
|
|
148
|
-
|
|
149
|
-
|
|
249
|
+
/** Generate and play a ZzFX sound
|
|
250
|
+
* @param {Array} zzfxSound - Array of ZzFX parameters, ex. [.5,.5]
|
|
251
|
+
* @return {Array} - Array of audio samples
|
|
252
|
+
* @memberof Audio */
|
|
253
|
+
const zzfx = (...zzfxSound) => playSamples([zzfxG(...zzfxSound)]);
|
|
254
|
+
|
|
255
|
+
/** Sample rate used for all ZzFX sounds
|
|
256
|
+
* @default 44100
|
|
257
|
+
* @memberof Audio */
|
|
258
|
+
const zzfxR = 44100;
|
|
150
259
|
|
|
151
|
-
|
|
260
|
+
/** Generate samples for a ZzFX sound
|
|
261
|
+
* @memberof Audio */
|
|
262
|
+
function zzfxG
|
|
152
263
|
(
|
|
153
264
|
// parameters
|
|
154
265
|
volume = 1, randomness = .05, frequency = 220, attack = 0, sustain = 0,
|
|
@@ -192,7 +303,7 @@ function zzfxG // generate samples
|
|
|
192
303
|
1 - tremolo + tremolo*Math.sin(PI2*i/repeatTime) // tremolo
|
|
193
304
|
: 1) *
|
|
194
305
|
sign(s)*(abs(s)**shapeCurve) * // curve 0=square, 2=pointy
|
|
195
|
-
volume *
|
|
306
|
+
volume * soundVolume * ( // envelope
|
|
196
307
|
i < attack ? i/attack : // attack
|
|
197
308
|
i < attack + decay ? // decay
|
|
198
309
|
1-((i-attack)/decay)*(1-sustainVolume) : // decay falloff
|
|
@@ -233,6 +344,13 @@ function zzfxG // generate samples
|
|
|
233
344
|
///////////////////////////////////////////////////////////////////////////////
|
|
234
345
|
// ZzFX Music Renderer v2.0.3 by Keith Clark and Frank Force
|
|
235
346
|
|
|
347
|
+
/** Generate samples for a ZzFM song with given parameters
|
|
348
|
+
* @param {Array} instruments - Array of ZzFX sound paramaters
|
|
349
|
+
* @param {Array} patterns - Array of pattern data
|
|
350
|
+
* @param {Array} sequence - Array of pattern indexes
|
|
351
|
+
* @param {Number} [BPM=125] - Playback speed of the song in BPM
|
|
352
|
+
* @returns {Array} - Left and right channel sample data
|
|
353
|
+
* @memberof Audio */
|
|
236
354
|
function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
237
355
|
{
|
|
238
356
|
let instrumentParameters;
|
|
@@ -11,11 +11,9 @@ del %OUTPUT_FILENAME%
|
|
|
11
11
|
rem combine code
|
|
12
12
|
type engineDebug.js >> %OUTPUT_FILENAME%
|
|
13
13
|
echo.>> %OUTPUT_FILENAME%
|
|
14
|
-
type
|
|
14
|
+
type engineUtilities.js >> %OUTPUT_FILENAME%
|
|
15
15
|
echo.>> %OUTPUT_FILENAME%
|
|
16
|
-
type
|
|
17
|
-
echo.>> %OUTPUT_FILENAME%
|
|
18
|
-
type engine.js >> %OUTPUT_FILENAME%
|
|
16
|
+
type engineSettings.js >> %OUTPUT_FILENAME%
|
|
19
17
|
echo.>> %OUTPUT_FILENAME%
|
|
20
18
|
type engineObject.js >> %OUTPUT_FILENAME%
|
|
21
19
|
echo.>> %OUTPUT_FILENAME%
|
|
@@ -27,12 +25,14 @@ type engineAudio.js >> %OUTPUT_FILENAME%
|
|
|
27
25
|
echo.>> %OUTPUT_FILENAME%
|
|
28
26
|
type engineTileLayer.js >> %OUTPUT_FILENAME%
|
|
29
27
|
echo.>> %OUTPUT_FILENAME%
|
|
30
|
-
type
|
|
28
|
+
type engineParticles.js >> %OUTPUT_FILENAME%
|
|
31
29
|
echo.>> %OUTPUT_FILENAME%
|
|
32
|
-
type
|
|
30
|
+
type engineMedals.js >> %OUTPUT_FILENAME%
|
|
33
31
|
echo.>> %OUTPUT_FILENAME%
|
|
34
32
|
type engineWebGL.js >> %OUTPUT_FILENAME%
|
|
35
33
|
echo.>> %OUTPUT_FILENAME%
|
|
34
|
+
type engine.js >> %OUTPUT_FILENAME%
|
|
35
|
+
echo.>> %OUTPUT_FILENAME%
|
|
36
36
|
|
|
37
37
|
rem --- BUILD ENGINE RELEASE ---
|
|
38
38
|
|
|
@@ -44,9 +44,9 @@ del %OUTPUT_FILENAME%
|
|
|
44
44
|
rem combine code
|
|
45
45
|
type engineRelease.js >> %OUTPUT_FILENAME%
|
|
46
46
|
echo.>> %OUTPUT_FILENAME%
|
|
47
|
-
type
|
|
47
|
+
type engineUtilities.js >> %OUTPUT_FILENAME%
|
|
48
48
|
echo.>> %OUTPUT_FILENAME%
|
|
49
|
-
type
|
|
49
|
+
type engineSettings.js >> %OUTPUT_FILENAME%
|
|
50
50
|
echo.>> %OUTPUT_FILENAME%
|
|
51
51
|
type engine.js >> %OUTPUT_FILENAME%
|
|
52
52
|
echo.>> %OUTPUT_FILENAME%
|
|
@@ -60,9 +60,9 @@ type engineAudio.js >> %OUTPUT_FILENAME%
|
|
|
60
60
|
echo.>> %OUTPUT_FILENAME%
|
|
61
61
|
type engineTileLayer.js >> %OUTPUT_FILENAME%
|
|
62
62
|
echo.>> %OUTPUT_FILENAME%
|
|
63
|
-
type
|
|
63
|
+
type engineParticles.js >> %OUTPUT_FILENAME%
|
|
64
64
|
echo.>> %OUTPUT_FILENAME%
|
|
65
|
-
type
|
|
65
|
+
type engineMedals.js >> %OUTPUT_FILENAME%
|
|
66
66
|
echo.>> %OUTPUT_FILENAME%
|
|
67
67
|
type engineWebGL.js >> %OUTPUT_FILENAME%
|
|
68
68
|
echo.>> %OUTPUT_FILENAME%
|
|
File without changes
|