littlejsengine 1.15.9 → 1.16.1
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 +66 -83
- package/dist/littlejs.esm.js +318 -330
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +306 -319
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +229 -242
- package/examples/box2d/game.js +1 -1
- package/examples/breakout/game.js +3 -3
- package/examples/electron/game.js +1 -2
- package/examples/electron/index.html +2 -2
- package/examples/htmlMenu/game.js +0 -1
- package/examples/index.html +1 -1
- package/examples/module/game.js +1 -2
- package/examples/particles/index.html +1 -1
- package/examples/platformer/game.js +4 -4
- package/examples/puzzle/game.js +2 -2
- package/examples/shorts/base.html +3 -3
- package/examples/shorts/box2dPool.js +2 -2
- package/examples/shorts/empty.js +1 -1
- package/examples/shorts/{systemFont.js → fontImage.js} +3 -3
- package/examples/shorts/fps.js +1 -1
- package/examples/shorts/helloWorld.js +2 -2
- package/examples/shorts/nineSlice.js +2 -2
- package/examples/shorts/slidingPuzzle.js +1 -1
- package/examples/starter/game.js +1 -2
- package/examples/starter/index.html +2 -2
- package/examples/stress/index.html +1 -1
- package/examples/typescript/game.js +1 -2
- package/examples/typescript/game.ts +1 -2
- package/package.json +1 -1
- package/plugins/box2d.js +8 -8
- package/plugins/drawUtilities.js +6 -6
- package/plugins/postProcess.js +13 -20
- package/plugins/uiSystem.js +15 -3
- package/reference.md +4 -6
- package/src/engine.js +35 -37
- package/src/engineAudio.js +3 -3
- package/src/engineDebug.js +78 -78
- package/src/engineDraw.js +107 -109
- package/src/engineExport.js +12 -11
- package/src/engineInput.js +1 -1
- package/src/engineMedals.js +3 -3
- package/src/engineObject.js +4 -2
- package/src/engineRelease.js +1 -1
- package/src/engineSettings.js +20 -30
- package/src/engineTileLayer.js +5 -4
- package/src/engineUtilities.js +2 -10
- package/src/engineWebGL.js +6 -5
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.
|
|
36
|
+
const engineVersion = '1.16.1';
|
|
37
37
|
|
|
38
38
|
/** Frames per second to update
|
|
39
39
|
* @type {number}
|
|
@@ -180,8 +180,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
180
180
|
mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
|
|
181
181
|
|
|
182
182
|
// disable smoothing for pixel art
|
|
183
|
-
|
|
184
|
-
mainContext.imageSmoothingEnabled = !tilesPixelated;
|
|
183
|
+
mainContext.imageSmoothingEnabled = !tilesPixelated;
|
|
185
184
|
|
|
186
185
|
// setup gl rendering if enabled
|
|
187
186
|
glPreRender();
|
|
@@ -193,7 +192,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
193
192
|
// update time keeping
|
|
194
193
|
let frameTimeDeltaMS = frameTimeMS - frameTimeLastMS;
|
|
195
194
|
frameTimeLastMS = frameTimeMS;
|
|
196
|
-
if (debug ||
|
|
195
|
+
if (debug || debugWatermark)
|
|
197
196
|
averageFPS = lerp(averageFPS, 1e3/(frameTimeDeltaMS||1), .05);
|
|
198
197
|
const debugSpeedUp = debug && keyIsDown('Equal'); // +
|
|
199
198
|
const debugSpeedDown = debug && keyIsDown('Minus'); // -
|
|
@@ -221,6 +220,8 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
221
220
|
debugUpdate();
|
|
222
221
|
gameUpdatePost();
|
|
223
222
|
inputUpdatePost();
|
|
223
|
+
if (debugVideoCaptureIsActive())
|
|
224
|
+
renderFrame();
|
|
224
225
|
}
|
|
225
226
|
else
|
|
226
227
|
{
|
|
@@ -284,19 +285,19 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
284
285
|
glFlush();
|
|
285
286
|
debugVideoCaptureUpdate();
|
|
286
287
|
|
|
287
|
-
if (
|
|
288
|
+
if (debugWatermark && !debugVideoCaptureIsActive())
|
|
288
289
|
{
|
|
289
290
|
// update fps display
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
291
|
+
mainContext.textAlign = 'right';
|
|
292
|
+
mainContext.textBaseline = 'top';
|
|
293
|
+
mainContext.font = '1em monospace';
|
|
294
|
+
mainContext.fillStyle = '#000';
|
|
294
295
|
const text = engineName + ' ' + 'v' + engineVersion + ' / '
|
|
295
296
|
+ drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
|
|
296
297
|
+ (glEnable ? ' GL' : ' 2D') ;
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
298
|
+
mainContext.fillText(text, mainCanvas.width-3, 3);
|
|
299
|
+
mainContext.fillStyle = '#fff';
|
|
300
|
+
mainContext.fillText(text, mainCanvas.width-2, 2);
|
|
300
301
|
}
|
|
301
302
|
drawCount = 0;
|
|
302
303
|
}
|
|
@@ -316,8 +317,8 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
316
317
|
const fixedAspect = canvasFixedSize.x / canvasFixedSize.y;
|
|
317
318
|
const w = innerAspect < fixedAspect ? '100%' : '';
|
|
318
319
|
const h = innerAspect < fixedAspect ? '' : '100%';
|
|
319
|
-
|
|
320
|
-
|
|
320
|
+
mainCanvas.style.width = w;
|
|
321
|
+
mainCanvas.style.height = h;
|
|
321
322
|
if (glCanvas)
|
|
322
323
|
{
|
|
323
324
|
glCanvas.style.width = w;
|
|
@@ -332,6 +333,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
332
333
|
|
|
333
334
|
// responsive aspect ratio with native resolution
|
|
334
335
|
const innerAspect = innerWidth / innerHeight;
|
|
336
|
+
ASSERT(canvasMinAspect <= canvasMaxAspect);
|
|
335
337
|
if (canvasMaxAspect && innerAspect > canvasMaxAspect)
|
|
336
338
|
{
|
|
337
339
|
// full height
|
|
@@ -346,12 +348,12 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
346
348
|
}
|
|
347
349
|
}
|
|
348
350
|
|
|
349
|
-
// clear main
|
|
350
|
-
|
|
351
|
-
|
|
351
|
+
// clear main canvas and set size
|
|
352
|
+
mainCanvas.width = mainCanvasSize.x;
|
|
353
|
+
mainCanvas.height = mainCanvasSize.y;
|
|
352
354
|
|
|
353
355
|
// apply the clear color to main canvas
|
|
354
|
-
if (canvasClearColor.a > 0)
|
|
356
|
+
if (canvasClearColor.a > 0 && !glEnable)
|
|
355
357
|
{
|
|
356
358
|
mainContext.fillStyle = canvasClearColor.toString();
|
|
357
359
|
mainContext.fillRect(0, 0, mainCanvasSize.x, mainCanvasSize.y);
|
|
@@ -359,9 +361,8 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
359
361
|
}
|
|
360
362
|
|
|
361
363
|
// set default line join and cap
|
|
362
|
-
|
|
363
|
-
mainContext.
|
|
364
|
-
mainContext.lineCap = overlayContext.lineCap = lineCap;
|
|
364
|
+
mainContext.lineJoin = 'round';
|
|
365
|
+
mainContext.lineCap = 'round';
|
|
365
366
|
}
|
|
366
367
|
|
|
367
368
|
// wait for gameInit to load
|
|
@@ -373,6 +374,9 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
373
374
|
if (headlessMode)
|
|
374
375
|
return startEngine();
|
|
375
376
|
|
|
377
|
+
// setup webgl
|
|
378
|
+
glInit(rootElement);
|
|
379
|
+
|
|
376
380
|
// setup html
|
|
377
381
|
const styleRoot =
|
|
378
382
|
'margin:0;' + // fill the window
|
|
@@ -383,36 +387,30 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
383
387
|
'touch-action:none;' + // prevent mobile pinch to resize
|
|
384
388
|
'-webkit-touch-callout:none'; // compatibility for ios
|
|
385
389
|
rootElement.style.cssText = styleRoot;
|
|
386
|
-
drawCanvas = mainCanvas = document.createElement('canvas');
|
|
387
|
-
rootElement.appendChild(mainCanvas);
|
|
390
|
+
drawCanvas = mainCanvas = rootElement.appendChild(document.createElement('canvas'));
|
|
388
391
|
drawContext = mainContext = mainCanvas.getContext('2d');
|
|
389
392
|
|
|
390
393
|
// init stuff and start engine
|
|
391
394
|
inputInit();
|
|
392
395
|
audioInit();
|
|
393
396
|
debugInit();
|
|
394
|
-
glInit();
|
|
395
|
-
|
|
396
|
-
// create overlay canvas for hud to appear above gl canvas
|
|
397
|
-
overlayCanvas = document.createElement('canvas')
|
|
398
|
-
rootElement.appendChild(overlayCanvas);
|
|
399
|
-
overlayContext = overlayCanvas.getContext('2d');
|
|
400
397
|
|
|
401
398
|
// setup canvases
|
|
402
399
|
// transform way is still more reliable then flexbox or grid
|
|
403
400
|
const styleCanvas = 'position:absolute;'+ // allow canvases to overlap
|
|
404
401
|
'top:50%;left:50%;transform:translate(-50%,-50%)'; // center on screen
|
|
405
|
-
mainCanvas.style.cssText =
|
|
402
|
+
mainCanvas.style.cssText = styleCanvas;
|
|
406
403
|
if (glCanvas)
|
|
407
404
|
glCanvas.style.cssText = styleCanvas;
|
|
408
405
|
setCanvasPixelated(canvasPixelated);
|
|
409
|
-
setOverlayCanvasPixelated(overlayCanvasPixelated);
|
|
410
406
|
updateCanvas();
|
|
411
407
|
glPreRender();
|
|
412
408
|
|
|
413
|
-
// create offscreen
|
|
414
|
-
workCanvas = new OffscreenCanvas(
|
|
415
|
-
workContext = workCanvas.getContext('2d'
|
|
409
|
+
// create offscreen canvases for image processing
|
|
410
|
+
workCanvas = new OffscreenCanvas(64, 64);
|
|
411
|
+
workContext = workCanvas.getContext('2d');
|
|
412
|
+
workReadCanvas = new OffscreenCanvas(64, 64);
|
|
413
|
+
workReadContext = workReadCanvas.getContext('2d', { willReadFrequently: true });
|
|
416
414
|
|
|
417
415
|
// create promises for loading images
|
|
418
416
|
const promises = imageSources.map((src, textureIndex)=>
|
|
@@ -468,9 +466,9 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
468
466
|
// LittleJS Splash Screen
|
|
469
467
|
function drawEngineSplashScreen(t)
|
|
470
468
|
{
|
|
471
|
-
const x =
|
|
472
|
-
const w =
|
|
473
|
-
const h =
|
|
469
|
+
const x = mainContext;
|
|
470
|
+
const w = mainCanvas.width = innerWidth;
|
|
471
|
+
const h = mainCanvas.height = innerHeight;
|
|
474
472
|
|
|
475
473
|
{
|
|
476
474
|
// background
|
|
@@ -748,7 +746,7 @@ function engineObjectsRaycast(start, end, objects=engineObjects)
|
|
|
748
746
|
* - Debug functionality is disabled to reduce size and increase performance
|
|
749
747
|
*/
|
|
750
748
|
|
|
751
|
-
let
|
|
749
|
+
let debugWatermark = 0;
|
|
752
750
|
let debugKey = '';
|
|
753
751
|
const debug = 0;
|
|
754
752
|
const debugOverlay = 0;
|
|
@@ -908,11 +906,7 @@ function percent(value, valueA, valueB)
|
|
|
908
906
|
* @return {number}
|
|
909
907
|
* @memberof Utilities */
|
|
910
908
|
function lerp(valueA, valueB, percent)
|
|
911
|
-
{
|
|
912
|
-
if (valueA >= 0 && valueA <= 1 && ((valueB < 0 || valueB > 1) && (percent < 0 || percent > 1)))
|
|
913
|
-
console.warn('lerp() parameter order changed! use lerp(start, end, p)');
|
|
914
|
-
return valueA + clamp(percent) * (valueB-valueA);
|
|
915
|
-
}
|
|
909
|
+
{ return valueA + clamp(percent) * (valueB-valueA); }
|
|
916
910
|
|
|
917
911
|
/** Gets percent between percentA and percentB and linearly interpolates between lerpA and lerpB
|
|
918
912
|
* A shortcut for lerp(lerpA, lerpB, percent(value, percentA, percentB))
|
|
@@ -943,11 +937,7 @@ function distanceWrap(valueA, valueB, wrapSize=1)
|
|
|
943
937
|
* @return {number}
|
|
944
938
|
* @memberof Utilities */
|
|
945
939
|
function lerpWrap(valueA, valueB, percent, wrapSize=1)
|
|
946
|
-
{
|
|
947
|
-
if (valueA >= 0 && valueA <= 1 && ((valueB < 0 || valueB > 1) && (percent < 0 || percent > 1)))
|
|
948
|
-
console.warn('lerpWrap() parameter order changed! use lerpWrap(start, end, p)');
|
|
949
|
-
return valueA + clamp(percent) * distanceWrap(valueB, valueA, wrapSize);
|
|
950
|
-
}
|
|
940
|
+
{ return valueA + clamp(percent) * distanceWrap(valueB, valueA, wrapSize); }
|
|
951
941
|
|
|
952
942
|
/** Returns signed wrapped distance between the two angles passed in
|
|
953
943
|
* @param {number} angleA
|
|
@@ -2087,15 +2077,7 @@ let canvasFixedSize = vec2();
|
|
|
2087
2077
|
* @type {boolean}
|
|
2088
2078
|
* @default
|
|
2089
2079
|
* @memberof Settings */
|
|
2090
|
-
let canvasPixelated =
|
|
2091
|
-
|
|
2092
|
-
/** Use nearest canvas scaling for more pixelated look
|
|
2093
|
-
* - If enabled sets css image-rendering:pixelated
|
|
2094
|
-
* - This defaults to false because text looks better with smoothing
|
|
2095
|
-
* @type {boolean}
|
|
2096
|
-
* @default
|
|
2097
|
-
* @memberof Settings */
|
|
2098
|
-
let overlayCanvasPixelated = false;
|
|
2080
|
+
let canvasPixelated = false;
|
|
2099
2081
|
|
|
2100
2082
|
/** Disables texture filtering for crisper pixel art
|
|
2101
2083
|
* @type {boolean}
|
|
@@ -2143,13 +2125,19 @@ let glCircleSides = 32;
|
|
|
2143
2125
|
* @type {Vector2}
|
|
2144
2126
|
* @default Vector2(16,16)
|
|
2145
2127
|
* @memberof Settings */
|
|
2146
|
-
let
|
|
2128
|
+
let tileDefaultSize = vec2(16);
|
|
2147
2129
|
|
|
2148
|
-
/**
|
|
2130
|
+
/** Default padding pixels around tiles
|
|
2149
2131
|
* @type {number}
|
|
2150
2132
|
* @default
|
|
2151
2133
|
* @memberof Settings */
|
|
2152
|
-
let
|
|
2134
|
+
let tileDefaultPadding = 0;
|
|
2135
|
+
|
|
2136
|
+
/** Default amount of pixels smaller to draw tiles to prevent neighbor bleeding
|
|
2137
|
+
* @type {number}
|
|
2138
|
+
* @default
|
|
2139
|
+
* @memberof Settings */
|
|
2140
|
+
let tileDefaultBleed = 0;
|
|
2153
2141
|
|
|
2154
2142
|
///////////////////////////////////////////////////////////////////////////////
|
|
2155
2143
|
// Object settings
|
|
@@ -2387,7 +2375,6 @@ function setCanvasMaxAspect(aspect) { canvasMaxAspect = aspect; }
|
|
|
2387
2375
|
function setCanvasFixedSize(size) { canvasFixedSize = size.copy(); }
|
|
2388
2376
|
|
|
2389
2377
|
/** Use nearest scaling algorithm for canvas for more pixelated look
|
|
2390
|
-
* - If enabled sets css image-rendering:pixelated
|
|
2391
2378
|
* @param {boolean} pixelated
|
|
2392
2379
|
* @memberof Settings */
|
|
2393
2380
|
function setCanvasPixelated(pixelated)
|
|
@@ -2399,18 +2386,6 @@ function setCanvasPixelated(pixelated)
|
|
|
2399
2386
|
glCanvas.style.imageRendering = pixelated ? 'pixelated' : '';
|
|
2400
2387
|
}
|
|
2401
2388
|
|
|
2402
|
-
/** Use nearest scaling algorithm for canvas for more pixelated look
|
|
2403
|
-
* - If enabled sets css image-rendering:pixelated
|
|
2404
|
-
* - This defaults to false because text looks better with smoothing
|
|
2405
|
-
* @param {boolean} pixelated
|
|
2406
|
-
* @memberof Settings */
|
|
2407
|
-
function setOverlayCanvasPixelated(pixelated)
|
|
2408
|
-
{
|
|
2409
|
-
overlayCanvasPixelated = pixelated;
|
|
2410
|
-
if (overlayCanvas)
|
|
2411
|
-
overlayCanvas.style.imageRendering = pixelated ? 'pixelated' : '';
|
|
2412
|
-
}
|
|
2413
|
-
|
|
2414
2389
|
/** Disables texture filtering for crisper pixel art
|
|
2415
2390
|
* @param {boolean} pixelated
|
|
2416
2391
|
* @memberof Settings */
|
|
@@ -2454,12 +2429,17 @@ function setGLCircleSides(sides) { glCircleSides = sides; }
|
|
|
2454
2429
|
/** Set default size of tiles in pixels
|
|
2455
2430
|
* @param {Vector2} size
|
|
2456
2431
|
* @memberof Settings */
|
|
2457
|
-
function
|
|
2432
|
+
function setTileDefaultSize(size) { tileDefaultSize = size.copy(); }
|
|
2458
2433
|
|
|
2459
|
-
/**
|
|
2460
|
-
* @param {number}
|
|
2434
|
+
/** Default padding pixels around tiles
|
|
2435
|
+
* @param {number} padding
|
|
2461
2436
|
* @memberof Settings */
|
|
2462
|
-
function
|
|
2437
|
+
function setTileDefaultPadding(padding) { tileDefaultPadding = padding; }
|
|
2438
|
+
|
|
2439
|
+
/** Default amount of pixels smaller to draw tiles to prevent neighbor bleeding
|
|
2440
|
+
* @param {number} bleed
|
|
2441
|
+
* @memberof Settings */
|
|
2442
|
+
function setTileDefaultBleed(bleed) { tileDefaultBleed = bleed; }
|
|
2463
2443
|
|
|
2464
2444
|
/** Set if collisions between objects are enabled
|
|
2465
2445
|
* @param {boolean} enable
|
|
@@ -2610,7 +2590,7 @@ function setMedalsPreventUnlock(preventUnlock) { medalsPreventUnlock = preventUn
|
|
|
2610
2590
|
/** Set if watermark with FPS should be shown
|
|
2611
2591
|
* @param {boolean} show
|
|
2612
2592
|
* @memberof Debug */
|
|
2613
|
-
function
|
|
2593
|
+
function setDebugWatermark(show) { debugWatermark = show; }
|
|
2614
2594
|
|
|
2615
2595
|
/** Set key code used to toggle debug mode, Esc by default
|
|
2616
2596
|
* @param {string} key
|
|
@@ -3046,10 +3026,11 @@ class EngineObject
|
|
|
3046
3026
|
* @return {number} -1 if this.mirror is true, or 1 if not mirrored */
|
|
3047
3027
|
getMirrorSign() { return this.mirror ? -1 : 1; }
|
|
3048
3028
|
|
|
3049
|
-
/** Attaches a child to this with a
|
|
3029
|
+
/** Attaches a child to this with a local transform, returns child for chaining
|
|
3050
3030
|
* @param {EngineObject} child
|
|
3051
3031
|
* @param {Vector2} [localPos=(0,0)]
|
|
3052
|
-
* @param {number} [localAngle]
|
|
3032
|
+
* @param {number} [localAngle]
|
|
3033
|
+
* @return {EngineObject} The child object added */
|
|
3053
3034
|
addChild(child, localPos=vec2(), localAngle=0)
|
|
3054
3035
|
{
|
|
3055
3036
|
ASSERT(!child.parent && !this.children.includes(child));
|
|
@@ -3059,6 +3040,7 @@ class EngineObject
|
|
|
3059
3040
|
child.parent = this;
|
|
3060
3041
|
child.localPos = localPos.copy();
|
|
3061
3042
|
child.localAngle = localAngle;
|
|
3043
|
+
return child;
|
|
3062
3044
|
}
|
|
3063
3045
|
|
|
3064
3046
|
/** Removes a child from this one
|
|
@@ -3149,7 +3131,6 @@ class EngineObject
|
|
|
3149
3131
|
* There are 3 canvas/contexts available to draw to...
|
|
3150
3132
|
* mainCanvas - 2D background canvas, non WebGL stuff like tile layers are drawn here.
|
|
3151
3133
|
* glCanvas - Used by the accelerated WebGL batch rendering system.
|
|
3152
|
-
* overlayCanvas - Another 2D canvas that appears on top of the other 2 canvases.
|
|
3153
3134
|
*
|
|
3154
3135
|
* The WebGL rendering system is very fast with some caveats...
|
|
3155
3136
|
* - Switching blend modes (additive) or textures causes another draw call which is expensive in excess
|
|
@@ -3169,16 +3150,6 @@ let mainCanvas;
|
|
|
3169
3150
|
* @memberof Draw */
|
|
3170
3151
|
let mainContext;
|
|
3171
3152
|
|
|
3172
|
-
/** A canvas that appears on top of everything the same size as mainCanvas
|
|
3173
|
-
* @type {HTMLCanvasElement}
|
|
3174
|
-
* @memberof Draw */
|
|
3175
|
-
let overlayCanvas;
|
|
3176
|
-
|
|
3177
|
-
/** 2d context for overlayCanvas
|
|
3178
|
-
* @type {CanvasRenderingContext2D}
|
|
3179
|
-
* @memberof Draw */
|
|
3180
|
-
let overlayContext;
|
|
3181
|
-
|
|
3182
3153
|
/** The default canvas to use for drawing, usually mainCanvas
|
|
3183
3154
|
* @type {HTMLCanvasElement|OffscreenCanvas}
|
|
3184
3155
|
* @memberof Draw */
|
|
@@ -3199,6 +3170,16 @@ let workCanvas;
|
|
|
3199
3170
|
* @memberof Draw */
|
|
3200
3171
|
let workContext;
|
|
3201
3172
|
|
|
3173
|
+
/** Offscreen canvas with willReadFrequently that can be used for image processing
|
|
3174
|
+
* @type {OffscreenCanvas}
|
|
3175
|
+
* @memberof Draw */
|
|
3176
|
+
let workReadCanvas;
|
|
3177
|
+
|
|
3178
|
+
/** Offscreen canvas with willReadFrequently that can be used for image processing
|
|
3179
|
+
* @type {OffscreenCanvasRenderingContext2D}
|
|
3180
|
+
* @memberof Draw */
|
|
3181
|
+
let workReadContext;
|
|
3182
|
+
|
|
3202
3183
|
/** The size of the main canvas (and other secondary canvases)
|
|
3203
3184
|
* @type {Vector2}
|
|
3204
3185
|
* @memberof Draw */
|
|
@@ -3221,7 +3202,7 @@ let drawCount;
|
|
|
3221
3202
|
* - This can take vecs or floats for easier use and conversion
|
|
3222
3203
|
* - If an index is passed in, the tile size and index will determine the position
|
|
3223
3204
|
* @param {Vector2|number} [pos=0] - Position of the tile in pixels, or tile index
|
|
3224
|
-
* @param {Vector2|number} [size
|
|
3205
|
+
* @param {Vector2|number} [size] - Size of tile in pixels
|
|
3225
3206
|
* @param {number} [textureIndex] - Texture index to use
|
|
3226
3207
|
* @param {number} [padding] - How many pixels padding around tiles
|
|
3227
3208
|
* @return {TileInfo}
|
|
@@ -3231,7 +3212,7 @@ let drawCount;
|
|
|
3231
3212
|
* tile(1, 16, 3) // a tile at index 1 of size 16 on texture 3
|
|
3232
3213
|
* tile(vec2(4,8), vec2(30,10)) // a tile at index (4,8) with a size of (30,10)
|
|
3233
3214
|
* @memberof Draw */
|
|
3234
|
-
function tile(pos=new Vector2, size=
|
|
3215
|
+
function tile(pos=new Vector2, size=tileDefaultSize, textureIndex=0, padding=tileDefaultPadding)
|
|
3235
3216
|
{
|
|
3236
3217
|
if (headlessMode)
|
|
3237
3218
|
return new TileInfo;
|
|
@@ -3270,13 +3251,13 @@ function tile(pos=new Vector2, size=tileSizeDefault, textureIndex=0, padding=0)
|
|
|
3270
3251
|
class TileInfo
|
|
3271
3252
|
{
|
|
3272
3253
|
/** Create a tile info object
|
|
3273
|
-
* @param {Vector2} [pos=(0,0)]
|
|
3274
|
-
* @param {Vector2} [size
|
|
3275
|
-
* @param {number} [textureIndex]
|
|
3276
|
-
* @param {number} [padding]
|
|
3277
|
-
* @param {number} [
|
|
3254
|
+
* @param {Vector2} [pos=(0,0)] - Top left corner of tile in pixels
|
|
3255
|
+
* @param {Vector2} [size] - Size of tile in pixels
|
|
3256
|
+
* @param {number} [textureIndex] - Texture index to use
|
|
3257
|
+
* @param {number} [padding] - How many pixels padding around tiles
|
|
3258
|
+
* @param {number} [bleed] - How many pixels smaller to draw tiles
|
|
3278
3259
|
*/
|
|
3279
|
-
constructor(pos=vec2(), size=
|
|
3260
|
+
constructor(pos=vec2(), size=tileDefaultSize, textureIndex=0, padding=tileDefaultPadding, bleed=tileDefaultBleed)
|
|
3280
3261
|
{
|
|
3281
3262
|
/** @property {Vector2} - Top left corner of tile in pixels */
|
|
3282
3263
|
this.pos = pos.copy();
|
|
@@ -3289,7 +3270,7 @@ class TileInfo
|
|
|
3289
3270
|
/** @property {TextureInfo} - The texture info for this tile */
|
|
3290
3271
|
this.textureInfo = textureInfos[this.textureIndex];
|
|
3291
3272
|
/** @property {number} - Shrinks tile by this many pixels to prevent neighbors bleeding */
|
|
3292
|
-
this.
|
|
3273
|
+
this.bleed = bleed;
|
|
3293
3274
|
}
|
|
3294
3275
|
|
|
3295
3276
|
/** Returns a copy of this tile offset by a vector
|
|
@@ -3297,7 +3278,7 @@ class TileInfo
|
|
|
3297
3278
|
* @return {TileInfo}
|
|
3298
3279
|
*/
|
|
3299
3280
|
offset(offset)
|
|
3300
|
-
{ return new TileInfo(this.pos.add(offset), this.size, this.textureIndex, this.padding, this.
|
|
3281
|
+
{ return new TileInfo(this.pos.add(offset), this.size, this.textureIndex, this.padding, this.bleed); }
|
|
3301
3282
|
|
|
3302
3283
|
/** Returns a copy of this tile offset by a number of animation frames
|
|
3303
3284
|
* @param {number} frame - Offset to apply in animation frames
|
|
@@ -3320,7 +3301,7 @@ class TileInfo
|
|
|
3320
3301
|
this.size = textureInfo.size.copy();
|
|
3321
3302
|
this.textureInfo = textureInfo;
|
|
3322
3303
|
// do not use padding or bleed
|
|
3323
|
-
this.
|
|
3304
|
+
this.bleed = this.padding = 0;
|
|
3324
3305
|
return this;
|
|
3325
3306
|
}
|
|
3326
3307
|
}
|
|
@@ -3386,7 +3367,7 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
3386
3367
|
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
3387
3368
|
|
|
3388
3369
|
const textureInfo = tileInfo && tileInfo.textureInfo;
|
|
3389
|
-
const
|
|
3370
|
+
const bleed = tileInfo?.bleed ?? 0;
|
|
3390
3371
|
if (useWebGL && glEnable)
|
|
3391
3372
|
{
|
|
3392
3373
|
ASSERT(!!glContext, 'WebGL is not enabled!');
|
|
@@ -3401,13 +3382,13 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
3401
3382
|
const w = tileInfo.size.x * sizeInverse.x;
|
|
3402
3383
|
const h = tileInfo.size.y * sizeInverse.y;
|
|
3403
3384
|
glSetTexture(textureInfo.glTexture);
|
|
3404
|
-
if (
|
|
3385
|
+
if (bleed)
|
|
3405
3386
|
{
|
|
3406
|
-
const
|
|
3407
|
-
const
|
|
3387
|
+
const bleedX = sizeInverse.x*bleed;
|
|
3388
|
+
const bleedY = sizeInverse.y*bleed;
|
|
3408
3389
|
glDraw(pos.x, pos.y, mirror ? -size.x : size.x, size.y, angle,
|
|
3409
|
-
x +
|
|
3410
|
-
x -
|
|
3390
|
+
x + bleedX, y + bleedY,
|
|
3391
|
+
x - bleedX + w, y - bleedY + h,
|
|
3411
3392
|
color.rgbaInt(), additiveColor && additiveColor.rgbaInt());
|
|
3412
3393
|
}
|
|
3413
3394
|
else
|
|
@@ -3435,7 +3416,7 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
|
3435
3416
|
// calculate uvs and render
|
|
3436
3417
|
const x = tileInfo.pos.x, y = tileInfo.pos.y;
|
|
3437
3418
|
const w = tileInfo.size.x, h = tileInfo.size.y;
|
|
3438
|
-
drawImageColor(context, textureInfo.image, x, y, w, h, -.5, -.5, 1, 1, color, additiveColor,
|
|
3419
|
+
drawImageColor(context, textureInfo.image, x, y, w, h, -.5, -.5, 1, 1, color, additiveColor, bleed);
|
|
3439
3420
|
}
|
|
3440
3421
|
else
|
|
3441
3422
|
{
|
|
@@ -3800,26 +3781,7 @@ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, f
|
|
|
3800
3781
|
drawTextScreen(text, pos, size, color, lineWidth, lineColor, textAlign, font, fontStyle, maxWidth, angle, context);
|
|
3801
3782
|
}
|
|
3802
3783
|
|
|
3803
|
-
/** Draw text
|
|
3804
|
-
* Automatically splits new lines into rows
|
|
3805
|
-
* @param {string|number} text
|
|
3806
|
-
* @param {Vector2} pos
|
|
3807
|
-
* @param {number} [size]
|
|
3808
|
-
* @param {Color} [color=(1,1,1,1)]
|
|
3809
|
-
* @param {number} [lineWidth]
|
|
3810
|
-
* @param {Color} [lineColor=(0,0,0,1)]
|
|
3811
|
-
* @param {CanvasTextAlign} [textAlign='center']
|
|
3812
|
-
* @param {string} [font=fontDefault]
|
|
3813
|
-
* @param {string} [fontStyle]
|
|
3814
|
-
* @param {number} [maxWidth]
|
|
3815
|
-
* @param {number} [angle]
|
|
3816
|
-
* @memberof Draw */
|
|
3817
|
-
function drawTextOverlay(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font, fontStyle, maxWidth, angle=0)
|
|
3818
|
-
{
|
|
3819
|
-
drawText(text, pos, size, color, lineWidth, lineColor, textAlign, font, fontStyle, maxWidth, angle, overlayContext);
|
|
3820
|
-
}
|
|
3821
|
-
|
|
3822
|
-
/** Draw text on overlay canvas in screen space
|
|
3784
|
+
/** Draw text in screen space
|
|
3823
3785
|
* Automatically splits new lines into rows
|
|
3824
3786
|
* @param {string|number} text
|
|
3825
3787
|
* @param {Vector2} pos
|
|
@@ -3832,9 +3794,9 @@ function drawTextOverlay(text, pos, size=1, color, lineWidth=0, lineColor, textA
|
|
|
3832
3794
|
* @param {string} [fontStyle]
|
|
3833
3795
|
* @param {number} [maxWidth]
|
|
3834
3796
|
* @param {number} [angle]
|
|
3835
|
-
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=
|
|
3797
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
|
|
3836
3798
|
* @memberof Draw */
|
|
3837
|
-
function drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK, textAlign='center', font=fontDefault, fontStyle='', maxWidth, angle=0, context=
|
|
3799
|
+
function drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK, textAlign='center', font=fontDefault, fontStyle='', maxWidth, angle=0, context=mainContext)
|
|
3838
3800
|
{
|
|
3839
3801
|
ASSERT(isString(text), 'text must be a string');
|
|
3840
3802
|
ASSERT(isVector2(pos), 'pos must be a vec2');
|
|
@@ -3878,16 +3840,16 @@ function drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=B
|
|
|
3878
3840
|
* @memberof Draw */
|
|
3879
3841
|
function screenToWorld(screenPos)
|
|
3880
3842
|
{
|
|
3843
|
+
ASSERT(isVector2(screenPos), 'screenPos must be a vec2');
|
|
3844
|
+
|
|
3881
3845
|
let x = (screenPos.x - mainCanvasSize.x/2 + .5) / cameraScale;
|
|
3882
3846
|
let y = (screenPos.y - mainCanvasSize.y/2 + .5) / -cameraScale;
|
|
3883
3847
|
if (cameraAngle)
|
|
3884
3848
|
{
|
|
3885
3849
|
// apply camera rotation
|
|
3886
3850
|
const c = cos(-cameraAngle), s = sin(-cameraAngle);
|
|
3887
|
-
const
|
|
3888
|
-
|
|
3889
|
-
x = rotatedX;
|
|
3890
|
-
y = rotatedY;
|
|
3851
|
+
const xr = x * c - y * s, yr = x * s + y * c;
|
|
3852
|
+
x = xr; y = yr;
|
|
3891
3853
|
}
|
|
3892
3854
|
return new Vector2(x + cameraPos.x, y + cameraPos.y);
|
|
3893
3855
|
}
|
|
@@ -3898,16 +3860,16 @@ function screenToWorld(screenPos)
|
|
|
3898
3860
|
* @memberof Draw */
|
|
3899
3861
|
function worldToScreen(worldPos)
|
|
3900
3862
|
{
|
|
3863
|
+
ASSERT(isVector2(worldPos), 'worldPos must be a vec2');
|
|
3864
|
+
|
|
3901
3865
|
let x = worldPos.x - cameraPos.x;
|
|
3902
3866
|
let y = worldPos.y - cameraPos.y;
|
|
3903
3867
|
if (cameraAngle)
|
|
3904
3868
|
{
|
|
3905
3869
|
// apply inverse camera rotation
|
|
3906
3870
|
const c = cos(cameraAngle), s = sin(cameraAngle);
|
|
3907
|
-
const
|
|
3908
|
-
|
|
3909
|
-
x = rotatedX;
|
|
3910
|
-
y = rotatedY;
|
|
3871
|
+
const xr = x * c - y * s, yr = x * s + y * c;
|
|
3872
|
+
x = xr; y = yr;
|
|
3911
3873
|
}
|
|
3912
3874
|
return new Vector2
|
|
3913
3875
|
(
|
|
@@ -3922,16 +3884,16 @@ function worldToScreen(worldPos)
|
|
|
3922
3884
|
* @memberof Draw */
|
|
3923
3885
|
function screenToWorldDelta(screenDelta)
|
|
3924
3886
|
{
|
|
3887
|
+
ASSERT(isVector2(screenDelta), 'screenDelta must be a vec2');
|
|
3888
|
+
|
|
3925
3889
|
let x = screenDelta.x / cameraScale;
|
|
3926
3890
|
let y = screenDelta.y / -cameraScale;
|
|
3927
3891
|
if (cameraAngle)
|
|
3928
3892
|
{
|
|
3929
3893
|
// apply camera rotation
|
|
3930
3894
|
const c = cos(-cameraAngle), s = sin(-cameraAngle);
|
|
3931
|
-
const
|
|
3932
|
-
|
|
3933
|
-
x = rotatedX;
|
|
3934
|
-
y = rotatedY;
|
|
3895
|
+
const xr = x * c - y * s, yr = x * s + y * c;
|
|
3896
|
+
x = xr; y = yr;
|
|
3935
3897
|
}
|
|
3936
3898
|
return new Vector2(x, y);
|
|
3937
3899
|
}
|
|
@@ -3942,16 +3904,16 @@ function screenToWorldDelta(screenDelta)
|
|
|
3942
3904
|
* @memberof Draw */
|
|
3943
3905
|
function worldToScreenDelta(worldDelta)
|
|
3944
3906
|
{
|
|
3907
|
+
ASSERT(isVector2(worldDelta), 'worldDelta must be a vec2');
|
|
3908
|
+
|
|
3945
3909
|
let x = worldDelta.x;
|
|
3946
3910
|
let y = worldDelta.y;
|
|
3947
3911
|
if (cameraAngle)
|
|
3948
3912
|
{
|
|
3949
3913
|
// apply inverse camera rotation
|
|
3950
3914
|
const c = cos(cameraAngle), s = sin(cameraAngle);
|
|
3951
|
-
const
|
|
3952
|
-
|
|
3953
|
-
x = rotatedX;
|
|
3954
|
-
y = rotatedY;
|
|
3915
|
+
const xr = x * c - y * s, yr = x * s + y * c;
|
|
3916
|
+
x = xr; y = yr;
|
|
3955
3917
|
}
|
|
3956
3918
|
return new Vector2(x * cameraScale, y * -cameraScale);
|
|
3957
3919
|
}
|
|
@@ -3964,6 +3926,10 @@ function worldToScreenDelta(worldDelta)
|
|
|
3964
3926
|
* @memberof Draw */
|
|
3965
3927
|
function screenToWorldTransform(screenPos, screenSize, screenAngle=0)
|
|
3966
3928
|
{
|
|
3929
|
+
ASSERT(isVector2(screenPos), 'screenPos must be a vec2');
|
|
3930
|
+
ASSERT(isVector2(screenSize), 'screenSize must be a vec2');
|
|
3931
|
+
ASSERT(isNumber(screenAngle), 'screenAngle must be a number');
|
|
3932
|
+
|
|
3967
3933
|
return [
|
|
3968
3934
|
screenToWorld(screenPos),
|
|
3969
3935
|
screenSize.scale(1/cameraScale),
|
|
@@ -3979,6 +3945,10 @@ function screenToWorldTransform(screenPos, screenSize, screenAngle=0)
|
|
|
3979
3945
|
* @memberof Draw */
|
|
3980
3946
|
function worldToScreenTransform(worldPos, worldSize, worldAngle=0)
|
|
3981
3947
|
{
|
|
3948
|
+
ASSERT(isVector2(worldPos), 'worldPos must be a vec2');
|
|
3949
|
+
ASSERT(isVector2(worldSize), 'worldSize must be a vec2');
|
|
3950
|
+
ASSERT(isNumber(worldAngle), 'worldAngle must be a number');
|
|
3951
|
+
|
|
3982
3952
|
return [
|
|
3983
3953
|
worldToScreen(worldPos),
|
|
3984
3954
|
worldSize.scale(cameraScale),
|
|
@@ -3991,8 +3961,8 @@ function worldToScreenTransform(worldPos, worldSize, worldAngle=0)
|
|
|
3991
3961
|
* @memberof Draw */
|
|
3992
3962
|
function getCameraSize() { return mainCanvasSize.scale(1/cameraScale); }
|
|
3993
3963
|
|
|
3994
|
-
/** Check if a point or circle is on screen
|
|
3995
|
-
* If size is a Vector2, uses the
|
|
3964
|
+
/** Check if a box, point, or circle is on screen with a circle test
|
|
3965
|
+
* If size is a Vector2, uses the length as diameter
|
|
3996
3966
|
* This can be used to cull offscreen objects from render or update
|
|
3997
3967
|
* @param {Vector2} pos - world space position
|
|
3998
3968
|
* @param {Vector2|number} size - world space size or diameter
|
|
@@ -4000,12 +3970,30 @@ function getCameraSize() { return mainCanvasSize.scale(1/cameraScale); }
|
|
|
4000
3970
|
* @memberof Draw */
|
|
4001
3971
|
function isOnScreen(pos, size=0)
|
|
4002
3972
|
{
|
|
4003
|
-
pos
|
|
3973
|
+
ASSERT(isVector2(pos), 'pos must be a vec2');
|
|
3974
|
+
ASSERT(isVector2(size) || isNumber(size), 'size must be a vec2 or number');
|
|
3975
|
+
|
|
3976
|
+
// optimized circle on screen test
|
|
3977
|
+
// pos = worldToScreen(pos);
|
|
3978
|
+
let x = pos.x - cameraPos.x;
|
|
3979
|
+
let y = pos.y - cameraPos.y;
|
|
3980
|
+
if (cameraAngle)
|
|
3981
|
+
{
|
|
3982
|
+
// apply inverse camera rotation
|
|
3983
|
+
const c = cos(cameraAngle), s = sin(cameraAngle);
|
|
3984
|
+
const xr = x * c - y * s, yr = x * s + y * c;
|
|
3985
|
+
x = xr; y = yr;
|
|
3986
|
+
}
|
|
3987
|
+
x *= cameraScale*2; y *= -cameraScale*2;
|
|
3988
|
+
|
|
4004
3989
|
if (size instanceof Vector2)
|
|
4005
|
-
size =
|
|
4006
|
-
size *= cameraScale
|
|
4007
|
-
|
|
4008
|
-
|
|
3990
|
+
size = size.length(); // use length of vector as diameter
|
|
3991
|
+
size *= cameraScale;
|
|
3992
|
+
|
|
3993
|
+
// check against screen bounds
|
|
3994
|
+
const w = mainCanvasSize.x, h = mainCanvasSize.y;
|
|
3995
|
+
return x + size > -w && x - size < w &&
|
|
3996
|
+
y + size > -h && y - size < h;
|
|
4009
3997
|
}
|
|
4010
3998
|
|
|
4011
3999
|
/** Enable normal or additive blend mode
|
|
@@ -4019,18 +4007,19 @@ function setBlendMode(additive=false, context)
|
|
|
4019
4007
|
context.globalCompositeOperation = additive ? 'lighter' : 'source-over';
|
|
4020
4008
|
}
|
|
4021
4009
|
|
|
4022
|
-
/** Combines
|
|
4023
|
-
* This is necessary for things like
|
|
4010
|
+
/** Combines LittleJS canvases onto the main canvas
|
|
4011
|
+
* This is necessary for things like screenshots and video
|
|
4024
4012
|
* @memberof Draw */
|
|
4025
4013
|
function combineCanvases()
|
|
4026
4014
|
{
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4015
|
+
const w = mainCanvasSize.x, h = mainCanvasSize.y;
|
|
4016
|
+
workCanvas.width = w;
|
|
4017
|
+
workCanvas.height = h;
|
|
4018
|
+
workContext.fillRect(0,0,w,h); // remove background alpha
|
|
4019
|
+
glCopyToContext(workContext);
|
|
4020
|
+
workContext.drawImage(mainCanvas, 0, 0);
|
|
4021
|
+
mainCanvas.width |= 0;
|
|
4022
|
+
mainContext.drawImage(workCanvas, 0, 0);
|
|
4034
4023
|
}
|
|
4035
4024
|
|
|
4036
4025
|
/** Helper function to draw an image with color and additive color applied
|
|
@@ -4047,18 +4036,18 @@ function combineCanvases()
|
|
|
4047
4036
|
* @param {number} dHeight
|
|
4048
4037
|
* @param {Color} color
|
|
4049
4038
|
* @param {Color} [additiveColor]
|
|
4050
|
-
* @param {number} [
|
|
4039
|
+
* @param {number} [bleed] - How many pixels to shrink the source, used to fix bleeding
|
|
4051
4040
|
* @memberof Draw */
|
|
4052
|
-
function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight, color, additiveColor,
|
|
4041
|
+
function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight, color, additiveColor, bleed=0)
|
|
4053
4042
|
{
|
|
4054
4043
|
function isWhite(c) { return c.r >= 1 && c.g >= 1 && c.b >= 1; }
|
|
4055
4044
|
function isBlack(c) { return c.r <= 0 && c.g <= 0 && c.b <= 0 && c.a <= 0; }
|
|
4056
|
-
const sx2 =
|
|
4057
|
-
const sy2 =
|
|
4045
|
+
const sx2 = bleed;
|
|
4046
|
+
const sy2 = bleed;
|
|
4058
4047
|
sWidth = max(1,sWidth|0);
|
|
4059
4048
|
sHeight = max(1,sHeight|0);
|
|
4060
|
-
const sWidth2 = sWidth - 2*
|
|
4061
|
-
const sHeight2 = sHeight - 2*
|
|
4049
|
+
const sWidth2 = sWidth - 2*bleed;
|
|
4050
|
+
const sHeight2 = sHeight - 2*bleed;
|
|
4062
4051
|
if (!canvasColorTiles || (additiveColor ? isWhite(color.add(additiveColor)) && additiveColor.a <= 0 : isWhite(color)))
|
|
4063
4052
|
{
|
|
4064
4053
|
// white texture with no additive alpha, no need to tint
|
|
@@ -4069,12 +4058,12 @@ function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth,
|
|
|
4069
4058
|
else
|
|
4070
4059
|
{
|
|
4071
4060
|
// copy to offscreen canvas
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4061
|
+
workReadCanvas.width = sWidth;
|
|
4062
|
+
workReadCanvas.height = sHeight;
|
|
4063
|
+
workReadContext.drawImage(image, sx|0, sy|0, sWidth, sHeight, 0, 0, sWidth, sHeight);
|
|
4075
4064
|
|
|
4076
4065
|
// tint image using offscreen work context
|
|
4077
|
-
const imageData =
|
|
4066
|
+
const imageData = workReadContext.getImageData(0, 0, sWidth, sHeight);
|
|
4078
4067
|
const data = imageData.data;
|
|
4079
4068
|
if (additiveColor && !isBlack(additiveColor))
|
|
4080
4069
|
{
|
|
@@ -4083,8 +4072,8 @@ function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth,
|
|
|
4083
4072
|
const colorAdd = [additiveColor.r * 255, additiveColor.g * 255, additiveColor.b * 255, additiveColor.a * 255];
|
|
4084
4073
|
for (let i = 0; i < data.length; ++i)
|
|
4085
4074
|
data[i] = data[i] * colorMultiply[i&3] + colorAdd[i&3] |0;
|
|
4086
|
-
|
|
4087
|
-
context.drawImage(
|
|
4075
|
+
workReadContext.putImageData(imageData, 0, 0);
|
|
4076
|
+
context.drawImage(workReadCanvas, sx2, sy2, sWidth2, sHeight2, dx, dy, dWidth, dHeight);
|
|
4088
4077
|
}
|
|
4089
4078
|
else
|
|
4090
4079
|
{
|
|
@@ -4095,9 +4084,9 @@ function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth,
|
|
|
4095
4084
|
data[i+1] *= color.g;
|
|
4096
4085
|
data[i+2] *= color.b;
|
|
4097
4086
|
}
|
|
4098
|
-
|
|
4087
|
+
workReadContext.putImageData(imageData, 0, 0);
|
|
4099
4088
|
context.globalAlpha = color.a;
|
|
4100
|
-
context.drawImage(
|
|
4089
|
+
context.drawImage(workReadCanvas, sx2, sy2, sWidth2, sHeight2, dx, dy, dWidth, dHeight);
|
|
4101
4090
|
context.globalAlpha = 1;
|
|
4102
4091
|
}
|
|
4103
4092
|
}
|
|
@@ -4159,7 +4148,7 @@ class FontImage
|
|
|
4159
4148
|
constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1))
|
|
4160
4149
|
{
|
|
4161
4150
|
// load default font image
|
|
4162
|
-
if (!engineFontImage)
|
|
4151
|
+
if (!image && !engineFontImage)
|
|
4163
4152
|
{
|
|
4164
4153
|
engineFontImage = new Image;
|
|
4165
4154
|
engineFontImage.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAAYAQAAAAA9+x6JAAAAAnRSTlMAAHaTzTgAAAGiSURBVHjaZZABhxxBEIUf6ECLBdFY+Q0PMNgf0yCgsSAGZcT9sgIPtBWwIA5wgAPEoHUyJeeSlW+gjK+fegWwtROWpVQEyWh2npdpBmTUFVhb29RINgLIukoXr5LIAvYQ5ve+1FqWEMqNKTX3FAJHyQDRZvmKWubAACcv5z5Gtg2oyCWE+Yk/8JZQX1jTTCpKAFGIgza+dJCNBF2UskRlsgwitHbSV0QLgt9sTPtsRlvJjEr8C/FARWA2bJ/TtJ7lko34dNDn6usJUMzuErP89UUBJbWeozrwLLncXczd508deAjLWipLO4Q5XGPcJvPu92cNDaN0P5G1FL0nSOzddZOrJ6rNhbXGmeDvO3TF7DeJWl4bvaYQTNHCTeuqKZmbjHaSOFes+IX/+IhHrnAkXOAsfn24EM68XieIECoccD4KZLk/odiwzeo2rovYdhvb2HYFgyznJyDpYJdYOmfXgVdJTaUi4xA2uWYNYec9BLeqdl9EsoTw582mSFDX2DxVLbNt9U3YYoeatBad1c2Tj8t2akrjaIGJNywKB/7h75/gN3vCMSaadIUTAAAAAElFTkSuQmCC';
|
|
@@ -4182,23 +4171,14 @@ class FontImage
|
|
|
4182
4171
|
this.drawTextScreen(text, worldToScreen(pos).floor(), scale*cameraScale|0, center, context);
|
|
4183
4172
|
}
|
|
4184
4173
|
|
|
4185
|
-
/** Draw text
|
|
4186
|
-
* @param {string|number} text
|
|
4187
|
-
* @param {Vector2} pos
|
|
4188
|
-
* @param {number} [scale]
|
|
4189
|
-
* @param {boolean} [center]
|
|
4190
|
-
*/
|
|
4191
|
-
drawTextOverlay(text, pos, scale=4, center)
|
|
4192
|
-
{ this.drawText(text, pos, scale, center, overlayContext); }
|
|
4193
|
-
|
|
4194
|
-
/** Draw text on overlay canvas in screen space using the image font
|
|
4174
|
+
/** Draw text in screen space using the image font
|
|
4195
4175
|
* @param {string|number} text
|
|
4196
4176
|
* @param {Vector2} pos
|
|
4197
4177
|
* @param {number} [scale]
|
|
4198
4178
|
* @param {boolean} [center]
|
|
4199
4179
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=drawContext]
|
|
4200
4180
|
*/
|
|
4201
|
-
drawTextScreen(text, pos, scale=4, center=true, context=
|
|
4181
|
+
drawTextScreen(text, pos, scale=4, center=true, context=mainContext)
|
|
4202
4182
|
{
|
|
4203
4183
|
context.save();
|
|
4204
4184
|
const size = this.tileSize;
|
|
@@ -4948,7 +4928,7 @@ function inputRender()
|
|
|
4948
4928
|
return;
|
|
4949
4929
|
|
|
4950
4930
|
// setup the canvas
|
|
4951
|
-
const context =
|
|
4931
|
+
const context = mainContext;
|
|
4952
4932
|
context.save();
|
|
4953
4933
|
context.globalAlpha = alpha*touchGamepadAlpha;
|
|
4954
4934
|
context.strokeStyle = '#fff';
|
|
@@ -5190,12 +5170,12 @@ class Sound
|
|
|
5190
5170
|
///////////////////////////////////////////////////////////////////////////////
|
|
5191
5171
|
|
|
5192
5172
|
/**
|
|
5193
|
-
* Sound Wave Object -
|
|
5194
|
-
* - this can be used to play wave, mp3, and ogg files
|
|
5173
|
+
* Sound Wave Object - Loads and stores an audio file for later use
|
|
5174
|
+
* - this can be used to load and play wave, mp3, and ogg files
|
|
5195
5175
|
* @extends Sound
|
|
5196
5176
|
* @memberof Audio
|
|
5197
5177
|
* @example
|
|
5198
|
-
* //
|
|
5178
|
+
* // load an audio asset file
|
|
5199
5179
|
* const sound_example = new SoundWave('sound.mp3');
|
|
5200
5180
|
*
|
|
5201
5181
|
* // play the sound
|
|
@@ -6147,8 +6127,8 @@ class TileLayer extends CanvasLayer
|
|
|
6147
6127
|
if (!this.context) return;
|
|
6148
6128
|
|
|
6149
6129
|
// save current render settings
|
|
6150
|
-
/** @type {[HTMLCanvasElement|OffscreenCanvas, CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D, Vector2, Vector2, number]} */
|
|
6151
|
-
this.savedRenderSettings = [drawCanvas, drawContext, mainCanvasSize, cameraPos, cameraScale];
|
|
6130
|
+
/** @type {[HTMLCanvasElement|OffscreenCanvas, CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D, Vector2, Vector2, number, Color]} */
|
|
6131
|
+
this.savedRenderSettings = [drawCanvas, drawContext, mainCanvasSize, cameraPos, cameraScale, canvasClearColor];
|
|
6152
6132
|
|
|
6153
6133
|
// set the draw canvas and context to this layer
|
|
6154
6134
|
// use camera settings to match this layer's canvas
|
|
@@ -6157,6 +6137,7 @@ class TileLayer extends CanvasLayer
|
|
|
6157
6137
|
cameraPos = this.size.scale(.5);
|
|
6158
6138
|
const tileSize = this.tileInfo ? this.tileInfo.size : vec2(1);
|
|
6159
6139
|
cameraScale = tileSize.x;
|
|
6140
|
+
canvasClearColor = CLEAR_BLACK;
|
|
6160
6141
|
mainCanvasSize = this.size.multiply(tileSize);
|
|
6161
6142
|
if (clear)
|
|
6162
6143
|
{
|
|
@@ -6166,7 +6147,7 @@ class TileLayer extends CanvasLayer
|
|
|
6166
6147
|
}
|
|
6167
6148
|
|
|
6168
6149
|
// disable smoothing for pixel art
|
|
6169
|
-
|
|
6150
|
+
drawContext.imageSmoothingEnabled = !tilesPixelated;
|
|
6170
6151
|
|
|
6171
6152
|
// setup gl rendering if enabled
|
|
6172
6153
|
glPreRender();
|
|
@@ -6182,7 +6163,7 @@ class TileLayer extends CanvasLayer
|
|
|
6182
6163
|
//debugSaveCanvas(this.canvas);
|
|
6183
6164
|
|
|
6184
6165
|
// set stuff back to normal
|
|
6185
|
-
[drawCanvas, drawContext, mainCanvasSize, cameraPos, cameraScale] = this.savedRenderSettings;
|
|
6166
|
+
[drawCanvas, drawContext, mainCanvasSize, cameraPos, cameraScale, canvasClearColor] = this.savedRenderSettings;
|
|
6186
6167
|
}
|
|
6187
6168
|
|
|
6188
6169
|
/** Draw the tile at a given position in the tile grid
|
|
@@ -6895,10 +6876,10 @@ class Medal
|
|
|
6895
6876
|
*/
|
|
6896
6877
|
render(hidePercent=0)
|
|
6897
6878
|
{
|
|
6898
|
-
const context =
|
|
6879
|
+
const context = mainContext;
|
|
6899
6880
|
const width = min(medalDisplaySize.x, mainCanvas.width);
|
|
6900
6881
|
const height = medalDisplaySize.y;
|
|
6901
|
-
const x =
|
|
6882
|
+
const x = mainCanvas.width - width;
|
|
6902
6883
|
const y = -height*hidePercent;
|
|
6903
6884
|
const backgroundColor = hsl(0,0,.9);
|
|
6904
6885
|
|
|
@@ -6939,7 +6920,7 @@ class Medal
|
|
|
6939
6920
|
{
|
|
6940
6921
|
// draw the image or icon
|
|
6941
6922
|
if (this.image)
|
|
6942
|
-
|
|
6923
|
+
mainContext.drawImage(this.image, pos.x-size/2, pos.y-size/2, size, size);
|
|
6943
6924
|
else
|
|
6944
6925
|
drawTextScreen(this.icon, pos, size*.7, BLACK);
|
|
6945
6926
|
}
|
|
@@ -6960,7 +6941,7 @@ class Medal
|
|
|
6960
6941
|
* @namespace WebGL
|
|
6961
6942
|
*/
|
|
6962
6943
|
|
|
6963
|
-
/** The WebGL canvas which appears
|
|
6944
|
+
/** The WebGL canvas which appears below the main canvas
|
|
6964
6945
|
* @type {HTMLCanvasElement}
|
|
6965
6946
|
* @memberof WebGL */
|
|
6966
6947
|
let glCanvas;
|
|
@@ -6990,7 +6971,7 @@ const gl_MAX_POLY_VERTEXES = gl_ARRAY_BUFFER_SIZE / gl_POLY_VERTEX_BYTE_STRIDE |
|
|
|
6990
6971
|
///////////////////////////////////////////////////////////////////////////////
|
|
6991
6972
|
|
|
6992
6973
|
// Initialize WebGL, called automatically by the engine
|
|
6993
|
-
function glInit()
|
|
6974
|
+
function glInit(rootElement)
|
|
6994
6975
|
{
|
|
6995
6976
|
// keep set of texture infos so they can be restored if context is lost
|
|
6996
6977
|
glTextureInfos = new Set;
|
|
@@ -7014,8 +6995,7 @@ function glInit()
|
|
|
7014
6995
|
return;
|
|
7015
6996
|
}
|
|
7016
6997
|
|
|
7017
|
-
// attach the WebGL canvas
|
|
7018
|
-
const rootElement = mainCanvas.parentElement;
|
|
6998
|
+
// attach the WebGL canvas;
|
|
7019
6999
|
rootElement.appendChild(glCanvas);
|
|
7020
7000
|
|
|
7021
7001
|
// startup webgl
|
|
@@ -7233,6 +7213,9 @@ function glClearCanvas()
|
|
|
7233
7213
|
glCanvas.width = drawCanvas.width;
|
|
7234
7214
|
glCanvas.height = drawCanvas.height;
|
|
7235
7215
|
glContext.viewport(0, 0, glCanvas.width, glCanvas.height);
|
|
7216
|
+
const color = canvasClearColor;
|
|
7217
|
+
if (color.a > 0)
|
|
7218
|
+
glContext.clearColor(color.r, color.g, color.b, color.a);
|
|
7236
7219
|
glContext.clear(glContext.COLOR_BUFFER_BIT);
|
|
7237
7220
|
}
|
|
7238
7221
|
|
|
@@ -7462,7 +7445,6 @@ function glDraw(x, y, sizeX, sizeY, angle=0, uv0X=0, uv0Y=0, uv1X=1, uv1Y=1, rgb
|
|
|
7462
7445
|
glFlush();
|
|
7463
7446
|
glSetInstancedMode();
|
|
7464
7447
|
|
|
7465
|
-
glPolyMode = false;
|
|
7466
7448
|
let offset = glBatchCount++ * gl_INDICES_PER_INSTANCE;
|
|
7467
7449
|
glPositionData[offset++] = x;
|
|
7468
7450
|
glPositionData[offset++] = y;
|
|
@@ -7983,13 +7965,12 @@ class PostProcessPlugin
|
|
|
7983
7965
|
{
|
|
7984
7966
|
/** Create global post processing shader
|
|
7985
7967
|
* @param {string} shaderCode
|
|
7986
|
-
* @param {boolean} [includeOverlay]
|
|
7987
7968
|
* @param {boolean} [includeMainCanvas]
|
|
7988
7969
|
* @example
|
|
7989
7970
|
* // create the post process plugin object
|
|
7990
7971
|
* new PostProcessPlugin(shaderCode);
|
|
7991
7972
|
*/
|
|
7992
|
-
constructor(shaderCode,
|
|
7973
|
+
constructor(shaderCode, includeMainCanvas=true)
|
|
7993
7974
|
{
|
|
7994
7975
|
ASSERT(!postProcess, 'Post process already initialized');
|
|
7995
7976
|
postProcess = this;
|
|
@@ -8061,17 +8042,19 @@ class PostProcessPlugin
|
|
|
8061
8042
|
// clear out the buffer
|
|
8062
8043
|
glFlush();
|
|
8063
8044
|
|
|
8064
|
-
|
|
8045
|
+
// setup texture
|
|
8046
|
+
glContext.activeTexture(glContext.TEXTURE0);
|
|
8047
|
+
glContext.bindTexture(glContext.TEXTURE_2D, postProcess.texture);
|
|
8048
|
+
if (includeMainCanvas)
|
|
8065
8049
|
{
|
|
8066
|
-
// copy
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
}
|
|
8050
|
+
// copy main canvas to work canvas
|
|
8051
|
+
workCanvas.width = mainCanvasSize.x;
|
|
8052
|
+
workCanvas.height = mainCanvasSize.y;
|
|
8053
|
+
glCopyToContext(workContext);
|
|
8054
|
+
workContext.drawImage(mainCanvas, 0, 0);
|
|
8055
|
+
|
|
8056
|
+
// copy work canvas to texture
|
|
8057
|
+
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, workCanvas);
|
|
8075
8058
|
}
|
|
8076
8059
|
|
|
8077
8060
|
// setup shader program to draw a quad
|
|
@@ -8080,14 +8063,6 @@ class PostProcessPlugin
|
|
|
8080
8063
|
glContext.pixelStorei(glContext.UNPACK_FLIP_Y_WEBGL, 1);
|
|
8081
8064
|
glContext.disable(glContext.BLEND);
|
|
8082
8065
|
|
|
8083
|
-
// set textures, pass in the 2d canvas and gl canvas in separate texture channels
|
|
8084
|
-
glContext.activeTexture(glContext.TEXTURE0);
|
|
8085
|
-
glContext.bindTexture(glContext.TEXTURE_2D, postProcess.texture);
|
|
8086
|
-
if (includeMainCanvas || includeOverlay)
|
|
8087
|
-
{
|
|
8088
|
-
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, mainCanvas);
|
|
8089
|
-
}
|
|
8090
|
-
|
|
8091
8066
|
// set vertex position attribute
|
|
8092
8067
|
const vertexByteStride = 8;
|
|
8093
8068
|
const pLocation = glContext.getAttribLocation(postProcess.shader, 'p');
|
|
@@ -8316,12 +8291,14 @@ class UISystemPlugin
|
|
|
8316
8291
|
* // create the ui plugin object
|
|
8317
8292
|
* new UISystemPlugin;
|
|
8318
8293
|
*/
|
|
8319
|
-
constructor(context=
|
|
8294
|
+
constructor(context=mainContext)
|
|
8320
8295
|
{
|
|
8321
8296
|
ASSERT(!uiSystem, 'UI system already initialized');
|
|
8322
8297
|
uiSystem = this;
|
|
8323
8298
|
|
|
8324
8299
|
// default settings
|
|
8300
|
+
/** @property {boolean} - Activate when mouse is pressed down instead of clicked */
|
|
8301
|
+
this.activateOnPress = false;
|
|
8325
8302
|
/** @property {Color} - Default fill color for UI elements */
|
|
8326
8303
|
this.defaultColor = WHITE;
|
|
8327
8304
|
/** @property {Color} - Default outline color for UI elements */
|
|
@@ -8973,13 +8950,15 @@ class UIObject
|
|
|
8973
8950
|
uiSystem.uiObjects.push(this);
|
|
8974
8951
|
}
|
|
8975
8952
|
|
|
8976
|
-
/** Add a child UIObject to this object
|
|
8977
|
-
* @param {UIObject} child
|
|
8953
|
+
/** Add a child UIObject to this object, returns child for chaining
|
|
8954
|
+
* @param {UIObject} child
|
|
8955
|
+
* @return {UIObject} The child object added */
|
|
8978
8956
|
addChild(child)
|
|
8979
8957
|
{
|
|
8980
8958
|
ASSERT(!child.parent && !this.children.includes(child));
|
|
8981
8959
|
this.children.push(child);
|
|
8982
8960
|
child.parent = this;
|
|
8961
|
+
return child;
|
|
8983
8962
|
}
|
|
8984
8963
|
|
|
8985
8964
|
/** Remove a child UIObject from this object
|
|
@@ -9052,8 +9031,16 @@ class UIObject
|
|
|
9052
9031
|
if (uiSystem.activeObject && !isActive)
|
|
9053
9032
|
uiSystem.activeObject.onRelease();
|
|
9054
9033
|
uiSystem.activeObject = this;
|
|
9034
|
+
|
|
9035
|
+
if (uiSystem.activateOnPress)
|
|
9036
|
+
{
|
|
9037
|
+
this.onClick();
|
|
9038
|
+
if (!this.soundPress && this.soundClick)
|
|
9039
|
+
this.soundClick.play();
|
|
9040
|
+
}
|
|
9055
9041
|
}
|
|
9056
9042
|
}
|
|
9043
|
+
if (!uiSystem.activateOnPress)
|
|
9057
9044
|
if (!mouseDown && this.isActiveObject() && this.interactive)
|
|
9058
9045
|
{
|
|
9059
9046
|
this.onClick();
|
|
@@ -11493,33 +11480,33 @@ async function box2dInit()
|
|
|
11493
11480
|
color = getDebugColor(color);
|
|
11494
11481
|
point1 = box2d.vec2FromPointer(point1);
|
|
11495
11482
|
point2 = box2d.vec2FromPointer(point2);
|
|
11496
|
-
drawLine(point1, point2, debugLineWidth, color, vec2(), 0, false
|
|
11483
|
+
drawLine(point1, point2, debugLineWidth, color, vec2(), 0, false);
|
|
11497
11484
|
};
|
|
11498
11485
|
debugDraw.DrawPolygon = function(vertices, vertexCount, color)
|
|
11499
11486
|
{
|
|
11500
11487
|
color = getDebugColor(color);
|
|
11501
11488
|
const points = getPointsList(vertices, vertexCount);
|
|
11502
|
-
drawPoly(points, CLEAR_WHITE, debugLineWidth, color, vec2(), 0, false
|
|
11489
|
+
drawPoly(points, CLEAR_WHITE, debugLineWidth, color, vec2(), 0, false);
|
|
11503
11490
|
};
|
|
11504
11491
|
debugDraw.DrawSolidPolygon = function(vertices, vertexCount, color)
|
|
11505
11492
|
{
|
|
11506
11493
|
color = getDebugColor(color);
|
|
11507
11494
|
const points = getPointsList(vertices, vertexCount);
|
|
11508
|
-
drawPoly(points, color, 0, color, vec2(), 0, false
|
|
11495
|
+
drawPoly(points, color, 0, color, vec2(), 0, false);
|
|
11509
11496
|
};
|
|
11510
11497
|
debugDraw.DrawCircle = function(center, radius, color)
|
|
11511
11498
|
{
|
|
11512
11499
|
color = getDebugColor(color);
|
|
11513
11500
|
center = box2d.vec2FromPointer(center);
|
|
11514
|
-
drawCircle(center, radius*2, CLEAR_WHITE, debugLineWidth, color, false
|
|
11501
|
+
drawCircle(center, radius*2, CLEAR_WHITE, debugLineWidth, color, false);
|
|
11515
11502
|
};
|
|
11516
11503
|
debugDraw.DrawSolidCircle = function(center, radius, axis, color)
|
|
11517
11504
|
{
|
|
11518
11505
|
color = getDebugColor(color);
|
|
11519
11506
|
center = box2d.vec2FromPointer(center);
|
|
11520
11507
|
axis = box2d.vec2FromPointer(axis).scale(radius);
|
|
11521
|
-
drawCircle(center, radius*2, color, debugLineWidth, color, false
|
|
11522
|
-
drawLine(vec2(), axis, debugLineWidth, color, center, 0, false
|
|
11508
|
+
drawCircle(center, radius*2, color, debugLineWidth, color, false);
|
|
11509
|
+
drawLine(vec2(), axis, debugLineWidth, color, center, 0, false);
|
|
11523
11510
|
};
|
|
11524
11511
|
debugDraw.DrawTransform = function(transform)
|
|
11525
11512
|
{
|
|
@@ -11528,8 +11515,8 @@ async function box2dInit()
|
|
|
11528
11515
|
const angle = -transform.get_q().GetAngle();
|
|
11529
11516
|
const p1 = vec2(1,0), c1 = rgb(.75,0,0,.8);
|
|
11530
11517
|
const p2 = vec2(0,1), c2 = rgb(0,.75,0,.8);
|
|
11531
|
-
drawLine(vec2(), p1, debugLineWidth, c1, pos, angle, false
|
|
11532
|
-
drawLine(vec2(), p2, debugLineWidth, c2, pos, angle, false
|
|
11518
|
+
drawLine(vec2(), p1, debugLineWidth, c1, pos, angle, false);
|
|
11519
|
+
drawLine(vec2(), p2, debugLineWidth, c2, pos, angle, false);
|
|
11533
11520
|
}
|
|
11534
11521
|
|
|
11535
11522
|
debugDraw.AppendFlags(box2d.instance.b2Draw.e_shapeBit);
|
|
@@ -11549,8 +11536,8 @@ async function box2dInit()
|
|
|
11549
11536
|
|
|
11550
11537
|
///////////////////////////////////////////////////////////////////////////////
|
|
11551
11538
|
|
|
11552
|
-
/** Draw a scalable nine-slice UI element to the
|
|
11553
|
-
* This function can not apply color because it draws using the
|
|
11539
|
+
/** Draw a scalable nine-slice UI element to the main canvas in screen space
|
|
11540
|
+
* This function can not apply color because it draws using the 2d context
|
|
11554
11541
|
* @param {Vector2} pos - Screen space position
|
|
11555
11542
|
* @param {Vector2} size - Screen space size
|
|
11556
11543
|
* @param {TileInfo} startTile - Starting tile for the nine-slice pattern
|
|
@@ -11560,7 +11547,7 @@ async function box2dInit()
|
|
|
11560
11547
|
* @memberof DrawUtilities */
|
|
11561
11548
|
function drawNineSliceScreen(pos, size, startTile, borderSize=32, extraSpace=2, angle=0)
|
|
11562
11549
|
{
|
|
11563
|
-
drawNineSlice(pos, size, startTile, WHITE, borderSize, BLACK, extraSpace, angle, false, true
|
|
11550
|
+
drawNineSlice(pos, size, startTile, WHITE, borderSize, BLACK, extraSpace, angle, false, true);
|
|
11564
11551
|
}
|
|
11565
11552
|
|
|
11566
11553
|
/** Draw a scalable nine-slice UI element in world space
|
|
@@ -11609,8 +11596,8 @@ function drawNineSlice(pos, size, startTile, color, borderSize=1, additiveColor,
|
|
|
11609
11596
|
}
|
|
11610
11597
|
}
|
|
11611
11598
|
|
|
11612
|
-
/** Draw a scalable three-slice UI element to the
|
|
11613
|
-
* This function can not apply color because it draws using the
|
|
11599
|
+
/** Draw a scalable three-slice UI element to the main canvas in screen space
|
|
11600
|
+
* This function can not apply color because it draws using the 2d context
|
|
11614
11601
|
* @param {Vector2} pos - Screen space position
|
|
11615
11602
|
* @param {Vector2} size - Screen space size
|
|
11616
11603
|
* @param {TileInfo} startTile - Starting tile for the three-slice pattern
|
|
@@ -11620,7 +11607,7 @@ function drawNineSlice(pos, size, startTile, color, borderSize=1, additiveColor,
|
|
|
11620
11607
|
* @memberof DrawUtilities */
|
|
11621
11608
|
function drawThreeSliceScreen(pos, size, startTile, borderSize=32, extraSpace=2, angle=0)
|
|
11622
11609
|
{
|
|
11623
|
-
drawThreeSlice(pos, size, startTile, WHITE, borderSize, BLACK, extraSpace, angle, false, true
|
|
11610
|
+
drawThreeSlice(pos, size, startTile, WHITE, borderSize, BLACK, extraSpace, angle, false, true);
|
|
11624
11611
|
}
|
|
11625
11612
|
|
|
11626
11613
|
/** Draw a scalable three-slice UI element in world space
|