littlejsengine 1.16.1 → 1.17.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 +287 -240
- package/dist/littlejs.esm.js +1419 -1259
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +1076 -910
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +977 -815
- package/examples/box2d/gameObjects.js +6 -6
- package/examples/breakout/game.js +5 -6
- package/examples/electron/index.html +2 -2
- package/examples/electron/tiles.png +0 -0
- package/examples/htmlMenu/tiles.png +0 -0
- package/examples/index.html +1 -1
- package/examples/logo.png +0 -0
- package/examples/logo2.png +0 -0
- package/examples/module/tiles.png +0 -0
- package/examples/platformer/gameEffects.js +24 -23
- package/examples/platformer/gameLevel.js +24 -25
- package/examples/shorts/base.html +2 -1
- package/examples/shorts/clock.js +3 -3
- package/examples/shorts/fontImage.js +4 -3
- package/examples/shorts/parallax.js +1 -1
- package/examples/shorts/sequencer.js +1 -1
- package/examples/shorts/shapes.js +1 -1
- package/examples/shorts/texture.js +10 -6
- package/examples/shorts/tiles.png +0 -0
- package/examples/shorts/tiltedView.js +2 -0
- package/examples/starter/index.html +3 -2
- package/examples/starter/tiles.png +0 -0
- package/examples/typescript/tiles.png +0 -0
- package/examples/uiSystem/game.js +1 -1
- package/examples/uiSystem/tiles.png +0 -0
- package/package.json +1 -1
- package/plugins/postProcess.js +47 -28
- package/plugins/uiSystem.js +16 -16
- package/reference.md +6 -6
- package/src/engine.js +186 -198
- package/src/engineAudio.js +6 -10
- package/src/engineBuild.js +1 -0
- package/src/engineDebug.js +100 -98
- package/src/engineDraw.js +185 -148
- package/src/engineExport.js +327 -333
- package/src/engineFont.png +0 -0
- package/src/engineInput.js +17 -26
- package/src/engineMath.js +1112 -0
- package/src/engineMedals.js +4 -4
- package/src/engineObject.js +27 -27
- package/src/engineParticles.js +2 -2
- package/src/engineRelease.js +1 -3
- package/src/engineSettings.js +2 -2
- package/src/engineTileLayer.js +200 -176
- package/src/engineUtilities.js +48 -1097
- package/src/engineWebGL.js +127 -79
package/src/engineTileLayer.js
CHANGED
|
@@ -32,7 +32,7 @@ function tileCollisionGetData(pos)
|
|
|
32
32
|
|
|
33
33
|
/** Check if a tile layer collides with another object
|
|
34
34
|
* @param {Vector2} pos
|
|
35
|
-
* @param {Vector2} [size=(
|
|
35
|
+
* @param {Vector2} [size=vec2()]
|
|
36
36
|
* @param {EngineObject} [object] - An object or undefined for generic test
|
|
37
37
|
* @param {boolean} [solidOnly] - Only check solid layers if true
|
|
38
38
|
* @return {TileCollisionLayer}
|
|
@@ -150,20 +150,20 @@ function tileLayersLoad(tileMapData, tileInfo=tile(), renderOrder=0, collisionLa
|
|
|
150
150
|
class TileLayerData
|
|
151
151
|
{
|
|
152
152
|
/** Create a tile layer data object, one for each tile in a TileLayer
|
|
153
|
-
* @param {number} [tile]
|
|
153
|
+
* @param {number} [tile] - The tile to use, untextured if undefined
|
|
154
154
|
* @param {number} [direction] - Integer direction of tile, in 90 degree increments
|
|
155
|
-
* @param {boolean} [mirror]
|
|
156
|
-
* @param {Color} [color]
|
|
155
|
+
* @param {boolean} [mirror] - If the tile should be mirrored along the x axis
|
|
156
|
+
* @param {Color} [color] - Color of the tile */
|
|
157
157
|
constructor(tile, direction=0, mirror=false, color=new Color)
|
|
158
158
|
{
|
|
159
|
-
/** @property {number}
|
|
160
|
-
this.tile
|
|
161
|
-
/** @property {number}
|
|
159
|
+
/** @property {number} - The tile to use, untextured if undefined */
|
|
160
|
+
this.tile = tile;
|
|
161
|
+
/** @property {number} - Integer direction of tile, in 90 degree increments */
|
|
162
162
|
this.direction = direction;
|
|
163
163
|
/** @property {boolean} - If the tile should be mirrored along the x axis */
|
|
164
|
-
this.mirror
|
|
165
|
-
/** @property {Color}
|
|
166
|
-
this.color
|
|
164
|
+
this.mirror = mirror;
|
|
165
|
+
/** @property {Color} - Color of the tile */
|
|
166
|
+
this.color = color.copy();
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
/** Set this tile to clear, it will not be rendered */
|
|
@@ -174,7 +174,7 @@ class TileLayerData
|
|
|
174
174
|
/**
|
|
175
175
|
* Canvas Layer - cached off screen rendering system
|
|
176
176
|
* - Contains an offscreen canvas that can be rendered to
|
|
177
|
-
* - WebGL rendering is optional, call
|
|
177
|
+
* - WebGL rendering is optional, call updateWebGL to enable/update
|
|
178
178
|
* @extends EngineObject
|
|
179
179
|
* @memberof TileLayers
|
|
180
180
|
* @example
|
|
@@ -188,8 +188,9 @@ class CanvasLayer extends EngineObject
|
|
|
188
188
|
* @param {number} [angle] - Angle the layer is rotated by
|
|
189
189
|
* @param {number} [renderOrder] - Objects sorted by renderOrder
|
|
190
190
|
* @param {Vector2} [canvasSize] - Default size of canvas, can be changed later
|
|
191
|
+
* @param {boolean} [useWebGL] - Should this layer use WebGL for rendering
|
|
191
192
|
*/
|
|
192
|
-
constructor(position, size, angle=0, renderOrder=0, canvasSize=vec2(512))
|
|
193
|
+
constructor(position, size, angle=0, renderOrder=0, canvasSize=vec2(512), useWebGL=glEnable)
|
|
193
194
|
{
|
|
194
195
|
ASSERT(isVector2(canvasSize), 'canvasSize must be a Vector2');
|
|
195
196
|
super(position, size, undefined, angle, WHITE, renderOrder);
|
|
@@ -199,13 +200,10 @@ class CanvasLayer extends EngineObject
|
|
|
199
200
|
/** @property {OffscreenCanvasRenderingContext2D} - The 2D canvas context used by this layer */
|
|
200
201
|
this.context = this.canvas?.getContext('2d');
|
|
201
202
|
/** @property {TextureInfo} - Texture info to use for this object rendering */
|
|
202
|
-
const useWebGL = false; // do not use webgl by default
|
|
203
203
|
this.textureInfo = new TextureInfo(this.canvas, useWebGL);
|
|
204
|
-
/** @property {boolean} - True if WebGL texture needs to be refreshed */
|
|
205
|
-
this.refreshWebGL = false;
|
|
206
204
|
|
|
207
205
|
// disable physics by default
|
|
208
|
-
this.mass =
|
|
206
|
+
this.mass = 0;
|
|
209
207
|
}
|
|
210
208
|
|
|
211
209
|
/** Destroy this canvas layer */
|
|
@@ -220,7 +218,7 @@ class CanvasLayer extends EngineObject
|
|
|
220
218
|
// Render the layer, called automatically by the engine
|
|
221
219
|
render()
|
|
222
220
|
{
|
|
223
|
-
this.draw(this.pos, this.size, this.
|
|
221
|
+
this.draw(this.pos, this.size, this.color, this.angle, this.mirror, this.additiveColor);
|
|
224
222
|
}
|
|
225
223
|
|
|
226
224
|
/** Draw this canvas layer centered in world space, with color applied if using WebGL
|
|
@@ -233,103 +231,54 @@ class CanvasLayer extends EngineObject
|
|
|
233
231
|
* @param {boolean} [screenSpace] - If true the pos and size are in screen space
|
|
234
232
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context] - Canvas 2D context to draw to
|
|
235
233
|
* @memberof Draw */
|
|
236
|
-
draw(pos, size,
|
|
234
|
+
draw(pos, size, color=WHITE, angle=0, mirror=false, additiveColor, screenSpace=false, context)
|
|
237
235
|
{
|
|
238
|
-
const useWebGL = glEnable && this.textureInfo.hasWebGL();
|
|
239
|
-
if (useWebGL && this.refreshWebGL)
|
|
240
|
-
{
|
|
241
|
-
// update the WebGL texture
|
|
242
|
-
this.textureInfo.createWebGLTexture();
|
|
243
|
-
this.refreshWebGL = false;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
236
|
// draw the canvas layer as a single tile that uses the whole texture
|
|
247
237
|
const tileInfo = new TileInfo().setFullImage(this.textureInfo);
|
|
238
|
+
const useWebGL = this.hasWebGL();
|
|
248
239
|
drawTile(pos, size, tileInfo, color, angle, mirror, additiveColor, useWebGL, screenSpace, context);
|
|
249
240
|
}
|
|
250
241
|
|
|
251
|
-
/**
|
|
252
|
-
* @callback Canvas2DDrawCallback - Function that draws to a canvas 2D context
|
|
253
|
-
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} context
|
|
254
|
-
* @memberof TileLayers
|
|
255
|
-
*/
|
|
256
|
-
|
|
257
|
-
/** Draw onto the layer canvas in world space (bypass WebGL)
|
|
258
|
-
* @param {Vector2} pos
|
|
259
|
-
* @param {Vector2} size
|
|
260
|
-
* @param {number} angle
|
|
261
|
-
* @param {boolean} mirror
|
|
262
|
-
* @param {Canvas2DDrawCallback} drawFunction */
|
|
263
|
-
drawCanvas2D(pos, size, angle, mirror, drawFunction)
|
|
264
|
-
{
|
|
265
|
-
if (!this.context) return;
|
|
266
|
-
|
|
267
|
-
const context = this.context;
|
|
268
|
-
context.save();
|
|
269
|
-
pos = pos.subtract(this.pos).multiply(this.tileInfo.size);
|
|
270
|
-
size = size.multiply(this.tileInfo.size);
|
|
271
|
-
context.translate(pos.x, this.canvas.height - pos.y);
|
|
272
|
-
context.rotate(angle);
|
|
273
|
-
context.scale(mirror ? -size.x : size.x, size.y);
|
|
274
|
-
drawFunction(context);
|
|
275
|
-
context.restore();
|
|
276
|
-
}
|
|
277
|
-
|
|
278
242
|
/** Draw a tile onto the layer canvas in world space
|
|
279
243
|
* @param {Vector2} pos
|
|
280
|
-
* @param {Vector2} [size=(1
|
|
244
|
+
* @param {Vector2} [size=vec2(1)]
|
|
281
245
|
* @param {TileInfo} [tileInfo]
|
|
282
|
-
* @param {Color} [color=
|
|
283
|
-
* @param {number} [angle
|
|
284
|
-
* @param {boolean} [mirror
|
|
285
|
-
drawTile(pos, size=vec2(1), tileInfo, color=new Color, angle, mirror)
|
|
246
|
+
* @param {Color} [color=WHITE]
|
|
247
|
+
* @param {number} [angle]
|
|
248
|
+
* @param {boolean} [mirror] */
|
|
249
|
+
drawTile(pos, size=vec2(1), tileInfo, color=new Color, angle=0, mirror=false)
|
|
286
250
|
{
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
// untextured
|
|
301
|
-
context.fillStyle = color.toString();
|
|
302
|
-
context.fillRect(-.5, -.5, 1, 1);
|
|
303
|
-
}
|
|
304
|
-
});
|
|
251
|
+
pos = pos.subtract(this.pos).multiply(this.tileInfo.size);
|
|
252
|
+
size = size.multiply(this.tileInfo.size);
|
|
253
|
+
pos.y = this.canvas.height - pos.y;
|
|
254
|
+
|
|
255
|
+
// draw the tile onto the layer canvas
|
|
256
|
+
const oldMainCanvasSize = mainCanvasSize;
|
|
257
|
+
mainCanvasSize = vec2(this.canvas.width, this.canvas.height);
|
|
258
|
+
const useWebGL = this.hasWebGL();
|
|
259
|
+
useWebGL && glSetRenderTarget(this.textureInfo.glTexture);
|
|
260
|
+
const drawContext = useWebGL ? undefined : this.context;
|
|
261
|
+
drawTile(pos, size, tileInfo, color, angle, mirror, undefined, useWebGL, true, drawContext);
|
|
262
|
+
useWebGL && glSetRenderTarget();
|
|
263
|
+
mainCanvasSize = oldMainCanvasSize;
|
|
305
264
|
}
|
|
306
265
|
|
|
307
266
|
/** Draw a rectangle onto the layer canvas in world space
|
|
308
267
|
* @param {Vector2} pos
|
|
309
|
-
* @param {Vector2} [size=(1
|
|
310
|
-
* @param {Color} [color=
|
|
311
|
-
* @param {number} [angle
|
|
268
|
+
* @param {Vector2} [size=vec2(1)]
|
|
269
|
+
* @param {Color} [color=WHITE]
|
|
270
|
+
* @param {number} [angle] */
|
|
312
271
|
drawRect(pos, size, color, angle)
|
|
313
272
|
{ this.drawTile(pos, size, undefined, color, angle); }
|
|
314
273
|
|
|
315
|
-
/** Create
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
*/
|
|
319
|
-
useWebGL(enable=true, immediate=false)
|
|
320
|
-
{
|
|
321
|
-
if (!immediate && enable && this.textureInfo.hasWebGL())
|
|
322
|
-
{
|
|
323
|
-
// refresh the texture when needed
|
|
324
|
-
this.refreshWebGL = true;
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
274
|
+
/** Create WebGL texture if necessary and copy layer canvas to it */
|
|
275
|
+
updateWebGL()
|
|
276
|
+
{ this.textureInfo.createWebGLTexture(); }
|
|
327
277
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
}
|
|
278
|
+
/** Check if this layer is using WebGL
|
|
279
|
+
* @return {boolean} */
|
|
280
|
+
hasWebGL()
|
|
281
|
+
{ return glEnable && this.textureInfo.hasWebGL(); }
|
|
333
282
|
}
|
|
334
283
|
|
|
335
284
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -348,50 +297,67 @@ class CanvasLayer extends EngineObject
|
|
|
348
297
|
class TileLayer extends CanvasLayer
|
|
349
298
|
{
|
|
350
299
|
/** Create a tile layer object
|
|
351
|
-
* @param {Vector2} position
|
|
352
|
-
* @param {Vector2} size
|
|
353
|
-
* @param {TileInfo} [tileInfo]
|
|
300
|
+
* @param {Vector2} position - World space position
|
|
301
|
+
* @param {Vector2} size - World space size
|
|
302
|
+
* @param {TileInfo} [tileInfo] - Default tile info for layer (used for size and texture)
|
|
354
303
|
* @param {number} [renderOrder] - Objects are sorted by renderOrder
|
|
355
304
|
*/
|
|
356
305
|
constructor(position, size, tileInfo=tile(), renderOrder=0)
|
|
357
306
|
{
|
|
358
307
|
const canvasSize = tileInfo ? size.multiply(tileInfo.size) : size;
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
308
|
+
const useWebGL = true;
|
|
309
|
+
super(position, size, 0, renderOrder, canvasSize, useWebGL);
|
|
310
|
+
|
|
311
|
+
/** @property {TileInfo} - Default tile info for layer */
|
|
312
|
+
this.tileInfo = undefined;
|
|
313
|
+
/** @property {Array<TileLayerData>} - Default tile info for layer */
|
|
365
314
|
this.data = [];
|
|
366
|
-
|
|
367
|
-
|
|
315
|
+
/** @property {boolean} - Is this layer using a webgl texture? */
|
|
316
|
+
this.isUsingWebGL = false;
|
|
368
317
|
|
|
369
318
|
if (headlessMode)
|
|
370
319
|
{
|
|
371
|
-
// disable rendering
|
|
372
|
-
this.
|
|
373
|
-
this.
|
|
374
|
-
this.redrawStart
|
|
375
|
-
this.redrawEnd
|
|
376
|
-
this.drawTileData
|
|
377
|
-
this.
|
|
378
|
-
this.
|
|
320
|
+
// disable rendering in headless mode
|
|
321
|
+
this.render = () => {};
|
|
322
|
+
this.redraw = () => {};
|
|
323
|
+
this.redrawStart = () => {};
|
|
324
|
+
this.redrawEnd = () => {};
|
|
325
|
+
this.drawTileData = () => {};
|
|
326
|
+
this.redrawTileData = () => {};
|
|
327
|
+
this.drawLayerTile = () => {};
|
|
328
|
+
this.drawLayerRect = () => {};
|
|
329
|
+
this.clearLayerRect = () => {};
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (tileInfo)
|
|
334
|
+
{
|
|
335
|
+
// set tile info
|
|
336
|
+
this.tileInfo = tileInfo.frame(0);
|
|
337
|
+
this.tileInfo.bleed = 0; // disable bleed for tile layers
|
|
379
338
|
}
|
|
339
|
+
|
|
340
|
+
// init tile data
|
|
341
|
+
for (let j = this.size.area(); j--;)
|
|
342
|
+
this.data.push(new TileLayerData);
|
|
380
343
|
}
|
|
381
344
|
|
|
382
345
|
/** Set data at a given position in the array
|
|
383
346
|
* @param {Vector2} layerPos - Local position in array
|
|
384
|
-
* @param {TileLayerData} data
|
|
347
|
+
* @param {TileLayerData} data - Data to set
|
|
385
348
|
* @param {boolean} [redraw] - Force the tile to redraw if true */
|
|
386
349
|
setData(layerPos, data, redraw=false)
|
|
387
350
|
{
|
|
351
|
+
layerPos = layerPos.floor();
|
|
388
352
|
ASSERT(isVector2(layerPos), 'layerPos must be a Vector2');
|
|
389
353
|
ASSERT(data instanceof TileLayerData, 'data must be a TileLayerData');
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
354
|
+
|
|
355
|
+
if (!layerPos.arrayCheck(this.size)) return;
|
|
356
|
+
this.data[(layerPos.y|0)*this.size.x+layerPos.x|0] = data;
|
|
357
|
+
|
|
358
|
+
if (!redraw) return;
|
|
359
|
+
const isRedraw = drawContext === this.context;
|
|
360
|
+
isRedraw ? this.drawTileData(layerPos) : this.redrawTileData(layerPos);
|
|
395
361
|
}
|
|
396
362
|
|
|
397
363
|
/** Get data at a given position in the array
|
|
@@ -400,7 +366,18 @@ class TileLayer extends CanvasLayer
|
|
|
400
366
|
getData(layerPos)
|
|
401
367
|
{
|
|
402
368
|
ASSERT(isVector2(layerPos), 'layerPos must be a Vector2');
|
|
403
|
-
return layerPos.arrayCheck(this.size) && this.data[(layerPos.y|0)*this.size.x+layerPos.x|0];
|
|
369
|
+
return layerPos.arrayCheck(this.size) && this.data[(layerPos.y|0)*this.size.x+layerPos.x|0];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Update the tile layer, refresh texture if needed
|
|
373
|
+
update()
|
|
374
|
+
{
|
|
375
|
+
if (!glEnable && this.isUsingWebGL)
|
|
376
|
+
{
|
|
377
|
+
// redraw the layer if webgl was disabled or context lost
|
|
378
|
+
this.isUsingWebGL = false;
|
|
379
|
+
this.redraw();
|
|
380
|
+
}
|
|
404
381
|
}
|
|
405
382
|
|
|
406
383
|
// Render the tile layer, called automatically by the engine
|
|
@@ -408,78 +385,76 @@ class TileLayer extends CanvasLayer
|
|
|
408
385
|
{
|
|
409
386
|
ASSERT(drawContext !== this.context, 'must call redrawEnd() after drawing tiles!');
|
|
410
387
|
|
|
411
|
-
if (this.refreshWebGL)
|
|
412
|
-
{
|
|
413
|
-
// update the WebGL texture
|
|
414
|
-
this.textureInfo.createWebGLTexture();
|
|
415
|
-
this.refreshWebGL = false;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// draw the tile layer as a single tile
|
|
419
|
-
const tileInfo = new TileInfo().setFullImage(this.textureInfo);
|
|
420
388
|
const size = this.drawSize || this.size;
|
|
421
389
|
const pos = this.pos.add(size.scale(.5));
|
|
422
|
-
|
|
423
|
-
drawTile(pos, size, tileInfo, WHITE, 0, false, CLEAR_BLACK, useWebGL);
|
|
390
|
+
this.draw(pos, this.size, this.color, this.angle, this.mirror, this.additiveColor);
|
|
424
391
|
}
|
|
425
392
|
|
|
393
|
+
/** Called after this layer is redrawn, does nothing by default */
|
|
394
|
+
onRedraw() {}
|
|
395
|
+
|
|
426
396
|
/** Draw all the tile data to an offscreen canvas
|
|
427
|
-
* - This may be slow
|
|
397
|
+
* - This may be slow if not using webgl but only needs to be done once */
|
|
428
398
|
redraw()
|
|
429
399
|
{
|
|
430
400
|
this.redrawStart(true);
|
|
431
401
|
for (let x = this.size.x; x--;)
|
|
432
402
|
for (let y = this.size.y; y--;)
|
|
433
403
|
this.drawTileData(vec2(x,y), false);
|
|
404
|
+
this.hasWebGL() && glFlush();
|
|
405
|
+
this.onRedraw();
|
|
434
406
|
this.redrawEnd();
|
|
435
|
-
this.useWebGL();
|
|
436
407
|
}
|
|
437
408
|
|
|
438
409
|
/** Call to start the redraw process
|
|
439
|
-
* - This can be used to manually update
|
|
410
|
+
* - This can be used to manually update parts of the level
|
|
440
411
|
* @param {boolean} [clear] - Should it clear the canvas before drawing */
|
|
441
412
|
redrawStart(clear=false)
|
|
442
413
|
{
|
|
443
414
|
if (!this.context) return;
|
|
444
|
-
|
|
415
|
+
ASSERT(drawContext !== this.context);
|
|
416
|
+
|
|
445
417
|
// save current render settings
|
|
446
|
-
/** @type {[
|
|
447
|
-
this.savedRenderSettings = [
|
|
418
|
+
/** @type {[CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D, Vector2, Vector2, number, Color]} */
|
|
419
|
+
this.savedRenderSettings = [drawContext, mainCanvasSize, cameraPos, cameraScale, canvasClearColor];
|
|
448
420
|
|
|
449
421
|
// set the draw canvas and context to this layer
|
|
450
422
|
// use camera settings to match this layer's canvas
|
|
451
|
-
drawCanvas = this.canvas;
|
|
452
423
|
drawContext = this.context;
|
|
453
|
-
|
|
454
|
-
const tileSize = this.tileInfo ? this.tileInfo.size : vec2(1);
|
|
455
|
-
cameraScale = tileSize.x;
|
|
456
|
-
canvasClearColor = CLEAR_BLACK;
|
|
424
|
+
const tileSize = this.tileInfo?.size ?? vec2(1);
|
|
457
425
|
mainCanvasSize = this.size.multiply(tileSize);
|
|
458
|
-
|
|
426
|
+
canvasClearColor = CLEAR_BLACK;
|
|
427
|
+
cameraPos = this.size.multiply(tileSize).scale(.5);
|
|
428
|
+
cameraScale = 1;
|
|
429
|
+
|
|
430
|
+
// set render target to this layer
|
|
431
|
+
this.isUsingWebGL = this.hasWebGL();
|
|
432
|
+
if (this.isUsingWebGL)
|
|
433
|
+
glSetRenderTarget(this.textureInfo.glTexture, clear);
|
|
434
|
+
else
|
|
459
435
|
{
|
|
460
|
-
//
|
|
461
|
-
|
|
462
|
-
|
|
436
|
+
// disable smoothing for pixel art
|
|
437
|
+
this.context.imageSmoothingEnabled = !tilesPixelated;
|
|
438
|
+
if (clear)
|
|
439
|
+
{
|
|
440
|
+
// clear and set size
|
|
441
|
+
this.canvas.width = mainCanvasSize.x;
|
|
442
|
+
this.canvas.height = mainCanvasSize.y;
|
|
443
|
+
}
|
|
463
444
|
}
|
|
464
|
-
|
|
465
|
-
// disable smoothing for pixel art
|
|
466
|
-
drawContext.imageSmoothingEnabled = !tilesPixelated;
|
|
467
|
-
|
|
468
|
-
// setup gl rendering if enabled
|
|
469
|
-
glPreRender();
|
|
470
445
|
}
|
|
471
446
|
|
|
472
447
|
/** Call to end the redraw process */
|
|
473
448
|
redrawEnd()
|
|
474
449
|
{
|
|
475
450
|
if (!this.context) return;
|
|
451
|
+
ASSERT(drawContext === this.context);
|
|
476
452
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
//debugSaveCanvas(this.canvas);
|
|
453
|
+
if (glEnable && this.textureInfo.glTexture)
|
|
454
|
+
glSetRenderTarget();
|
|
480
455
|
|
|
481
456
|
// set stuff back to normal
|
|
482
|
-
[
|
|
457
|
+
[drawContext, mainCanvasSize, cameraPos, cameraScale, canvasClearColor] = this.savedRenderSettings;
|
|
483
458
|
}
|
|
484
459
|
|
|
485
460
|
/** Draw the tile at a given position in the tile grid
|
|
@@ -491,24 +466,75 @@ class TileLayer extends CanvasLayer
|
|
|
491
466
|
drawTileData(layerPos, clear=true)
|
|
492
467
|
{
|
|
493
468
|
if (!this.context) return;
|
|
469
|
+
ASSERT(drawContext === this.context, 'must call redrawStart() before drawing tiles');
|
|
494
470
|
|
|
495
|
-
// clear out where the tile was, for
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
const pos = layerPos.multiply(s);
|
|
500
|
-
this.context.clearRect(pos.x, this.canvas.height-pos.y, s.x, -s.y);
|
|
501
|
-
}
|
|
471
|
+
// clear out where the tile was, can be skipped for fully opaque tiles
|
|
472
|
+
const drawSize = this.tileInfo?.size ?? vec2(1);
|
|
473
|
+
const drawPos = layerPos.multiply(drawSize);
|
|
474
|
+
clear && this.clearLayerRect(drawPos, drawSize);
|
|
502
475
|
|
|
503
476
|
// draw the tile if it has layer data
|
|
504
477
|
const d = this.getData(layerPos);
|
|
505
|
-
if (d.tile
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
478
|
+
if (!d.tile) return;
|
|
479
|
+
|
|
480
|
+
const tileInfo = this.tileInfo && this.tileInfo.tile(d.tile);
|
|
481
|
+
this.drawLayerTile(drawPos, drawSize, tileInfo, d.color, d.direction*PI/2, d.mirror);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/** Draw the tile at a given position in the tile grid
|
|
485
|
+
* This can be used to clear tiles when they are destroyed
|
|
486
|
+
* For better performance use drawTileData inside a redrawStart/End block
|
|
487
|
+
* @param {Vector2} layerPos
|
|
488
|
+
* @param {boolean} [clear] - should the old tile be cleared
|
|
489
|
+
*/
|
|
490
|
+
redrawTileData(layerPos, clear=true)
|
|
491
|
+
{
|
|
492
|
+
if (!this.context) return;
|
|
493
|
+
ASSERT(drawContext !== this.context, 'redrawStart() should not be active when calling redrawTileData(), instead use drawTileData()');
|
|
494
|
+
|
|
495
|
+
this.redrawStart();
|
|
496
|
+
this.drawTileData(layerPos, clear);
|
|
497
|
+
this.redrawEnd();
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/** Draw textured tile in layer space
|
|
501
|
+
* @param {Vector2} pos - Position in pixel coordinates
|
|
502
|
+
* @param {Vector2} [size=vec2(1)] - Size of the tile
|
|
503
|
+
* @param {TileInfo} [tileInfo] - Tile info to use, untextured if undefined
|
|
504
|
+
* @param {Color} [color=WHITE] - Color to modulate with
|
|
505
|
+
* @param {number} [angle] - Angle to rotate by
|
|
506
|
+
* @param {boolean} [mirror] - Is image flipped along the Y axis?
|
|
507
|
+
* @param {Color} [additiveColor] - Additive color to be applied if any */
|
|
508
|
+
drawLayerTile(pos, size=vec2(1), tileInfo, color=WHITE,
|
|
509
|
+
angle=0, mirror, additiveColor)
|
|
510
|
+
{
|
|
511
|
+
const drawPos = pos.add(size.scale(.5));
|
|
512
|
+
drawTile(drawPos, size, tileInfo, color, angle, mirror, additiveColor);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/** Clear a rectangle in layer space
|
|
516
|
+
* @param {Vector2} pos
|
|
517
|
+
* @param {Vector2} size
|
|
518
|
+
* @param {Color} [color=WHITE] - Color to modulate with
|
|
519
|
+
* @param {number} [angle] - Angle to rotate by
|
|
520
|
+
*/
|
|
521
|
+
drawLayerRect(pos, size, color, angle=0)
|
|
522
|
+
{ this.drawLayerTile(pos, size, undefined, color, angle); }
|
|
523
|
+
|
|
524
|
+
/** Clear a rectangle in layer space
|
|
525
|
+
* @param {Vector2} pos - position in pixel coordinates
|
|
526
|
+
* @param {Vector2} size
|
|
527
|
+
*/
|
|
528
|
+
clearLayerRect(pos, size)
|
|
529
|
+
{
|
|
530
|
+
ASSERT(drawContext === this.context, 'must call redrawStart() before clearing tiles');
|
|
531
|
+
|
|
532
|
+
const x = pos.x, y = this.canvas.height - pos.y - size.y;
|
|
533
|
+
const useWebGL = this.hasWebGL();
|
|
534
|
+
if (useWebGL)
|
|
535
|
+
glClearRect(x, y, size.x, size.y);
|
|
536
|
+
else
|
|
537
|
+
this.context.clearRect(x, y, size.x, size.y);
|
|
512
538
|
}
|
|
513
539
|
}
|
|
514
540
|
|
|
@@ -517,7 +543,6 @@ class TileLayer extends CanvasLayer
|
|
|
517
543
|
* Tile Collision Layer - a tile layer with collision
|
|
518
544
|
* - adds collision data and functions to TileLayer
|
|
519
545
|
* - there can be multiple tile collision layers
|
|
520
|
-
* - tile collision layers should not overlap each other
|
|
521
546
|
* @extends TileLayer
|
|
522
547
|
* @memberof TileLayers
|
|
523
548
|
*/
|
|
@@ -547,8 +572,7 @@ class TileCollisionLayer extends TileLayer
|
|
|
547
572
|
/** Destroy this tile layer */
|
|
548
573
|
destroy()
|
|
549
574
|
{
|
|
550
|
-
if (this.destroyed)
|
|
551
|
-
return;
|
|
575
|
+
if (this.destroyed) return;
|
|
552
576
|
|
|
553
577
|
// remove from collision layers array and destroy
|
|
554
578
|
const index = tileCollisionLayers.indexOf(this);
|
|
@@ -590,7 +614,7 @@ class TileCollisionLayer extends TileLayer
|
|
|
590
614
|
|
|
591
615
|
/** Check if collision with another object should occur
|
|
592
616
|
* @param {Vector2} pos
|
|
593
|
-
* @param {Vector2} [size=(
|
|
617
|
+
* @param {Vector2} [size=vec2()]
|
|
594
618
|
* @param {EngineObject} [object]
|
|
595
619
|
* @return {boolean} */
|
|
596
620
|
collisionTest(pos, size=new Vector2, object)
|