littlejsengine 1.11.13 → 1.12.4
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 +1418 -109
- package/dist/littlejs.esm.js +3495 -581
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +3258 -399
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +3147 -379
- package/examples/box2d/game.js +73 -45
- package/examples/box2d/gameObjects.js +96 -92
- package/examples/box2d/index.html +2 -7
- package/examples/box2d/scenes.js +82 -92
- package/examples/breakout/game.js +62 -30
- package/examples/breakout/gameObjects.js +45 -47
- package/examples/breakout/index.html +1 -5
- package/examples/breakoutTutorial/game.js +36 -29
- package/examples/breakoutTutorial/index.html +1 -3
- package/examples/empty/game.js +5 -2
- package/examples/empty/index.html +1 -3
- package/examples/htmlMenu/game.js +25 -19
- package/examples/htmlMenu/index.html +5 -7
- package/examples/index.html +2 -3
- package/examples/module/game.js +32 -34
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +27 -22
- package/examples/platformer/game.js +71 -48
- package/examples/platformer/gameCharacter.js +42 -34
- package/examples/platformer/gameEffects.js +82 -75
- package/examples/platformer/gameLevel.js +67 -38
- package/examples/platformer/{gameLevelData.js → gameLevelData.json} +1 -11
- package/examples/platformer/gameObjects.js +70 -64
- package/examples/platformer/gamePlayer.js +12 -7
- package/examples/platformer/index.html +1 -9
- package/examples/puzzle/game.js +58 -42
- package/examples/puzzle/index.html +1 -3
- package/examples/shorts/base.html +2 -2
- package/examples/shorts/particles.js +1 -1
- package/examples/shorts/platformer.js +1 -1
- package/examples/shorts/tileLayer.js +5 -6
- package/examples/shorts/tiles.png +0 -0
- package/examples/starter/build.js +4 -4
- package/examples/starter/game.js +9 -12
- package/examples/starter/index.html +13 -13
- package/examples/stress/index.html +44 -43
- package/examples/typescript/build.js +17 -18
- package/examples/typescript/game.js +32 -34
- package/examples/typescript/game.ts +32 -34
- package/examples/typescript/index.html +1 -1
- package/examples/uiSystem/game.js +33 -36
- package/examples/uiSystem/index.html +1 -5
- package/package.json +3 -3
- package/plugins/box2d.js +1556 -640
- package/plugins/{Box2D_v2.3.1_min.wasm.js → box2d.wasm.js} +1 -1
- package/plugins/newgrounds.js +7 -8
- package/plugins/pluginExport.js +50 -0
- package/plugins/postProcess.js +94 -93
- package/plugins/uiSystem.js +145 -161
- package/plugins/zzfxm.js +163 -0
- package/reference.md +29 -27
- package/src/engine.js +15 -20
- package/src/engineAudio.js +74 -204
- package/src/engineBuild.js +29 -4
- package/src/engineDebug.js +105 -9
- package/src/engineDraw.js +27 -14
- package/src/engineExport.js +12 -8
- package/src/engineInput.js +3 -1
- package/src/engineObject.js +18 -14
- package/src/engineParticles.js +6 -1
- package/src/engineRelease.js +6 -1
- package/src/engineSettings.js +8 -8
- package/src/engineTileLayer.js +179 -96
- package/src/engineUtilities.js +5 -11
- package/src/engineWebGL.js +19 -7
- package/examples/starter/build/index.html +0 -2
- package/examples/starter/build/index.js +0 -1
- package/examples/starter/build/tiles.png +0 -0
- package/examples/starter/game.zip +0 -0
- package/examples/typescript/build/dist/littlejs.esm.js +0 -4834
- package/examples/typescript/build/examples/typescript/build.js +0 -24
- package/examples/typescript/build/examples/typescript/game.js +0 -102
- /package/plugins/{Box2D_v2.3.1_min.wasm.wasm → box2d.wasm.wasm} +0 -0
package/plugins/uiSystem.js
CHANGED
|
@@ -1,166 +1,150 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LittleJS User Interface Plugin
|
|
3
|
+
* - call new UISystemPlugin() to setup the UI system
|
|
3
4
|
* - Nested Menus
|
|
4
5
|
* - Text
|
|
5
6
|
* - Buttons
|
|
6
7
|
* - Checkboxes
|
|
7
8
|
* - Images
|
|
8
|
-
* @namespace UISystemPlugin
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
///////////////////////////////////////////////////////////////////////////////
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
* @type {Color}
|
|
19
|
-
* @memberof UISystemPlugin */
|
|
20
|
-
let uiDefaultColor = WHITE;
|
|
21
|
-
|
|
22
|
-
/** Default outline color for UI elements
|
|
23
|
-
* @type {Color}
|
|
24
|
-
* @memberof UISystemPlugin */
|
|
25
|
-
let uiDefaultLineColor = BLACK;
|
|
26
|
-
|
|
27
|
-
/** Default text color for UI elements
|
|
28
|
-
* @type {Color}
|
|
29
|
-
* @memberof UISystemPlugin */
|
|
30
|
-
let uiDefaultTextColor = BLACK;
|
|
31
|
-
|
|
32
|
-
/** Default button color for UI elements
|
|
33
|
-
* @type {Color}
|
|
34
|
-
* @memberof UISystemPlugin */
|
|
35
|
-
let uiDefaultButtonColor = hsl(0,0,.5);
|
|
36
|
-
|
|
37
|
-
/** Default hover color for UI elements
|
|
38
|
-
* @type {Color}
|
|
39
|
-
* @memberof UISystemPlugin */
|
|
40
|
-
let uiDefaultHoverColor = hsl(0,0,.7);
|
|
41
|
-
|
|
42
|
-
/** Default line width for UI elements
|
|
43
|
-
* @type {number}
|
|
44
|
-
* @memberof UISystemPlugin */
|
|
45
|
-
let uiDefaultLineWidth = 4;
|
|
46
|
-
|
|
47
|
-
/** Default font for UI elements
|
|
48
|
-
* @type {string}
|
|
49
|
-
* @memberof UISystemPlugin */
|
|
50
|
-
let uiDefaultFont = 'arial';
|
|
51
|
-
|
|
52
|
-
/** List of all UI elements
|
|
53
|
-
* @type {Array<UIObject>}
|
|
54
|
-
* @memberof UISystemPlugin */
|
|
55
|
-
let uiObjects = [];
|
|
56
|
-
|
|
57
|
-
/** Context to render UI elements to
|
|
58
|
-
* @type {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D}
|
|
59
|
-
* @memberof UISystemPlugin */
|
|
60
|
-
let uiContext;
|
|
61
|
-
|
|
62
|
-
/** Set up the UI system, typically called in gameInit
|
|
63
|
-
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=overlayContext]
|
|
64
|
-
* @memberof UISystemPlugin */
|
|
65
|
-
function initUISystem(context=overlayContext)
|
|
66
|
-
{
|
|
67
|
-
uiContext = context;
|
|
68
|
-
engineAddPlugin(uiUpdate, uiRender);
|
|
15
|
+
/** Global UI system plugin object
|
|
16
|
+
* @type {UISystemPlugin} */
|
|
17
|
+
let uiSystem;
|
|
69
18
|
|
|
70
|
-
|
|
71
|
-
|
|
19
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
20
|
+
/**
|
|
21
|
+
* UI System Global Object
|
|
22
|
+
*/
|
|
23
|
+
class UISystemPlugin
|
|
24
|
+
{
|
|
25
|
+
/** Create the global UI system object
|
|
26
|
+
* @param {CanvasRenderingContext2D} [context]
|
|
27
|
+
* @example
|
|
28
|
+
* // create the ui plugin object
|
|
29
|
+
* new UISystemPlugin;
|
|
30
|
+
*/
|
|
31
|
+
constructor(context=overlayContext)
|
|
72
32
|
{
|
|
73
|
-
|
|
33
|
+
ASSERT(!uiSystem, 'UI system already initialized');
|
|
34
|
+
uiSystem = this;
|
|
35
|
+
|
|
36
|
+
/** @property {Color} - Default fill color for UI elements */
|
|
37
|
+
this.defaultColor = WHITE;
|
|
38
|
+
/** @property {Color} - Default outline color for UI elements */
|
|
39
|
+
this.defaultLineColor = BLACK;
|
|
40
|
+
/** @property {Color} - Default text color for UI elements */
|
|
41
|
+
this.defaultTextColor = BLACK;
|
|
42
|
+
/** @property {Color} - Default button color for UI elements */
|
|
43
|
+
this.defaultButtonColor = hsl(0,0,.5);
|
|
44
|
+
/** @property {Color} - Default hover color for UI elements */
|
|
45
|
+
this.defaultHoverColor = hsl(0,0,.7);
|
|
46
|
+
/** @property {number} - Default line width for UI elements */
|
|
47
|
+
this.defaultLineWidth = 4;
|
|
48
|
+
/** @property {string} - Default font for UI elements */
|
|
49
|
+
this.defaultFont = 'arial';
|
|
50
|
+
/** @property {Array<UIObject>} - List of all UI elements */
|
|
51
|
+
this.uiObjects = [];
|
|
52
|
+
/** @property {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} - Context to render UI elements to */
|
|
53
|
+
this.uiContext = context;
|
|
54
|
+
|
|
55
|
+
engineAddPlugin(uiUpdate, uiRender);
|
|
56
|
+
|
|
57
|
+
// setup recursive update and render
|
|
58
|
+
function uiUpdate()
|
|
74
59
|
{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
60
|
+
function updateObject(o)
|
|
61
|
+
{
|
|
62
|
+
if (!o.visible)
|
|
63
|
+
return;
|
|
64
|
+
if (o.parent)
|
|
65
|
+
o.pos = o.localPos.add(o.parent.pos);
|
|
66
|
+
o.update();
|
|
67
|
+
for(const c of o.children)
|
|
68
|
+
updateObject(c);
|
|
69
|
+
}
|
|
70
|
+
uiSystem.uiObjects.forEach(o=> o.parent || updateObject(o));
|
|
71
|
+
}
|
|
72
|
+
function uiRender()
|
|
73
|
+
{
|
|
74
|
+
function renderObject(o)
|
|
75
|
+
{
|
|
76
|
+
if (!o.visible)
|
|
77
|
+
return;
|
|
78
|
+
if (o.parent)
|
|
79
|
+
o.pos = o.localPos.add(o.parent.pos);
|
|
80
|
+
o.render();
|
|
81
|
+
for(const c of o.children)
|
|
82
|
+
renderObject(c);
|
|
83
|
+
}
|
|
84
|
+
uiSystem.uiObjects.forEach(o=> o.parent || renderObject(o));
|
|
82
85
|
}
|
|
83
|
-
uiObjects.forEach(o=> o.parent || updateObject(o));
|
|
84
86
|
}
|
|
85
|
-
|
|
87
|
+
|
|
88
|
+
/** Draw a rectangle to the UI context
|
|
89
|
+
* @param {Vector2} pos
|
|
90
|
+
* @param {Vector2} size
|
|
91
|
+
* @param {Color} [color=uiSystem.defaultColor]
|
|
92
|
+
* @param {number} [lineWidth=uiSystem.defaultLineWidth]
|
|
93
|
+
* @param {Color} [lineColor=uiSystem.defaultLineColor] */
|
|
94
|
+
drawRect(pos, size, color=uiSystem.defaultColor, lineWidth=uiSystem.defaultLineWidth, lineColor=uiSystem.defaultLineColor)
|
|
86
95
|
{
|
|
87
|
-
|
|
96
|
+
uiSystem.uiContext.fillStyle = color.toString();
|
|
97
|
+
uiSystem.uiContext.beginPath();
|
|
98
|
+
uiSystem.uiContext.rect(pos.x-size.x/2, pos.y-size.y/2, size.x, size.y);
|
|
99
|
+
uiSystem.uiContext.fill();
|
|
100
|
+
if (lineWidth)
|
|
88
101
|
{
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
o.pos = o.localPos.add(o.parent.pos);
|
|
93
|
-
o.render();
|
|
94
|
-
for(const c of o.children)
|
|
95
|
-
renderObject(c);
|
|
102
|
+
uiSystem.uiContext.strokeStyle = lineColor.toString();
|
|
103
|
+
uiSystem.uiContext.lineWidth = lineWidth;
|
|
104
|
+
uiSystem.uiContext.stroke();
|
|
96
105
|
}
|
|
97
|
-
uiObjects.forEach(o=> o.parent || renderObject(o));
|
|
98
106
|
}
|
|
99
|
-
}
|
|
100
107
|
|
|
101
|
-
/** Draw a
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
* @memberof UISystemPlugin */
|
|
108
|
-
function drawUIRect(pos, size, color=uiDefaultColor, lineWidth=uiDefaultLineWidth, lineColor=uiDefaultLineColor)
|
|
109
|
-
{
|
|
110
|
-
uiContext.fillStyle = color.toString();
|
|
111
|
-
uiContext.beginPath();
|
|
112
|
-
uiContext.rect(pos.x-size.x/2, pos.y-size.y/2, size.x, size.y);
|
|
113
|
-
uiContext.fill();
|
|
114
|
-
if (lineWidth)
|
|
108
|
+
/** Draw a line to the UI context
|
|
109
|
+
* @param {Vector2} posA
|
|
110
|
+
* @param {Vector2} posB
|
|
111
|
+
* @param {number} [lineWidth=uiSystem.defaultLineWidth]
|
|
112
|
+
* @param {Color} [lineColor=uiSystem.defaultLineColor] */
|
|
113
|
+
drawLine(posA, posB, lineWidth=uiSystem.defaultLineWidth, lineColor=uiSystem.defaultLineColor)
|
|
115
114
|
{
|
|
116
|
-
uiContext.strokeStyle = lineColor.toString();
|
|
117
|
-
uiContext.lineWidth = lineWidth;
|
|
118
|
-
uiContext.
|
|
115
|
+
uiSystem.uiContext.strokeStyle = lineColor.toString();
|
|
116
|
+
uiSystem.uiContext.lineWidth = lineWidth;
|
|
117
|
+
uiSystem.uiContext.beginPath();
|
|
118
|
+
uiSystem.uiContext.lineTo(posA.x, posA.y);
|
|
119
|
+
uiSystem.uiContext.lineTo(posB.x, posB.y);
|
|
120
|
+
uiSystem.uiContext.stroke();
|
|
119
121
|
}
|
|
120
|
-
}
|
|
121
122
|
|
|
122
|
-
/** Draw a
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
uiContext.lineTo(posA.x, posA.y);
|
|
134
|
-
uiContext.lineTo(posB.x, posB.y);
|
|
135
|
-
uiContext.stroke();
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/** Draw a tile to the UI context
|
|
139
|
-
* @param {Vector2} pos
|
|
140
|
-
* @param {Vector2} size
|
|
141
|
-
* @param {TileInfo} tileInfo
|
|
142
|
-
* @param {Color} [color=uiDefaultColor]
|
|
143
|
-
* @param {number} [angle]
|
|
144
|
-
* @param {boolean} [mirror]
|
|
145
|
-
* @memberof UISystemPlugin */
|
|
146
|
-
function drawUITile(pos, size, tileInfo, color=uiDefaultColor, angle=0, mirror=false)
|
|
147
|
-
{
|
|
148
|
-
drawTile(pos, size, tileInfo, color, angle, mirror, BLACK, false, true, uiContext);
|
|
149
|
-
}
|
|
123
|
+
/** Draw a tile to the UI context
|
|
124
|
+
* @param {Vector2} pos
|
|
125
|
+
* @param {Vector2} size
|
|
126
|
+
* @param {TileInfo} tileInfo
|
|
127
|
+
* @param {Color} [color=uiSystem.defaultColor]
|
|
128
|
+
* @param {number} [angle]
|
|
129
|
+
* @param {boolean} [mirror] */
|
|
130
|
+
drawTile(pos, size, tileInfo, color=uiSystem.defaultColor, angle=0, mirror=false)
|
|
131
|
+
{
|
|
132
|
+
drawTile(pos, size, tileInfo, color, angle, mirror, BLACK, false, true, uiSystem.uiContext);
|
|
133
|
+
}
|
|
150
134
|
|
|
151
|
-
/** Draw text to the UI context
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
135
|
+
/** Draw text to the UI context
|
|
136
|
+
* @param {string} text
|
|
137
|
+
* @param {Vector2} pos
|
|
138
|
+
* @param {Vector2} size
|
|
139
|
+
* @param {Color} [color=uiSystem.defaultColor]
|
|
140
|
+
* @param {number} [lineWidth=uiSystem.defaultLineWidth]
|
|
141
|
+
* @param {Color} [lineColor=uiSystem.defaultLineColor]
|
|
142
|
+
* @param {string} [align]
|
|
143
|
+
* @param {string} [font=uiSystem.defaultFont] */
|
|
144
|
+
drawText(text, pos, size, color=uiSystem.defaultColor, lineWidth=uiSystem.defaultLineWidth, lineColor=uiSystem.defaultLineColor, align='center', font=uiSystem.defaultFont)
|
|
145
|
+
{
|
|
146
|
+
drawTextScreen(text, pos, size.y, color, lineWidth, lineColor, align, font, size.x, uiSystem.uiContext);
|
|
147
|
+
}
|
|
164
148
|
}
|
|
165
149
|
|
|
166
150
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -182,24 +166,24 @@ class UIObject
|
|
|
182
166
|
/** @property {Vector2} - Screen space size of the object */
|
|
183
167
|
this.size = size.copy();
|
|
184
168
|
/** @property {Color} */
|
|
185
|
-
this.color =
|
|
169
|
+
this.color = uiSystem.defaultColor;
|
|
186
170
|
/** @property {Color} */
|
|
187
|
-
this.lineColor =
|
|
171
|
+
this.lineColor = uiSystem.defaultLineColor;
|
|
188
172
|
/** @property {Color} */
|
|
189
|
-
this.textColor =
|
|
173
|
+
this.textColor = uiSystem.defaultTextColor;
|
|
190
174
|
/** @property {Color} */
|
|
191
|
-
this.hoverColor =
|
|
175
|
+
this.hoverColor = uiSystem.defaultHoverColor;
|
|
192
176
|
/** @property {number} */
|
|
193
|
-
this.lineWidth =
|
|
177
|
+
this.lineWidth = uiSystem.defaultLineWidth;
|
|
194
178
|
/** @property {string} */
|
|
195
|
-
this.font =
|
|
179
|
+
this.font = uiSystem.defaultFont;
|
|
196
180
|
/** @property {boolean} */
|
|
197
181
|
this.visible = true;
|
|
198
182
|
/** @property {Array<UIObject>} */
|
|
199
183
|
this.children = [];
|
|
200
184
|
/** @property {UIObject} */
|
|
201
185
|
this.parent = undefined;
|
|
202
|
-
uiObjects.push(this);
|
|
186
|
+
uiSystem.uiObjects.push(this);
|
|
203
187
|
}
|
|
204
188
|
|
|
205
189
|
/** Add a child UIObject to this object
|
|
@@ -256,7 +240,7 @@ class UIObject
|
|
|
256
240
|
render()
|
|
257
241
|
{
|
|
258
242
|
if (this.size.x && this.size.y)
|
|
259
|
-
|
|
243
|
+
uiSystem.drawRect(this.pos, this.size, this.color, this.lineWidth, this.lineColor);
|
|
260
244
|
}
|
|
261
245
|
|
|
262
246
|
/** Called when the mouse enters the object */
|
|
@@ -287,9 +271,9 @@ class UIText extends UIObject
|
|
|
287
271
|
* @param {Vector2} [size]
|
|
288
272
|
* @param {string} [text]
|
|
289
273
|
* @param {string} [align]
|
|
290
|
-
* @param {string} [font=
|
|
274
|
+
* @param {string} [font=uiSystem.defaultFont]
|
|
291
275
|
*/
|
|
292
|
-
constructor(pos, size, text='', align='center', font=
|
|
276
|
+
constructor(pos, size, text='', align='center', font=uiSystem.defaultFont)
|
|
293
277
|
{
|
|
294
278
|
super(pos, size);
|
|
295
279
|
|
|
@@ -303,7 +287,7 @@ class UIText extends UIObject
|
|
|
303
287
|
}
|
|
304
288
|
render()
|
|
305
289
|
{
|
|
306
|
-
|
|
290
|
+
uiSystem.drawText(this.text, this.pos, this.size, this.textColor, this.lineWidth, this.lineColor, this.align, this.font);
|
|
307
291
|
}
|
|
308
292
|
}
|
|
309
293
|
|
|
@@ -336,7 +320,7 @@ class UITile extends UIObject
|
|
|
336
320
|
}
|
|
337
321
|
render()
|
|
338
322
|
{
|
|
339
|
-
|
|
323
|
+
uiSystem.drawTile(this.pos, this.size, this.tileInfo, this.color, this.angle, this.mirror);
|
|
340
324
|
}
|
|
341
325
|
}
|
|
342
326
|
|
|
@@ -351,9 +335,9 @@ class UIButton extends UIObject
|
|
|
351
335
|
* @param {Vector2} [pos]
|
|
352
336
|
* @param {Vector2} [size]
|
|
353
337
|
* @param {string} [text]
|
|
354
|
-
* @param {Color} [color=
|
|
338
|
+
* @param {Color} [color=uiSystem.defaultButtonColor]
|
|
355
339
|
*/
|
|
356
|
-
constructor(pos, size, text, color=
|
|
340
|
+
constructor(pos, size, text='', color=uiSystem.defaultButtonColor)
|
|
357
341
|
{
|
|
358
342
|
super(pos, size);
|
|
359
343
|
|
|
@@ -365,9 +349,9 @@ class UIButton extends UIObject
|
|
|
365
349
|
{
|
|
366
350
|
const lineColor = this.mouseIsHeld ? this.color : this.lineColor;
|
|
367
351
|
const color = this.mouseIsOver? this.hoverColor : this.color;
|
|
368
|
-
|
|
352
|
+
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor);
|
|
369
353
|
const textSize = vec2(this.size.x, this.size.y*.8);
|
|
370
|
-
|
|
354
|
+
uiSystem.drawText(this.text, this.pos, textSize,
|
|
371
355
|
this.textColor, 0, undefined, this.align, this.font);
|
|
372
356
|
}
|
|
373
357
|
}
|
|
@@ -399,12 +383,12 @@ class UICheckbox extends UIObject
|
|
|
399
383
|
render()
|
|
400
384
|
{
|
|
401
385
|
const color = this.mouseIsOver? this.hoverColor : this.color;
|
|
402
|
-
|
|
386
|
+
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, this.lineColor);
|
|
403
387
|
if (this.checked)
|
|
404
388
|
{
|
|
405
389
|
// draw an X if checked
|
|
406
|
-
|
|
407
|
-
|
|
390
|
+
uiSystem.drawLine(this.pos.add(this.size.multiply(vec2(-.5,-.5))), this.pos.add(this.size.multiply(vec2(.5,.5))), this.lineWidth, this.lineColor);
|
|
391
|
+
uiSystem.drawLine(this.pos.add(this.size.multiply(vec2(-.5,.5))), this.pos.add(this.size.multiply(vec2(.5,-.5))), this.lineWidth, this.lineColor);
|
|
408
392
|
}
|
|
409
393
|
}
|
|
410
394
|
}
|
|
@@ -421,10 +405,10 @@ class UIScrollbar extends UIObject
|
|
|
421
405
|
* @param {Vector2} [size]
|
|
422
406
|
* @param {number} [value]
|
|
423
407
|
* @param {string} [text]
|
|
424
|
-
* @param {Color} [color=
|
|
408
|
+
* @param {Color} [color=uiSystem.defaultButtonColor]
|
|
425
409
|
* @param {Color} [handleColor=WHITE]
|
|
426
410
|
*/
|
|
427
|
-
constructor(pos, size, value=.5, text='', color=
|
|
411
|
+
constructor(pos, size, value=.5, text='', color=uiSystem.defaultButtonColor, handleColor=WHITE)
|
|
428
412
|
{
|
|
429
413
|
super(pos, size);
|
|
430
414
|
|
|
@@ -453,7 +437,7 @@ class UIScrollbar extends UIObject
|
|
|
453
437
|
{
|
|
454
438
|
const lineColor = this.mouseIsHeld ? this.color : this.lineColor;
|
|
455
439
|
const color = this.mouseIsOver? this.hoverColor : this.color;
|
|
456
|
-
|
|
440
|
+
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor);
|
|
457
441
|
|
|
458
442
|
const handleSize = vec2(this.size.y);
|
|
459
443
|
const handleWidth = this.size.x - handleSize.x;
|
|
@@ -461,10 +445,10 @@ class UIScrollbar extends UIObject
|
|
|
461
445
|
const p2 = this.pos.x + handleWidth/2;
|
|
462
446
|
const handlePos = vec2(lerp(this.value, p1, p2), this.pos.y);
|
|
463
447
|
const barColor = this.mouseIsHeld ? this.color : this.handleColor;
|
|
464
|
-
|
|
448
|
+
uiSystem.drawRect(handlePos, handleSize, barColor, this.lineWidth, this.lineColor);
|
|
465
449
|
|
|
466
450
|
const textSize = vec2(this.size.x, this.size.y*.8);
|
|
467
|
-
|
|
451
|
+
uiSystem.drawText(this.text, this.pos, textSize,
|
|
468
452
|
this.textColor, 0, undefined, this.align, this.font);
|
|
469
453
|
}
|
|
470
|
-
}
|
|
454
|
+
}
|
package/plugins/zzfxm.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LittleJS ZzFXM Plugin
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Music Object - Stores a zzfx music track for later use
|
|
9
|
+
*
|
|
10
|
+
* <a href=https://keithclark.github.io/ZzFXM/>Create music with the ZzFXM tracker.</a>
|
|
11
|
+
* @example
|
|
12
|
+
* // create some music
|
|
13
|
+
* const music_example = new Music(
|
|
14
|
+
* [
|
|
15
|
+
* [ // instruments
|
|
16
|
+
* [,0,400] // simple note
|
|
17
|
+
* ],
|
|
18
|
+
* [ // patterns
|
|
19
|
+
* [ // pattern 1
|
|
20
|
+
* [ // channel 0
|
|
21
|
+
* 0, -1, // instrument 0, left speaker
|
|
22
|
+
* 1, 0, 9, 1 // channel notes
|
|
23
|
+
* ],
|
|
24
|
+
* [ // channel 1
|
|
25
|
+
* 0, 1, // instrument 0, right speaker
|
|
26
|
+
* 0, 12, 17, -1 // channel notes
|
|
27
|
+
* ]
|
|
28
|
+
* ],
|
|
29
|
+
* ],
|
|
30
|
+
* [0, 0, 0, 0], // sequence, play pattern 0 four times
|
|
31
|
+
* 90 // BPM
|
|
32
|
+
* ]);
|
|
33
|
+
*
|
|
34
|
+
* // play the music
|
|
35
|
+
* music_example.play();
|
|
36
|
+
*/
|
|
37
|
+
class ZzFXMusic extends Sound
|
|
38
|
+
{
|
|
39
|
+
/** Create a music object and cache the zzfx music samples for later use
|
|
40
|
+
* @param {[Array, Array, Array, number]} zzfxMusic - Array of zzfx music parameters
|
|
41
|
+
*/
|
|
42
|
+
constructor(zzfxMusic)
|
|
43
|
+
{
|
|
44
|
+
super(undefined);
|
|
45
|
+
|
|
46
|
+
if (!soundEnable || headlessMode) return;
|
|
47
|
+
this.randomness = 0;
|
|
48
|
+
this.sampleChannels = zzfxM(...zzfxMusic);
|
|
49
|
+
this.sampleRate = zzfxR;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Play the music
|
|
53
|
+
* @param {number} [volume=1] - How much to scale volume by
|
|
54
|
+
* @param {boolean} [loop] - True if the music should loop
|
|
55
|
+
* @return {AudioBufferSourceNode} - The audio source node
|
|
56
|
+
*/
|
|
57
|
+
playMusic(volume, loop=false)
|
|
58
|
+
{ return super.play(undefined, volume, 1, 1, loop); }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
62
|
+
// ZzFX Music Renderer v2.0.3 by Keith Clark and Frank Force
|
|
63
|
+
|
|
64
|
+
/** Generate samples for a ZzFM song with given parameters
|
|
65
|
+
* @param {Array} instruments - Array of ZzFX sound parameters
|
|
66
|
+
* @param {Array} patterns - Array of pattern data
|
|
67
|
+
* @param {Array} sequence - Array of pattern indexes
|
|
68
|
+
* @param {number} [BPM] - Playback speed of the song in BPM
|
|
69
|
+
* @return {Array} - Left and right channel sample data */
|
|
70
|
+
function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
71
|
+
{
|
|
72
|
+
let i, j, k;
|
|
73
|
+
let instrumentParameters;
|
|
74
|
+
let note;
|
|
75
|
+
let sample;
|
|
76
|
+
let patternChannel;
|
|
77
|
+
let notFirstBeat;
|
|
78
|
+
let stop;
|
|
79
|
+
let instrument;
|
|
80
|
+
let attenuation;
|
|
81
|
+
let outSampleOffset;
|
|
82
|
+
let isSequenceEnd;
|
|
83
|
+
let sampleOffset = 0;
|
|
84
|
+
let nextSampleOffset;
|
|
85
|
+
let sampleBuffer = [];
|
|
86
|
+
let leftChannelBuffer = [];
|
|
87
|
+
let rightChannelBuffer = [];
|
|
88
|
+
let channelIndex = 0;
|
|
89
|
+
let panning = 0;
|
|
90
|
+
let hasMore = 1;
|
|
91
|
+
let sampleCache = {};
|
|
92
|
+
let beatLength = zzfxR / BPM * 60 >> 2;
|
|
93
|
+
|
|
94
|
+
// for each channel in order until there are no more
|
|
95
|
+
for (; hasMore; channelIndex++) {
|
|
96
|
+
|
|
97
|
+
// reset current values
|
|
98
|
+
sampleBuffer = [hasMore = notFirstBeat = outSampleOffset = 0];
|
|
99
|
+
|
|
100
|
+
// for each pattern in sequence
|
|
101
|
+
sequence.forEach((patternIndex, sequenceIndex) => {
|
|
102
|
+
// get pattern for current channel, use empty 1 note pattern if none found
|
|
103
|
+
patternChannel = patterns[patternIndex][channelIndex] || [0, 0, 0];
|
|
104
|
+
|
|
105
|
+
// check if there are more channels
|
|
106
|
+
hasMore |= patterns[patternIndex][channelIndex]&&1;
|
|
107
|
+
|
|
108
|
+
// get next offset, use the length of first channel
|
|
109
|
+
nextSampleOffset = outSampleOffset + (patterns[patternIndex][0].length - 2 - (notFirstBeat?0:1)) * beatLength;
|
|
110
|
+
// for each beat in pattern, plus one extra if end of sequence
|
|
111
|
+
isSequenceEnd = sequenceIndex == sequence.length - 1;
|
|
112
|
+
for (i = 2, k = outSampleOffset; i < patternChannel.length + isSequenceEnd; notFirstBeat = ++i) {
|
|
113
|
+
|
|
114
|
+
// <channel-note>
|
|
115
|
+
note = patternChannel[i];
|
|
116
|
+
|
|
117
|
+
// stop if end, different instrument or new note
|
|
118
|
+
stop = i == patternChannel.length + isSequenceEnd - 1 && isSequenceEnd ||
|
|
119
|
+
instrument != (patternChannel[0] || 0) || note | 0;
|
|
120
|
+
|
|
121
|
+
// fill buffer with samples for previous beat, most cpu intensive part
|
|
122
|
+
for (j = 0; j < beatLength && notFirstBeat;
|
|
123
|
+
|
|
124
|
+
// fade off attenuation at end of beat if stopping note, prevents clicking
|
|
125
|
+
j++ > beatLength - 99 && stop && attenuation < 1? attenuation += 1 / 99 : 0
|
|
126
|
+
) {
|
|
127
|
+
// copy sample to stereo buffers with panning
|
|
128
|
+
sample = (1 - attenuation) * sampleBuffer[sampleOffset++] / 2 || 0;
|
|
129
|
+
leftChannelBuffer[k] = (leftChannelBuffer[k] || 0) - sample * panning + sample;
|
|
130
|
+
rightChannelBuffer[k] = (rightChannelBuffer[k++] || 0) + sample * panning + sample;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// set up for next note
|
|
134
|
+
if (note) {
|
|
135
|
+
// set attenuation
|
|
136
|
+
attenuation = note % 1;
|
|
137
|
+
panning = patternChannel[1] || 0;
|
|
138
|
+
if (note |= 0) {
|
|
139
|
+
// get cached sample
|
|
140
|
+
sampleBuffer = sampleCache[
|
|
141
|
+
[
|
|
142
|
+
instrument = patternChannel[sampleOffset = 0] || 0,
|
|
143
|
+
note
|
|
144
|
+
]
|
|
145
|
+
] = sampleCache[[instrument, note]] || (
|
|
146
|
+
// add sample to cache
|
|
147
|
+
instrumentParameters = [...instruments[instrument]],
|
|
148
|
+
instrumentParameters[2] = (instrumentParameters[2] || 220) * 2**(note / 12 - 1),
|
|
149
|
+
|
|
150
|
+
// allow negative values to stop notes
|
|
151
|
+
note > 0 ? zzfxG(...instrumentParameters) : []
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// update the sample offset
|
|
158
|
+
outSampleOffset = nextSampleOffset;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return [leftChannelBuffer, rightChannelBuffer];
|
|
163
|
+
}
|