littlejsengine 1.18.28 → 1.19.3
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/FAQ.md +5 -0
- package/README.md +207 -199
- package/dist/littlejs.d.ts +2099 -48
- package/dist/littlejs.esm.js +16251 -10315
- package/dist/littlejs.esm.min.js +13 -1
- package/dist/littlejs.js +15747 -9888
- package/dist/littlejs.min.js +13 -1
- package/dist/littlejs.release.js +15719 -9867
- package/package.json +1 -1
- package/plugins/audioEffects.js +371 -0
- package/plugins/lightSystem.js +5 -3
- package/plugins/math3d.js +870 -0
- package/plugins/medalSystem.js +280 -280
- package/plugins/pluginExport.js +181 -115
- package/plugins/postProcess.js +241 -166
- package/plugins/render3d.js +4006 -0
- package/plugins/textureSheet.js +458 -458
- package/plugins/threejs.js +6 -1
- package/plugins/tweenSystem.js +528 -526
- package/plugins/zzfxm.js +159 -166
- package/src/engine.js +172 -137
- package/src/engineAudio.js +918 -775
- package/src/engineBuild.mjs +3 -0
- package/src/engineDebug.js +15 -8
- package/src/engineDraw.js +1672 -1510
- package/src/engineExport.js +407 -396
- package/src/engineInput.js +1 -1
- package/src/engineLogo.js +4 -3
- package/src/engineMath.js +69 -0
- package/src/engineObject.js +560 -551
- package/src/engineSettings.js +759 -725
- package/src/engineTileLayer.js +3 -3
- package/src/engineUtilities.js +13 -0
- package/src/engineWebGL.js +1005 -941
package/plugins/zzfxm.js
CHANGED
|
@@ -1,167 +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
|
|
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
|
|
38
|
-
* music_example.
|
|
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
|
-
|
|
52
|
-
this.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
let
|
|
77
|
-
let
|
|
78
|
-
let
|
|
79
|
-
let
|
|
80
|
-
let
|
|
81
|
-
let
|
|
82
|
-
let
|
|
83
|
-
let
|
|
84
|
-
let
|
|
85
|
-
let
|
|
86
|
-
let
|
|
87
|
-
let
|
|
88
|
-
let
|
|
89
|
-
let
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
// update the sample offset
|
|
162
|
-
outSampleOffset = nextSampleOffset;
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
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]} 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];
|
|
167
160
|
}
|