littlejsengine 1.9.0 → 1.9.2

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.
Files changed (63) hide show
  1. package/README.md +7 -7
  2. package/{build → dist}/littlejs.d.ts +84 -77
  3. package/{build → dist}/littlejs.esm.js +245 -143
  4. package/dist/littlejs.esm.min.js +1 -0
  5. package/{build → dist}/littlejs.js +245 -143
  6. package/dist/littlejs.min.js +1 -0
  7. package/{build → dist}/littlejs.release.js +239 -141
  8. package/examples/breakout/game.js +2 -2
  9. package/examples/breakout/gameObjects.js +3 -3
  10. package/examples/breakout/index.html +3 -3
  11. package/examples/breakoutTutorial/index.html +2 -2
  12. package/examples/electron/build.js +1 -1
  13. package/examples/electron/game.js +49 -38
  14. package/examples/electron/index.html +2 -2
  15. package/examples/electron/tiles.png +0 -0
  16. package/examples/empty/index.html +1 -1
  17. package/examples/js13k/build.js +2 -2
  18. package/examples/js13k/game.js +10 -9
  19. package/examples/js13k/index.html +13 -13
  20. package/examples/js13k/tiles.png +0 -0
  21. package/examples/module/game.js +45 -41
  22. package/examples/module/index.html +1 -1
  23. package/examples/module/tiles.png +0 -0
  24. package/examples/particles/index.html +1 -1
  25. package/examples/platformer/data/gameTileData.tmx +143 -0
  26. package/examples/platformer/data/gameTileData.tsx +4 -0
  27. package/examples/platformer/game.js +0 -1
  28. package/examples/platformer/gameCharacter.js +1 -1
  29. package/examples/platformer/gameEffects.js +42 -110
  30. package/examples/platformer/gameLevel.js +149 -183
  31. package/examples/platformer/gameObjects.js +61 -16
  32. package/examples/platformer/gamePlayer.js +3 -2
  33. package/examples/platformer/gameTileData.js +181 -0
  34. package/examples/platformer/index.html +8 -7
  35. package/examples/platformer/tiles.png +0 -0
  36. package/examples/platformer/tilesLevel.png +0 -0
  37. package/examples/puzzle/game.js +12 -12
  38. package/examples/puzzle/index.html +2 -2
  39. package/examples/starter/build.js +2 -2
  40. package/examples/starter/game.js +6 -6
  41. package/examples/starter/index.html +13 -13
  42. package/examples/starter/tiles.png +0 -0
  43. package/examples/stress/index.html +2 -2
  44. package/examples/typescript/build.bat +4 -1
  45. package/examples/typescript/game.js +34 -31
  46. package/examples/typescript/game.ts +40 -36
  47. package/examples/typescript/index.html +1 -1
  48. package/examples/typescript/tiles.png +0 -0
  49. package/package.json +3 -3
  50. package/src/engine.js +1 -1
  51. package/src/engineAudio.js +4 -10
  52. package/src/engineBuild.js +9 -2
  53. package/src/engineDebug.js +6 -2
  54. package/src/engineDraw.js +27 -27
  55. package/src/engineInput.js +7 -7
  56. package/src/engineMedals.js +2 -2
  57. package/src/engineObject.js +7 -7
  58. package/src/engineParticles.js +9 -9
  59. package/src/engineTileLayer.js +38 -33
  60. package/src/engineUtilities.js +136 -35
  61. package/src/engineWebGL.js +8 -10
  62. package/build/littlejs.esm.min.js +0 -1
  63. package/build/littlejs.min.js +0 -1
@@ -1,12 +1,12 @@
1
1
  /*
2
- Little TypeScript Demo
2
+ Little JS TypeScript Demo
3
3
  - A simple starter project
4
- - Builds to a JavaScript file from TypeScript
4
+ - Shows how to use LittleJS with TypeScript
5
5
  */
6
6
  'use strict';
7
7
  // import module
8
- import * as LittleJS from '../../build/littlejs.esm.js';
9
- const { Vector2, Color, Timer, vec2, tile } = LittleJS;
8
+ import * as LittleJS from '../../dist/littlejs.esm.js';
9
+ const { Vector2, Color, Timer, tile, vec2, hsl, rgb } = LittleJS;
10
10
  // show the LittleJS splash screen
11
11
  LittleJS.setShowSplashScreen(true);
12
12
  // sound effects
@@ -16,51 +16,52 @@ const medal_example = new LittleJS.Medal(0, 'Example Medal', 'Welcome to LittleJ
16
16
  LittleJS.medalsInit('Hello World');
17
17
  // game variables
18
18
  let particleEmitter;
19
- let gameTimer = new Timer;
20
19
  ///////////////////////////////////////////////////////////////////////////////
21
20
  function gameInit() {
22
21
  // create tile collision and visible tile layer
23
- LittleJS.initTileCollision(vec2(32, 16));
24
- const pos = new Vector2;
25
- const tileLayer = new LittleJS.TileLayer(pos, LittleJS.tileCollisionSize);
22
+ const tileCollisionSize = vec2(32, 16);
23
+ LittleJS.initTileCollision(tileCollisionSize);
24
+ const pos = vec2();
25
+ const tileLayer = new LittleJS.TileLayer(pos, tileCollisionSize);
26
26
  // get level data from the tiles image
27
- const imageLevelDataRow = 1;
28
27
  const mainContext = LittleJS.mainContext;
29
28
  const tileImage = LittleJS.textureInfos[0].image;
30
29
  mainContext.drawImage(tileImage, 0, 0);
31
- for (pos.x = LittleJS.tileCollisionSize.x; pos.x--;)
32
- for (pos.y = LittleJS.tileCollisionSize.y; pos.y--;) {
33
- const imageData = mainContext.getImageData(pos.x, 16 * (imageLevelDataRow + 1) - pos.y - 1, 1, 1).data;
34
- if (imageData[0]) {
35
- const tileIndex = 1;
36
- const direction = LittleJS.randInt(4);
37
- const mirror = LittleJS.randInt(2) ? true : false;
38
- const color = LittleJS.randColor();
39
- const data = new LittleJS.TileLayerData(tileIndex, direction, mirror, color);
40
- tileLayer.setData(pos, data);
41
- LittleJS.setTileCollisionData(pos, 1);
42
- }
30
+ const imageData = mainContext.getImageData(0, 0, tileImage.width, tileImage.height).data;
31
+ for (pos.x = tileCollisionSize.x; pos.x--;)
32
+ for (pos.y = tileCollisionSize.y; pos.y--;) {
33
+ // check if this pixel is set
34
+ const i = pos.x + tileImage.width * (15 + tileCollisionSize.y - pos.y);
35
+ if (!imageData[4 * i])
36
+ continue;
37
+ // set tile data
38
+ const tileIndex = 1;
39
+ const direction = LittleJS.randInt(4);
40
+ const mirror = !LittleJS.randInt(2);
41
+ const color = LittleJS.randColor();
42
+ const data = new LittleJS.TileLayerData(tileIndex, direction, mirror, color);
43
+ tileLayer.setData(pos, data);
44
+ LittleJS.setTileCollisionData(pos, 1);
43
45
  }
46
+ // draw tile layer with new data
44
47
  tileLayer.redraw();
45
48
  // move camera to center of collision
46
- LittleJS.setCameraPos(LittleJS.tileCollisionSize.scale(.5));
49
+ LittleJS.setCameraPos(tileCollisionSize.scale(.5));
50
+ LittleJS.setCameraScale(48);
47
51
  // enable gravity
48
52
  LittleJS.setGravity(-.01);
49
53
  // create particle emitter
50
- const center = LittleJS.tileCollisionSize.scale(.5).add(vec2(0, 9));
51
- particleEmitter = new LittleJS.ParticleEmitter(center, 0, // emitPos, emitAngle
54
+ particleEmitter = new LittleJS.ParticleEmitter(vec2(16, 9), 0, // emitPos, emitAngle
52
55
  1, 0, 500, Math.PI, // emitSize, emitTime, emitRate, emiteCone
53
- LittleJS.tile(0, 16), // tileIndex, tileSize
54
- new Color(1, 1, 1), new Color(0, 0, 0), // colorStartA, colorStartB
55
- new Color(1, 1, 1, 0), new Color(0, 0, 0, 0), // colorEndA, colorEndB
56
+ tile(0, 16), // tileIndex, tileSize
57
+ hsl(1, 1, 1), hsl(0, 0, 0), // colorStartA, colorStartB
58
+ hsl(0, 0, 0, 0), hsl(0, 0, 0, 0), // colorEndA, colorEndB
56
59
  2, .2, .2, .1, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
57
60
  .99, 1, 1, Math.PI, // damping, angleDamping, gravityScale, cone
58
61
  .05, .5, true, true // fadeRate, randomness, collide, additive
59
62
  );
60
63
  particleEmitter.elasticity = .3; // bounce when it collides
61
64
  particleEmitter.trailScale = 2; // stretch in direction of motion
62
- // start the game timer
63
- gameTimer.set();
64
65
  }
65
66
  ///////////////////////////////////////////////////////////////////////////////
66
67
  function gameUpdate() {
@@ -68,7 +69,7 @@ function gameUpdate() {
68
69
  // play sound when mouse is pressed
69
70
  sound_click.play(LittleJS.mousePos);
70
71
  // change particle color and set to fade out
71
- particleEmitter.colorStartA = new Color;
72
+ particleEmitter.colorStartA = hsl();
72
73
  particleEmitter.colorStartB = LittleJS.randColor();
73
74
  particleEmitter.colorEndA = particleEmitter.colorStartA.scale(1, 0);
74
75
  particleEmitter.colorEndB = particleEmitter.colorStartB.scale(1, 0);
@@ -85,7 +86,9 @@ function gameUpdatePost() {
85
86
  ///////////////////////////////////////////////////////////////////////////////
86
87
  function gameRender() {
87
88
  // draw a grey square in the background without using webgl
88
- LittleJS.drawRect(LittleJS.cameraPos, LittleJS.tileCollisionSize.add(vec2(5)), new Color(.2, .2, .2), 0, false);
89
+ LittleJS.drawRect(vec2(16, 8), vec2(20, 14), hsl(0, 0, .6), 0, false);
90
+ // draw the logo as a tile
91
+ LittleJS.drawTile(vec2(21, 5), vec2(4.5), tile(3, 128));
89
92
  }
90
93
  ///////////////////////////////////////////////////////////////////////////////
91
94
  function gameRenderPost() {
@@ -1,14 +1,14 @@
1
1
  /*
2
- Little TypeScript Demo
2
+ Little JS TypeScript Demo
3
3
  - A simple starter project
4
- - Builds to a JavaScript file from TypeScript
4
+ - Shows how to use LittleJS with TypeScript
5
5
  */
6
6
 
7
7
  'use strict';
8
8
 
9
9
  // import module
10
- import * as LittleJS from '../../build/littlejs.esm.js';
11
- const {Vector2, Color, Timer, vec2, tile} = LittleJS;
10
+ import * as LittleJS from '../../dist/littlejs.esm.js';
11
+ const {Vector2, Color, Timer, tile, vec2, hsl, rgb} = LittleJS;
12
12
 
13
13
  // show the LittleJS splash screen
14
14
  LittleJS.setShowSplashScreen(true);
@@ -21,62 +21,63 @@ const medal_example = new LittleJS.Medal(0, 'Example Medal', 'Welcome to LittleJ
21
21
  LittleJS.medalsInit('Hello World');
22
22
 
23
23
  // game variables
24
- let particleEmitter: LittleJS.ParticleEmitter;
25
- let gameTimer = new Timer;
24
+ let particleEmitter;
26
25
 
27
26
  ///////////////////////////////////////////////////////////////////////////////
28
27
  function gameInit()
29
28
  {
30
29
  // create tile collision and visible tile layer
31
- LittleJS.initTileCollision(vec2(32, 16));
32
- const pos = new Vector2;
33
- const tileLayer = new LittleJS.TileLayer(pos, LittleJS.tileCollisionSize);
30
+ const tileCollisionSize = vec2(32, 16);
31
+ LittleJS.initTileCollision(tileCollisionSize);
32
+ const pos = vec2();
33
+ const tileLayer = new LittleJS.TileLayer(pos, tileCollisionSize);
34
34
 
35
35
  // get level data from the tiles image
36
- const imageLevelDataRow = 1;
37
36
  const mainContext = LittleJS.mainContext;
38
37
  const tileImage = LittleJS.textureInfos[0].image;
39
38
  mainContext.drawImage(tileImage, 0, 0);
40
- for (pos.x = LittleJS.tileCollisionSize.x; pos.x--;)
41
- for (pos.y = LittleJS.tileCollisionSize.y; pos.y--;)
39
+ const imageData = mainContext.getImageData(0,0,tileImage.width,tileImage.height).data;
40
+ for (pos.x = tileCollisionSize.x; pos.x--;)
41
+ for (pos.y = tileCollisionSize.y; pos.y--;)
42
42
  {
43
- const imageData = mainContext.getImageData(pos.x, 16*(imageLevelDataRow+1)-pos.y-1, 1, 1).data;
44
- if (imageData[0])
45
- {
46
- const tileIndex = 1;
47
- const direction = LittleJS.randInt(4)
48
- const mirror = LittleJS.randInt(2) ? true : false;
49
- const color = LittleJS.randColor();
50
- const data = new LittleJS.TileLayerData(tileIndex, direction, mirror, color);
51
- tileLayer.setData(pos, data);
52
- LittleJS.setTileCollisionData(pos, 1);
53
- }
43
+ // check if this pixel is set
44
+ const i = pos.x + tileImage.width*(15 + tileCollisionSize.y - pos.y);
45
+ if (!imageData[4*i])
46
+ continue;
47
+
48
+ // set tile data
49
+ const tileIndex = 1;
50
+ const direction = LittleJS.randInt(4)
51
+ const mirror = !LittleJS.randInt(2);
52
+ const color = LittleJS.randColor();
53
+ const data = new LittleJS.TileLayerData(tileIndex, direction, mirror, color);
54
+ tileLayer.setData(pos, data);
55
+ LittleJS.setTileCollisionData(pos, 1);
54
56
  }
57
+
58
+ // draw tile layer with new data
55
59
  tileLayer.redraw();
56
60
 
57
61
  // move camera to center of collision
58
- LittleJS.setCameraPos(LittleJS.tileCollisionSize.scale(.5));
62
+ LittleJS.setCameraPos(tileCollisionSize.scale(.5));
63
+ LittleJS.setCameraScale(48);
59
64
 
60
65
  // enable gravity
61
66
  LittleJS.setGravity(-.01);
62
67
 
63
68
  // create particle emitter
64
- const center = LittleJS.tileCollisionSize.scale(.5).add(vec2(0,9));
65
69
  particleEmitter = new LittleJS.ParticleEmitter(
66
- center, 0, // emitPos, emitAngle
67
- 1, 0, 500, Math.PI, // emitSize, emitTime, emitRate, emiteCone
68
- LittleJS.tile(0, 16), // tileIndex, tileSize
69
- new Color(1,1,1), new Color(0,0,0), // colorStartA, colorStartB
70
- new Color(1,1,1,0), new Color(0,0,0,0), // colorEndA, colorEndB
70
+ vec2(16,9), 0, // emitPos, emitAngle
71
+ 1, 0, 500, Math.PI, // emitSize, emitTime, emitRate, emiteCone
72
+ tile(0, 16), // tileIndex, tileSize
73
+ hsl(1,1,1), hsl(0,0,0), // colorStartA, colorStartB
74
+ hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
71
75
  2, .2, .2, .1, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
72
76
  .99, 1, 1, Math.PI, // damping, angleDamping, gravityScale, cone
73
- .05, .5, true, true // fadeRate, randomness, collide, additive
77
+ .05, .5, true, true // fadeRate, randomness, collide, additive
74
78
  );
75
79
  particleEmitter.elasticity = .3; // bounce when it collides
76
80
  particleEmitter.trailScale = 2; // stretch in direction of motion
77
-
78
- // start the game timer
79
- gameTimer.set();
80
81
  }
81
82
 
82
83
  ///////////////////////////////////////////////////////////////////////////////
@@ -88,7 +89,7 @@ function gameUpdate()
88
89
  sound_click.play(LittleJS.mousePos);
89
90
 
90
91
  // change particle color and set to fade out
91
- particleEmitter.colorStartA = new Color;
92
+ particleEmitter.colorStartA = hsl();
92
93
  particleEmitter.colorStartB = LittleJS.randColor();
93
94
  particleEmitter.colorEndA = particleEmitter.colorStartA.scale(1,0);
94
95
  particleEmitter.colorEndB = particleEmitter.colorStartB.scale(1,0);
@@ -112,7 +113,10 @@ function gameUpdatePost()
112
113
  function gameRender()
113
114
  {
114
115
  // draw a grey square in the background without using webgl
115
- LittleJS.drawRect(LittleJS.cameraPos, LittleJS.tileCollisionSize.add(vec2(5)), new Color(.2,.2,.2), 0, false);
116
+ LittleJS.drawRect(vec2(16,8), vec2(20,14), hsl(0,0,.6), 0, false);
117
+
118
+ // draw the logo as a tile
119
+ LittleJS.drawTile(vec2(21,5), vec2(4.5), tile(3,128));
116
120
  }
117
121
 
118
122
  ///////////////////////////////////////////////////////////////////////////////
@@ -6,4 +6,4 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- Add your game scripts here -->
9
- <script src=game.js?1812 type=module></script>
9
+ <script src=game.js?192 type=module></script>
Binary file
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.9.0",
3
+ "version": "1.9.2",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
- "main": "build/littlejs.esm.js",
6
- "types": "build/littlejs.esm.js",
5
+ "main": "dist/littlejs.esm.js",
6
+ "types": "dist/littlejs.d.ts",
7
7
  "repository": {
8
8
  "type": "git",
9
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.9.0';
33
+ const engineVersion = '1.9.2';
34
34
 
35
35
  /** Frames per second to update objects
36
36
  * @type {Number}
@@ -146,22 +146,19 @@ class SoundWave extends Sound
146
146
  this.randomness = randomness;
147
147
 
148
148
  if (!soundEnable) return;
149
- if (!soundDecoderContext)
150
- soundDecoderContext = new AudioContext;
151
149
 
152
150
  fetch(filename)
153
151
  .then(response => response.arrayBuffer())
154
- .then(arrayBuffer => soundDecoderContext.decodeAudioData(arrayBuffer))
152
+ .then(arrayBuffer => audioContext.decodeAudioData(arrayBuffer))
155
153
  .then(audioBuffer =>
156
154
  {
157
155
  this.sampleChannels = [];
158
156
  for (let i = audioBuffer.numberOfChannels; i--;)
159
- this.sampleChannels[i] = audioBuffer.getChannelData(i);
157
+ this.sampleChannels[i] = Array.from(audioBuffer.getChannelData(i));
160
158
  this.sampleRate = audioBuffer.sampleRate;
161
159
  });
162
160
  }
163
161
  }
164
- let soundDecoderContext; // audio context used only to decode audio files
165
162
 
166
163
  /**
167
164
  * Music Object - Stores a zzfx music track for later use
@@ -275,8 +272,9 @@ function getNoteFrequency(semitoneOffset, rootFrequency=220)
275
272
  ///////////////////////////////////////////////////////////////////////////////
276
273
 
277
274
  /** Audio context used by the engine
275
+ * @type {AudioContext}
278
276
  * @memberof Audio */
279
- let audioContext;
277
+ let audioContext = new AudioContext;
280
278
 
281
279
  /** Play cached audio samples with given settings
282
280
  * @param {Array} sampleChannels - Array of arrays of samples to play (for stereo playback)
@@ -291,10 +289,6 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=false, sample
291
289
  {
292
290
  if (!soundEnable) return;
293
291
 
294
- // create audio context if needed
295
- if (!audioContext)
296
- audioContext = new AudioContext;
297
-
298
292
  // prevent sounds from building up if they can't be played
299
293
  if (audioContext.state != 'running')
300
294
  {
@@ -11,7 +11,7 @@
11
11
  'use strict';
12
12
 
13
13
  const ENGINE_NAME = 'littlejs';
14
- const BUILD_FOLDER = 'build';
14
+ const BUILD_FOLDER = 'dist';
15
15
  const SOURCE_FOLDER = 'src';
16
16
  const engineSourceFiles =
17
17
  [
@@ -158,7 +158,14 @@ function typeScriptBuildStep(filename)
158
158
  {
159
159
  try
160
160
  {
161
- child_process.execSync(`npx tsc ${filename} --declaration --allowJs --emitDeclarationOnly --outFile ${BUILD_FOLDER}/${ENGINE_NAME}.d.ts`);
161
+ const tsFilename = `${BUILD_FOLDER}/${ENGINE_NAME}.d.ts`
162
+ child_process.execSync(`npx tsc ${filename} --declaration --allowJs --emitDeclarationOnly --outFile ${tsFilename}`);
163
+
164
+ // Remove declare module part
165
+ //let fileContent = fs.readFileSync(tsFilename, 'utf8');
166
+ //const r = new RegExp(`declare module "${ENGINE_NAME}\.esm" \{([\\s\\S]*?)\}`);
167
+ //fs.writeFileSync(tsFilename, fileContent.replace(r, '$1'));
168
+
162
169
  }
163
170
  catch (e) { handleError(e, 'Failed to run TypeScript build step!'); }
164
171
  };
@@ -54,9 +54,13 @@ let debugPrimitives = [], debugPhysics = false, debugRaycast = false, debugParti
54
54
 
55
55
  /** Asserts if the experssion is false, does not do anything in release builds
56
56
  * @param {Boolean} assert
57
- * @param {Object} output
57
+ * @param {Object} [output]
58
58
  * @memberof Debug */
59
- function ASSERT(assert, output) { enableAsserts && console.assert(assert, output); }
59
+ function ASSERT(assert, output)
60
+ {
61
+ if (enableAsserts)
62
+ output ? console.assert(assert, output) : console.assert(assert);
63
+ }
60
64
 
61
65
  /** Draw a debug rectangle in world space
62
66
  * @param {Vector2} pos
package/src/engineDraw.js CHANGED
@@ -61,7 +61,7 @@ let drawCount;
61
61
  * Create a tile info object
62
62
  * - This can take vecs or floats for easier use and conversion
63
63
  * - If an index is passed in, the tile size and index will determine the position
64
- * @param {(Number|Vector2)} [pos=Vector2()] - Top left corner of tile in pixels or index
64
+ * @param {(Number|Vector2)} [pos=(0,0)] - Top left corner of tile in pixels or index
65
65
  * @param {(Number|Vector2)} [size=tileSizeDefault] - Size of tile in pixels
66
66
  * @param {Number} [textureIndex] - Texture index to use
67
67
  * @return {TileInfo}
@@ -104,7 +104,7 @@ function tile(pos=vec2(), size=tileSizeDefault, textureIndex=0)
104
104
  class TileInfo
105
105
  {
106
106
  /** Create a tile info object
107
- * @param {Vector2} [pos=Vector2()] - Top left corner of tile in pixels
107
+ * @param {Vector2} [pos=(0,0)] - Top left corner of tile in pixels
108
108
  * @param {Vector2} [size=tileSizeDefault] - Size of tile in pixels
109
109
  * @param {Number} [textureIndex] - Texture index to use
110
110
  */
@@ -181,16 +181,16 @@ function worldToScreen(worldPos)
181
181
  }
182
182
 
183
183
  /** Draw textured tile centered in world space, with color applied if using WebGL
184
- * @param {Vector2} pos - Center of the tile in world space
185
- * @param {Vector2} [size=Vector2(1,1)] - Size of the tile in world space
186
- * @param {TileInfo}[tileInfo] - Tile info to use, untextured if undefined
187
- * @param {Color} [color=Color()] - Color to modulate with
188
- * @param {Number} [angle] - Angle to rotate by
189
- * @param {Boolean} [mirror] - If true image is flipped along the Y axis
190
- * @param {Color} [additiveColor=Color(0,0,0,0)] - Additive color to be applied
191
- * @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
192
- * @param {Boolean} [screenSpace] - If true the pos and size are in screen space
193
- * @param {CanvasRenderingContext2D} [context] - Canvas 2D context to draw to
184
+ * @param {Vector2} pos - Center of the tile in world space
185
+ * @param {Vector2} [size=(1,1)] - Size of the tile in world space
186
+ * @param {TileInfo}[tileInfo] - Tile info to use, untextured if undefined
187
+ * @param {Color} [color=(1,1,1,1)] - Color to modulate with
188
+ * @param {Number} [angle] - Angle to rotate by
189
+ * @param {Boolean} [mirror] - If true image is flipped along the Y axis
190
+ * @param {Color} [additiveColor=(0,0,0,0)] - Additive color to be applied
191
+ * @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
192
+ * @param {Boolean} [screenSpace=false] - If true the pos and size are in screen space
193
+ * @param {CanvasRenderingContext2D} [context] - Canvas 2D context to draw to
194
194
  * @memberof Draw */
195
195
  function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
196
196
  angle=0, mirror, additiveColor=new Color(0,0,0,0), useWebGL=glEnable, screenSpace, context)
@@ -258,11 +258,11 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
258
258
 
259
259
  /** Draw colored rect centered on pos
260
260
  * @param {Vector2} pos
261
- * @param {Vector2} [size=Vector2(1,1)]
262
- * @param {Color} [color=Color()]
261
+ * @param {Vector2} [size=(1,1)]
262
+ * @param {Color} [color=(1,1,1,1)]
263
263
  * @param {Number} [angle]
264
264
  * @param {Boolean} [useWebGL=glEnable]
265
- * @param {Boolean} [screenSpace]
265
+ * @param {Boolean} [screenSpace=false]
266
266
  * @param {CanvasRenderingContext2D} [context]
267
267
  * @memberof Draw */
268
268
  function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
@@ -272,8 +272,8 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
272
272
 
273
273
  /** Draw colored polygon using passed in points
274
274
  * @param {Array} points - Array of Vector2 points
275
- * @param {Color} [color=Color()]
276
- * @param {Boolean} [screenSpace]
275
+ * @param {Color} [color=(1,1,1,1)]
276
+ * @param {Boolean} [screenSpace=false]
277
277
  * @param {CanvasRenderingContext2D} [context=mainContext]
278
278
  * @memberof Draw */
279
279
  function drawPoly(points, color=new Color, screenSpace, context=mainContext)
@@ -289,9 +289,9 @@ function drawPoly(points, color=new Color, screenSpace, context=mainContext)
289
289
  * @param {Vector2} posA
290
290
  * @param {Vector2} posB
291
291
  * @param {Number} [thickness]
292
- * @param {Color} [color=Color()]
292
+ * @param {Color} [color=(1,1,1,1)]
293
293
  * @param {Boolean} [useWebGL=glEnable]
294
- * @param {Boolean} [screenSpace]
294
+ * @param {Boolean} [screenSpace=false]
295
295
  * @param {CanvasRenderingContext2D} [context]
296
296
  * @memberof Draw */
297
297
  function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
@@ -307,7 +307,7 @@ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, contex
307
307
  * @param {Number} angle
308
308
  * @param {Boolean} mirror
309
309
  * @param {Function} drawFunction
310
- * @param {Boolean} [screenSpace]
310
+ * @param {Boolean} [screenSpace=false]
311
311
  * @param {CanvasRenderingContext2D} [context=mainContext]
312
312
  * @memberof Draw */
313
313
  function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, context=mainContext)
@@ -349,9 +349,9 @@ function setBlendMode(additive, useWebGL=glEnable, context)
349
349
  * @param {String} text
350
350
  * @param {Vector2} pos
351
351
  * @param {Number} [size]
352
- * @param {Color} [color=Color()]
352
+ * @param {Color} [color=(1,1,1,1)]
353
353
  * @param {Number} [lineWidth]
354
- * @param {Color} [lineColor=Color(0,0,0)]
354
+ * @param {Color} [lineColor=(0,0,0,1)]
355
355
  * @param {CanvasTextAlign} [textAlign='center']
356
356
  * @param {String} [font=fontDefault]
357
357
  * @param {CanvasRenderingContext2D} [context=overlayContext]
@@ -366,9 +366,9 @@ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, f
366
366
  * @param {String} text
367
367
  * @param {Vector2} pos
368
368
  * @param {Number} [size]
369
- * @param {Color} [color=Color()]
369
+ * @param {Color} [color=(1,1,1,1)]
370
370
  * @param {Number} [lineWidth]
371
- * @param {Color} [lineColor=Color(0,0,0)]
371
+ * @param {Color} [lineColor=(0,0,0,1)]
372
372
  * @param {CanvasTextAlign} [textAlign]
373
373
  * @param {String} [font=fontDefault]
374
374
  * @param {CanvasRenderingContext2D} [context=overlayContext]
@@ -411,9 +411,9 @@ let engineFontImage;
411
411
  class FontImage
412
412
  {
413
413
  /** Create an image font
414
- * @param {HTMLImageElement} [image] - Image for the font, if undefined default font is used
415
- * @param {Vector2} [tileSize=Vector2(8)] - Size of the font source tiles
416
- * @param {Vector2} [paddingSize=Vector2(0,1)] - How much extra space to add between characters
414
+ * @param {HTMLImageElement} [image] - Image for the font, if undefined default font is used
415
+ * @param {Vector2} [tileSize=(8,8)] - Size of the font source tiles
416
+ * @param {Vector2} [paddingSize=(0,1)] - How much extra space to add between characters
417
417
  * @param {CanvasRenderingContext2D} [context=overlayContext] - context to draw to
418
418
  */
419
419
  constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1), context=overlayContext)
@@ -191,10 +191,10 @@ function inputUpdatePost()
191
191
  ///////////////////////////////////////////////////////////////////////////////
192
192
  // Mouse event handlers
193
193
 
194
- onmousedown = (e)=> {isUsingGamepad = false; inputData[0][e.button] = 3; window.onmousemove(e); e.button && e.preventDefault();}
194
+ onmousedown = (e)=> {isUsingGamepad = false; inputData[0][e.button] = 3; mousePosScreen = mouseToScreen(e); e.button && e.preventDefault();}
195
195
  onmouseup = (e)=> inputData[0][e.button] = inputData[0][e.button] & 2 | 4;
196
196
  onmousemove = (e)=> mousePosScreen = mouseToScreen(e);
197
- onwheel = (e)=> e.ctrlKey || (mouseWheel = sign(e.deltaY));
197
+ onwheel = (e)=> mouseWheel = e.ctrlKey ? 0 : sign(e.deltaY);
198
198
  oncontextmenu = (e)=> false; // prevent right click menu
199
199
 
200
200
  // convert a mouse or touch event position to screen space
@@ -288,7 +288,7 @@ function gamepadsUpdate()
288
288
  ///////////////////////////////////////////////////////////////////////////////
289
289
 
290
290
  /** Pulse the vibration hardware if it exists
291
- * @param {Number} [pattern] - a single value in miliseconds or vibration interval array
291
+ * @param {Number|Array} [pattern] - single value in ms or vibration interval array
292
292
  * @memberof Input */
293
293
  function vibrate(pattern=100)
294
294
  { vibrateEnable && navigator && navigator.vibrate && navigator.vibrate(pattern); }
@@ -314,9 +314,9 @@ if (isTouchDevice)
314
314
  // handle all touch events the same way
315
315
  ontouchstart = ontouchmove = ontouchend = (e)=>
316
316
  {
317
- // fix stalled audio on mobile
318
- if (soundEnable)
319
- audioContext ? audioContext.resume() : zzfx(0);
317
+ // fix stalled audio requiring user interaction
318
+ if (soundEnable && audioContext && audioContext.state != 'running')
319
+ zzfx(0);
320
320
 
321
321
  // check if touching and pass to mouse events
322
322
  const touching = e.touches.length;
@@ -462,7 +462,7 @@ function touchGamepadRender()
462
462
  const rightCenter = vec2(mainCanvasSize.x-touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
463
463
  for (let i=4; i--;)
464
464
  {
465
- const pos = rightCenter.add(vec2().setAngle(i*PI/2, touchGamepadSize/2));
465
+ const pos = rightCenter.add(vec2().setDirection(i, touchGamepadSize/2));
466
466
  overlayContext.fillStyle = touchGamepadButtons[i] ? '#fff' : '#000';
467
467
  overlayContext.beginPath();
468
468
  overlayContext.arc(pos.x, pos.y, touchGamepadSize/4, 0,9);
@@ -90,8 +90,8 @@ class Medal
90
90
  // draw containing rect and clip to that region
91
91
  context.save();
92
92
  context.beginPath();
93
- context.fillStyle = rgb(.9,.9,.9).toString();
94
- context.strokeStyle = rgb(0,0,0).toString();
93
+ context.fillStyle = new Color(.9,.9,.9).toString();
94
+ context.strokeStyle = new Color(0,0,0).toString();
95
95
  context.lineWidth = 3;
96
96
  context.rect(x, y, width, medalDisplaySize.y);
97
97
  context.fill();
@@ -32,12 +32,12 @@
32
32
  class EngineObject
33
33
  {
34
34
  /** Create an engine object and adds it to the list of objects
35
- * @param {Vector2} [pos=Vector2()] - World space position of the object
36
- * @param {Vector2} [size=Vector2(1,1)] - World space size of the object
37
- * @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
38
- * @param {Number} [angle] - Angle the object is rotated by
39
- * @param {Color} [color=Color()] - Color to apply to tile when rendered
40
- * @param {Number} [renderOrder] - Objects sorted by renderOrder before being rendered
35
+ * @param {Vector2} [pos=(0,0)] - World space position of the object
36
+ * @param {Vector2} [size=(1,1)] - World space size of the object
37
+ * @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
38
+ * @param {Number} [angle] - Angle the object is rotated by
39
+ * @param {Color} [color=(1,1,1,1)] - Color to apply to tile when rendered
40
+ * @param {Number} [renderOrder] - Objects sorted by renderOrder before being rendered
41
41
  */
42
42
  constructor(pos=vec2(), size=vec2(1), tileInfo, angle=0, color, renderOrder=0)
43
43
  {
@@ -337,7 +337,7 @@ class EngineObject
337
337
 
338
338
  /** Attaches a child to this with a given local transform
339
339
  * @param {EngineObject} child
340
- * @param {Vector2} [localPos=Vector2()]
340
+ * @param {Vector2} [localPos=(0,0)]
341
341
  * @param {Number} [localAngle] */
342
342
  addChild(child, localPos=vec2(), localAngle=0)
343
343
  {
@@ -10,12 +10,12 @@
10
10
  * @example
11
11
  * // create a particle emitter
12
12
  * let pos = vec2(2,3);
13
- * let particleEmiter = new ParticleEmitter
13
+ * let particleEmitter = new ParticleEmitter
14
14
  * (
15
- * pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
16
- * tile(0, 16), // tileInfo
17
- * new Color(1,1,1), new Color(0,0,0), // colorStartA, colorStartB
18
- * new Color(1,1,1,0), new Color(0,0,0,0), // colorEndA, colorEndB
15
+ * pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
16
+ * tile(0, 16), // tileInfo
17
+ * rgb(1,1,1), rgb(0,0,0), // colorStartA, colorStartB
18
+ * rgb(1,1,1,0), rgb(0,0,0,0), // colorEndA, colorEndB
19
19
  * 2, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
20
20
  * .99, 1, 1, PI, .05, // damping, angleDamping, gravityScale, particleCone, fadeRate,
21
21
  * .5, 1 // randomness, collide, additive, randomColorLinear, renderOrder
@@ -31,10 +31,10 @@ class ParticleEmitter extends EngineObject
31
31
  * @param {Number} [emitRate] - How many particles per second to spawn, does not emit if 0
32
32
  * @param {Number} [emitConeAngle=PI] - Local angle to apply velocity to particles from emitter
33
33
  * @param {TileInfo} [tileInfo] - Tile info to render particles (undefined is untextured)
34
- * @param {Color} [colorStartA=Color()] - Color at start of life 1, randomized between start colors
35
- * @param {Color} [colorStartB=Color()] - Color at start of life 2, randomized between start colors
36
- * @param {Color} [colorEndA=Color(1,1,1,0)] - Color at end of life 1, randomized between end colors
37
- * @param {Color} [colorEndB=Color(1,1,1,0)] - Color at end of life 2, randomized between end colors
34
+ * @param {Color} [colorStartA=(1,1,1,1)] - Color at start of life 1, randomized between start colors
35
+ * @param {Color} [colorStartB=(1,1,1,1)] - Color at start of life 2, randomized between start colors
36
+ * @param {Color} [colorEndA=(1,1,1,0)] - Color at end of life 1, randomized between end colors
37
+ * @param {Color} [colorEndB=(1,1,1,0)] - Color at end of life 2, randomized between end colors
38
38
  * @param {Number} [particleTime] - How long particles live
39
39
  * @param {Number} [sizeStart] - How big are particles at start
40
40
  * @param {Number} [sizeEnd] - How big are particles at end