littlejsengine 1.15.2 → 1.15.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/dist/littlejs.d.ts +32 -9
- package/dist/littlejs.esm.js +128 -62
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +128 -62
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +92 -40
- package/examples/electron/index.html +2 -2
- package/examples/shorts/base.html +1 -1
- package/examples/shorts/box2dCar.js +1 -1
- package/examples/shorts/music.js +1 -0
- package/examples/shorts/musicPlayer.js +1 -0
- package/examples/shorts/sequencer.js +2 -0
- package/examples/shorts/sound.js +1 -0
- package/examples/shorts/timers.js +1 -0
- package/examples/shorts/uiSystem.js +1 -0
- package/examples/shorts/videoPlayer.js +2 -1
- package/examples/starter/index.html +2 -2
- package/examples/uiSystem/game.js +1 -0
- package/package.json +1 -1
- package/plugins/uiSystem.js +30 -3
- package/src/engine.js +1 -1
- package/src/engineAudio.js +0 -1
- package/src/engineDebug.js +36 -22
- package/src/engineDraw.js +56 -32
- package/src/engineInput.js +1 -1
- package/src/engineObject.js +3 -1
- package/src/engineTileLayer.js +1 -1
package/dist/littlejs.release.js
CHANGED
|
@@ -33,7 +33,7 @@ const engineName = 'LittleJS';
|
|
|
33
33
|
* @type {string}
|
|
34
34
|
* @default
|
|
35
35
|
* @memberof Engine */
|
|
36
|
-
const engineVersion = '1.15.
|
|
36
|
+
const engineVersion = '1.15.3';
|
|
37
37
|
|
|
38
38
|
/** Frames per second to update
|
|
39
39
|
* @type {number}
|
|
@@ -2997,7 +2997,9 @@ class EngineObject
|
|
|
2997
2997
|
{
|
|
2998
2998
|
ASSERT(child.parent === this && this.children.includes(child));
|
|
2999
2999
|
ASSERT(child instanceof EngineObject, 'child must be an EngineObject');
|
|
3000
|
-
this.children.
|
|
3000
|
+
const index = this.children.indexOf(child);
|
|
3001
|
+
ASSERT(index >= 0, 'child not found in children array');
|
|
3002
|
+
index >= 0 && this.children.splice(index, 1);
|
|
3001
3003
|
child.parent = 0;
|
|
3002
3004
|
}
|
|
3003
3005
|
|
|
@@ -3316,15 +3318,11 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
3316
3318
|
|
|
3317
3319
|
const textureInfo = tileInfo && tileInfo.textureInfo;
|
|
3318
3320
|
const bleedScale = tileInfo ? tileInfo.bleedScale : 0;
|
|
3319
|
-
if (useWebGL)
|
|
3321
|
+
if (useWebGL && glEnable)
|
|
3320
3322
|
{
|
|
3321
3323
|
ASSERT(!!glContext, 'WebGL is not enabled!');
|
|
3322
3324
|
if (screenSpace)
|
|
3323
|
-
|
|
3324
|
-
// convert to world space
|
|
3325
|
-
pos = screenToWorld(pos);
|
|
3326
|
-
size = size.scale(1/cameraScale);
|
|
3327
|
-
}
|
|
3325
|
+
[pos, size, angle] = screenToWorldTransform(pos, size, angle);
|
|
3328
3326
|
if (textureInfo)
|
|
3329
3327
|
{
|
|
3330
3328
|
// calculate uvs and render
|
|
@@ -3412,7 +3410,8 @@ function drawRectGradient(pos, size, colorTop=WHITE, colorBottom=BLACK, angle=0,
|
|
|
3412
3410
|
ASSERT(isColor(colorTop) && isColor(colorBottom), 'color is invalid');
|
|
3413
3411
|
ASSERT(isNumber(angle), 'angle must be a number');
|
|
3414
3412
|
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
3415
|
-
|
|
3413
|
+
|
|
3414
|
+
if (useWebGL && glEnable)
|
|
3416
3415
|
{
|
|
3417
3416
|
ASSERT(!!glContext, 'WebGL is not enabled!');
|
|
3418
3417
|
if (screenSpace)
|
|
@@ -3420,6 +3419,7 @@ function drawRectGradient(pos, size, colorTop=WHITE, colorBottom=BLACK, angle=0,
|
|
|
3420
3419
|
// convert to world space
|
|
3421
3420
|
pos = screenToWorld(pos);
|
|
3422
3421
|
size = size.scale(1/cameraScale);
|
|
3422
|
+
angle += cameraAngle;
|
|
3423
3423
|
}
|
|
3424
3424
|
// build 4 corner points for the rectangle
|
|
3425
3425
|
const points = [], colors = [];
|
|
@@ -3475,17 +3475,14 @@ function drawLineList(points, width=.1, color, wrap=false, pos=vec2(), angle=0,
|
|
|
3475
3475
|
ASSERT(isVector2(pos), 'pos must be a vec2');
|
|
3476
3476
|
ASSERT(isNumber(angle), 'angle must be a number');
|
|
3477
3477
|
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
3478
|
-
|
|
3478
|
+
|
|
3479
|
+
if (useWebGL && glEnable)
|
|
3479
3480
|
{
|
|
3480
3481
|
ASSERT(!!glContext, 'WebGL is not enabled!');
|
|
3481
|
-
let
|
|
3482
|
+
let size = vec2(1);
|
|
3482
3483
|
if (screenSpace)
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
pos = screenToWorld(pos);
|
|
3486
|
-
scale = 1/cameraScale;
|
|
3487
|
-
}
|
|
3488
|
-
glDrawOutlineTransform(points, color.rgbaInt(), width, pos.x, pos.y, scale, scale, angle, wrap);
|
|
3484
|
+
[pos, size, angle] = screenToWorldTransform(pos, size, angle);
|
|
3485
|
+
glDrawOutlineTransform(points, color.rgbaInt(), width, pos.x, pos.y, size.x, size.y, angle, wrap);
|
|
3489
3486
|
}
|
|
3490
3487
|
else
|
|
3491
3488
|
{
|
|
@@ -3581,19 +3578,15 @@ function drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos=vec2(),
|
|
|
3581
3578
|
ASSERT(isNumber(angle), 'angle must be a number');
|
|
3582
3579
|
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
3583
3580
|
|
|
3584
|
-
if (useWebGL)
|
|
3581
|
+
if (useWebGL && glEnable)
|
|
3585
3582
|
{
|
|
3586
3583
|
ASSERT(!!glContext, 'WebGL is not enabled!');
|
|
3587
|
-
let
|
|
3584
|
+
let size = vec2(1);
|
|
3588
3585
|
if (screenSpace)
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
pos = screenToWorld(pos);
|
|
3592
|
-
scale = 1/cameraScale;
|
|
3593
|
-
}
|
|
3594
|
-
glDrawPointsTransform(points, color.rgbaInt(), pos.x, pos.y, scale, scale, angle);
|
|
3586
|
+
[pos, size, angle] = screenToWorldTransform(pos, size, angle);
|
|
3587
|
+
glDrawPointsTransform(points, color.rgbaInt(), pos.x, pos.y, size.x, size.y, angle);
|
|
3595
3588
|
if (lineWidth > 0)
|
|
3596
|
-
glDrawOutlineTransform(points, lineColor.rgbaInt(), lineWidth, pos.x, pos.y,
|
|
3589
|
+
glDrawOutlineTransform(points, lineColor.rgbaInt(), lineWidth, pos.x, pos.y, size.x, size.y, angle);
|
|
3597
3590
|
}
|
|
3598
3591
|
else
|
|
3599
3592
|
{
|
|
@@ -3636,7 +3629,7 @@ function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineC
|
|
|
3636
3629
|
ASSERT(lineWidth >= 0 && lineWidth < size.x && lineWidth < size.y, 'invalid lineWidth');
|
|
3637
3630
|
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
3638
3631
|
|
|
3639
|
-
if (useWebGL)
|
|
3632
|
+
if (useWebGL && glEnable)
|
|
3640
3633
|
{
|
|
3641
3634
|
// draw as a regular polygon
|
|
3642
3635
|
const sides = glCircleSides;
|
|
@@ -3699,14 +3692,10 @@ function drawCanvas2D(pos, size, angle=0, mirror=false, drawFunction, screenSpac
|
|
|
3699
3692
|
ASSERT(typeof drawFunction === 'function', 'drawFunction must be a function');
|
|
3700
3693
|
|
|
3701
3694
|
if (!screenSpace)
|
|
3702
|
-
|
|
3703
|
-
// transform from world space to screen space
|
|
3704
|
-
pos = worldToScreen(pos);
|
|
3705
|
-
size = size.scale(cameraScale);
|
|
3706
|
-
}
|
|
3695
|
+
[pos, size, angle] = worldToScreenTransform(pos, size, angle);
|
|
3707
3696
|
context.save();
|
|
3708
3697
|
context.translate(pos.x+.5, pos.y+.5);
|
|
3709
|
-
context.rotate(angle
|
|
3698
|
+
context.rotate(angle);
|
|
3710
3699
|
context.scale(mirror ? -size.x : size.x, -size.y);
|
|
3711
3700
|
drawFunction(context);
|
|
3712
3701
|
context.restore();
|
|
@@ -3732,7 +3721,14 @@ function drawCanvas2D(pos, size, angle=0, mirror=false, drawFunction, screenSpac
|
|
|
3732
3721
|
* @memberof Draw */
|
|
3733
3722
|
function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font, fontStyle, maxWidth, angle=0, context=drawContext)
|
|
3734
3723
|
{
|
|
3735
|
-
|
|
3724
|
+
// convert to screen space
|
|
3725
|
+
pos = worldToScreen(pos);
|
|
3726
|
+
size *= cameraScale;
|
|
3727
|
+
lineWidth *= cameraScale;
|
|
3728
|
+
angle -= cameraAngle;
|
|
3729
|
+
angle *= -1;
|
|
3730
|
+
|
|
3731
|
+
drawTextScreen(text, pos, size, color, lineWidth, lineColor, textAlign, font, fontStyle, maxWidth, angle, context);
|
|
3736
3732
|
}
|
|
3737
3733
|
|
|
3738
3734
|
/** Draw text on overlay canvas in world space
|
|
@@ -3891,6 +3887,36 @@ function worldToScreenDelta(worldDelta)
|
|
|
3891
3887
|
return new Vector2(x * cameraScale, y * -cameraScale);
|
|
3892
3888
|
}
|
|
3893
3889
|
|
|
3890
|
+
/** Convert screen space transform to world space
|
|
3891
|
+
* @param {Vector2} screenPos
|
|
3892
|
+
* @param {Vector2} screenSize
|
|
3893
|
+
* @param {number} [screenAngle]
|
|
3894
|
+
* @return {[Vector2, Vector2, number]} - [pos, size, angle]
|
|
3895
|
+
* @memberof Draw */
|
|
3896
|
+
function screenToWorldTransform(screenPos, screenSize, screenAngle=0)
|
|
3897
|
+
{
|
|
3898
|
+
return [
|
|
3899
|
+
screenToWorld(screenPos),
|
|
3900
|
+
screenSize.scale(1/cameraScale),
|
|
3901
|
+
screenAngle + cameraAngle
|
|
3902
|
+
];
|
|
3903
|
+
}
|
|
3904
|
+
|
|
3905
|
+
/** Convert world space transform to screen space
|
|
3906
|
+
* @param {Vector2} worldPos
|
|
3907
|
+
* @param {Vector2} worldSize
|
|
3908
|
+
* @param {number} [worldAngle]
|
|
3909
|
+
* @return {[Vector2, Vector2, number]} - [pos, size, angle]
|
|
3910
|
+
* @memberof Draw */
|
|
3911
|
+
function worldToScreenTransform(worldPos, worldSize, worldAngle=0)
|
|
3912
|
+
{
|
|
3913
|
+
return [
|
|
3914
|
+
worldToScreen(worldPos),
|
|
3915
|
+
worldSize.scale(cameraScale),
|
|
3916
|
+
worldAngle - cameraAngle
|
|
3917
|
+
];
|
|
3918
|
+
}
|
|
3919
|
+
|
|
3894
3920
|
/** Get the camera's visible area in world space
|
|
3895
3921
|
* @return {Vector2}
|
|
3896
3922
|
* @memberof Draw */
|
|
@@ -4298,7 +4324,7 @@ function inputUpdate()
|
|
|
4298
4324
|
if (headlessMode) return;
|
|
4299
4325
|
|
|
4300
4326
|
// clear input when lost focus (prevent stuck keys)
|
|
4301
|
-
if(!(touchInputEnable && isTouchDevice) && !document.hasFocus())
|
|
4327
|
+
if (!(touchInputEnable && isTouchDevice) && !document.hasFocus())
|
|
4302
4328
|
inputClear();
|
|
4303
4329
|
|
|
4304
4330
|
// update mouse world space position and delta
|
|
@@ -4856,7 +4882,6 @@ class Sound
|
|
|
4856
4882
|
ASSERT(isNumber(pitch), 'pitch must be a number');
|
|
4857
4883
|
ASSERT(isNumber(randomnessScale), 'randomnessScale must be a number');
|
|
4858
4884
|
|
|
4859
|
-
|
|
4860
4885
|
if (!soundEnable || headlessMode) return;
|
|
4861
4886
|
if (!this.sampleChannels) return;
|
|
4862
4887
|
|
|
@@ -5989,7 +6014,7 @@ class TileCollisionLayer extends TileLayer
|
|
|
5989
6014
|
// remove from collision layers array and destroy
|
|
5990
6015
|
const index = tileCollisionLayers.indexOf(this);
|
|
5991
6016
|
ASSERT(index >= 0, 'tile collision layer not found in array');
|
|
5992
|
-
tileCollisionLayers.splice(index, 1);
|
|
6017
|
+
index >= 0 && tileCollisionLayers.splice(index, 1);
|
|
5993
6018
|
super.destroy();
|
|
5994
6019
|
}
|
|
5995
6020
|
|
|
@@ -8035,6 +8060,7 @@ class UISystemPlugin
|
|
|
8035
8060
|
ASSERT(!uiSystem, 'UI system already initialized');
|
|
8036
8061
|
uiSystem = this;
|
|
8037
8062
|
|
|
8063
|
+
// default settings
|
|
8038
8064
|
/** @property {Color} - Default fill color for UI elements */
|
|
8039
8065
|
this.defaultColor = WHITE;
|
|
8040
8066
|
/** @property {Color} - Default outline color for UI elements */
|
|
@@ -8063,6 +8089,13 @@ class UISystemPlugin
|
|
|
8063
8089
|
this.defaultSoundRelease = undefined;
|
|
8064
8090
|
/** @property {Sound} - Default sound when interactive UI element is clicked */
|
|
8065
8091
|
this.defaultSoundClick = undefined;
|
|
8092
|
+
/** @property {Color} - Color for shadow */
|
|
8093
|
+
this.defaultShadowColor = CLEAR_BLACK;
|
|
8094
|
+
/** @property {number} - Size of shadow blur */
|
|
8095
|
+
this.defaultShadowBlur = 5;
|
|
8096
|
+
/** @property {Vector2} - Offset of shadow blur */
|
|
8097
|
+
this.defaultShadowOffset = vec2(5);
|
|
8098
|
+
// system state
|
|
8066
8099
|
/** @property {Array<UIObject>} - List of all UI elements */
|
|
8067
8100
|
this.uiObjects = [];
|
|
8068
8101
|
/** @property {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} - Context to render UI elements to */
|
|
@@ -8153,8 +8186,11 @@ class UISystemPlugin
|
|
|
8153
8186
|
* @param {number} [lineWidth]
|
|
8154
8187
|
* @param {Color} [lineColor]
|
|
8155
8188
|
* @param {number} [cornerRadius]
|
|
8156
|
-
* @param {Color} [gradientColor]
|
|
8157
|
-
|
|
8189
|
+
* @param {Color} [gradientColor]
|
|
8190
|
+
* @param {Color} [shadowColor]
|
|
8191
|
+
* @param {number} [shadowBlur]
|
|
8192
|
+
* @param {Color} [shadowOffset] */
|
|
8193
|
+
drawRect(pos, size, color=WHITE, lineWidth=0, lineColor=BLACK, cornerRadius=0, gradientColor, shadowColor=BLACK, shadowBlur=0, shadowOffset=vec2())
|
|
8158
8194
|
{
|
|
8159
8195
|
ASSERT(isVector2(pos), 'pos must be a vec2');
|
|
8160
8196
|
ASSERT(isVector2(size), 'size must be a vec2');
|
|
@@ -8176,12 +8212,22 @@ class UISystemPlugin
|
|
|
8176
8212
|
}
|
|
8177
8213
|
else
|
|
8178
8214
|
context.fillStyle = color.toString();
|
|
8215
|
+
if (shadowBlur || shadowOffset.x || shadowOffset.y)
|
|
8216
|
+
if (shadowColor.a > 0)
|
|
8217
|
+
{
|
|
8218
|
+
// setup shadow
|
|
8219
|
+
context.shadowColor = shadowColor.toString();
|
|
8220
|
+
context.shadowBlur = shadowBlur;
|
|
8221
|
+
context.shadowOffsetX = shadowOffset.x;
|
|
8222
|
+
context.shadowOffsetY = shadowOffset.y;
|
|
8223
|
+
}
|
|
8179
8224
|
context.beginPath();
|
|
8180
8225
|
if (cornerRadius && context['roundRect'])
|
|
8181
8226
|
context['roundRect'](pos.x-size.x/2, pos.y-size.y/2, size.x, size.y, cornerRadius);
|
|
8182
8227
|
else
|
|
8183
8228
|
context.rect(pos.x-size.x/2, pos.y-size.y/2, size.x, size.y);
|
|
8184
8229
|
context.fill();
|
|
8230
|
+
context.shadowColor = '#0000'
|
|
8185
8231
|
if (lineWidth)
|
|
8186
8232
|
{
|
|
8187
8233
|
context.strokeStyle = lineColor.toString();
|
|
@@ -8370,6 +8416,12 @@ class UIObject
|
|
|
8370
8416
|
this.dragActivate = false;
|
|
8371
8417
|
/** @property {boolean} - True if this can be a hover object */
|
|
8372
8418
|
this.canBeHover = true;
|
|
8419
|
+
/** @property {Color} - Color for shadow, undefined if no shadow */
|
|
8420
|
+
this.shadowColor = uiSystem.defaultShadowColor?.copy();
|
|
8421
|
+
/** @property {number} - Size of shadow blur */
|
|
8422
|
+
this.shadowBlur = uiSystem.defaultShadowBlur;
|
|
8423
|
+
/** @property {Vector2} - Offset of shadow blur */
|
|
8424
|
+
this.shadowOffset = uiSystem.defaultShadowOffset.copy();
|
|
8373
8425
|
uiSystem.uiObjects.push(this);
|
|
8374
8426
|
|
|
8375
8427
|
/** @property {Vector2} - How much to offset the text shadow or undefined */
|
|
@@ -8487,7 +8539,7 @@ class UIObject
|
|
|
8487
8539
|
|
|
8488
8540
|
const lineColor = this.interactive && this.isActiveObject() && !this.disabled ? this.color : this.lineColor;
|
|
8489
8541
|
const color = this.disabled ? this.disabledColor : this.interactive ? this.isActiveObject() ? this.activeColor || this.color : this.isHoverObject() ? this.hoverColor : this.color : this.color;
|
|
8490
|
-
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor, this.cornerRadius, this.gradientColor);
|
|
8542
|
+
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor, this.cornerRadius, this.gradientColor, this.shadowColor, this.shadowBlur, this.shadowOffset);
|
|
8491
8543
|
}
|
|
8492
8544
|
|
|
8493
8545
|
/** Special update when object is not visible */
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../dist/littlejs.js?1.15.
|
|
10
|
+
<script src=../../dist/littlejs.js?1.15.3></script>
|
|
11
11
|
|
|
12
12
|
<!-- Add your game scripts here -->
|
|
13
|
-
<script src=game.js?1.15.
|
|
13
|
+
<script src=game.js?1.15.3></script>
|
|
@@ -39,7 +39,7 @@ class CarObject extends Box2dObject
|
|
|
39
39
|
joint.setSpringFrequencyHz(frequency);
|
|
40
40
|
joint.setMaxMotorTorque(maxTorque);
|
|
41
41
|
joint.enableMotor(!i);
|
|
42
|
-
const friction =
|
|
42
|
+
const friction = 20;
|
|
43
43
|
wheel.addCircle(2, vec2(), 1, friction);
|
|
44
44
|
wheel.motorJoint = joint;
|
|
45
45
|
this.wheels[i] = wheel;
|
package/examples/shorts/music.js
CHANGED
|
@@ -8,6 +8,7 @@ function gameInit()
|
|
|
8
8
|
uiSystem.defaultSoundPress = new Sound([.5,0,220]);
|
|
9
9
|
uiSystem.defaultSoundClick = new Sound([.5,0,440]);
|
|
10
10
|
uiSystem.defaultCornerRadius = 20;
|
|
11
|
+
uiSystem.defaultShadowColor = BLACK;
|
|
11
12
|
canvasClearColor = hsl(.9,.3,.2);
|
|
12
13
|
|
|
13
14
|
// setup music player UI
|
|
@@ -28,6 +28,7 @@ class UISequencerButton extends UIButton
|
|
|
28
28
|
this.cornerRadius = 0;
|
|
29
29
|
this.dragActivate = true;
|
|
30
30
|
this.isOn = false;
|
|
31
|
+
this.shadowColor = CLEAR_BLACK;
|
|
31
32
|
|
|
32
33
|
// set instrument and color based on track
|
|
33
34
|
const pianoStart = 2;
|
|
@@ -70,6 +71,7 @@ function gameInit()
|
|
|
70
71
|
// initialize UI system
|
|
71
72
|
new UISystemPlugin;
|
|
72
73
|
uiSystem.defaultCornerRadius = 8;
|
|
74
|
+
uiSystem.defaultShadowColor = BLACK;
|
|
73
75
|
canvasClearColor = hsl(0,0,.3);
|
|
74
76
|
|
|
75
77
|
// create sequencer buttons
|
package/examples/shorts/sound.js
CHANGED
|
@@ -5,6 +5,7 @@ function gameInit()
|
|
|
5
5
|
uiSystem.defaultSoundPress = new Sound([.5,0,220]);
|
|
6
6
|
uiSystem.defaultSoundClick = new Sound([.5,0,440]);
|
|
7
7
|
uiSystem.defaultCornerRadius = 8;
|
|
8
|
+
uiSystem.defaultShadowColor = BLACK;
|
|
8
9
|
|
|
9
10
|
// example button that returns to menu
|
|
10
11
|
const buttonBack = new UIButton(mainCanvasSize.scale(.5), vec2(200),
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../dist/littlejs.js?1.15.
|
|
10
|
+
<script src=../../dist/littlejs.js?1.15.3></script>
|
|
11
11
|
|
|
12
12
|
<!-- LittleJS Engine Source
|
|
13
13
|
<script src=../../src/engine.js></script>
|
|
@@ -31,4 +31,4 @@
|
|
|
31
31
|
-->
|
|
32
32
|
|
|
33
33
|
<!-- Add your game scripts here -->
|
|
34
|
-
<script src=game.js?1.15.
|
|
34
|
+
<script src=game.js?1.15.3></script>
|
|
@@ -25,6 +25,7 @@ function createUI()
|
|
|
25
25
|
LJS.uiSystem.defaultSoundClick = new LJS.Sound([.5,0,440]);
|
|
26
26
|
LJS.uiSystem.defaultCornerRadius = 8;
|
|
27
27
|
LJS.uiSystem.defaultGradientColor = LJS.WHITE;
|
|
28
|
+
LJS.uiSystem.defaultShadowColor = LJS.BLACK;
|
|
28
29
|
|
|
29
30
|
// setup root to attach all ui elements to
|
|
30
31
|
uiRoot = new LJS.UIObject;
|
package/package.json
CHANGED
package/plugins/uiSystem.js
CHANGED
|
@@ -36,6 +36,7 @@ class UISystemPlugin
|
|
|
36
36
|
ASSERT(!uiSystem, 'UI system already initialized');
|
|
37
37
|
uiSystem = this;
|
|
38
38
|
|
|
39
|
+
// default settings
|
|
39
40
|
/** @property {Color} - Default fill color for UI elements */
|
|
40
41
|
this.defaultColor = WHITE;
|
|
41
42
|
/** @property {Color} - Default outline color for UI elements */
|
|
@@ -64,6 +65,13 @@ class UISystemPlugin
|
|
|
64
65
|
this.defaultSoundRelease = undefined;
|
|
65
66
|
/** @property {Sound} - Default sound when interactive UI element is clicked */
|
|
66
67
|
this.defaultSoundClick = undefined;
|
|
68
|
+
/** @property {Color} - Color for shadow */
|
|
69
|
+
this.defaultShadowColor = CLEAR_BLACK;
|
|
70
|
+
/** @property {number} - Size of shadow blur */
|
|
71
|
+
this.defaultShadowBlur = 5;
|
|
72
|
+
/** @property {Vector2} - Offset of shadow blur */
|
|
73
|
+
this.defaultShadowOffset = vec2(5);
|
|
74
|
+
// system state
|
|
67
75
|
/** @property {Array<UIObject>} - List of all UI elements */
|
|
68
76
|
this.uiObjects = [];
|
|
69
77
|
/** @property {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} - Context to render UI elements to */
|
|
@@ -154,8 +162,11 @@ class UISystemPlugin
|
|
|
154
162
|
* @param {number} [lineWidth]
|
|
155
163
|
* @param {Color} [lineColor]
|
|
156
164
|
* @param {number} [cornerRadius]
|
|
157
|
-
* @param {Color} [gradientColor]
|
|
158
|
-
|
|
165
|
+
* @param {Color} [gradientColor]
|
|
166
|
+
* @param {Color} [shadowColor]
|
|
167
|
+
* @param {number} [shadowBlur]
|
|
168
|
+
* @param {Color} [shadowOffset] */
|
|
169
|
+
drawRect(pos, size, color=WHITE, lineWidth=0, lineColor=BLACK, cornerRadius=0, gradientColor, shadowColor=BLACK, shadowBlur=0, shadowOffset=vec2())
|
|
159
170
|
{
|
|
160
171
|
ASSERT(isVector2(pos), 'pos must be a vec2');
|
|
161
172
|
ASSERT(isVector2(size), 'size must be a vec2');
|
|
@@ -177,12 +188,22 @@ class UISystemPlugin
|
|
|
177
188
|
}
|
|
178
189
|
else
|
|
179
190
|
context.fillStyle = color.toString();
|
|
191
|
+
if (shadowBlur || shadowOffset.x || shadowOffset.y)
|
|
192
|
+
if (shadowColor.a > 0)
|
|
193
|
+
{
|
|
194
|
+
// setup shadow
|
|
195
|
+
context.shadowColor = shadowColor.toString();
|
|
196
|
+
context.shadowBlur = shadowBlur;
|
|
197
|
+
context.shadowOffsetX = shadowOffset.x;
|
|
198
|
+
context.shadowOffsetY = shadowOffset.y;
|
|
199
|
+
}
|
|
180
200
|
context.beginPath();
|
|
181
201
|
if (cornerRadius && context['roundRect'])
|
|
182
202
|
context['roundRect'](pos.x-size.x/2, pos.y-size.y/2, size.x, size.y, cornerRadius);
|
|
183
203
|
else
|
|
184
204
|
context.rect(pos.x-size.x/2, pos.y-size.y/2, size.x, size.y);
|
|
185
205
|
context.fill();
|
|
206
|
+
context.shadowColor = '#0000'
|
|
186
207
|
if (lineWidth)
|
|
187
208
|
{
|
|
188
209
|
context.strokeStyle = lineColor.toString();
|
|
@@ -371,6 +392,12 @@ class UIObject
|
|
|
371
392
|
this.dragActivate = false;
|
|
372
393
|
/** @property {boolean} - True if this can be a hover object */
|
|
373
394
|
this.canBeHover = true;
|
|
395
|
+
/** @property {Color} - Color for shadow, undefined if no shadow */
|
|
396
|
+
this.shadowColor = uiSystem.defaultShadowColor?.copy();
|
|
397
|
+
/** @property {number} - Size of shadow blur */
|
|
398
|
+
this.shadowBlur = uiSystem.defaultShadowBlur;
|
|
399
|
+
/** @property {Vector2} - Offset of shadow blur */
|
|
400
|
+
this.shadowOffset = uiSystem.defaultShadowOffset.copy();
|
|
374
401
|
uiSystem.uiObjects.push(this);
|
|
375
402
|
|
|
376
403
|
/** @property {Vector2} - How much to offset the text shadow or undefined */
|
|
@@ -488,7 +515,7 @@ class UIObject
|
|
|
488
515
|
|
|
489
516
|
const lineColor = this.interactive && this.isActiveObject() && !this.disabled ? this.color : this.lineColor;
|
|
490
517
|
const color = this.disabled ? this.disabledColor : this.interactive ? this.isActiveObject() ? this.activeColor || this.color : this.isHoverObject() ? this.hoverColor : this.color : this.color;
|
|
491
|
-
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor, this.cornerRadius, this.gradientColor);
|
|
518
|
+
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor, this.cornerRadius, this.gradientColor, this.shadowColor, this.shadowBlur, this.shadowOffset);
|
|
492
519
|
}
|
|
493
520
|
|
|
494
521
|
/** Special update when object is not visible */
|
package/src/engine.js
CHANGED
package/src/engineAudio.js
CHANGED