littlejsengine 1.8.1 → 1.8.4

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.
@@ -1181,6 +1181,7 @@ class EngineObject
1181
1181
  // set passed in params
1182
1182
  ASSERT(isVector2(pos) && isVector2(size)); // ensure pos and size are vec2s
1183
1183
  ASSERT(typeof tileInfo !== 'number' || !tileInfo); // prevent old style calls
1184
+ ASSERT(!(renderOrder instanceof Color)); // prevent old style calls
1184
1185
  // to fix old calls, replace with tile(tileIndex, tileSize)
1185
1186
 
1186
1187
  /** @property {Vector2} - World space position of the object */
@@ -1702,16 +1703,18 @@ function worldToScreen(worldPos)
1702
1703
  * @param {Color} [additiveColor=Color(0,0,0,0)] - Additive color to be applied
1703
1704
  * @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
1704
1705
  * @param {Boolean} [screenSpace=0] - If true the pos and size are in screen space
1706
+ * @param {CanvasRenderingContext2D} [context] - Canvas 2D context to draw to
1705
1707
  * @memberof Draw */
1706
1708
  function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
1707
- angle=0, mirror, additiveColor=new Color(0,0,0,0), useWebGL=glEnable, screenSpace)
1709
+ angle=0, mirror, additiveColor=new Color(0,0,0,0), useWebGL=glEnable, screenSpace, context)
1708
1710
  {
1711
+ ASSERT(!context || !useWebGL); // context only supported in canvas 2D mode
1709
1712
  ASSERT(typeof tileInfo !== 'number' || !tileInfo); // prevent old style calls
1710
1713
  // to fix old calls, replace with tile(tileIndex, tileSize)
1711
1714
 
1712
1715
  showWatermark && ++drawCount;
1713
1716
  const textureInfo = tileInfo && tileInfo.getTextureInfo();
1714
- if (glEnable && useWebGL)
1717
+ if (useWebGL)
1715
1718
  {
1716
1719
  if (screenSpace)
1717
1720
  {
@@ -1762,7 +1765,7 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
1762
1765
  context.fillStyle = color;
1763
1766
  context.fillRect(-.5, -.5, 1, 1);
1764
1767
  }
1765
- }, undefined, screenSpace);
1768
+ }, screenSpace, context);
1766
1769
  }
1767
1770
  }
1768
1771
 
@@ -1773,28 +1776,36 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
1773
1776
  * @param {Number} [angle=0]
1774
1777
  * @param {Boolean} [useWebGL=glEnable]
1775
1778
  * @param {Boolean} [screenSpace=0]
1779
+ * @param {CanvasRenderingContext2D} [context]
1776
1780
  * @memberof Draw */
1777
- function drawRect(pos, size, color, angle, useWebGL, screenSpace)
1778
- { drawTile(pos, size, undefined, color, angle, 0, undefined, useWebGL, screenSpace); }
1781
+ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
1782
+ {
1783
+ drawTile(pos, size, undefined, color, angle, 0, undefined, useWebGL, screenSpace, context);
1784
+ }
1779
1785
 
1780
1786
  /** Draw colored polygon using passed in points
1781
1787
  * @param {Array} points - Array of Vector2 points
1782
1788
  * @param {Color} [color=Color()]
1783
1789
  * @param {Boolean} [useWebGL=glEnable]
1784
1790
  * @param {Boolean} [screenSpace=0]
1791
+ * @param {CanvasRenderingContext2D} [context]
1785
1792
  * @memberof Draw */
1786
- function drawPoly(points, color=new Color, useWebGL=glEnable, screenSpace)
1793
+ function drawPoly(points, color=new Color, useWebGL=glEnable, screenSpace, context)
1787
1794
  {
1795
+ ASSERT(!context || !useWebGL); // context only supported in canvas 2D mode
1796
+
1788
1797
  if (useWebGL)
1789
1798
  glDrawPoints(screenSpace ? points.map(screenToWorld) : points, color.rgbaInt());
1790
1799
  else
1791
1800
  {
1792
1801
  // draw using canvas
1793
- mainContext.fillStyle = color;
1794
- mainContext.beginPath();
1802
+ if (!context)
1803
+ context = mainContext;
1804
+ context.fillStyle = color;
1805
+ context.beginPath();
1795
1806
  for (const point of screenSpace ? points : points.map(worldToScreen))
1796
- mainContext.lineTo(point.x, point.y);
1797
- mainContext.fill();
1807
+ context.lineTo(point.x, point.y);
1808
+ context.fill();
1798
1809
  }
1799
1810
  }
1800
1811
 
@@ -1805,12 +1816,13 @@ function drawPoly(points, color=new Color, useWebGL=glEnable, screenSpace)
1805
1816
  * @param {Color} [color=Color()]
1806
1817
  * @param {Boolean} [useWebGL=glEnable]
1807
1818
  * @param {Boolean} [screenSpace=0]
1819
+ * @param {CanvasRenderingContext2D} [context]
1808
1820
  * @memberof Draw */
1809
- function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace)
1821
+ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
1810
1822
  {
1811
1823
  const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
1812
1824
  const size = vec2(thickness, halfDelta.length()*2);
1813
- drawRect(posA.add(halfDelta), size, color, halfDelta.angle(), useWebGL, screenSpace);
1825
+ drawRect(posA.add(halfDelta), size, color, halfDelta.angle(), useWebGL, screenSpace, context);
1814
1826
  }
1815
1827
 
1816
1828
  /** Draw directly to a 2d canvas context in world space
@@ -1819,10 +1831,10 @@ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace)
1819
1831
  * @param {Number} angle
1820
1832
  * @param {Boolean} mirror
1821
1833
  * @param {Function} drawFunction
1822
- * @param {CanvasRenderingContext2D} [context=mainContext]
1823
1834
  * @param {Boolean} [screenSpace=0]
1835
+ * @param {CanvasRenderingContext2D} [context=mainContext]
1824
1836
  * @memberof Draw */
1825
- function drawCanvas2D(pos, size, angle, mirror, drawFunction, context = mainContext, screenSpace)
1837
+ function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, context=mainContext)
1826
1838
  {
1827
1839
  if (!screenSpace)
1828
1840
  {
@@ -1841,13 +1853,19 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, context = mainCont
1841
1853
  /** Enable normal or additive blend mode
1842
1854
  * @param {Boolean} [additive=0]
1843
1855
  * @param {Boolean} [useWebGL=glEnable]
1856
+ * @param {CanvasRenderingContext2D} [context=mainContext]
1844
1857
  * @memberof Draw */
1845
- function setBlendMode(additive, useWebGL=glEnable)
1858
+ function setBlendMode(additive, useWebGL=glEnable, context)
1846
1859
  {
1847
- if (glEnable && useWebGL)
1848
- glSetBlendMode(additive);
1860
+ ASSERT(!context || !useWebGL); // context only supported in canvas 2D mode
1861
+ if (useWebGL)
1862
+ glAdditive = additive;
1849
1863
  else
1850
- mainContext.globalCompositeOperation = additive ? 'lighter' : 'source-over';
1864
+ {
1865
+ if (!context)
1866
+ context = mainContext;
1867
+ context.globalCompositeOperation = additive ? 'lighter' : 'source-over';
1868
+ }
1851
1869
  }
1852
1870
 
1853
1871
  /** Draw text on overlay canvas in world space
@@ -2499,7 +2517,8 @@ class Sound
2499
2517
  if (zzfxSound)
2500
2518
  {
2501
2519
  // generate zzfx sound now for fast playback
2502
- this.randomness = zzfxSound[1] || (zzfxSound[1] = 0);
2520
+ this.randomness = zzfxSound[1] || 0;
2521
+ zzfxSound[1] = 0; // generate without randomness
2503
2522
  this.sampleChannels = [zzfxG(...zzfxSound)];
2504
2523
  this.sampleRate = zzfxR;
2505
2524
  }
@@ -4005,21 +4024,20 @@ function glInit()
4005
4024
  '#version 300 es\n' + // specify GLSL ES version
4006
4025
  'precision highp float;'+ // use highp for better accuracy
4007
4026
  'uniform mat4 m;'+ // transform matrix
4008
- 'in vec2 p,t;'+ // position, uv
4009
- 'in vec4 c,a;'+ // color, additiveColor
4027
+ 'in vec4 p,c,a;'+ // position, uv, color, additiveColor
4010
4028
  'out vec4 v,d,e;'+ // return uv, color, additiveColor
4011
4029
  'void main(){'+ // shader entry point
4012
- 'gl_Position=m*vec4(p,1,1);'+ // transform position
4013
- 'v=vec4(t,p);d=c;e=a;'+ // pass stuff to fragment shader
4030
+ 'gl_Position=m*vec4(p.xy,1,1);'+ // transform position
4031
+ 'v=p;d=c;e=a;'+ // pass stuff to fragment shader
4014
4032
  '}' // end of shader
4015
4033
  ,
4016
4034
  '#version 300 es\n' + // specify GLSL ES version
4017
4035
  'precision highp float;'+ // use highp for better accuracy
4018
- 'in vec4 v,d,e;'+ // uv, color, additiveColor
4036
+ 'in vec4 v,d,e;'+ // position, uv, color, additiveColor
4019
4037
  'uniform sampler2D s;'+ // texture
4020
4038
  'out vec4 c;'+ // out color
4021
4039
  'void main(){'+ // shader entry point
4022
- 'c=texture(s,v.xy)*d+e;'+ // modulate texture by color plus additive
4040
+ 'c=texture(s,v.zw)*d+e;'+ // modulate texture by color plus additive
4023
4041
  '}' // end of shader
4024
4042
  );
4025
4043
 
@@ -4044,7 +4062,7 @@ function glPreRender()
4044
4062
  glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = textureInfos[0].glTexture);
4045
4063
  glContext.bindBuffer(gl_ARRAY_BUFFER, glArrayBuffer);
4046
4064
  glContext.bufferData(gl_ARRAY_BUFFER, gl_VERTEX_BUFFER_SIZE, gl_DYNAMIC_DRAW);
4047
- glSetBlendMode();
4065
+ glAdditive = 0;
4048
4066
 
4049
4067
  // set vertex attributes
4050
4068
  let offset = 0;
@@ -4055,33 +4073,25 @@ function glPreRender()
4055
4073
  glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
4056
4074
  offset += size*typeSize;
4057
4075
  }
4058
- initVertexAttribArray('p', gl_FLOAT, 4, 2); // position
4059
- initVertexAttribArray('t', gl_FLOAT, 4, 2); // texture coords
4076
+ initVertexAttribArray('p', gl_FLOAT, 4, 4); // position & texture coords
4060
4077
  initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
4061
4078
  initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
4062
4079
 
4063
4080
  // build the transform matrix
4064
4081
  const sx = 2 * cameraScale / mainCanvas.width;
4065
4082
  const sy = 2 * cameraScale / mainCanvas.height;
4083
+ const cx = -1 - sx*cameraPos.x;
4084
+ const cy = -1 - sy*cameraPos.y;
4066
4085
  glContext.uniformMatrix4fv(glContext.getUniformLocation(glShader, 'm'), 0,
4067
4086
  new Float32Array([
4068
- sx, 0, 0, 0,
4069
- 0, sy, 0, 0,
4070
- 1, 1, -1, 1,
4071
- -1-sx*cameraPos.x, -1-sy*cameraPos.y, 0, 0
4087
+ sx, 0, 0, 0,
4088
+ 0, sy, 0, 0,
4089
+ 1, 1, -1, 1,
4090
+ cx, cy, 0, 0
4072
4091
  ])
4073
4092
  );
4074
4093
  }
4075
4094
 
4076
- /** Set the WebGl blend mode, normally you should call setBlendMode instead
4077
- * @param {Boolean} [additive=0]
4078
- * @memberof WebGL */
4079
- function glSetBlendMode(additive=0)
4080
- {
4081
- // setup blending
4082
- glAdditive = additive;
4083
- }
4084
-
4085
4095
  /** Set the WebGl texture, called automatically if using multiple textures
4086
4096
  * - This may also flush the gl buffer resulting in more draw calls and worse performance
4087
4097
  * @param {WebGLTexture} texture
@@ -4317,8 +4327,11 @@ function glRenderPostProcess()
4317
4327
  glFlush(); // clear out the buffer
4318
4328
  mainContext.drawImage(glCanvas, 0, 0); // copy to the main canvas
4319
4329
  }
4320
- else // set viewport
4330
+ else
4331
+ {
4332
+ // set the viewport
4321
4333
  glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
4334
+ }
4322
4335
 
4323
4336
  if (glPostIncludeOverlay)
4324
4337
  {
@@ -4422,7 +4435,7 @@ const engineName = 'LittleJS';
4422
4435
  * @type {String}
4423
4436
  * @default
4424
4437
  * @memberof Engine */
4425
- const engineVersion = '1.8.1';
4438
+ const engineVersion = '1.8.4';
4426
4439
 
4427
4440
  /** Frames per second to update objects
4428
4441
  * @type {Number}
@@ -4483,7 +4496,7 @@ let frameTimeLastMS = 0, frameTimeBufferMS = 0, averageFPS = 0;
4483
4496
  * @param {Function} gameUpdatePost - Called after physics and objects are updated, setup camera and prepare for render
4484
4497
  * @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
4485
4498
  * @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
4486
- * @param {String} [imageSources='tiles.png'] - Image to load
4499
+ * @param {Array} [imageSources=['tiles.png']] - Image to load
4487
4500
  * @memberof Engine */
4488
4501
  function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=['tiles.png'])
4489
4502
  {
@@ -134,7 +134,7 @@ class Ball extends EngineObject
134
134
  this.velocity = this.velocity.normalize(speed);
135
135
 
136
136
  // scale bounce sound pitch by speed
137
- sound_bounce.play(this.pos, 1, speed);
137
+ sound_bounce.play(this.pos, 1, speed*2);
138
138
 
139
139
  if (o == paddle)
140
140
  {
@@ -6,6 +6,6 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?181></script>
10
- <script src=gameObjects.js?181></script>
11
- <script src=game.js?181></script>
9
+ <script src=../../build/littlejs.js?183></script>
10
+ <script src=gameObjects.js?183></script>
11
+ <script src=game.js?183></script>
@@ -9,6 +9,8 @@ You can get the [LittleJS code using GitHub](https://github.com/KilledByAPixel/L
9
9
 
10
10
  In this tutorial we will make a breakout style game with a player controllable paddle, a ball that bounces, and bricks that break when hit. This is a great introduction to LittleJS and takes only around 30 minutes to complete.
11
11
 
12
+ [The tutorial is also available on YouTube!](https://youtu.be/tSwDx-NWTXE?si=bkjMa8-7AN2Wg5MO)
13
+
12
14
  ## [You can play the result of this tutorial here.](https://killedbyapixel.github.io/LittleJS/examples/breakoutTutorial/)
13
15
 
14
16
  ![LittleJS Screenshot](images/9.png)
@@ -237,7 +239,7 @@ this.color = new Color(0,0,0,0); // make object invisible
237
239
 
238
240
  ## Debug Display
239
241
 
240
- This is a good time to try opening up the debug info by pressing ~. This feature will allow for a selection of debug overlays while also showing all game objects with more info displayed for the object closest to the mouse. It can be really useful when trying to diagnose bugs and understand what is going on.
242
+ This is a good time to try opening up the debug info by pressing escape. This feature will allow for a selection of debug overlays while also showing all game objects with more info displayed for the object closest to the mouse. It can be really useful when trying to diagnose bugs and understand what is going on.
241
243
 
242
244
  ![LittleJS Screenshot](images/7.png)
243
245
 
@@ -6,5 +6,5 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?181></script>
10
- <script src=game.js?181></script>
9
+ <script src=../../build/littlejs.js?183></script>
10
+ <script src=game.js?183></script>
@@ -7,7 +7,7 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- LittleJS Engine -->
10
- <script src=../../build/littlejs.js?181></script>
10
+ <script src=../../build/littlejs.js?183></script>
11
11
 
12
12
  <!-- Add your game scripts here -->
13
- <script src=game.js?181></script>
13
+ <script src=game.js?183></script>
@@ -1,18 +1,18 @@
1
1
  <head><title>LittleJS JS13K Project</title></head><body>
2
2
 
3
3
  <!-- LittleJS Engine -->
4
- <script src=../../src/engineDebug.js?181></script>
5
- <script src=../../src/engineUtilities.js?181></script>
6
- <script src=../../src/engineSettings.js?181></script>
7
- <script src=../../src/engineObject.js?181></script>
8
- <script src=../../src/engineDraw.js?181></script>
9
- <script src=../../src/engineInput.js?181></script>
10
- <script src=../../src/engineAudio.js?181></script>
11
- <script src=../../src/engineTileLayer.js?181></script>
12
- <script src=../../src/engineParticles.js?181></script>
13
- <script src=../../src/engineMedals.js?181></script>
14
- <script src=../../src/engineWebGL.js?181></script>
15
- <script src=../../src/engine.js?181></script>
4
+ <script src=../../src/engineDebug.js?183></script>
5
+ <script src=../../src/engineUtilities.js?183></script>
6
+ <script src=../../src/engineSettings.js?183></script>
7
+ <script src=../../src/engineObject.js?183></script>
8
+ <script src=../../src/engineDraw.js?183></script>
9
+ <script src=../../src/engineInput.js?183></script>
10
+ <script src=../../src/engineAudio.js?183></script>
11
+ <script src=../../src/engineTileLayer.js?183></script>
12
+ <script src=../../src/engineParticles.js?183></script>
13
+ <script src=../../src/engineMedals.js?183></script>
14
+ <script src=../../src/engineWebGL.js?183></script>
15
+ <script src=../../src/engine.js?183></script>
16
16
 
17
17
  <!-- Add your game scripts here -->
18
- <script src=game.js?181></script>
18
+ <script src=game.js?183></script>
@@ -8,7 +8,7 @@
8
8
 
9
9
  // import module
10
10
  import * as LittleJS from '../../build/littlejs.esm.js';
11
- const {Vector2, Color, Timer, vec2} = LittleJS;
11
+ const {Vector2, Color, Timer, vec2, tile} = LittleJS;
12
12
 
13
13
  // sound effects
14
14
  const sound_click = new LittleJS.Sound([1,.5]);
@@ -7,4 +7,4 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- Add your game scripts here -->
10
- <script src=game.js?181 type=module></script>
10
+ <script src=game.js?183 type=module></script>
@@ -10,7 +10,7 @@ button { margin:1px; }
10
10
  </style>
11
11
  </head><body>
12
12
 
13
- <script src=../../build/littlejs.js?181></script>
13
+ <script src=../../build/littlejs.js?183></script>
14
14
  <script>
15
15
 
16
16
  'use strict';
@@ -6,9 +6,9 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?181></script>
10
- <script src=gameObjects.js?181></script>
11
- <script src=gamePlayer.js?181></script>
12
- <script src=gameEffects.js?181></script>
13
- <script src=gameLevel.js?181></script>
14
- <script src=game.js?181></script>
9
+ <script src=../../build/littlejs.js?183></script>
10
+ <script src=gameObjects.js?183></script>
11
+ <script src=gamePlayer.js?183></script>
12
+ <script src=gameEffects.js?183></script>
13
+ <script src=gameLevel.js?183></script>
14
+ <script src=game.js?183></script>
@@ -6,5 +6,5 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?181></script>
10
- <script src=game.js?181></script>
9
+ <script src=../../build/littlejs.js?183></script>
10
+ <script src=game.js?183></script>
@@ -7,18 +7,18 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- LittleJS Engine -->
10
- <script src=../../src/engineDebug.js?181></script>
11
- <script src=../../src/engineUtilities.js?181></script>
12
- <script src=../../src/engineSettings.js?181></script>
13
- <script src=../../src/engineObject.js?181></script>
14
- <script src=../../src/engineDraw.js?181></script>
15
- <script src=../../src/engineInput.js?181></script>
16
- <script src=../../src/engineAudio.js?181></script>
17
- <script src=../../src/engineTileLayer.js?181></script>
18
- <script src=../../src/engineParticles.js?181></script>
19
- <script src=../../src/engineMedals.js?181></script>
20
- <script src=../../src/engineWebGL.js?181></script>
21
- <script src=../../src/engine.js?181></script>
10
+ <script src=../../src/engineDebug.js?183></script>
11
+ <script src=../../src/engineUtilities.js?183></script>
12
+ <script src=../../src/engineSettings.js?183></script>
13
+ <script src=../../src/engineObject.js?183></script>
14
+ <script src=../../src/engineDraw.js?183></script>
15
+ <script src=../../src/engineInput.js?183></script>
16
+ <script src=../../src/engineAudio.js?183></script>
17
+ <script src=../../src/engineTileLayer.js?183></script>
18
+ <script src=../../src/engineParticles.js?183></script>
19
+ <script src=../../src/engineMedals.js?183></script>
20
+ <script src=../../src/engineWebGL.js?183></script>
21
+ <script src=../../src/engine.js?183></script>
22
22
 
23
23
  <!-- Add your game scripts here -->
24
- <script src=game.js?181></script>
24
+ <script src=game.js?183></script>
@@ -6,7 +6,8 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.min.js?181></script>
9
+ <!-- LittleJS Engine -->
10
+ <script src=../../build/littlejs.min.js?183></script>
10
11
  <script>
11
12
 
12
13
  /*
@@ -27,8 +28,7 @@ class TestObject extends EngineObject
27
28
  {
28
29
  constructor(pos)
29
30
  {
30
- super(pos, vec2(1), 0, vec2(16), 0, spriteColor);
31
-
31
+ super(pos, vec2(1), tile(0), 0, spriteColor);
32
32
  this.additiveColor = spriteAdditiveColor;
33
33
  this.setCollision();
34
34
  }
@@ -8,7 +8,7 @@
8
8
 
9
9
  // import module
10
10
  import * as LittleJS from '../../build/littlejs.esm.js';
11
- const {Vector2, Color, Timer, vec2} = LittleJS;
11
+ const {Vector2, Color, Timer, vec2, tile} = LittleJS;
12
12
 
13
13
  // sound effects
14
14
  const sound_click = new LittleJS.Sound([1,.5]);
@@ -7,4 +7,4 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- Add your game scripts here -->
10
- <script src=game.js?181 type=module></script>
10
+ <script src=game.js?183 type=module></script>
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.8.1",
3
+ "version": "1.8.4",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
5
  "main": "build/littlejs.esm.js",
6
+ "types": "build/littlejs.esm.js",
6
7
  "repository": {
7
8
  "type": "git",
8
9
  "url": "git+https://github.com/KilledByAPixel/LittleJS.git"
package/src/engine.js CHANGED
@@ -30,7 +30,7 @@ const engineName = 'LittleJS';
30
30
  * @type {String}
31
31
  * @default
32
32
  * @memberof Engine */
33
- const engineVersion = '1.8.1';
33
+ const engineVersion = '1.8.4';
34
34
 
35
35
  /** Frames per second to update objects
36
36
  * @type {Number}
@@ -91,7 +91,7 @@ let frameTimeLastMS = 0, frameTimeBufferMS = 0, averageFPS = 0;
91
91
  * @param {Function} gameUpdatePost - Called after physics and objects are updated, setup camera and prepare for render
92
92
  * @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
93
93
  * @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
94
- * @param {String} [imageSources='tiles.png'] - Image to load
94
+ * @param {Array} [imageSources=['tiles.png']] - Image to load
95
95
  * @memberof Engine */
96
96
  function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=['tiles.png'])
97
97
  {
@@ -45,7 +45,8 @@ class Sound
45
45
  if (zzfxSound)
46
46
  {
47
47
  // generate zzfx sound now for fast playback
48
- this.randomness = zzfxSound[1] || (zzfxSound[1] = 0);
48
+ this.randomness = zzfxSound[1] || 0;
49
+ zzfxSound[1] = 0; // generate without randomness
49
50
  this.sampleChannels = [zzfxG(...zzfxSound)];
50
51
  this.sampleRate = zzfxR;
51
52
  }
package/src/engineDraw.js CHANGED
@@ -188,16 +188,18 @@ function worldToScreen(worldPos)
188
188
  * @param {Color} [additiveColor=Color(0,0,0,0)] - Additive color to be applied
189
189
  * @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
190
190
  * @param {Boolean} [screenSpace=0] - If true the pos and size are in screen space
191
+ * @param {CanvasRenderingContext2D} [context] - Canvas 2D context to draw to
191
192
  * @memberof Draw */
192
193
  function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
193
- angle=0, mirror, additiveColor=new Color(0,0,0,0), useWebGL=glEnable, screenSpace)
194
+ angle=0, mirror, additiveColor=new Color(0,0,0,0), useWebGL=glEnable, screenSpace, context)
194
195
  {
196
+ ASSERT(!context || !useWebGL); // context only supported in canvas 2D mode
195
197
  ASSERT(typeof tileInfo !== 'number' || !tileInfo); // prevent old style calls
196
198
  // to fix old calls, replace with tile(tileIndex, tileSize)
197
199
 
198
200
  showWatermark && ++drawCount;
199
201
  const textureInfo = tileInfo && tileInfo.getTextureInfo();
200
- if (glEnable && useWebGL)
202
+ if (useWebGL)
201
203
  {
202
204
  if (screenSpace)
203
205
  {
@@ -248,7 +250,7 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
248
250
  context.fillStyle = color;
249
251
  context.fillRect(-.5, -.5, 1, 1);
250
252
  }
251
- }, undefined, screenSpace);
253
+ }, screenSpace, context);
252
254
  }
253
255
  }
254
256
 
@@ -259,28 +261,36 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
259
261
  * @param {Number} [angle=0]
260
262
  * @param {Boolean} [useWebGL=glEnable]
261
263
  * @param {Boolean} [screenSpace=0]
264
+ * @param {CanvasRenderingContext2D} [context]
262
265
  * @memberof Draw */
263
- function drawRect(pos, size, color, angle, useWebGL, screenSpace)
264
- { drawTile(pos, size, undefined, color, angle, 0, undefined, useWebGL, screenSpace); }
266
+ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
267
+ {
268
+ drawTile(pos, size, undefined, color, angle, 0, undefined, useWebGL, screenSpace, context);
269
+ }
265
270
 
266
271
  /** Draw colored polygon using passed in points
267
272
  * @param {Array} points - Array of Vector2 points
268
273
  * @param {Color} [color=Color()]
269
274
  * @param {Boolean} [useWebGL=glEnable]
270
275
  * @param {Boolean} [screenSpace=0]
276
+ * @param {CanvasRenderingContext2D} [context]
271
277
  * @memberof Draw */
272
- function drawPoly(points, color=new Color, useWebGL=glEnable, screenSpace)
278
+ function drawPoly(points, color=new Color, useWebGL=glEnable, screenSpace, context)
273
279
  {
280
+ ASSERT(!context || !useWebGL); // context only supported in canvas 2D mode
281
+
274
282
  if (useWebGL)
275
283
  glDrawPoints(screenSpace ? points.map(screenToWorld) : points, color.rgbaInt());
276
284
  else
277
285
  {
278
286
  // draw using canvas
279
- mainContext.fillStyle = color;
280
- mainContext.beginPath();
287
+ if (!context)
288
+ context = mainContext;
289
+ context.fillStyle = color;
290
+ context.beginPath();
281
291
  for (const point of screenSpace ? points : points.map(worldToScreen))
282
- mainContext.lineTo(point.x, point.y);
283
- mainContext.fill();
292
+ context.lineTo(point.x, point.y);
293
+ context.fill();
284
294
  }
285
295
  }
286
296
 
@@ -291,12 +301,13 @@ function drawPoly(points, color=new Color, useWebGL=glEnable, screenSpace)
291
301
  * @param {Color} [color=Color()]
292
302
  * @param {Boolean} [useWebGL=glEnable]
293
303
  * @param {Boolean} [screenSpace=0]
304
+ * @param {CanvasRenderingContext2D} [context]
294
305
  * @memberof Draw */
295
- function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace)
306
+ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
296
307
  {
297
308
  const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
298
309
  const size = vec2(thickness, halfDelta.length()*2);
299
- drawRect(posA.add(halfDelta), size, color, halfDelta.angle(), useWebGL, screenSpace);
310
+ drawRect(posA.add(halfDelta), size, color, halfDelta.angle(), useWebGL, screenSpace, context);
300
311
  }
301
312
 
302
313
  /** Draw directly to a 2d canvas context in world space
@@ -305,10 +316,10 @@ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace)
305
316
  * @param {Number} angle
306
317
  * @param {Boolean} mirror
307
318
  * @param {Function} drawFunction
308
- * @param {CanvasRenderingContext2D} [context=mainContext]
309
319
  * @param {Boolean} [screenSpace=0]
320
+ * @param {CanvasRenderingContext2D} [context=mainContext]
310
321
  * @memberof Draw */
311
- function drawCanvas2D(pos, size, angle, mirror, drawFunction, context = mainContext, screenSpace)
322
+ function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, context=mainContext)
312
323
  {
313
324
  if (!screenSpace)
314
325
  {
@@ -327,13 +338,19 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, context = mainCont
327
338
  /** Enable normal or additive blend mode
328
339
  * @param {Boolean} [additive=0]
329
340
  * @param {Boolean} [useWebGL=glEnable]
341
+ * @param {CanvasRenderingContext2D} [context=mainContext]
330
342
  * @memberof Draw */
331
- function setBlendMode(additive, useWebGL=glEnable)
343
+ function setBlendMode(additive, useWebGL=glEnable, context)
332
344
  {
333
- if (glEnable && useWebGL)
334
- glSetBlendMode(additive);
345
+ ASSERT(!context || !useWebGL); // context only supported in canvas 2D mode
346
+ if (useWebGL)
347
+ glAdditive = additive;
335
348
  else
336
- mainContext.globalCompositeOperation = additive ? 'lighter' : 'source-over';
349
+ {
350
+ if (!context)
351
+ context = mainContext;
352
+ context.globalCompositeOperation = additive ? 'lighter' : 'source-over';
353
+ }
337
354
  }
338
355
 
339
356
  /** Draw text on overlay canvas in world space