littlejsengine 1.19.3 → 1.20.0

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 (50) hide show
  1. package/FAQ.md +841 -820
  2. package/README.md +29 -25
  3. package/dist/littlejs.d.ts +2455 -935
  4. package/dist/littlejs.esm.js +30344 -21110
  5. package/dist/littlejs.esm.min.js +4 -3
  6. package/dist/littlejs.js +30259 -21052
  7. package/dist/littlejs.min.js +2 -2
  8. package/dist/littlejs.release.js +26567 -20455
  9. package/package.json +10 -5
  10. package/plugins/audioEffects.js +28 -24
  11. package/plugins/box2d.js +2516 -2073
  12. package/plugins/drawUtilities.js +206 -31
  13. package/plugins/gltf.js +740 -0
  14. package/plugins/jsconfig.json +19 -0
  15. package/plugins/lightSystem.js +719 -332
  16. package/plugins/math3d.js +58 -17
  17. package/plugins/medalSystem.js +326 -280
  18. package/plugins/newgrounds.js +400 -199
  19. package/plugins/pathFinder.js +208 -175
  20. package/plugins/pluginExport.js +15 -0
  21. package/plugins/postProcess.js +56 -13
  22. package/plugins/render3d.js +1643 -1577
  23. package/plugins/render3dDebug.js +109 -0
  24. package/plugins/render3dExtras.js +1754 -0
  25. package/plugins/render3dVoxels.js +502 -0
  26. package/plugins/textureSheet.js +496 -458
  27. package/plugins/threejs.js +183 -163
  28. package/plugins/tweakables.js +411 -0
  29. package/plugins/tweenSystem.js +263 -145
  30. package/plugins/uiSystem.js +2024 -1687
  31. package/plugins/zzfxm.js +159 -159
  32. package/src/engine.js +191 -75
  33. package/src/engineAudio.js +229 -125
  34. package/src/engineBuild.mjs +289 -256
  35. package/src/engineDebug.js +912 -742
  36. package/src/engineDraw.js +295 -193
  37. package/src/engineEditor.js +2431 -0
  38. package/src/engineExport.js +12 -0
  39. package/src/engineInput.js +1462 -1293
  40. package/src/engineMath.js +1274 -1252
  41. package/src/engineObject.js +194 -80
  42. package/src/engineParticles.js +583 -532
  43. package/src/engineRelease.js +67 -45
  44. package/src/engineSettings.js +77 -29
  45. package/src/engineTileLayer.js +995 -741
  46. package/src/engineUtilities.js +19 -13
  47. package/src/engineWebGL.js +239 -82
  48. package/src/jsconfig.json +17 -13
  49. package/plugins/box2d.wasm.js +0 -630
  50. package/plugins/box2d.wasm.wasm +0 -0
package/plugins/zzfxm.js CHANGED
@@ -1,160 +1,160 @@
1
- /**
2
- * LittleJS ZzFXM Plugin
3
- * @namespace ZzFXM
4
- */
5
-
6
- 'use strict';
7
-
8
- /**
9
- * Music Object - Stores a zzfx music track for later use
10
- *
11
- * <a href=https://keithclark.github.io/ZzFXM/>Create music with the ZzFXM tracker.</a>
12
- * @extends Sound
13
- * @memberof ZzFXM
14
- * @example
15
- * // create some music
16
- * const music_example = new ZzFXMusic(
17
- * [
18
- * [ // instruments
19
- * [,0,400] // simple note
20
- * ],
21
- * [ // patterns
22
- * [ // pattern 1
23
- * [ // channel 0
24
- * 0, -1, // instrument 0, left speaker
25
- * 1, 0, 9, 1 // channel notes
26
- * ],
27
- * [ // channel 1
28
- * 0, 1, // instrument 0, right speaker
29
- * 0, 12, 17, -1 // channel notes
30
- * ]
31
- * ],
32
- * ],
33
- * [0, 0, 0, 0], // sequence, play pattern 0 four times
34
- * 90 // BPM
35
- * ]);
36
- *
37
- * // play the music on a loop
38
- * music_example.playMusic();
39
- */
40
- class ZzFXMusic extends Sound
41
- {
42
- /** Create a music object and cache the zzfx music samples for later use
43
- * @param {[Array, Array, Array, number]} zzfxMusic - Array of zzfx music parameters
44
- */
45
- constructor(zzfxMusic)
46
- {
47
- super(undefined);
48
-
49
- if (!soundEnable || headlessMode) return;
50
- this.randomness = 0;
51
- super.sampleChannels = zzfxM(...zzfxMusic); // the setter, without declaring a field that hides it in the typings
52
- this.loadedPercent = 1; // generated in place, so it is loaded like a zzfx sound
53
- this.onloadCallback?.(this);
54
- }
55
- }
56
-
57
- ///////////////////////////////////////////////////////////////////////////////
58
- // ZzFX Music Renderer v2.0.3 by Keith Clark and Frank Force
59
-
60
- /** Generate samples for a ZzFM song with given parameters
61
- * @param {Array} instruments - Array of ZzFX sound parameters
62
- * @param {Array} patterns - Array of pattern data
63
- * @param {Array} sequence - Array of pattern indexes
64
- * @param {number} [BPM] - Playback speed of the song in BPM
65
- * @return {Array} - Left and right channel sample data
66
- * @memberof ZzFXM */
67
- function zzfxM(instruments, patterns, sequence, BPM = 125)
68
- {
69
- let i, j, k;
70
- let instrumentParameters;
71
- let note;
72
- let sample;
73
- let patternChannel;
74
- let notFirstBeat;
75
- let stop;
76
- let instrument;
77
- let attenuation;
78
- let outSampleOffset;
79
- let isSequenceEnd;
80
- let sampleOffset = 0;
81
- let nextSampleOffset;
82
- let sampleBuffer = [];
83
- let leftChannelBuffer = [];
84
- let rightChannelBuffer = [];
85
- let channelIndex = 0;
86
- let panning = 0;
87
- let hasMore = 1;
88
- let sampleCache = {};
89
- let beatLength = audioDefaultSampleRate / BPM * 60 >> 2;
90
-
91
- // for each channel in order until there are no more
92
- for (; hasMore; channelIndex++) {
93
-
94
- // reset current values
95
- sampleBuffer = [hasMore = notFirstBeat = outSampleOffset = 0];
96
-
97
- // for each pattern in sequence
98
- sequence.forEach((patternIndex, sequenceIndex)=> {
99
- // get pattern for current channel, use empty 1 note pattern if none found
100
- patternChannel = patterns[patternIndex][channelIndex] || [0, 0, 0];
101
-
102
- // check if there are more channels
103
- hasMore |= patterns[patternIndex][channelIndex]&&1;
104
-
105
- // get next offset, use the length of first channel
106
- nextSampleOffset = outSampleOffset + (patterns[patternIndex][0].length - 2 - (notFirstBeat?0:1)) * beatLength;
107
- // for each beat in pattern, plus one extra if end of sequence
108
- isSequenceEnd = sequenceIndex === sequence.length - 1;
109
- for (i = 2, k = outSampleOffset; i < patternChannel.length + isSequenceEnd; notFirstBeat = ++i) {
110
-
111
- // <channel-note>
112
- note = patternChannel[i];
113
-
114
- // stop if end, different instrument or new note
115
- stop = i === patternChannel.length + isSequenceEnd - 1 && isSequenceEnd ||
116
- instrument !== (patternChannel[0] || 0) || note | 0;
117
-
118
- // fill buffer with samples for previous beat, most cpu intensive part
119
- for (j = 0; j < beatLength && notFirstBeat;
120
-
121
- // fade off attenuation at end of beat if stopping note, prevents clicking
122
- j++ > beatLength - 99 && stop && attenuation < 1? attenuation += 1 / 99 : 0
123
- ) {
124
- // copy sample to stereo buffers with panning
125
- sample = (1 - attenuation) * sampleBuffer[sampleOffset++] / 2 || 0;
126
- leftChannelBuffer[k] = (leftChannelBuffer[k] || 0) - sample * panning + sample;
127
- rightChannelBuffer[k] = (rightChannelBuffer[k++] || 0) + sample * panning + sample;
128
- }
129
-
130
- // set up for next note
131
- if (note) {
132
- // set attenuation
133
- attenuation = note % 1;
134
- panning = patternChannel[1] || 0;
135
- if (note |= 0) {
136
- // get cached sample
137
- sampleBuffer = sampleCache[
138
- [
139
- instrument = patternChannel[sampleOffset = 0] || 0,
140
- note
141
- ]
142
- ] = sampleCache[[instrument, note]] || (
143
- // add sample to cache
144
- instrumentParameters = [...instruments[instrument]],
145
- instrumentParameters[2] = (instrumentParameters[2] || 220) * 2**(note / 12 - 1),
146
-
147
- // allow negative values to stop notes
148
- note > 0 ? zzfxG(...instrumentParameters) : []
149
- );
150
- }
151
- }
152
- }
153
-
154
- // update the sample offset
155
- outSampleOffset = nextSampleOffset;
156
- });
157
- }
158
-
159
- return [leftChannelBuffer, rightChannelBuffer];
1
+ /**
2
+ * LittleJS ZzFXM Plugin
3
+ * @namespace ZzFXM
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ /**
9
+ * Music Object - Stores a zzfx music track for later use
10
+ *
11
+ * <a href=https://keithclark.github.io/ZzFXM/>Create music with the ZzFXM tracker.</a>
12
+ * @extends Sound
13
+ * @memberof ZzFXM
14
+ * @example
15
+ * // create some music
16
+ * const music_example = new ZzFXMusic(
17
+ * [
18
+ * [ // instruments
19
+ * [,0,400] // simple note
20
+ * ],
21
+ * [ // patterns
22
+ * [ // pattern 1
23
+ * [ // channel 0
24
+ * 0, -1, // instrument 0, left speaker
25
+ * 1, 0, 9, 1 // channel notes
26
+ * ],
27
+ * [ // channel 1
28
+ * 0, 1, // instrument 0, right speaker
29
+ * 0, 12, 17, -1 // channel notes
30
+ * ]
31
+ * ],
32
+ * ],
33
+ * [0, 0, 0, 0], // sequence, play pattern 0 four times
34
+ * 90 // BPM
35
+ * ]);
36
+ *
37
+ * // play the music on a loop
38
+ * music_example.playMusic();
39
+ */
40
+ class ZzFXMusic extends Sound
41
+ {
42
+ /** Create a music object and cache the zzfx music samples for later use
43
+ * @param {[Array, Array, Array, number?, ...any[]]} zzfxMusic - Array of zzfx music parameters: instruments, patterns, sequence, and an optional BPM; anything after it, like the tracker's metadata, is ignored
44
+ */
45
+ constructor(zzfxMusic)
46
+ {
47
+ super(undefined);
48
+
49
+ if (!soundEnable || headlessMode) return;
50
+ const [instruments, patterns, sequence, BPM] = zzfxMusic;
51
+ super.sampleChannels = zzfxM(instruments, patterns, sequence, BPM); // the setter, without declaring a field that hides it in the typings
52
+ this.buildSampleBuffer(); // hand the samples to an audio buffer now, like a zzfx sound, so the arrays are released
53
+ this.loadedPercent = 1; // generated in place, so it is loaded like a zzfx sound
54
+ }
55
+ }
56
+
57
+ ///////////////////////////////////////////////////////////////////////////////
58
+ // ZzFX Music Renderer v2.0.3 by Keith Clark and Frank Force
59
+
60
+ /** Generate samples for a ZzFM song with given parameters
61
+ * @param {Array} instruments - Array of ZzFX sound parameters
62
+ * @param {Array} patterns - Array of pattern data
63
+ * @param {Array} sequence - Array of pattern indexes
64
+ * @param {number} [BPM] - Playback speed of the song in BPM
65
+ * @return {Array} - Left and right channel sample data
66
+ * @memberof ZzFXM */
67
+ function zzfxM(instruments, patterns, sequence, BPM = 125)
68
+ {
69
+ let i, j, k;
70
+ let instrumentParameters;
71
+ let note;
72
+ let sample;
73
+ let patternChannel;
74
+ let notFirstBeat;
75
+ let stop;
76
+ let instrument;
77
+ let attenuation;
78
+ let outSampleOffset;
79
+ let isSequenceEnd;
80
+ let sampleOffset = 0;
81
+ let nextSampleOffset;
82
+ let sampleBuffer = [];
83
+ let leftChannelBuffer = [];
84
+ let rightChannelBuffer = [];
85
+ let channelIndex = 0;
86
+ let panning = 0;
87
+ let hasMore = 1;
88
+ let sampleCache = {};
89
+ let beatLength = audioDefaultSampleRate / BPM * 60 >> 2;
90
+
91
+ // for each channel in order until there are no more
92
+ for (; hasMore; channelIndex++) {
93
+
94
+ // reset current values
95
+ sampleBuffer = [hasMore = notFirstBeat = outSampleOffset = 0];
96
+
97
+ // for each pattern in sequence
98
+ sequence.forEach((patternIndex, sequenceIndex)=> {
99
+ // get pattern for current channel, use empty 1 note pattern if none found
100
+ patternChannel = patterns[patternIndex][channelIndex] || [0, 0, 0];
101
+
102
+ // check if there are more channels
103
+ hasMore |= patterns[patternIndex][channelIndex]&&1;
104
+
105
+ // get next offset, use the length of first channel
106
+ nextSampleOffset = outSampleOffset + (patterns[patternIndex][0].length - 2 - (notFirstBeat?0:1)) * beatLength;
107
+ // for each beat in pattern, plus one extra if end of sequence
108
+ isSequenceEnd = sequenceIndex === sequence.length - 1;
109
+ for (i = 2, k = outSampleOffset; i < patternChannel.length + isSequenceEnd; notFirstBeat = ++i) {
110
+
111
+ // <channel-note>
112
+ note = patternChannel[i];
113
+
114
+ // stop if end, different instrument or new note
115
+ stop = i === patternChannel.length + isSequenceEnd - 1 && isSequenceEnd ||
116
+ instrument !== (patternChannel[0] || 0) || note | 0;
117
+
118
+ // fill buffer with samples for previous beat, most cpu intensive part
119
+ for (j = 0; j < beatLength && notFirstBeat;
120
+
121
+ // fade off attenuation at end of beat if stopping note, prevents clicking
122
+ j++ > beatLength - 99 && stop && attenuation < 1? attenuation += 1 / 99 : 0
123
+ ) {
124
+ // copy sample to stereo buffers with panning
125
+ sample = (1 - attenuation) * sampleBuffer[sampleOffset++] / 2 || 0;
126
+ leftChannelBuffer[k] = (leftChannelBuffer[k] || 0) - sample * panning + sample;
127
+ rightChannelBuffer[k] = (rightChannelBuffer[k++] || 0) + sample * panning + sample;
128
+ }
129
+
130
+ // set up for next note
131
+ if (note) {
132
+ // set attenuation
133
+ attenuation = note % 1;
134
+ panning = patternChannel[1] || 0;
135
+ if (note |= 0) {
136
+ // get cached sample
137
+ sampleBuffer = sampleCache[
138
+ [
139
+ instrument = patternChannel[sampleOffset = 0] || 0,
140
+ note
141
+ ]
142
+ ] = sampleCache[[instrument, note]] || (
143
+ // add sample to cache
144
+ instrumentParameters = [...instruments[instrument]],
145
+ instrumentParameters[2] = (instrumentParameters[2] || 220) * 2**(note / 12 - 1),
146
+
147
+ // allow negative values to stop notes
148
+ note > 0 ? zzfxG(...instrumentParameters) : []
149
+ );
150
+ }
151
+ }
152
+ }
153
+
154
+ // update the sample offset
155
+ outSampleOffset = nextSampleOffset;
156
+ });
157
+ }
158
+
159
+ return [leftChannelBuffer, rightChannelBuffer];
160
160
  }