littlejsengine 1.17.1 → 1.17.5

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/src/engineDraw.js CHANGED
@@ -258,7 +258,7 @@ function drawTile(pos, size=vec2(1), tileInfo, color=WHITE,
258
258
  ASSERT(!additiveColor || isColor(additiveColor), 'additiveColor must be a color');
259
259
  ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
260
260
 
261
- const textureInfo = tileInfo && tileInfo.textureInfo;
261
+ const textureInfo = tileInfo?.textureInfo;
262
262
  const bleed = tileInfo?.bleed ?? 0;
263
263
  if (useWebGL && glEnable)
264
264
  {
@@ -564,9 +564,12 @@ function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineC
564
564
  ASSERT(isColor(color) && isColor(lineColor), 'color is invalid');
565
565
  ASSERT(isNumber(angle), 'angle must be a number');
566
566
  ASSERT(isNumber(lineWidth), 'lineWidth must be a number');
567
- ASSERT(lineWidth >= 0 && lineWidth < size.x && lineWidth < size.y, 'invalid lineWidth');
567
+ ASSERT(lineWidth >= 0, 'lineWidth must be a positive value or 0');
568
568
  ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
569
569
 
570
+ // clamp line width to prevent artifacts
571
+ lineWidth = clamp(lineWidth, 0, Math.min(size.x, size.y));
572
+
570
573
  if (useWebGL && glEnable)
571
574
  {
572
575
  // draw as a regular polygon
@@ -315,7 +315,6 @@ export
315
315
  audioMasterGain,
316
316
  audioDefaultSampleRate,
317
317
  Sound,
318
- SoundWave,
319
318
  SoundInstance,
320
319
  speak,
321
320
  speakStop,
@@ -408,9 +408,9 @@ function inputInit()
408
408
  function touchInputInit()
409
409
  {
410
410
  // add non passive touch event listeners
411
- document.addEventListener('touchstart', (e) => handleTouch(e), { passive: false });
412
- document.addEventListener('touchmove', (e) => handleTouch(e), { passive: false });
413
- document.addEventListener('touchend', (e) => handleTouch(e), { passive: false });
411
+ document.addEventListener('touchstart', (e)=> handleTouch(e), { passive: false });
412
+ document.addEventListener('touchmove', (e)=> handleTouch(e), { passive: false });
413
+ document.addEventListener('touchend', (e)=> handleTouch(e), { passive: false });
414
414
 
415
415
  // handle all touch events the same way
416
416
  let wasTouching;
@@ -616,7 +616,7 @@ function inputUpdate()
616
616
  // poll gamepads
617
617
  const maxGamepads = 8;
618
618
  const gamepads = navigator.getGamepads();
619
- const gamepadCount = min(maxGamepads, gamepads.length)
619
+ const gamepadCount = min(maxGamepads, gamepads.length);
620
620
  for (let i=0; i<gamepadCount; ++i)
621
621
  {
622
622
  // get or create gamepad data
package/src/engineMath.js CHANGED
@@ -16,25 +16,25 @@
16
16
  const PI = Math.PI;
17
17
 
18
18
  /** Returns absolute value of value passed in
19
- * @param {number} value
19
+ * @param {number} x
20
20
  * @return {number}
21
21
  * @memberof Math */
22
22
  const abs = Math.abs;
23
23
 
24
24
  /** Returns floored value of value passed in
25
- * @param {number} value
25
+ * @param {number} x
26
26
  * @return {number}
27
27
  * @memberof Math */
28
28
  const floor = Math.floor;
29
29
 
30
30
  /** Returns ceiled value of value passed in
31
- * @param {number} value
31
+ * @param {number} x
32
32
  * @return {number}
33
33
  * @memberof Math */
34
34
  const ceil = Math.ceil;
35
35
 
36
36
  /** Returns rounded value passed in
37
- * @param {number} value
37
+ * @param {number} x
38
38
  * @return {number}
39
39
  * @memberof Math */
40
40
  const round = Math.round;
@@ -52,7 +52,7 @@ const min = Math.min;
52
52
  const max = Math.max;
53
53
 
54
54
  /** Returns the sign of value passed in
55
- * @param {number} value
55
+ * @param {number} x
56
56
  * @return {number}
57
57
  * @memberof Math */
58
58
  const sign = Math.sign;
@@ -64,25 +64,25 @@ const sign = Math.sign;
64
64
  const hypot = Math.hypot;
65
65
 
66
66
  /** Returns log2 of value passed in
67
- * @param {number} value
67
+ * @param {number} x
68
68
  * @return {number}
69
69
  * @memberof Math */
70
70
  const log2 = Math.log2;
71
71
 
72
72
  /** Returns sin of value passed in
73
- * @param {number} value
73
+ * @param {number} x
74
74
  * @return {number}
75
75
  * @memberof Math */
76
76
  const sin = Math.sin;
77
77
 
78
78
  /** Returns cos of value passed in
79
- * @param {number} value
79
+ * @param {number} x
80
80
  * @return {number}
81
81
  * @memberof Math */
82
82
  const cos = Math.cos;
83
83
 
84
84
  /** Returns tan of value passed in
85
- * @param {number} value
85
+ * @param {number} x
86
86
  * @return {number}
87
87
  * @memberof Math */
88
88
  const tan = Math.tan;
@@ -277,7 +277,7 @@ class EngineObject
277
277
  if (this.collideTiles)
278
278
  {
279
279
  // check collision against tiles
280
- const hitLayer = tileCollisionTest(this.pos, this.size, this)
280
+ const hitLayer = tileCollisionTest(this.pos, this.size, this);
281
281
  if (hitLayer)
282
282
  {
283
283
  // if already was stuck in collision, don't do anything
@@ -183,17 +183,17 @@ class TileLayerData
183
183
  class CanvasLayer extends EngineObject
184
184
  {
185
185
  /** Create a canvas layer object
186
- * @param {Vector2} [position] - World space position of the layer
186
+ * @param {Vector2} [pos] - World space position of the layer
187
187
  * @param {Vector2} [size] - World space size of the layer
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
191
  * @param {boolean} [useWebGL] - Should this layer use WebGL for rendering
192
192
  */
193
- constructor(position, size, angle=0, renderOrder=0, canvasSize=vec2(512), useWebGL=glEnable)
193
+ constructor(pos, size, angle=0, renderOrder=0, canvasSize=vec2(512), useWebGL=true)
194
194
  {
195
195
  ASSERT(isVector2(canvasSize), 'canvasSize must be a Vector2');
196
- super(position, size, undefined, angle, WHITE, renderOrder);
196
+ super(pos, size, undefined, angle, WHITE, renderOrder);
197
197
 
198
198
  /** @property {HTMLCanvasElement} - The canvas used by this layer */
199
199
  this.canvas = headlessMode ? undefined : new OffscreenCanvas(canvasSize.x, canvasSize.y);
@@ -297,16 +297,16 @@ class CanvasLayer extends EngineObject
297
297
  class TileLayer extends CanvasLayer
298
298
  {
299
299
  /** Create a tile layer object
300
- * @param {Vector2} position - World space position
300
+ * @param {Vector2} pos - World space position
301
301
  * @param {Vector2} size - World space size
302
302
  * @param {TileInfo} [tileInfo] - Default tile info for layer (used for size and texture)
303
303
  * @param {number} [renderOrder] - Objects are sorted by renderOrder
304
+ * @param {boolean} [useWebGL] - Should this layer use WebGL for rendering
304
305
  */
305
- constructor(position, size, tileInfo=tile(), renderOrder=0)
306
+ constructor(pos, size, tileInfo=tile(), renderOrder=0, useWebGL=true)
306
307
  {
307
308
  const canvasSize = tileInfo ? size.multiply(tileInfo.size) : size;
308
- const useWebGL = true;
309
- super(position, size, 0, renderOrder, canvasSize, useWebGL);
309
+ super(pos, size, 0, renderOrder, canvasSize, useWebGL);
310
310
 
311
311
  /** @property {TileInfo} - Default tile info for layer */
312
312
  this.tileInfo = undefined;
@@ -318,15 +318,15 @@ class TileLayer extends CanvasLayer
318
318
  if (headlessMode)
319
319
  {
320
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 = () => {};
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
330
  return;
331
331
  }
332
332
 
@@ -360,6 +360,12 @@ class TileLayer extends CanvasLayer
360
360
  isRedraw ? this.drawTileData(layerPos) : this.redrawTileData(layerPos);
361
361
  }
362
362
 
363
+ /** Clear data at a given position in the array
364
+ * @param {Vector2} layerPos - Local position in array
365
+ * @param {boolean} [redraw] - Force the tile to redraw if true */
366
+ clearData(layerPos, redraw=false)
367
+ { this.setData(layerPos, new TileLayerData, redraw) }
368
+
363
369
  /** Get data at a given position in the array
364
370
  * @param {Vector2} layerPos - Local position in array
365
371
  * @return {TileLayerData} */
@@ -401,7 +407,7 @@ class TileLayer extends CanvasLayer
401
407
  for (let x = this.size.x; x--;)
402
408
  for (let y = this.size.y; y--;)
403
409
  this.drawTileData(vec2(x,y), false);
404
- this.hasWebGL() && glFlush();
410
+ this.isUsingWebGL && glFlush();
405
411
  this.onRedraw();
406
412
  this.redrawEnd();
407
413
  }
@@ -450,14 +456,13 @@ class TileLayer extends CanvasLayer
450
456
  if (!this.context) return;
451
457
  ASSERT(drawContext === this.context);
452
458
 
453
- if (glEnable && this.textureInfo.glTexture)
454
- glSetRenderTarget();
455
-
456
459
  // set stuff back to normal
460
+ if (this.isUsingWebGL)
461
+ glSetRenderTarget();
457
462
  [drawContext, mainCanvasSize, cameraPos, cameraScale, canvasClearColor] = this.savedRenderSettings;
458
463
  }
459
464
 
460
- /** Draw the tile at a given position in the tile grid
465
+ /** Draw the tile at a given position in the tile layer
461
466
  * This can be used to clear out tiles when they are destroyed
462
467
  * Tiles can also be redrawn if inside a redrawStart/End block
463
468
  * @param {Vector2} layerPos
@@ -481,7 +486,7 @@ class TileLayer extends CanvasLayer
481
486
  this.drawLayerTile(drawPos, drawSize, tileInfo, d.color, d.direction*PI/2, d.mirror);
482
487
  }
483
488
 
484
- /** Draw the tile at a given position in the tile grid
489
+ /** Draw the tile at a given position in the tile layer
485
490
  * This can be used to clear tiles when they are destroyed
486
491
  * For better performance use drawTileData inside a redrawStart/End block
487
492
  * @param {Vector2} layerPos
@@ -509,7 +514,7 @@ class TileLayer extends CanvasLayer
509
514
  angle=0, mirror, additiveColor)
510
515
  {
511
516
  const drawPos = pos.add(size.scale(.5));
512
- drawTile(drawPos, size, tileInfo, color, angle, mirror, additiveColor);
517
+ drawTile(drawPos, size, tileInfo, color, angle, mirror, additiveColor, this.isUsingWebGL);
513
518
  }
514
519
 
515
520
  /** Clear a rectangle in layer space
@@ -549,14 +554,15 @@ class TileLayer extends CanvasLayer
549
554
  class TileCollisionLayer extends TileLayer
550
555
  {
551
556
  /** Create a tile layer object
552
- * @param {Vector2} position - World space position
553
- * @param {Vector2} size - World space size
554
- * @param {TileInfo} [tileInfo] - Tile info for layer
557
+ * @param {Vector2} pos - World space position
558
+ * @param {Vector2} size - World space size
559
+ * @param {TileInfo} [tileInfo] - Tile info for layer
555
560
  * @param {number} [renderOrder] - Objects are sorted by renderOrder
561
+ * @param {boolean} [useWebGL] - Should this layer use WebGL for rendering
556
562
  */
557
- constructor(position, size, tileInfo=tile(), renderOrder=0)
563
+ constructor(pos, size, tileInfo=tile(), renderOrder=0, useWebGL=true)
558
564
  {
559
- super(position, size.floor(), tileInfo, renderOrder);
565
+ super(pos, size.floor(), tileInfo, renderOrder, useWebGL);
560
566
 
561
567
  /** @property {Array<number>} - The tile collision grid */
562
568
  this.collisionData = [];
@@ -592,24 +598,29 @@ class TileCollisionLayer extends TileLayer
592
598
  this.collisionData.fill(0);
593
599
  }
594
600
 
595
- /** Set tile collision data for a given cell in the grid
596
- * @param {Vector2} gridPos
601
+ /** Set tile collision data for a given cell in the layer
602
+ * @param {Vector2} layerPos
597
603
  * @param {number} [data] */
598
- setCollisionData(gridPos, data=1)
604
+ setCollisionData(layerPos, data=1)
599
605
  {
600
- ASSERT(isVector2(gridPos), 'gridPos must be a Vector2');
601
- const i = (gridPos.y|0)*this.size.x + gridPos.x|0;
602
- gridPos.arrayCheck(this.size) && (this.collisionData[i] = data);
606
+ ASSERT(isVector2(layerPos), 'layerPos must be a Vector2');
607
+ const i = (layerPos.y|0)*this.size.x + layerPos.x|0;
608
+ layerPos.arrayCheck(this.size) && (this.collisionData[i] = data);
603
609
  }
604
610
 
605
- /** Get tile collision data for a given cell in the grid
606
- * @param {Vector2} gridPos
611
+ /** Clear tile collision data for a given cell in the layer
612
+ * @param {Vector2} layerPos */
613
+ clearCollisionData(layerPos)
614
+ { this.setCollisionData(layerPos, 0); }
615
+
616
+ /** Get tile collision data for a given cell in the layer
617
+ * @param {Vector2} layerPos
607
618
  * @return {number} */
608
- getCollisionData(gridPos)
619
+ getCollisionData(layerPos)
609
620
  {
610
- ASSERT(isVector2(gridPos), 'gridPos must be a Vector2');
611
- const i = (gridPos.y|0)*this.size.x + gridPos.x|0;
612
- return gridPos.arrayCheck(this.size) ? this.collisionData[i] : 0;
621
+ ASSERT(isVector2(layerPos), 'layerPos must be a Vector2');
622
+ const i = (layerPos.y|0)*this.size.x + layerPos.x|0;
623
+ return layerPos.arrayCheck(this.size) ? this.collisionData[i] : 0;
613
624
  }
614
625
 
615
626
  /** Check if collision with another object should occur
@@ -259,7 +259,7 @@ function glPreRender(clear=true)
259
259
  p.x, p.y, 0, 1];
260
260
 
261
261
  // set the same transform matrix for both shaders
262
- const initUniform = (program, uniform, value) =>
262
+ const initUniform = (program, uniform, value)=>
263
263
  {
264
264
  glContext.useProgram(program);
265
265
  const location = glContext.getUniformLocation(program, uniform);
@@ -653,7 +653,7 @@ function glSetRenderTarget(texture, clear=false)
653
653
  glContext.bindFramebuffer(glContext.FRAMEBUFFER, glFramebuffer);
654
654
  glContext.framebufferTexture2D(glContext.FRAMEBUFFER,
655
655
  glContext.COLOR_ATTACHMENT0, glContext.TEXTURE_2D, texture, 0);
656
- glPreRender(clear);
656
+ glPreRender(clear);
657
657
  }
658
658
  else
659
659
  {