littlejsengine 1.14.4 → 1.14.7
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/README.md +3 -3
- package/dist/littlejs.d.ts +40 -14
- package/dist/littlejs.esm.js +119 -59
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +115 -57
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +108 -50
- package/examples/box2d/game.js +1 -3
- package/examples/box2d/gameObjects.js +2 -2
- package/examples/htmlMenu/game.js +1 -1
- package/examples/index.html +85 -49
- package/examples/puzzle/game.js +1 -2
- package/examples/shorts/animation.js +2 -2
- package/examples/shorts/box2d.js +1 -0
- package/examples/shorts/box2dCar.js +1 -0
- package/examples/shorts/flappyGame.js +2 -1
- package/examples/shorts/helloWorld.js +2 -2
- package/examples/shorts/hillGlideGame.js +6 -3
- package/examples/shorts/maze.js +1 -0
- package/examples/shorts/medals.js +3 -0
- package/examples/shorts/music.js +6 -8
- package/examples/shorts/platformer.js +1 -0
- package/examples/shorts/shapes.js +6 -6
- package/examples/shorts/sound.js +1 -0
- package/examples/shorts/spriteAtlas.js +1 -2
- package/examples/shorts/tileLayer.js +1 -0
- package/examples/shorts/tiltedView.js +1 -1
- package/examples/shorts/timers.js +34 -31
- package/examples/shorts/topDown.js +2 -1
- package/examples/shorts/uiSystem.js +3 -5
- package/examples/stress/index.html +1 -1
- package/examples/uiSystem/game.js +1 -1
- package/package.json +1 -1
- package/plugins/uiSystem.js +35 -17
- package/reference.md +1 -1
- package/src/engine.js +23 -6
- package/src/engineDebug.js +7 -7
- package/src/engineDraw.js +18 -11
- package/src/engineExport.js +4 -2
- package/src/engineSettings.js +10 -0
- package/src/engineUtilities.js +4 -0
- package/src/engineWebGL.js +18 -16
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.14.
|
|
36
|
+
const engineVersion = '1.14.7';
|
|
37
37
|
|
|
38
38
|
/** Frames per second to update
|
|
39
39
|
* @type {number}
|
|
@@ -172,15 +172,15 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
172
172
|
frameTimeBufferMS += paused ? 0 : frameTimeDeltaMS;
|
|
173
173
|
if (!debugSpeedUp)
|
|
174
174
|
frameTimeBufferMS = min(frameTimeBufferMS, 50); // clamp min framerate
|
|
175
|
-
if (debugVideoCaptureIsActive())
|
|
176
|
-
frameTimeBufferMS = 0; // no time smoothing when capturing video
|
|
177
|
-
updateCanvas();
|
|
178
175
|
|
|
179
176
|
if (paused)
|
|
180
177
|
{
|
|
178
|
+
updateCanvas();
|
|
179
|
+
|
|
181
180
|
// update object transforms even when paused
|
|
182
181
|
for (const o of engineObjects)
|
|
183
182
|
o.parent || o.updateTransforms();
|
|
183
|
+
|
|
184
184
|
inputUpdate();
|
|
185
185
|
pluginUpdateList.forEach(f=>f());
|
|
186
186
|
debugUpdate();
|
|
@@ -205,6 +205,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
205
205
|
time = frame++ / frameRate;
|
|
206
206
|
|
|
207
207
|
// update game and objects
|
|
208
|
+
updateCanvas();
|
|
208
209
|
inputUpdate();
|
|
209
210
|
gameUpdate();
|
|
210
211
|
pluginUpdateList.forEach(f=>f());
|
|
@@ -214,14 +215,23 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
214
215
|
debugUpdate();
|
|
215
216
|
gameUpdatePost();
|
|
216
217
|
inputUpdatePost();
|
|
218
|
+
|
|
219
|
+
if (debugVideoCaptureIsActive())
|
|
220
|
+
renderFrame();
|
|
217
221
|
}
|
|
218
222
|
|
|
219
223
|
// add the time smoothing back in
|
|
220
224
|
frameTimeBufferMS += deltaSmooth;
|
|
221
225
|
}
|
|
222
226
|
|
|
223
|
-
if (!
|
|
227
|
+
if (!debugVideoCaptureIsActive())
|
|
228
|
+
renderFrame();
|
|
229
|
+
requestAnimationFrame(engineUpdate);
|
|
230
|
+
|
|
231
|
+
function renderFrame()
|
|
224
232
|
{
|
|
233
|
+
if (headlessMode) return;
|
|
234
|
+
|
|
225
235
|
// render sort then render while removing destroyed objects
|
|
226
236
|
enginePreRender();
|
|
227
237
|
gameRender();
|
|
@@ -251,7 +261,6 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
251
261
|
}
|
|
252
262
|
drawCount = 0;
|
|
253
263
|
}
|
|
254
|
-
requestAnimationFrame(engineUpdate);
|
|
255
264
|
}
|
|
256
265
|
|
|
257
266
|
function updateCanvas()
|
|
@@ -277,6 +286,14 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
277
286
|
mainCanvas.height = min(innerHeight, canvasMaxSize.y);
|
|
278
287
|
}
|
|
279
288
|
|
|
289
|
+
// apply the clear color to main canvas
|
|
290
|
+
if (canvasClearColor.a > 0)
|
|
291
|
+
{
|
|
292
|
+
mainContext.fillStyle = canvasClearColor.toString();
|
|
293
|
+
mainContext.fillRect(0, 0, mainCanvasSize.x, mainCanvasSize.y);
|
|
294
|
+
mainContext.fillStyle = BLACK.toString();
|
|
295
|
+
}
|
|
296
|
+
|
|
280
297
|
// clear overlay canvas and set size
|
|
281
298
|
overlayCanvas.width = mainCanvas.width;
|
|
282
299
|
overlayCanvas.height = mainCanvas.height;
|
|
@@ -1678,6 +1695,10 @@ class Timer
|
|
|
1678
1695
|
* @return {number} */
|
|
1679
1696
|
getPercent() { return this.isSet()? 1-percent(this.time - time, 0, this.setTime) : 0; }
|
|
1680
1697
|
|
|
1698
|
+
/** Get the time this timer was set to, returns 0 if not set
|
|
1699
|
+
* @return {number} */
|
|
1700
|
+
getSetTime() { return this.isSet() ? this.setTime : 0; }
|
|
1701
|
+
|
|
1681
1702
|
/** Returns this timer expressed as a string
|
|
1682
1703
|
* @return {string} */
|
|
1683
1704
|
toString() { if (debug) { return this.isSet() ? Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ) : 'unset'; }}
|
|
@@ -1723,6 +1744,11 @@ let cameraScale = 32;
|
|
|
1723
1744
|
* @memberof Settings */
|
|
1724
1745
|
let canvasColorTiles = true;
|
|
1725
1746
|
|
|
1747
|
+
/** Color to clear the canvas to before render
|
|
1748
|
+
* @type {Color}
|
|
1749
|
+
* @memberof Draw */
|
|
1750
|
+
let canvasClearColor = CLEAR_BLACK;
|
|
1751
|
+
|
|
1726
1752
|
/** The max size of the canvas, centered if window is larger
|
|
1727
1753
|
* @type {Vector2}
|
|
1728
1754
|
* @default Vector2(1920,1080)
|
|
@@ -2001,6 +2027,11 @@ function setCameraScale(scale) { cameraScale = scale; }
|
|
|
2001
2027
|
* @memberof Settings */
|
|
2002
2028
|
function setCanvasColorTiles(colorTiles) { canvasColorTiles = colorTiles; }
|
|
2003
2029
|
|
|
2030
|
+
/** Set color to clear the canvas to before render
|
|
2031
|
+
* @param {Color} color
|
|
2032
|
+
* @memberof Settings */
|
|
2033
|
+
function setCanvasClearColor(color) { canvasClearColor = color; }
|
|
2034
|
+
|
|
2004
2035
|
/** Set max size of the canvas
|
|
2005
2036
|
* @param {Vector2} size
|
|
2006
2037
|
* @memberof Settings */
|
|
@@ -2829,8 +2860,9 @@ class TileInfo
|
|
|
2829
2860
|
* @param {Vector2} [size=tileSizeDefault] - Size of tile in pixels
|
|
2830
2861
|
* @param {number} [textureIndex] - Texture index to use
|
|
2831
2862
|
* @param {number} [padding] - How many pixels padding around tiles
|
|
2863
|
+
* @param {number} [bleedScale] - How many pixels smaller to draw tiles
|
|
2832
2864
|
*/
|
|
2833
|
-
constructor(pos=vec2(), size=tileSizeDefault, textureIndex=0, padding=0)
|
|
2865
|
+
constructor(pos=vec2(), size=tileSizeDefault, textureIndex=0, padding=0, bleedScale=tileFixBleedScale)
|
|
2834
2866
|
{
|
|
2835
2867
|
/** @property {Vector2} - Top left corner of tile in pixels */
|
|
2836
2868
|
this.pos = pos.copy();
|
|
@@ -2842,6 +2874,8 @@ class TileInfo
|
|
|
2842
2874
|
this.padding = padding;
|
|
2843
2875
|
/** @property {TextureInfo} - The texture info for this tile */
|
|
2844
2876
|
this.textureInfo = textureInfos[this.textureIndex];
|
|
2877
|
+
/** @property {float} - Shrinks tile by this many pixels to prevent neighbors bleeding */
|
|
2878
|
+
this.bleedScale = bleedScale;
|
|
2845
2879
|
}
|
|
2846
2880
|
|
|
2847
2881
|
/** Returns a copy of this tile offset by a vector
|
|
@@ -2849,7 +2883,7 @@ class TileInfo
|
|
|
2849
2883
|
* @return {TileInfo}
|
|
2850
2884
|
*/
|
|
2851
2885
|
offset(offset)
|
|
2852
|
-
{ return new TileInfo(this.pos.add(offset), this.size, this.textureIndex); }
|
|
2886
|
+
{ return new TileInfo(this.pos.add(offset), this.size, this.textureIndex, this.padding, this.bleedScale); }
|
|
2853
2887
|
|
|
2854
2888
|
/** Returns a copy of this tile offset by a number of animation frames
|
|
2855
2889
|
* @param {number} frame - Offset to apply in animation frames
|
|
@@ -2872,6 +2906,8 @@ class TileInfo
|
|
|
2872
2906
|
this.pos = new Vector2;
|
|
2873
2907
|
this.size = new Vector2(image.width, image.height);
|
|
2874
2908
|
this.textureInfo = new TextureInfo(image, glTexture);
|
|
2909
|
+
// do not use padding or bleed
|
|
2910
|
+
this.bleedScale = this.padding = 0;
|
|
2875
2911
|
return this;
|
|
2876
2912
|
}
|
|
2877
2913
|
}
|
|
@@ -2929,6 +2965,7 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
2929
2965
|
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
2930
2966
|
|
|
2931
2967
|
const textureInfo = tileInfo && tileInfo.textureInfo;
|
|
2968
|
+
const bleedScale = tileInfo ? tileInfo.bleedScale : 0;
|
|
2932
2969
|
if (useWebGL)
|
|
2933
2970
|
{
|
|
2934
2971
|
if (screenSpace)
|
|
@@ -2946,10 +2983,10 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
2946
2983
|
const w = tileInfo.size.x * sizeInverse.x;
|
|
2947
2984
|
const h = tileInfo.size.y * sizeInverse.y;
|
|
2948
2985
|
glSetTexture(textureInfo.glTexture);
|
|
2949
|
-
if (
|
|
2986
|
+
if (bleedScale)
|
|
2950
2987
|
{
|
|
2951
|
-
const tileImageFixBleedX = sizeInverse.x*
|
|
2952
|
-
const tileImageFixBleedY = sizeInverse.y*
|
|
2988
|
+
const tileImageFixBleedX = sizeInverse.x*bleedScale;
|
|
2989
|
+
const tileImageFixBleedY = sizeInverse.y*bleedScale;
|
|
2953
2990
|
glDraw(pos.x, pos.y, mirror ? -size.x : size.x, size.y, angle,
|
|
2954
2991
|
x + tileImageFixBleedX, y + tileImageFixBleedY,
|
|
2955
2992
|
x - tileImageFixBleedX + w, y - tileImageFixBleedY + h,
|
|
@@ -2980,7 +3017,7 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
2980
3017
|
// calculate uvs and render
|
|
2981
3018
|
const x = tileInfo.pos.x, y = tileInfo.pos.y;
|
|
2982
3019
|
const w = tileInfo.size.x, h = tileInfo.size.y;
|
|
2983
|
-
drawImageColor(context, textureInfo.image, x, y, w, h, -.5, -.5, 1, 1, color, additiveColor);
|
|
3020
|
+
drawImageColor(context, textureInfo.image, x, y, w, h, -.5, -.5, 1, 1, color, additiveColor, bleedScale);
|
|
2984
3021
|
}
|
|
2985
3022
|
else
|
|
2986
3023
|
{
|
|
@@ -3468,15 +3505,16 @@ function combineCanvases()
|
|
|
3468
3505
|
* @param {number} dHeight
|
|
3469
3506
|
* @param {Color} color
|
|
3470
3507
|
* @param {Color} [additiveColor]
|
|
3508
|
+
* @param {number} [bleedScale] - How much to shrink the source, used to fix bleeding
|
|
3471
3509
|
* @memberof Draw */
|
|
3472
|
-
function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight, color, additiveColor)
|
|
3510
|
+
function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight, color, additiveColor, bleedScale=0)
|
|
3473
3511
|
{
|
|
3474
3512
|
function isWhite(c) { return c.r >= 1 && c.g >= 1 && c.b >= 1; }
|
|
3475
3513
|
function isBlack(c) { return c.r <= 0 && c.g <= 0 && c.b <= 0 && c.a <= 0; }
|
|
3476
|
-
const sx2 =
|
|
3477
|
-
const sy2 =
|
|
3478
|
-
const sWidth2 = sWidth - 2*
|
|
3479
|
-
const sHeight2 = sHeight - 2*
|
|
3514
|
+
const sx2 = bleedScale;
|
|
3515
|
+
const sy2 = bleedScale;
|
|
3516
|
+
const sWidth2 = sWidth - 2*bleedScale;
|
|
3517
|
+
const sHeight2 = sHeight - 2*bleedScale;
|
|
3480
3518
|
if (!canvasColorTiles || (additiveColor ? isWhite(color.add(additiveColor)) && additiveColor.a <= 0 : isWhite(color)))
|
|
3481
3519
|
{
|
|
3482
3520
|
// white texture with no additive alpha, no need to tint
|
|
@@ -6316,7 +6354,8 @@ function glSetTexture(texture, wrap=false)
|
|
|
6316
6354
|
return;
|
|
6317
6355
|
|
|
6318
6356
|
glFlush();
|
|
6319
|
-
|
|
6357
|
+
glActiveTexture = texture;
|
|
6358
|
+
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture);
|
|
6320
6359
|
|
|
6321
6360
|
// set wrap mode
|
|
6322
6361
|
const wrapMode = wrap ? glContext.REPEAT : glContext.CLAMP_TO_EDGE;
|
|
@@ -6366,6 +6405,7 @@ function glCreateProgram(vsSource, fsSource)
|
|
|
6366
6405
|
}
|
|
6367
6406
|
|
|
6368
6407
|
/** Create WebGL texture from an image and init the texture settings
|
|
6408
|
+
* Restores the active texture when done
|
|
6369
6409
|
* @param {HTMLImageElement|HTMLCanvasElement|OffscreenCanvas} [image]
|
|
6370
6410
|
* @return {WebGLTexture}
|
|
6371
6411
|
* @memberof WebGL */
|
|
@@ -6375,30 +6415,29 @@ function glCreateTexture(image)
|
|
|
6375
6415
|
|
|
6376
6416
|
// build the texture
|
|
6377
6417
|
const texture = glContext.createTexture();
|
|
6378
|
-
|
|
6418
|
+
let mipMap = false;
|
|
6379
6419
|
if (image && image.width)
|
|
6380
6420
|
{
|
|
6381
6421
|
glSetTextureData(texture, image);
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
// use mipmap filtering
|
|
6385
|
-
glContext.generateMipmap(glContext.TEXTURE_2D);
|
|
6386
|
-
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MIN_FILTER, glContext.LINEAR_MIPMAP_LINEAR);
|
|
6387
|
-
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER, glContext.LINEAR);
|
|
6388
|
-
return texture;
|
|
6389
|
-
}
|
|
6422
|
+
glContext.bindTexture(glContext.TEXTURE_2D, texture);
|
|
6423
|
+
mipMap = !tilesPixelated && isPowerOfTwo(image.width) && isPowerOfTwo(image.height);
|
|
6390
6424
|
}
|
|
6391
6425
|
else
|
|
6392
6426
|
{
|
|
6393
6427
|
// create a white texture
|
|
6394
6428
|
const whitePixel = new Uint8Array([255, 255, 255, 255]);
|
|
6429
|
+
glContext.bindTexture(glContext.TEXTURE_2D, texture);
|
|
6395
6430
|
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, 1, 1, 0, glContext.RGBA, glContext.UNSIGNED_BYTE, whitePixel);
|
|
6396
6431
|
}
|
|
6397
6432
|
|
|
6398
6433
|
// set texture filtering
|
|
6399
|
-
const
|
|
6400
|
-
|
|
6401
|
-
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER,
|
|
6434
|
+
const magFilter = tilesPixelated ? glContext.NEAREST : glContext.LINEAR;
|
|
6435
|
+
const minFilter = mipMap ? glContext.LINEAR_MIPMAP_LINEAR : magFilter;
|
|
6436
|
+
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER, magFilter);
|
|
6437
|
+
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MIN_FILTER, minFilter);
|
|
6438
|
+
if (mipMap)
|
|
6439
|
+
glContext.generateMipmap(glContext.TEXTURE_2D);
|
|
6440
|
+
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture); // rebind active texture
|
|
6402
6441
|
return texture;
|
|
6403
6442
|
}
|
|
6404
6443
|
|
|
@@ -6411,7 +6450,7 @@ function glDeleteTexture(texture)
|
|
|
6411
6450
|
glContext.deleteTexture(texture);
|
|
6412
6451
|
}
|
|
6413
6452
|
|
|
6414
|
-
/** Set WebGL texture data from an image
|
|
6453
|
+
/** Set WebGL texture data from an image, restores the active texture when done
|
|
6415
6454
|
* @param {WebGLTexture} texture
|
|
6416
6455
|
* @param {HTMLImageElement|HTMLCanvasElement|OffscreenCanvas} image
|
|
6417
6456
|
* @memberof WebGL */
|
|
@@ -6423,6 +6462,7 @@ function glSetTextureData(texture, image)
|
|
|
6423
6462
|
ASSERT(!!image && image.width > 0, 'Invalid image data.');
|
|
6424
6463
|
glContext.bindTexture(glContext.TEXTURE_2D, texture);
|
|
6425
6464
|
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, image);
|
|
6465
|
+
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture); // rebind active texture
|
|
6426
6466
|
}
|
|
6427
6467
|
|
|
6428
6468
|
/** Draw all sprites and clear out the buffer, called automatically by the system whenever necessary
|
|
@@ -6568,7 +6608,7 @@ function glDrawPoints(points, rgba)
|
|
|
6568
6608
|
|
|
6569
6609
|
// setup triangle strip with degenerate verts at start and end
|
|
6570
6610
|
let offset = glBatchCount * gl_INDICES_PER_POLY_VERTEX;
|
|
6571
|
-
for(let i = vertCount; i--;)
|
|
6611
|
+
for (let i = vertCount; i--;)
|
|
6572
6612
|
{
|
|
6573
6613
|
const j = clamp(i-1, 0, vertCount-3);
|
|
6574
6614
|
const point = points[j];
|
|
@@ -6596,7 +6636,7 @@ function glDrawColoredPoints(points, pointColors)
|
|
|
6596
6636
|
|
|
6597
6637
|
// setup triangle strip with degenerate verts at start and end
|
|
6598
6638
|
let offset = glBatchCount * gl_INDICES_PER_POLY_VERTEX;
|
|
6599
|
-
for(let i = vertCount; i--;)
|
|
6639
|
+
for (let i = vertCount; i--;)
|
|
6600
6640
|
{
|
|
6601
6641
|
const j = clamp(i-1, 0, vertCount-3);
|
|
6602
6642
|
const point = points[j];
|
|
@@ -7319,6 +7359,8 @@ class UISystemPlugin
|
|
|
7319
7359
|
this.defaultLineWidth = 4;
|
|
7320
7360
|
/** @property {number} - Default rounded rect corner radius for UI elements */
|
|
7321
7361
|
this.defaultCornerRadius = 0;
|
|
7362
|
+
/** @property {number} - Default scale to use for fitting text to object */
|
|
7363
|
+
this.defaultTextScale = .8;
|
|
7322
7364
|
/** @property {string} - Default font for UI elements */
|
|
7323
7365
|
this.defaultFont = 'arial';
|
|
7324
7366
|
/** @property {Sound} - Default sound when interactive UI element is pressed */
|
|
@@ -7335,6 +7377,7 @@ class UISystemPlugin
|
|
|
7335
7377
|
engineAddPlugin(uiUpdate, uiRender);
|
|
7336
7378
|
|
|
7337
7379
|
// setup recursive update and render
|
|
7380
|
+
// update in reverse order to detect mouse enter/leave
|
|
7338
7381
|
function uiUpdate()
|
|
7339
7382
|
{
|
|
7340
7383
|
function updateInvisibleObject(o)
|
|
@@ -7359,7 +7402,11 @@ class UISystemPlugin
|
|
|
7359
7402
|
else
|
|
7360
7403
|
updateInvisibleObject(o);
|
|
7361
7404
|
}
|
|
7362
|
-
uiSystem.uiObjects.
|
|
7405
|
+
for (let i = uiSystem.uiObjects.length; i--;)
|
|
7406
|
+
{
|
|
7407
|
+
const o = uiSystem.uiObjects[i];
|
|
7408
|
+
o.parent || updateObject(o)
|
|
7409
|
+
}
|
|
7363
7410
|
}
|
|
7364
7411
|
function uiRender()
|
|
7365
7412
|
{
|
|
@@ -7438,10 +7485,11 @@ class UISystemPlugin
|
|
|
7438
7485
|
* @param {number} [lineWidth=uiSystem.defaultLineWidth]
|
|
7439
7486
|
* @param {Color} [lineColor=uiSystem.defaultLineColor]
|
|
7440
7487
|
* @param {string} [align]
|
|
7441
|
-
* @param {string} [font=uiSystem.defaultFont]
|
|
7442
|
-
|
|
7488
|
+
* @param {string} [font=uiSystem.defaultFont]
|
|
7489
|
+
* @param {boolean} [applyMaxWidth=true] */
|
|
7490
|
+
drawText(text, pos, size, color=uiSystem.defaultColor, lineWidth=uiSystem.defaultLineWidth, lineColor=uiSystem.defaultLineColor, align='center', font=uiSystem.defaultFont, applyMaxWidth=true)
|
|
7443
7491
|
{
|
|
7444
|
-
drawTextScreen(text, pos, size.y, color, lineWidth, lineColor, align, font, size.x, uiSystem.uiContext);
|
|
7492
|
+
drawTextScreen(text, pos, size.y, color, lineWidth, lineColor, align, font, applyMaxWidth ? size.x : undefined, uiSystem.uiContext);
|
|
7445
7493
|
}
|
|
7446
7494
|
}
|
|
7447
7495
|
|
|
@@ -7483,8 +7531,12 @@ class UIObject
|
|
|
7483
7531
|
this.cornerRadius = uiSystem.defaultCornerRadius;
|
|
7484
7532
|
/** @property {string} - Font for this objecct */
|
|
7485
7533
|
this.font = uiSystem.defaultFont;
|
|
7534
|
+
/** @property {number} - Override for text width */
|
|
7535
|
+
this.textWidth = undefined;
|
|
7486
7536
|
/** @property {number} - Override for text height */
|
|
7487
7537
|
this.textHeight = undefined;
|
|
7538
|
+
/** @property {number} - Scale text to fit in the object */
|
|
7539
|
+
this.textScale = uiSystem.defaultTextScale;
|
|
7488
7540
|
/** @property {boolean} - Should this object be drawn */
|
|
7489
7541
|
this.visible = true;
|
|
7490
7542
|
/** @property {Array<UIObject>} - A list of this object's children */
|
|
@@ -7594,6 +7646,16 @@ class UIObject
|
|
|
7594
7646
|
this.mouseIsOver = this.mouseIsHeld = false;
|
|
7595
7647
|
}
|
|
7596
7648
|
|
|
7649
|
+
/** Get the size for text with overrides and scale
|
|
7650
|
+
* @return {Vector2}
|
|
7651
|
+
*/
|
|
7652
|
+
getTextSize()
|
|
7653
|
+
{
|
|
7654
|
+
return vec2(
|
|
7655
|
+
this.textWidth || this.textScale * this.size.x,
|
|
7656
|
+
this.textHeight || this.textScale * this.size.y);
|
|
7657
|
+
}
|
|
7658
|
+
|
|
7597
7659
|
/** Called when the mouse enters the object */
|
|
7598
7660
|
onEnter() {}
|
|
7599
7661
|
|
|
@@ -7641,7 +7703,7 @@ class UIText extends UIObject
|
|
|
7641
7703
|
}
|
|
7642
7704
|
render()
|
|
7643
7705
|
{
|
|
7644
|
-
const textSize =
|
|
7706
|
+
const textSize = this.getTextSize();
|
|
7645
7707
|
uiSystem.drawText(this.text, this.pos, textSize, this.textColor, this.lineWidth, this.lineColor, this.align, this.font);
|
|
7646
7708
|
}
|
|
7647
7709
|
}
|
|
@@ -7709,9 +7771,8 @@ class UIButton extends UIObject
|
|
|
7709
7771
|
const color = this.disabled ? this.disabledColor : this.mouseIsOver ? this.hoverColor : this.color;
|
|
7710
7772
|
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor, this.cornerRadius);
|
|
7711
7773
|
|
|
7712
|
-
// draw the text
|
|
7713
|
-
const
|
|
7714
|
-
const textSize = vec2(this.size.x, this.textHeight || this.size.y*textScale);
|
|
7774
|
+
// draw the text scaled to fit
|
|
7775
|
+
const textSize = this.getTextSize();
|
|
7715
7776
|
uiSystem.drawText(this.text, this.pos, textSize,
|
|
7716
7777
|
this.textColor, 0, undefined, this.align, this.font);
|
|
7717
7778
|
}
|
|
@@ -7760,13 +7821,11 @@ class UICheckbox extends UIObject
|
|
|
7760
7821
|
uiSystem.drawLine(this.pos.add(s.multiply(vec2(-1,1))), this.pos.add(s.multiply(vec2(1,-1))), this.lineWidth, this.lineColor);
|
|
7761
7822
|
}
|
|
7762
7823
|
|
|
7763
|
-
// draw the text to the
|
|
7764
|
-
const
|
|
7765
|
-
const
|
|
7766
|
-
const textSize = vec2(this.size.x, this.textHeight || this.size.y*textScale);
|
|
7767
|
-
const pos = this.pos.add(vec2(this.size.x*gapScale,0));
|
|
7824
|
+
// draw the text next to the checkbox
|
|
7825
|
+
const textSize = this.getTextSize();
|
|
7826
|
+
const pos = this.pos.add(vec2(this.size.x,0));
|
|
7768
7827
|
uiSystem.drawText(this.text, pos, textSize,
|
|
7769
|
-
this.textColor, 0, undefined, 'left', this.font);
|
|
7828
|
+
this.textColor, 0, undefined, 'left', this.font, false);
|
|
7770
7829
|
}
|
|
7771
7830
|
}
|
|
7772
7831
|
|
|
@@ -7833,9 +7892,8 @@ class UIScrollbar extends UIObject
|
|
|
7833
7892
|
this.interactive && this.mouseIsHeld ? this.color : this.handleColor;
|
|
7834
7893
|
uiSystem.drawRect(handlePos, handleSize, handleColor, this.lineWidth, this.lineColor, this.cornerRadius);
|
|
7835
7894
|
|
|
7836
|
-
// draw the text on the scrollbar
|
|
7837
|
-
const
|
|
7838
|
-
const textSize = vec2(this.size.x, this.textHeight || this.size.y*textScale);
|
|
7895
|
+
// draw the text scaled to fit on the scrollbar
|
|
7896
|
+
const textSize = this.getTextSize();
|
|
7839
7897
|
uiSystem.drawText(this.text, this.pos, textSize,
|
|
7840
7898
|
this.textColor, 0, undefined, this.align, this.font);
|
|
7841
7899
|
}
|
package/examples/box2d/game.js
CHANGED
|
@@ -56,6 +56,7 @@ async function gameInit()
|
|
|
56
56
|
// start up LittleJS Box2D plugin
|
|
57
57
|
await LJS.box2dInit();
|
|
58
58
|
//LJS.box2dSetDebug(true); // enable box2d debug draw
|
|
59
|
+
LJS.setCanvasClearColor(hsl(0,0,.8));
|
|
59
60
|
|
|
60
61
|
// create a table of all sprites
|
|
61
62
|
const gameTile = (i)=> LJS.tile(i, 496, 0, 8);
|
|
@@ -136,9 +137,6 @@ function gameUpdatePost()
|
|
|
136
137
|
///////////////////////////////////////////////////////////////////////////////
|
|
137
138
|
function gameRender()
|
|
138
139
|
{
|
|
139
|
-
// draw a grey square in the background
|
|
140
|
-
LJS.drawRect(vec2(20,8), vec2(100), hsl(0,0,.8));
|
|
141
|
-
|
|
142
140
|
if (Scenes.scene == 5)
|
|
143
141
|
{
|
|
144
142
|
// raycast test
|
|
@@ -18,7 +18,7 @@ const density = 1;
|
|
|
18
18
|
const friction = .5;
|
|
19
19
|
const restitution = .2;
|
|
20
20
|
|
|
21
|
-
export function spawnBox(pos, size=1, color=LJS.WHITE, type=LJS.box2d.bodyTypeDynamic, applyTexture=
|
|
21
|
+
export function spawnBox(pos, size=1, color=LJS.WHITE, type=LJS.box2d.bodyTypeDynamic, applyTexture=false, angle=0)
|
|
22
22
|
{
|
|
23
23
|
size = typeof size === 'number' ? vec2(size) : size; // square
|
|
24
24
|
const o = new LJS.Box2dObject(pos, size, applyTexture && Game.spriteAtlas.squareOutline, angle, color, type);
|
|
@@ -27,7 +27,7 @@ export function spawnBox(pos, size=1, color=LJS.WHITE, type=LJS.box2d.bodyTypeDy
|
|
|
27
27
|
return o;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export function spawnCircle(pos, diameter=1, color=LJS.WHITE, type=LJS.box2d.bodyTypeDynamic, applyTexture=
|
|
30
|
+
export function spawnCircle(pos, diameter=1, color=LJS.WHITE, type=LJS.box2d.bodyTypeDynamic, applyTexture=false, angle=0)
|
|
31
31
|
{
|
|
32
32
|
const size = vec2(diameter);
|
|
33
33
|
const o = new LJS.Box2dObject(pos, size, applyTexture && Game.spriteAtlas.circleOutline, angle, color, type);
|
|
@@ -32,6 +32,7 @@ function gameInit()
|
|
|
32
32
|
button_exitMenu.onclick = function() { setMenuVisible(false); }
|
|
33
33
|
input_test.onchange = function() { alert('New text: ' + this.value); }
|
|
34
34
|
input_rangeTest.onchange = function() { alert('New value: ' + this.value); }
|
|
35
|
+
LJS.setCanvasClearColor(hsl(0,0,.2));
|
|
35
36
|
|
|
36
37
|
// show menu for demo
|
|
37
38
|
setMenuVisible(true);
|
|
@@ -60,7 +61,6 @@ function gameUpdatePost()
|
|
|
60
61
|
function gameRender()
|
|
61
62
|
{
|
|
62
63
|
// test game rendering
|
|
63
|
-
LJS.drawRect(vec2(), vec2(1e3), hsl(0,0,.2));
|
|
64
64
|
for (let i=0; i<1e3; ++i)
|
|
65
65
|
{
|
|
66
66
|
const time = LJS.time;
|