littlejsengine 1.14.11 → 1.14.19
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 +303 -137
- package/dist/littlejs.esm.js +936 -463
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +934 -462
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +859 -417
- package/examples/box2d/game.js +3 -2
- package/examples/box2d/gameObjects.js +2 -2
- package/examples/box2d/tiles.png +0 -0
- package/examples/breakout/game.js +5 -5
- package/examples/breakout/gameObjects.js +2 -2
- package/examples/breakoutTutorial/README.md +32 -32
- package/examples/breakoutTutorial/game.js +1 -1
- package/examples/electron/game.js +4 -4
- package/examples/electron/index.html +2 -2
- package/examples/electron/package.json +1 -8
- package/examples/index.html +67 -56
- package/examples/module/game.js +4 -4
- package/examples/platformer/gameEffects.js +5 -5
- package/examples/platformer/gameLevel.js +1 -1
- package/examples/platformer/gameObjects.js +4 -4
- package/examples/puzzle/game.js +1 -1
- package/examples/shorts/animation.js +1 -1
- package/examples/shorts/base.html +1 -1
- package/examples/shorts/blending.js +8 -14
- package/examples/shorts/box2d.js +7 -3
- package/examples/shorts/box2dCar.js +2 -1
- package/examples/shorts/empty.js +30 -0
- package/examples/shorts/helloWorld.js +1 -1
- package/examples/shorts/hillGlideGame.js +10 -4
- package/examples/shorts/landerGame.js +11 -8
- package/examples/shorts/medals.js +4 -4
- package/examples/shorts/music.js +29 -56
- package/examples/shorts/musicPlayer.js +135 -0
- package/examples/shorts/nineSlice.js +34 -15
- package/examples/shorts/parallax.js +5 -4
- package/examples/shorts/particles.js +15 -15
- package/examples/shorts/piano.js +15 -21
- package/examples/shorts/pongGame.js +6 -4
- package/examples/shorts/raycasting.js +9 -4
- package/examples/shorts/sequencer.js +122 -0
- package/examples/shorts/shader.js +29 -0
- package/examples/shorts/shapes.js +7 -4
- package/examples/shorts/slidingPuzzle.js +4 -2
- package/examples/shorts/sound.js +18 -9
- package/examples/shorts/spaceGame.js +12 -8
- package/examples/shorts/spriteAtlas.js +7 -7
- package/examples/shorts/starfield.js +1 -1
- package/examples/shorts/systemFont.js +2 -2
- package/examples/shorts/texture.js +2 -2
- package/examples/shorts/tileLayer.js +10 -10
- package/examples/shorts/tiltedView.js +24 -5
- package/examples/shorts/timers.js +10 -0
- package/examples/shorts/topDown.js +4 -1
- package/examples/shorts/uiSystem.js +8 -5
- package/examples/starter/game.js +4 -4
- package/examples/starter/index.html +2 -2
- package/examples/style.css +1 -0
- package/examples/typescript/game.js +4 -4
- package/examples/typescript/game.ts +4 -4
- package/examples/uiSystem/game.js +4 -3
- package/package.json +4 -2
- package/plugins/box2d.js +17 -2
- package/plugins/newgrounds.js +7 -5
- package/plugins/postProcess.js +76 -53
- package/plugins/uiSystem.js +192 -53
- package/plugins/zzfxm.js +5 -1
- package/reference.md +1 -1
- package/src/engine.js +60 -23
- package/src/engineAudio.js +44 -17
- package/src/engineDebug.js +75 -45
- package/src/engineDraw.js +94 -59
- package/src/engineExport.js +2 -1
- package/src/engineMedals.js +10 -2
- package/src/engineObject.js +14 -10
- package/src/engineParticles.js +60 -47
- package/src/engineSettings.js +7 -7
- package/src/engineTileLayer.js +73 -56
- package/src/engineUtilities.js +67 -20
- package/src/engineWebGL.js +134 -63
package/plugins/uiSystem.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* - Buttons
|
|
7
7
|
* - Checkboxes
|
|
8
8
|
* - Images
|
|
9
|
+
* @namespace UISystem
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
'use strict';
|
|
@@ -13,12 +14,14 @@
|
|
|
13
14
|
///////////////////////////////////////////////////////////////////////////////
|
|
14
15
|
|
|
15
16
|
/** Global UI system plugin object
|
|
16
|
-
* @type {UISystemPlugin}
|
|
17
|
+
* @type {UISystemPlugin}
|
|
18
|
+
* @memberof UISystem */
|
|
17
19
|
let uiSystem;
|
|
18
20
|
|
|
19
21
|
///////////////////////////////////////////////////////////////////////////////
|
|
20
22
|
/**
|
|
21
23
|
* UI System Global Object
|
|
24
|
+
* @memberof UISystem
|
|
22
25
|
*/
|
|
23
26
|
class UISystemPlugin
|
|
24
27
|
{
|
|
@@ -45,6 +48,8 @@ class UISystemPlugin
|
|
|
45
48
|
this.defaultHoverColor = hsl(0,0,.9);
|
|
46
49
|
/** @property {Color} - Default color for disabled UI elements */
|
|
47
50
|
this.defaultDisabledColor = hsl(0,0,.3);
|
|
51
|
+
/** @property {Color} - Uses a gradient fill combined with color */
|
|
52
|
+
this.defaultGradientColor = undefined;
|
|
48
53
|
/** @property {number} - Default line width for UI elements */
|
|
49
54
|
this.defaultLineWidth = 4;
|
|
50
55
|
/** @property {number} - Default rounded rect corner radius for UI elements */
|
|
@@ -52,7 +57,7 @@ class UISystemPlugin
|
|
|
52
57
|
/** @property {number} - Default scale to use for fitting text to object */
|
|
53
58
|
this.defaultTextScale = .8;
|
|
54
59
|
/** @property {string} - Default font for UI elements */
|
|
55
|
-
this.defaultFont =
|
|
60
|
+
this.defaultFont = fontDefault;
|
|
56
61
|
/** @property {Sound} - Default sound when interactive UI element is pressed */
|
|
57
62
|
this.defaultSoundPress = undefined;
|
|
58
63
|
/** @property {Sound} - Default sound when interactive UI element is released */
|
|
@@ -63,11 +68,15 @@ class UISystemPlugin
|
|
|
63
68
|
this.uiObjects = [];
|
|
64
69
|
/** @property {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} - Context to render UI elements to */
|
|
65
70
|
this.uiContext = context;
|
|
66
|
-
/** @property {UIObject} - Top most object user is over */
|
|
67
|
-
this.hoverObject = undefined;
|
|
68
71
|
/** @property {UIObject} - Object user is currently interacting with */
|
|
69
72
|
this.activeObject = undefined;
|
|
70
|
-
|
|
73
|
+
/** @property {UIObject} - Top most object user is over */
|
|
74
|
+
this.hoverObject = undefined;
|
|
75
|
+
/** @property {UIObject} - Hover object at start of update */
|
|
76
|
+
this.lastHoverObject = undefined;
|
|
77
|
+
/** @property {number} - If set ui coords will be renormalized to this canvas height */
|
|
78
|
+
this.nativeHeight = 0;
|
|
79
|
+
|
|
71
80
|
engineAddPlugin(uiUpdate, uiRender);
|
|
72
81
|
|
|
73
82
|
// setup recursive update and render
|
|
@@ -97,6 +106,7 @@ class UISystemPlugin
|
|
|
97
106
|
updateInvisibleObject(o);
|
|
98
107
|
}
|
|
99
108
|
// reset hover object at start of update
|
|
109
|
+
uiSystem.lastHoverObject = uiSystem.hoverObject;
|
|
100
110
|
uiSystem.hoverObject = undefined;
|
|
101
111
|
for (let i = uiSystem.uiObjects.length; i--;)
|
|
102
112
|
{
|
|
@@ -106,6 +116,17 @@ class UISystemPlugin
|
|
|
106
116
|
}
|
|
107
117
|
function uiRender()
|
|
108
118
|
{
|
|
119
|
+
const context = uiSystem.uiContext;
|
|
120
|
+
context.save();
|
|
121
|
+
if (uiSystem.nativeHeight)
|
|
122
|
+
{
|
|
123
|
+
// convert to native height
|
|
124
|
+
const s = mainCanvasSize.y / uiSystem.nativeHeight;
|
|
125
|
+
context.translate(-s*mainCanvasSize.x/2,0);
|
|
126
|
+
context.scale(s,s);
|
|
127
|
+
context.translate(mainCanvasSize.x/2/s,0);
|
|
128
|
+
}
|
|
129
|
+
|
|
109
130
|
function renderObject(o)
|
|
110
131
|
{
|
|
111
132
|
if (!o.visible)
|
|
@@ -117,6 +138,7 @@ class UISystemPlugin
|
|
|
117
138
|
renderObject(c);
|
|
118
139
|
}
|
|
119
140
|
uiSystem.uiObjects.forEach(o=> o.parent || renderObject(o));
|
|
141
|
+
context.restore();
|
|
120
142
|
}
|
|
121
143
|
}
|
|
122
144
|
|
|
@@ -126,11 +148,30 @@ class UISystemPlugin
|
|
|
126
148
|
* @param {Color} [color=uiSystem.defaultColor]
|
|
127
149
|
* @param {number} [lineWidth=uiSystem.defaultLineWidth]
|
|
128
150
|
* @param {Color} [lineColor=uiSystem.defaultLineColor]
|
|
129
|
-
* @param {number} [cornerRadius=uiSystem.defaultCornerRadius]
|
|
130
|
-
|
|
151
|
+
* @param {number} [cornerRadius=uiSystem.defaultCornerRadius]
|
|
152
|
+
* @param {Color} [gradientColor=uiSystem.defaultGradientColor] */
|
|
153
|
+
drawRect(pos, size, color=uiSystem.defaultColor, lineWidth=uiSystem.defaultLineWidth, lineColor=uiSystem.defaultLineColor, cornerRadius=uiSystem.defaultCornerRadius, gradientColor=uiSystem.defaultGradientColor)
|
|
131
154
|
{
|
|
155
|
+
ASSERT(isVector2(pos), 'pos must be a vec2');
|
|
156
|
+
ASSERT(isVector2(size), 'size must be a vec2');
|
|
157
|
+
ASSERT(isColor(color), 'color must be a color');
|
|
158
|
+
ASSERT(isNumber(lineWidth), 'lineWidth must be a number');
|
|
159
|
+
ASSERT(isColor(lineColor), 'lineColor must be a color');
|
|
160
|
+
ASSERT(isNumber(cornerRadius), 'cornerRadius must be a number');
|
|
161
|
+
|
|
132
162
|
const context = uiSystem.uiContext;
|
|
133
|
-
|
|
163
|
+
if (gradientColor)
|
|
164
|
+
{
|
|
165
|
+
const g = context.createLinearGradient(
|
|
166
|
+
pos.x, pos.y-size.y/2, pos.x, pos.y+size.y/2);
|
|
167
|
+
const c = color.toString();
|
|
168
|
+
g.addColorStop(0, c);
|
|
169
|
+
g.addColorStop(.5, gradientColor.toString());
|
|
170
|
+
g.addColorStop(1, c);
|
|
171
|
+
context.fillStyle = g;
|
|
172
|
+
}
|
|
173
|
+
else
|
|
174
|
+
context.fillStyle = color.toString();
|
|
134
175
|
context.beginPath();
|
|
135
176
|
if (cornerRadius && context['roundRect'])
|
|
136
177
|
context['roundRect'](pos.x-size.x/2, pos.y-size.y/2, size.x, size.y, cornerRadius);
|
|
@@ -152,6 +193,11 @@ class UISystemPlugin
|
|
|
152
193
|
* @param {Color} [lineColor=uiSystem.defaultLineColor] */
|
|
153
194
|
drawLine(posA, posB, lineWidth=uiSystem.defaultLineWidth, lineColor=uiSystem.defaultLineColor)
|
|
154
195
|
{
|
|
196
|
+
ASSERT(isVector2(posA), 'posA must be a vec2');
|
|
197
|
+
ASSERT(isVector2(posB), 'posB must be a vec2');
|
|
198
|
+
ASSERT(isNumber(lineWidth), 'lineWidth must be a number');
|
|
199
|
+
ASSERT(isColor(lineColor), 'lineColor must be a color');
|
|
200
|
+
|
|
155
201
|
const context = uiSystem.uiContext;
|
|
156
202
|
context.strokeStyle = lineColor.toString();
|
|
157
203
|
context.lineWidth = lineWidth;
|
|
@@ -182,17 +228,43 @@ class UISystemPlugin
|
|
|
182
228
|
* @param {Color} [lineColor=uiSystem.defaultLineColor]
|
|
183
229
|
* @param {string} [align]
|
|
184
230
|
* @param {string} [font=uiSystem.defaultFont]
|
|
231
|
+
* @param {string} [fontStyle]
|
|
185
232
|
* @param {boolean} [applyMaxWidth=true] */
|
|
186
|
-
drawText(text, pos, size, color=uiSystem.defaultColor, lineWidth=uiSystem.defaultLineWidth, lineColor=uiSystem.defaultLineColor, align='center', font=uiSystem.defaultFont, applyMaxWidth=true)
|
|
233
|
+
drawText(text, pos, size, color=uiSystem.defaultColor, lineWidth=uiSystem.defaultLineWidth, lineColor=uiSystem.defaultLineColor, align='center', font=uiSystem.defaultFont, fontStyle='', applyMaxWidth=true)
|
|
234
|
+
{
|
|
235
|
+
drawTextScreen(text, pos, size.y, color, lineWidth, lineColor, align, font, fontStyle, applyMaxWidth ? size.x : undefined, uiSystem.uiContext);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* @callback DragAndDropCallback - Callback for drag and drop events
|
|
240
|
+
* @param {DragEvent} event - The drag event
|
|
241
|
+
* @memberof UISystem
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
/** Setup drag and drop event handlers
|
|
245
|
+
* Automatically prevents defaults and calls the given functions
|
|
246
|
+
* @param {DragAndDropCallback} [onDrop] - when a file is dropped
|
|
247
|
+
* @param {DragAndDropCallback} [onDragEnter] - when a file is dragged onto the window
|
|
248
|
+
* @param {DragAndDropCallback} [onDragLeave] - when a file is dragged off the window
|
|
249
|
+
* @param {DragAndDropCallback} [onDragOver] - continously when dragging over */
|
|
250
|
+
setupDragAndDrop(onDrop, onDragEnter, onDragLeave, onDragOver)
|
|
187
251
|
{
|
|
188
|
-
|
|
252
|
+
function setCallback(callback, listenerType)
|
|
253
|
+
{
|
|
254
|
+
function listener(e) { e.preventDefault(); callback && callback(e); }
|
|
255
|
+
document.addEventListener(listenerType, listener);
|
|
256
|
+
}
|
|
257
|
+
setCallback(onDrop, 'drop');
|
|
258
|
+
setCallback(onDragEnter, 'dragenter');
|
|
259
|
+
setCallback(onDragLeave, 'dragleave');
|
|
260
|
+
setCallback(onDragOver, 'dragover');
|
|
189
261
|
}
|
|
190
262
|
}
|
|
191
263
|
|
|
192
264
|
///////////////////////////////////////////////////////////////////////////////
|
|
193
265
|
/**
|
|
194
266
|
* UI Object - Base level object for all UI elements
|
|
195
|
-
*/
|
|
267
|
+
* @memberof UISystem */
|
|
196
268
|
class UIObject
|
|
197
269
|
{
|
|
198
270
|
/** Create a UIObject
|
|
@@ -201,6 +273,9 @@ class UIObject
|
|
|
201
273
|
*/
|
|
202
274
|
constructor(pos=vec2(), size=vec2())
|
|
203
275
|
{
|
|
276
|
+
ASSERT(isVector2(pos), 'ui object pos must be a vec2');
|
|
277
|
+
ASSERT(isVector2(size), 'ui object size must be a vec2');
|
|
278
|
+
|
|
204
279
|
/** @property {Vector2} - Local position of the object */
|
|
205
280
|
this.localPos = pos.copy();
|
|
206
281
|
/** @property {Vector2} - Screen space position of the object */
|
|
@@ -208,27 +283,31 @@ class UIObject
|
|
|
208
283
|
/** @property {Vector2} - Screen space size of the object */
|
|
209
284
|
this.size = size.copy();
|
|
210
285
|
/** @property {Color} - Color of the object */
|
|
211
|
-
this.color = uiSystem.defaultColor;
|
|
286
|
+
this.color = uiSystem.defaultColor.copy();
|
|
212
287
|
/** @property {Color} - Color of the object when active, uses color if undefined */
|
|
213
288
|
this.activeColor = undefined;
|
|
214
289
|
/** @property {string} - Text for this ui object */
|
|
215
290
|
this.text = undefined;
|
|
216
291
|
/** @property {Color} - Color when disabled */
|
|
217
|
-
this.disabledColor = uiSystem.defaultDisabledColor;
|
|
292
|
+
this.disabledColor = uiSystem.defaultDisabledColor.copy();
|
|
218
293
|
/** @property {boolean} - Is this object disabled? */
|
|
219
294
|
this.disabled = false;
|
|
220
295
|
/** @property {Color} - Color for text */
|
|
221
|
-
this.textColor = uiSystem.defaultTextColor;
|
|
296
|
+
this.textColor = uiSystem.defaultTextColor.copy();
|
|
222
297
|
/** @property {Color} - Color used when hovering over the object */
|
|
223
|
-
this.hoverColor = uiSystem.defaultHoverColor;
|
|
298
|
+
this.hoverColor = uiSystem.defaultHoverColor.copy();
|
|
224
299
|
/** @property {Color} - Color for line drawing */
|
|
225
|
-
this.lineColor = uiSystem.defaultLineColor;
|
|
300
|
+
this.lineColor = uiSystem.defaultLineColor.copy();
|
|
301
|
+
/** @property {Color} - Uses a gradient fill combined with color */
|
|
302
|
+
this.gradientColor = uiSystem.defaultGradientColor ? uiSystem.defaultGradientColor.copy() : undefined;
|
|
226
303
|
/** @property {number} - Width for line drawing */
|
|
227
304
|
this.lineWidth = uiSystem.defaultLineWidth;
|
|
228
305
|
/** @property {number} - Corner radius for rounded rects */
|
|
229
306
|
this.cornerRadius = uiSystem.defaultCornerRadius;
|
|
230
307
|
/** @property {string} - Font for this objecct */
|
|
231
308
|
this.font = uiSystem.defaultFont;
|
|
309
|
+
/** @property {string} - Font style for this object or undefined */
|
|
310
|
+
this.fontStyle = undefined;
|
|
232
311
|
/** @property {number} - Override for text width */
|
|
233
312
|
this.textWidth = undefined;
|
|
234
313
|
/** @property {number} - Override for text height */
|
|
@@ -253,6 +332,8 @@ class UIObject
|
|
|
253
332
|
this.interactive = false;
|
|
254
333
|
/** @property {boolean} - Activate when dragged over with mouse held down */
|
|
255
334
|
this.dragActivate = false;
|
|
335
|
+
/** @property {boolean} - True if this can be a hover object */
|
|
336
|
+
this.canBeHover = true;
|
|
256
337
|
uiSystem.uiObjects.push(this);
|
|
257
338
|
}
|
|
258
339
|
|
|
@@ -276,31 +357,47 @@ class UIObject
|
|
|
276
357
|
child.parent = undefined;
|
|
277
358
|
}
|
|
278
359
|
|
|
360
|
+
/** Check if the mouse is overlapping a box in screen space
|
|
361
|
+
* @return {boolean} - True if overlapping
|
|
362
|
+
*/
|
|
363
|
+
isMouseOverlapping()
|
|
364
|
+
{
|
|
365
|
+
const size = !isTouchDevice ? this.size :
|
|
366
|
+
this.size.add(vec2(this.extraTouchSize || 0));
|
|
367
|
+
if (!uiSystem.nativeHeight)
|
|
368
|
+
return isOverlapping(this.pos, size, mousePosScreen);
|
|
369
|
+
|
|
370
|
+
const s = mainCanvasSize.y / uiSystem.nativeHeight;
|
|
371
|
+
const sInv = 1/s;
|
|
372
|
+
let pos = mousePosScreen.copy();
|
|
373
|
+
pos.x += s*mainCanvasSize.x/2;
|
|
374
|
+
pos.x *= sInv;
|
|
375
|
+
pos.y *= sInv;
|
|
376
|
+
pos.x -= sInv*mainCanvasSize.x/2;
|
|
377
|
+
return isOverlapping(this.pos, size, pos);
|
|
378
|
+
}
|
|
379
|
+
|
|
279
380
|
/** Update the object, called automatically by plugin once each frame */
|
|
280
381
|
update()
|
|
281
382
|
{
|
|
282
|
-
const wasHover = this
|
|
383
|
+
const wasHover = uiSystem.lastHoverObject === this;
|
|
283
384
|
const isActive = this.isActiveObject();
|
|
284
385
|
const mouseDown = mouseIsDown(0);
|
|
285
386
|
const mousePress = this.dragActivate ? mouseDown : mouseWasPressed(0);
|
|
286
|
-
if (
|
|
387
|
+
if (this.canBeHover)
|
|
287
388
|
if (mousePress || isActive || (!mouseDown && !isTouchDevice))
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
if (isOverlapping(this.pos, size, mousePosScreen))
|
|
291
|
-
uiSystem.hoverObject = this;
|
|
292
|
-
}
|
|
389
|
+
if (!uiSystem.hoverObject && this.isMouseOverlapping())
|
|
390
|
+
uiSystem.hoverObject = this;
|
|
293
391
|
if (this.isHoverObject())
|
|
294
392
|
{
|
|
295
|
-
if (mousePress)
|
|
296
|
-
inputClearKey(0,0,0,1,0); // clear mouse was pressed state
|
|
297
393
|
if (!this.disabled)
|
|
298
394
|
{
|
|
299
395
|
if (mousePress)
|
|
300
396
|
{
|
|
301
397
|
if (this.interactive)
|
|
302
398
|
{
|
|
303
|
-
this.
|
|
399
|
+
if (!this.dragActivate || (!wasHover || mouseWasPressed(0)))
|
|
400
|
+
this.onPress();
|
|
304
401
|
if (this.soundPress)
|
|
305
402
|
this.soundPress.play();
|
|
306
403
|
if (uiSystem.activeObject && !isActive)
|
|
@@ -308,13 +405,15 @@ class UIObject
|
|
|
308
405
|
uiSystem.activeObject = this;
|
|
309
406
|
}
|
|
310
407
|
}
|
|
311
|
-
if (!mouseDown &&
|
|
408
|
+
if (!mouseDown && this.isActiveObject() && this.interactive)
|
|
312
409
|
{
|
|
313
410
|
this.onClick();
|
|
314
411
|
if (this.soundClick)
|
|
315
412
|
this.soundClick.play();
|
|
316
413
|
}
|
|
317
414
|
}
|
|
415
|
+
// clear mouse was pressed state even when disabled
|
|
416
|
+
mousePress && inputClearKey(0,0,0,1,0);
|
|
318
417
|
}
|
|
319
418
|
if (isActive)
|
|
320
419
|
if (!mouseDown || (this.dragActivate && !this.isHoverObject()))
|
|
@@ -325,6 +424,7 @@ class UIObject
|
|
|
325
424
|
uiSystem.activeObject = undefined;
|
|
326
425
|
}
|
|
327
426
|
|
|
427
|
+
// call enter/leave events
|
|
328
428
|
if (this.isHoverObject() !== wasHover)
|
|
329
429
|
this.isHoverObject() ? this.onEnter() : this.onLeave();
|
|
330
430
|
}
|
|
@@ -335,7 +435,7 @@ class UIObject
|
|
|
335
435
|
if (!this.size.x || !this.size.y) return;
|
|
336
436
|
|
|
337
437
|
const lineColor = this.interactive && this.isActiveObject() && !this.disabled ? this.color : this.lineColor;
|
|
338
|
-
const color = this.
|
|
438
|
+
const color = this.disabled ? this.disabledColor : this.interactive ? this.isActiveObject() ? this.activeColor || this.color : this.isHoverObject() ? this.hoverColor : this.color : this.color;
|
|
339
439
|
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor, this.cornerRadius);
|
|
340
440
|
}
|
|
341
441
|
|
|
@@ -386,6 +486,7 @@ class UIObject
|
|
|
386
486
|
/**
|
|
387
487
|
* UIText - A UI object that displays text
|
|
388
488
|
* @extends UIObject
|
|
489
|
+
* @memberof UISystem
|
|
389
490
|
*/
|
|
390
491
|
class UIText extends UIObject
|
|
391
492
|
{
|
|
@@ -400,6 +501,10 @@ class UIText extends UIObject
|
|
|
400
501
|
{
|
|
401
502
|
super(pos, size);
|
|
402
503
|
|
|
504
|
+
ASSERT(isString(text), 'ui text must be a string');
|
|
505
|
+
ASSERT(['left','center','right'].includes(align), 'ui text align must be left, center, or right');
|
|
506
|
+
ASSERT(isString(font), 'ui text font must be a string');
|
|
507
|
+
|
|
403
508
|
// set properties
|
|
404
509
|
this.text = text;
|
|
405
510
|
this.align = align;
|
|
@@ -407,11 +512,13 @@ class UIText extends UIObject
|
|
|
407
512
|
|
|
408
513
|
// make text not outlined by default
|
|
409
514
|
this.lineWidth = 0;
|
|
515
|
+
// text can not be a hover object by default
|
|
516
|
+
this.canBeHover = false;
|
|
410
517
|
}
|
|
411
518
|
render()
|
|
412
519
|
{
|
|
413
520
|
const textSize = this.getTextSize();
|
|
414
|
-
uiSystem.drawText(this.text, this.pos, textSize, this.textColor, this.lineWidth, this.lineColor, this.align, this.font);
|
|
521
|
+
uiSystem.drawText(this.text, this.pos, textSize, this.textColor, this.lineWidth, this.lineColor, this.align, this.font, this.fontStyle);
|
|
415
522
|
}
|
|
416
523
|
}
|
|
417
524
|
|
|
@@ -419,6 +526,7 @@ class UIText extends UIObject
|
|
|
419
526
|
/**
|
|
420
527
|
* UITile - A UI object that displays a tile image
|
|
421
528
|
* @extends UIObject
|
|
529
|
+
* @memberof UISystem
|
|
422
530
|
*/
|
|
423
531
|
class UITile extends UIObject
|
|
424
532
|
{
|
|
@@ -433,15 +541,19 @@ class UITile extends UIObject
|
|
|
433
541
|
constructor(pos, size, tileInfo, color=WHITE, angle=0, mirror=false)
|
|
434
542
|
{
|
|
435
543
|
super(pos, size);
|
|
544
|
+
|
|
545
|
+
ASSERT(tileInfo instanceof TileInfo, 'ui tile tileInfo must be a TileInfo');
|
|
546
|
+
ASSERT(isColor(color), 'ui tile color must be a color');
|
|
547
|
+
ASSERT(isNumber(angle), 'ui tile angle must be a number');
|
|
548
|
+
|
|
436
549
|
/** @property {TileInfo} - Tile image to use */
|
|
437
550
|
this.tileInfo = tileInfo;
|
|
438
551
|
/** @property {number} - Angle to rotate in radians */
|
|
439
552
|
this.angle = angle;
|
|
440
553
|
/** @property {boolean} - Should it be mirrored? */
|
|
441
554
|
this.mirror = mirror;
|
|
442
|
-
|
|
443
555
|
// set properties
|
|
444
|
-
this.color = color;
|
|
556
|
+
this.color = color.copy();
|
|
445
557
|
}
|
|
446
558
|
render()
|
|
447
559
|
{
|
|
@@ -453,6 +565,7 @@ class UITile extends UIObject
|
|
|
453
565
|
/**
|
|
454
566
|
* UIButton - A UI object that acts as a button
|
|
455
567
|
* @extends UIObject
|
|
568
|
+
* @memberof UISystem
|
|
456
569
|
*/
|
|
457
570
|
class UIButton extends UIObject
|
|
458
571
|
{
|
|
@@ -466,9 +579,12 @@ class UIButton extends UIObject
|
|
|
466
579
|
{
|
|
467
580
|
super(pos, size);
|
|
468
581
|
|
|
582
|
+
ASSERT(isString(text), 'ui button must be a string');
|
|
583
|
+
ASSERT(isColor(color), 'ui button color must be a color');
|
|
584
|
+
|
|
469
585
|
// set properties
|
|
470
586
|
this.text = text;
|
|
471
|
-
this.color = color;
|
|
587
|
+
this.color = color.copy();
|
|
472
588
|
this.interactive = true;
|
|
473
589
|
}
|
|
474
590
|
render()
|
|
@@ -478,7 +594,7 @@ class UIButton extends UIObject
|
|
|
478
594
|
// draw the text scaled to fit
|
|
479
595
|
const textSize = this.getTextSize();
|
|
480
596
|
uiSystem.drawText(this.text, this.pos, textSize,
|
|
481
|
-
this.textColor, 0, undefined, this.align, this.font);
|
|
597
|
+
this.textColor, 0, undefined, this.align, this.font, this.fontStyle);
|
|
482
598
|
}
|
|
483
599
|
}
|
|
484
600
|
|
|
@@ -486,6 +602,7 @@ class UIButton extends UIObject
|
|
|
486
602
|
/**
|
|
487
603
|
* UICheckbox - A UI object that acts as a checkbox
|
|
488
604
|
* @extends UIObject
|
|
605
|
+
* @memberof UISystem
|
|
489
606
|
*/
|
|
490
607
|
class UICheckbox extends UIObject
|
|
491
608
|
{
|
|
@@ -499,12 +616,15 @@ class UICheckbox extends UIObject
|
|
|
499
616
|
constructor(pos, size, checked=false, text='', color=uiSystem.defaultButtonColor)
|
|
500
617
|
{
|
|
501
618
|
super(pos, size);
|
|
619
|
+
|
|
620
|
+
ASSERT(isString(text), 'ui checkbox must be a string');
|
|
621
|
+
ASSERT(isColor(color), 'ui checkbox color must be a color');
|
|
622
|
+
|
|
502
623
|
/** @property {boolean} - Current percentage value of this scrollbar 0-1 */
|
|
503
624
|
this.checked = checked;
|
|
504
|
-
|
|
505
625
|
// set properties
|
|
506
626
|
this.text = text;
|
|
507
|
-
this.color = color;
|
|
627
|
+
this.color = color.copy();
|
|
508
628
|
this.interactive = true;
|
|
509
629
|
}
|
|
510
630
|
onClick()
|
|
@@ -528,7 +648,7 @@ class UICheckbox extends UIObject
|
|
|
528
648
|
const textSize = this.getTextSize();
|
|
529
649
|
const pos = this.pos.add(vec2(this.size.x,0));
|
|
530
650
|
uiSystem.drawText(this.text, pos, textSize,
|
|
531
|
-
this.textColor, 0, undefined, 'left', this.font, false);
|
|
651
|
+
this.textColor, 0, undefined, 'left', this.font, this.fontStyle, false);
|
|
532
652
|
}
|
|
533
653
|
}
|
|
534
654
|
|
|
@@ -536,6 +656,7 @@ class UICheckbox extends UIObject
|
|
|
536
656
|
/**
|
|
537
657
|
* UIScrollbar - A UI object that acts as a scrollbar
|
|
538
658
|
* @extends UIObject
|
|
659
|
+
* @memberof UISystem
|
|
539
660
|
*/
|
|
540
661
|
class UIScrollbar extends UIObject
|
|
541
662
|
{
|
|
@@ -551,14 +672,19 @@ class UIScrollbar extends UIObject
|
|
|
551
672
|
{
|
|
552
673
|
super(pos, size);
|
|
553
674
|
|
|
675
|
+
ASSERT(isNumber(value), 'ui scrollbar value must be a number');
|
|
676
|
+
ASSERT(isString(text), 'ui scrollbar must be a string');
|
|
677
|
+
ASSERT(isColor(color), 'ui scrollbar color must be a color');
|
|
678
|
+
ASSERT(isColor(handleColor), 'ui scrollbar handleColor must be a color');
|
|
679
|
+
|
|
554
680
|
/** @property {number} - Current percentage value of this scrollbar 0-1 */
|
|
555
681
|
this.value = value;
|
|
556
682
|
/** @property {Color} - Color for the handle part of the scrollbar */
|
|
557
|
-
this.handleColor = handleColor;
|
|
683
|
+
this.handleColor = handleColor.copy();
|
|
558
684
|
|
|
559
685
|
// set properties
|
|
560
686
|
this.text = text;
|
|
561
|
-
this.color = color;
|
|
687
|
+
this.color = color.copy();
|
|
562
688
|
this.interactive = true;
|
|
563
689
|
}
|
|
564
690
|
update()
|
|
@@ -566,33 +692,46 @@ class UIScrollbar extends UIObject
|
|
|
566
692
|
super.update();
|
|
567
693
|
if (this.isActiveObject() && this.interactive)
|
|
568
694
|
{
|
|
695
|
+
// handle horizontal or vertical scrollbar
|
|
696
|
+
const isHorizontal = this.size.x > this.size.y;
|
|
697
|
+
const handleSize = isHorizontal ? this.size.y : this.size.x;
|
|
698
|
+
const barSize = isHorizontal ? this.size.x : this.size.y;
|
|
699
|
+
const centerPos = isHorizontal ? this.pos.x : this.pos.y;
|
|
700
|
+
|
|
569
701
|
// check if value changed
|
|
570
|
-
const
|
|
571
|
-
const
|
|
572
|
-
const
|
|
573
|
-
const p2 = this.pos.x + handleWidth/2;
|
|
702
|
+
const handleWidth = barSize - handleSize;
|
|
703
|
+
const p1 = centerPos - handleWidth/2;
|
|
704
|
+
const p2 = centerPos + handleWidth/2;
|
|
574
705
|
const oldValue = this.value;
|
|
575
|
-
this.value =
|
|
706
|
+
this.value = isHorizontal ?
|
|
707
|
+
percent(mousePosScreen.x, p1, p2) :
|
|
708
|
+
percent(mousePosScreen.y, p2, p1);
|
|
576
709
|
this.value === oldValue || this.onChange();
|
|
577
710
|
}
|
|
578
711
|
}
|
|
579
712
|
render()
|
|
580
713
|
{
|
|
581
714
|
super.render();
|
|
582
|
-
|
|
715
|
+
|
|
716
|
+
// handle horizontal or vertical scrollbar
|
|
717
|
+
const isHorizontal = this.size.x > this.size.y;
|
|
718
|
+
const handleSize = isHorizontal ? this.size.y : this.size.x;
|
|
719
|
+
const barSize = isHorizontal ? this.size.x : this.size.y;
|
|
720
|
+
const centerPos = isHorizontal ? this.pos.x : this.pos.y;
|
|
721
|
+
|
|
583
722
|
// draw the scrollbar handle
|
|
584
|
-
const
|
|
585
|
-
const
|
|
586
|
-
const
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
uiSystem.drawRect(handlePos, handleSize, handleColor, this.lineWidth, this.lineColor, this.cornerRadius);
|
|
723
|
+
const handleWidth = barSize - handleSize;
|
|
724
|
+
const p1 = centerPos - handleWidth/2;
|
|
725
|
+
const p2 = centerPos + handleWidth/2;
|
|
726
|
+
const handlePos = isHorizontal ?
|
|
727
|
+
vec2(lerp(p1, p2, this.value), this.pos.y) :
|
|
728
|
+
vec2(this.pos.x, lerp(p2, p1, this.value))
|
|
729
|
+
const handleColor = this.disabled ? this.disabledColor : this.handleColor;
|
|
730
|
+
uiSystem.drawRect(handlePos, vec2(handleSize), handleColor, this.lineWidth, this.lineColor, this.cornerRadius);
|
|
592
731
|
|
|
593
732
|
// draw the text scaled to fit on the scrollbar
|
|
594
733
|
const textSize = this.getTextSize();
|
|
595
734
|
uiSystem.drawText(this.text, this.pos, textSize,
|
|
596
|
-
this.textColor, 0, undefined, this.align, this.font);
|
|
735
|
+
this.textColor, 0, undefined, this.align, this.font, this.fontStyle);
|
|
597
736
|
}
|
|
598
737
|
}
|
package/plugins/zzfxm.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LittleJS ZzFXM Plugin
|
|
3
|
+
* @namespace ZzFXM
|
|
3
4
|
*/
|
|
4
5
|
|
|
5
6
|
'use strict';
|
|
@@ -8,6 +9,8 @@
|
|
|
8
9
|
* Music Object - Stores a zzfx music track for later use
|
|
9
10
|
*
|
|
10
11
|
* <a href=https://keithclark.github.io/ZzFXM/>Create music with the ZzFXM tracker.</a>
|
|
12
|
+
* @extends Sound
|
|
13
|
+
* @memberof ZzFXM
|
|
11
14
|
* @example
|
|
12
15
|
* // create some music
|
|
13
16
|
* const music_example = new Music(
|
|
@@ -66,7 +69,8 @@ class ZzFXMusic extends Sound
|
|
|
66
69
|
* @param {Array} patterns - Array of pattern data
|
|
67
70
|
* @param {Array} sequence - Array of pattern indexes
|
|
68
71
|
* @param {number} [BPM] - Playback speed of the song in BPM
|
|
69
|
-
* @return {Array} - Left and right channel sample data
|
|
72
|
+
* @return {Array} - Left and right channel sample data
|
|
73
|
+
* @memberof ZzFXM */
|
|
70
74
|
function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
71
75
|
{
|
|
72
76
|
let i, j, k;
|
package/reference.md
CHANGED
|
@@ -399,7 +399,7 @@ TileCollisionLayer.setCollisionData(pos, data=1) // Set tile collision data a
|
|
|
399
399
|
tileCollisionGetData(pos) // Get tile collision data at pos
|
|
400
400
|
tileCollisionTest(pos, size=(0,0), object) // Check if collision should occur
|
|
401
401
|
tileCollisionRaycast(posStart, posEnd, object) // Return the center of tile if hit
|
|
402
|
-
|
|
402
|
+
tileLayersLoad(tileMapData, tileInfo) // Load tile layers from exported data
|
|
403
403
|
|
|
404
404
|
```
|
|
405
405
|
|