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.
Files changed (99) hide show
  1. package/build.bat +5 -1
  2. package/docs/Audio.html +2268 -0
  3. package/docs/Color.html +2989 -0
  4. package/docs/Debug.html +2933 -0
  5. package/docs/Draw.html +4092 -0
  6. package/docs/EngineObject.html +4458 -0
  7. package/docs/Input.html +2482 -0
  8. package/docs/Medal.html +1007 -0
  9. package/docs/Medals.html +628 -0
  10. package/docs/Music.html +584 -0
  11. package/docs/Newgrounds.html +1399 -0
  12. package/docs/Particle.html +4535 -0
  13. package/docs/ParticleEmitter.html +7770 -0
  14. package/docs/Random.html +1774 -0
  15. package/docs/Settings.html +2679 -0
  16. package/docs/Sound.html +1249 -0
  17. package/docs/TileCollision.html +1409 -0
  18. package/docs/TileLayer.html +6948 -0
  19. package/docs/TileLayerData.html +1052 -0
  20. package/docs/Timer.html +1183 -0
  21. package/docs/Utilities.html +3281 -0
  22. package/docs/Vector2.html +4207 -0
  23. package/docs/WebGL.html +2327 -0
  24. package/docs/engine.js.html +429 -0
  25. package/docs/engineAudio.js.html +609 -0
  26. package/docs/engineDebug.js.html +725 -0
  27. package/docs/engineDraw.js.html +419 -0
  28. package/docs/engineInput.js.html +401 -0
  29. package/docs/engineMedals.js.html +461 -0
  30. package/docs/engineObject.js.html +518 -0
  31. package/docs/engineParticles.js.html +441 -0
  32. package/docs/engineSettings.js.html +349 -0
  33. package/docs/engineTileLayer.js.html +513 -0
  34. package/docs/engineUtilities.js.html +647 -0
  35. package/docs/engineWebGL.js.html +522 -0
  36. package/docs/fonts/MavenPro-Regular.ttf +0 -0
  37. package/docs/fonts/Montserrat-Regular.ttf +0 -0
  38. package/docs/fonts/Muli-Black.ttf +0 -0
  39. package/docs/fonts/OFL-hind.txt +93 -0
  40. package/docs/fonts/OFL-montserrat.txt +93 -0
  41. package/docs/global.html +1691 -0
  42. package/docs/index.css +6 -0
  43. package/docs/index.html +247 -0
  44. package/docs/scripts/fix-code-block.js +53 -0
  45. package/docs/scripts/fix-navbar.js +25 -0
  46. package/docs/scripts/linenumber.js +25 -0
  47. package/docs/scripts/misc.js +217 -0
  48. package/docs/scripts/resize.js +85 -0
  49. package/docs/scripts/search.js +83 -0
  50. package/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
  51. package/docs/scripts/third-party/fuse.js +9 -0
  52. package/docs/scripts/third-party/lang-css.js +2 -0
  53. package/docs/scripts/third-party/prettify.js +28 -0
  54. package/docs/static/favicon.png +0 -0
  55. package/docs/static/index.css +4 -0
  56. package/docs/styles/clean-jsdoc-theme-base.css +393 -0
  57. package/docs/styles/clean-jsdoc-theme-dark.css +324 -0
  58. package/docs/styles/clean-jsdoc-theme-light.css +319 -0
  59. package/docs/styles/reset.css +346 -0
  60. package/docs/styles/third-party/ionicons.min.css +11 -0
  61. package/docs/styles/third-party/prettify-jsdoc.css +111 -0
  62. package/docs/styles/third-party/prettify-tomorrow.css +5 -0
  63. package/engine/engine.all.js +1997 -744
  64. package/engine/engine.all.min.js +1 -1
  65. package/engine/engine.all.release.js +1743 -569
  66. package/engine/engine.js +107 -39
  67. package/engine/engineAudio.js +152 -34
  68. package/engine/{build.bat → engineBuild.bat} +10 -10
  69. package/engine/{buildSetup.bat → engineBuildSetup.bat} +0 -0
  70. package/engine/engineDebug.js +105 -32
  71. package/engine/engineDraw.js +137 -32
  72. package/engine/engineInput.js +111 -37
  73. package/engine/{engineMedal.js → engineMedals.js} +129 -56
  74. package/engine/engineObject.js +117 -67
  75. package/engine/engineParticles.js +282 -0
  76. package/engine/engineRelease.js +3 -9
  77. package/engine/engineSettings.js +190 -0
  78. package/engine/engineTileLayer.js +147 -44
  79. package/engine/engineUtilities.js +488 -0
  80. package/engine/engineWebGL.js +113 -74
  81. package/examples/breakout/game.js +1 -1
  82. package/examples/breakout/gameObjects.js +3 -3
  83. package/examples/breakout/index.html +3 -3
  84. package/examples/platformer/game.js +5 -7
  85. package/examples/platformer/gameEffects.js +7 -7
  86. package/examples/platformer/gameLevel.js +2 -2
  87. package/examples/platformer/gameObjects.js +4 -5
  88. package/examples/platformer/gamePlayer.js +3 -3
  89. package/examples/platformer/index.html +6 -6
  90. package/examples/puzzle/game.js +1 -2
  91. package/examples/puzzle/index.html +2 -2
  92. package/examples/stress/index.html +2 -8
  93. package/game.js +5 -11
  94. package/index.html +13 -13
  95. package/package.json +4 -4
  96. package/tiles.png +0 -0
  97. package/engine/engineConfig.js +0 -64
  98. package/engine/engineParticle.js +0 -199
  99. 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 2019 Frank Force
2
+ LittleJS - The Tiny JavaScript Game Engine That Can!
3
+ MIT License - Copyright 2021 Frank Force
4
4
 
5
5
  Engine Features
6
- - Engine and debug system are separate from game code
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
- - Automatically calls gameInit(), gameUpdate(), gameUpdatePost(), gameRender(), gameRenderPost()
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
- const engineVersion = '1.0.14';
25
- const FPS = 60, timeDelta = 1/FPS; // engine uses a fixed time step
26
- const tileImage = new Image(); // everything uses the same tile sheet
27
-
28
- // core engine variables
29
- let mainCanvas, mainContext, overlayCanvas, overlayContext, mainCanvasSize=vec2(),
30
- engineObjects=[], engineCollideObjects=[],
31
- cameraPos=vec2(), cameraScale=max(defaultTileSize.x, defaultTileSize.y),
32
- frame=0, time=0, realTime=0, paused=0, frameTimeLastMS=0, frameTimeBufferMS=0, debugFPS=0, gravity=0,
33
- tileImageSize, tileImageSizeInverse, shrinkTilesX, shrinkTilesY, drawCount;
34
-
35
- // call this function to start the engine
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
- realTime += frameTimeDeltaMS / 1e3;
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
- engineUpdateObjects();
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 (fixedWidth)
150
+ if (fixedSize.x)
120
151
  {
121
152
  // clear set fixed size
122
- mainCanvas.width = fixedWidth;
123
- mainCanvas.height = fixedHeight;
153
+ mainCanvas.width = fixedSize.x;
154
+ mainCanvas.height = fixedSize.y;
124
155
 
125
- if (fixedFitToWindow)
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
- // fit to window by adding space on top or bottom if necessary
128
- const aspect = innerWidth / innerHeight;
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, maxWidth);
143
- mainCanvas.height = min(innerHeight, maxHeight);
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
- function engineUpdateObjects()
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
  }
@@ -1,24 +1,42 @@
1
- /*
2
- LittleJS Audio System
3
- - ZzFX Sound Effects and ZzFXM Music
4
- - Caches sounds and music for fast playback
5
- - Can attenuate and apply stereo panning to sounds
6
- - Ability to play mp3, ogg, and wave files
7
- - Speech Synthesis wrapper functions
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
- constructor(zzfxSound, range=defaultSoundRange, taper=defaultSoundTaper)
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 to apply when played
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
- play(pos, volumeScale=1, pitchScale=1)
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
- volumeScale *= percent(lengthSquared**.5, range*this.taper, range);
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 = pitchScale + pitchScale * this.randomness*rand(-1,1);
54
- return playSamples([this.cachedSamples], volumeScale, playbackRate, pan);
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
- play(volumeScale = 1, loop = 1)
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, volumeScale, 1, 0, loop);
145
+ return playSamples(this.cachedSamples, volume, 1, 0, loop);
72
146
  }
73
147
  }
74
148
 
75
- ///////////////////////////////////////////////////////////////////////////////
76
-
77
- // play mp3 or wav audio from a local file or url
78
- function playAudioFile(url, volumeScale=1, loop=1)
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 = audioVolume * volumeScale;
160
+ audio.volume = soundVolume * volume;
84
161
  audio.loop = loop;
85
162
  audio.play();
86
163
  return audio;
87
164
  }
88
165
 
89
- // speak text with passed in settings
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*audioVolume*3;
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
- // stop all queued speech
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
- let audioContext; // audio context used by the engine
203
+ ///////////////////////////////////////////////////////////////////////////////
114
204
 
115
- // play cached samples with given settings
116
- function playSamples(sampleChannels, volume=1, playbackRate=1, pan=0, loop=0)
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 = playbackRate;
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':audioVolume*volume}))
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
- const zzfxR = 44100; // sample rate
149
- const zzfx = (...z) => playSamples([zzfxG(...z)]); // generate and play sound
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
- function zzfxG // generate samples
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 * audioVolume * ( // envelope
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 engineUtil.js >> %OUTPUT_FILENAME%
14
+ type engineUtilities.js >> %OUTPUT_FILENAME%
15
15
  echo.>> %OUTPUT_FILENAME%
16
- type engineConfig.js >> %OUTPUT_FILENAME%
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 engineParticle.js >> %OUTPUT_FILENAME%
28
+ type engineParticles.js >> %OUTPUT_FILENAME%
31
29
  echo.>> %OUTPUT_FILENAME%
32
- type engineMedal.js >> %OUTPUT_FILENAME%
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 engineUtil.js >> %OUTPUT_FILENAME%
47
+ type engineUtilities.js >> %OUTPUT_FILENAME%
48
48
  echo.>> %OUTPUT_FILENAME%
49
- type engineConfig.js >> %OUTPUT_FILENAME%
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 engineParticle.js >> %OUTPUT_FILENAME%
63
+ type engineParticles.js >> %OUTPUT_FILENAME%
64
64
  echo.>> %OUTPUT_FILENAME%
65
- type engineMedal.js >> %OUTPUT_FILENAME%
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