littlejsengine 1.11.2 → 1.11.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.
Files changed (56) hide show
  1. package/.vscode/launch.json +14 -0
  2. package/README.md +14 -20
  3. package/dist/littlejs.d.ts +41 -30
  4. package/dist/littlejs.esm.js +145 -141
  5. package/dist/littlejs.esm.min.js +1 -1
  6. package/dist/littlejs.js +141 -140
  7. package/dist/littlejs.min.js +1 -1
  8. package/dist/littlejs.release.js +138 -133
  9. package/examples/box2d/gameObjects.js +4 -4
  10. package/examples/box2d/scenes.js +2 -2
  11. package/examples/breakout/gameObjects.js +2 -2
  12. package/examples/breakoutTutorial/game.js +1 -1
  13. package/examples/index.html +1 -7
  14. package/examples/logo.png +0 -0
  15. package/examples/module/game.js +1 -1
  16. package/examples/platformer/game.js +2 -2
  17. package/examples/platformer/gameCharacter.js +5 -5
  18. package/examples/platformer/gameEffects.js +4 -4
  19. package/examples/platformer/gameObjects.js +2 -2
  20. package/examples/puzzle/game.js +2 -2
  21. package/examples/starter/game.js +10 -44
  22. package/examples/starter/tiles.png +0 -0
  23. package/jsconfig.json +1 -0
  24. package/package.json +1 -1
  25. package/plugins/box2d.js +10 -10
  26. package/plugins/newgrounds.js +1 -1
  27. package/src/engine.js +5 -3
  28. package/src/engineAudio.js +4 -4
  29. package/src/engineDebug.js +3 -7
  30. package/src/engineDraw.js +50 -25
  31. package/src/engineExport.js +4 -1
  32. package/src/engineInput.js +1 -1
  33. package/src/engineObject.js +8 -8
  34. package/src/engineParticles.js +6 -6
  35. package/src/engineSettings.js +5 -5
  36. package/src/engineTileLayer.js +2 -2
  37. package/src/engineUtilities.js +5 -5
  38. package/src/engineWebGL.js +52 -74
  39. package/examples/electron/build.js +0 -107
  40. package/examples/electron/electron.js +0 -43
  41. package/examples/electron/game.js +0 -131
  42. package/examples/electron/index.html +0 -13
  43. package/examples/electron/package.json +0 -22
  44. package/examples/electron/tiles.png +0 -0
  45. package/examples/js13k/build.bat +0 -2
  46. package/examples/js13k/build.js +0 -131
  47. package/examples/js13k/game.js +0 -118
  48. package/examples/js13k/index.html +0 -21
  49. package/examples/js13k/tiles.png +0 -0
  50. package/examples/typescript/build.bat +0 -5
  51. package/examples/typescript/build.js +0 -33
  52. package/examples/typescript/game.js +0 -102
  53. package/examples/typescript/game.ts +0 -134
  54. package/examples/typescript/index.html +0 -10
  55. package/examples/typescript/tiles.png +0 -0
  56. package/examples/typescript/tsconfig.json +0 -8
@@ -13,7 +13,7 @@ function spawnBox(pos, size=1, color=WHITE, type=box2dBodyTypeDynamic, applyText
13
13
  {
14
14
  size = typeof size == 'number' ? vec2(size) : size; // square
15
15
  const o = new Box2dObject(pos, size, applyTexture && spriteAtlas.squareOutline, angle, color, type);
16
- o.drawSize = size.scale(1.02); // slightly enarge to cover gaps
16
+ o.drawSize = size.scale(1.02); // slightly enlarge to cover gaps
17
17
  o.addBox(size);
18
18
  return o;
19
19
  }
@@ -405,7 +405,7 @@ class ClothObject extends Box2dObject
405
405
  const stress = vec2(j.GetReactionForce(1)).length();
406
406
  if (stress > this.maxJointStress || d2 > maxLength2*4)
407
407
  {
408
- // remove stessed joint
408
+ // remove stressed joint
409
409
  box2dDestroyJoint(j);
410
410
  joints[i] = 0;
411
411
  }
@@ -463,7 +463,7 @@ function explosion(pos, radius=3, strength=300)
463
463
  // smoke
464
464
  new ParticleEmitter(
465
465
  pos, 0, // pos, angle
466
- radius/2, .2, 50*radius, PI,// emitSize, emitTime, emitRate, emiteCone
466
+ radius/2, .2, 50*radius, PI,// emitSize, emitTime, emitRate, emitCone
467
467
  spriteAtlas.dot, // tileInfo
468
468
  hsl(0,0,0), hsl(0,0,0), // colorStartA, colorStartB
469
469
  hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
@@ -475,7 +475,7 @@ function explosion(pos, radius=3, strength=300)
475
475
  // fire
476
476
  new ParticleEmitter(
477
477
  pos, 0, // pos, angle
478
- radius, .1, 100*radius, PI, // emitSize, emitTime, emitRate, emiteCone
478
+ radius, .1, 100*radius, PI, // emitSize, emitTime, emitRate, emitCone
479
479
  spriteAtlas.dot, // tileInfo
480
480
  hsl(0,1,.5), hsl(.15,1,.5), // colorStartA, colorStartB
481
481
  hsl(0,1,.5,0), hsl(.1, 1,.5,0), // colorEndA, colorEndB
@@ -1,5 +1,5 @@
1
1
  /*
2
- LittleJS Box2D Example - Secenes
2
+ LittleJS Box2D Example - Scenes
3
3
  - Each scene demonstrates a feature of Box2D
4
4
  - Feel free to use tis code in your own projects
5
5
  - 0 = Shapes: box, circle, poly, and edge
@@ -122,7 +122,7 @@ function loadScene(_scene)
122
122
  const oaB = oB.localToWorld(vec2(0,oB.size.y/2));
123
123
  box2dCreatePulleyJoint(oA, oB, aA.pos, aB.pos, oaA, oaB);
124
124
 
125
- // a line to make it look like conneting rope
125
+ // a line to make it look like connecting rope
126
126
  const line = new EngineObject(vec2(20,15), vec2(10,.2), 0, 0, BLACK);
127
127
  line.gravityScale = 0;
128
128
  line.renderOrder = -1;
@@ -63,7 +63,7 @@ class Brick extends EngineObject
63
63
  const color2 = color1.lerp(hsl(), .5);
64
64
  new ParticleEmitter(
65
65
  this.pos, 0, // pos, angle
66
- this.size, .1, 200, PI, // emitSize, emitTime, emitRate, emiteCone
66
+ this.size, .1, 200, PI, // emitSize, emitTime, emitRate, emitCone
67
67
  tile(0, 16), // tileIndex, tileSize
68
68
  color1, color2, // colorStartA, colorStartB
69
69
  color1.scale(1,0), color2.scale(1,0), // colorEndA, colorEndB
@@ -99,7 +99,7 @@ class Ball extends EngineObject
99
99
  const color = hsl(0,0,.2);
100
100
  this.trailEffect = new ParticleEmitter(
101
101
  this.pos, 0, // pos, angle
102
- this.size, 0, 80, PI, // emitSize, emitTime, emitRate, emiteCone
102
+ this.size, 0, 80, PI, // emitSize, emitTime, emitRate, emitCone
103
103
  tile(0, 16), // tileIndex, tileSize
104
104
  color, color, // colorStartA, colorStartB
105
105
  color.scale(0), color.scale(0), // colorEndA, colorEndB
@@ -113,7 +113,7 @@ class Brick extends EngineObject
113
113
  const color = this.color;
114
114
  new ParticleEmitter(
115
115
  this.pos, 0, // pos, angle
116
- this.size, .1, 200, PI, // emitSize, emitTime, emitRate, emiteCone
116
+ this.size, .1, 200, PI, // emitSize, emitTime, emitRate, emitCone
117
117
  undefined, // tileInfo
118
118
  color, color, // colorStartA, colorStartB
119
119
  color.scale(1,0), color.scale(1,0), // colorEndA, colorEndB
@@ -16,8 +16,8 @@ iframe {width:480px; height:270px;}
16
16
  <a href="breakoutTutorial">Breakout Tutorial</a> - Tutorial Breakout example<br>
17
17
  <a href="puzzle">Puzzle</a> - Match 3 puzzle game with HD rendering and high score tracking<br>
18
18
  <a href="particles">Particle Designer</a> - Particle system editor and visualizer<br>
19
- <a href="js13k">JS13K Starter</a> - Special small size demo for JS13K Games<br>
20
19
  <a href="empty">Empty</a> - A blank hello world project for LittleJS<br>
20
+ <a href="module">LittleJS with Modules</a> - Loads LittleJS as a module<br>
21
21
  </p>
22
22
  <h2>Plugin Demos</h2>
23
23
  <p>
@@ -25,12 +25,6 @@ iframe {width:480px; height:270px;}
25
25
  <a href="uiSystem">UI System</a> - A simple hierarchical UI system using LittleJS rendering<br>
26
26
  <a href="htmlMenu">HTML UI Menu</a> - Example using html to create an overlay menu<br>
27
27
  </p>
28
- <h2>Environment Demos</h2>
29
- <p>
30
- <a href="module">LittleJS using modules</a> - Loads LittleJS as a module<br>
31
- <a href="typescript">LittleJS using TypeScript</a> - Uses LittleJS type definitions<br>
32
- <a href="electron">LittleJS building with Electron</a> - Builds to an executable<br>
33
- </p>
34
28
  <h2>Live Demos</h2>
35
29
  <p>
36
30
  <iframe id=iframe src="breakout"></iframe>
package/examples/logo.png CHANGED
Binary file
@@ -71,7 +71,7 @@ function gameInit()
71
71
  // create particle emitter
72
72
  particleEmitter = new LittleJS.ParticleEmitter(
73
73
  vec2(16,9), 0, // emitPos, emitAngle
74
- 1, 0, 500, Math.PI, // emitSize, emitTime, emitRate, emiteCone
74
+ 1, 0, 500, Math.PI, // emitSize, emitTime, emitRate, emitCone
75
75
  tile(0, 16), // tileIndex, tileSize
76
76
  hsl(1,1,1), hsl(0,0,0), // colorStartA, colorStartB
77
77
  hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
@@ -1,8 +1,8 @@
1
1
  /*
2
2
  Little JS Platforming Game
3
3
  - A basic platforming starter project
4
- - Platforming phyics and controls
5
- - Includes destructibe terrain
4
+ - Platforming physics and controls
5
+ - Includes destructible terrain
6
6
  - Control with keyboard, mouse, touch, or gamepad
7
7
  */
8
8
 
@@ -25,7 +25,7 @@ class Character extends GameObject
25
25
  this.dodgeTimer = new Timer;
26
26
  this.dodgeRechargeTimer = new Timer;
27
27
  this.deadTimer = new Timer;
28
- this.grendeThrowTimer = new Timer;
28
+ this.grenadeThrowTimer = new Timer;
29
29
  this.drawSize = vec2(1);
30
30
  this.color = hsl(rand(),1,.7);
31
31
  this.renderOrder = 10;
@@ -82,14 +82,14 @@ class Character extends GameObject
82
82
  if (!this.groundObject && this.getAliveTime() > .2)
83
83
  this.velocity.y += .2;
84
84
  }
85
- if (this.pressingThrow && !this.wasPressingThrow && !this.grendeThrowTimer.active())
85
+ if (this.pressingThrow && !this.wasPressingThrow && !this.grenadeThrowTimer.active())
86
86
  {
87
- // throw greande
87
+ // throw grenade
88
88
  const grenade = new Grenade(this.pos);
89
89
  grenade.velocity = this.velocity.add(vec2(this.getMirrorSign(),rand(.8,.7)).normalize(.2+rand(.02)));
90
90
  grenade.angleVelocity = this.getMirrorSign() * rand(.8,.5);
91
91
  sound_jump.play(this.pos);
92
- this.grendeThrowTimer.set(1);
92
+ this.grenadeThrowTimer.set(1);
93
93
  }
94
94
  this.wasPressingThrow = this.pressingThrow;
95
95
  }
@@ -276,7 +276,7 @@ class Character extends GameObject
276
276
  if (getTileCollisionData(pos.add(vec2(0,1))) // above
277
277
  && !getTileCollisionData(pos.add(vec2(1,0))) // left
278
278
  && !getTileCollisionData(pos.add(vec2(1,0)))) // right
279
- return false; // dont collide if something above it and nothing to left or right
279
+ return false; // don't collide if something above it and nothing to left or right
280
280
 
281
281
  // allow standing on top of ladders
282
282
  return !this.climbingLadder;
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  LittleJS Platformer Example - Effects
3
- - Plays different particle effects which can be persistant
3
+ - Plays different particle effects which can be persistent
4
4
  - Destroys terrain and makes explosions
5
5
  - Outlines tiles based on neighbor types
6
6
  - Generates parallax background layers
@@ -39,7 +39,7 @@ function makeDebris(pos, color = hsl(), amount = 50, size=.2, elasticity = .3)
39
39
  {
40
40
  const color2 = color.lerp(hsl(), .5);
41
41
  const emitter = new ParticleEmitter(
42
- pos, 0, 1, .1, amount/.1, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
42
+ pos, 0, 1, .1, amount/.1, PI, // pos, angle, emitSize, emitTime, emitRate, emitCone
43
43
  0, // tileInfo
44
44
  color, color2, // colorStartA, colorStartB
45
45
  color, color2, // colorEndA, colorEndB
@@ -97,7 +97,7 @@ function explosion(pos, radius=3)
97
97
  // smoke
98
98
  new ParticleEmitter(
99
99
  pos, 0, // pos, angle
100
- radius/2, .2, 50*radius, PI,// emitSize, emitTime, emitRate, emiteCone
100
+ radius/2, .2, 50*radius, PI,// emitSize, emitTime, emitRate, emitCone
101
101
  0, // tileInfo
102
102
  hsl(0,0,0), hsl(0,0,0), // colorStartA, colorStartB
103
103
  hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
@@ -109,7 +109,7 @@ function explosion(pos, radius=3)
109
109
  // fire
110
110
  new ParticleEmitter(
111
111
  pos, 0, // pos, angle
112
- radius/2, .1, 100*radius, PI, // emitSize, emitTime, emitRate, emiteCone
112
+ radius/2, .1, 100*radius, PI, // emitSize, emitTime, emitRate, emitCone
113
113
  0, // tileInfo
114
114
  rgb(1,.5,.1), rgb(1,.1,.1), // colorStartA, colorStartB
115
115
  rgb(1,.5,.1,0), rgb(1,.1,.1,0), // colorEndA, colorEndB
@@ -239,7 +239,7 @@ class Weapon extends EngineObject
239
239
 
240
240
  // shell effect
241
241
  this.addChild(this.shellEmitter = new ParticleEmitter(
242
- vec2(), 0, 0, 0, 0, .1, // pos, angle, emitSize, emitTime, emitRate, emiteCone
242
+ vec2(), 0, 0, 0, 0, .1, // pos, angle, emitSize, emitTime, emitRate, emitCone
243
243
  0, // tileInfo
244
244
  rgb(1,.8,.5), rgb(.9,.7,.5), // colorStartA, colorStartB
245
245
  rgb(1,.8,.5), rgb(.9,.7,.5), // colorEndA, colorEndB
@@ -360,7 +360,7 @@ class Bullet extends EngineObject
360
360
 
361
361
  // spark effects
362
362
  const emitter = new ParticleEmitter(
363
- this.pos, 0, 0, .1, 100, .5, // pos, angle, emitSize, emitTime, emitRate, emiteCone
363
+ this.pos, 0, 0, .1, 100, .5, // pos, angle, emitSize, emitTime, emitRate, emitCone
364
364
  0, // tileInfo
365
365
  rgb(1,1,0), rgb(1,0,0), // colorStartA, colorStartB
366
366
  rgb(1,1,0), rgb(1,0,0), // colorEndA, colorEndB
@@ -216,7 +216,7 @@ function gameRender()
216
216
  drawTile(drawPos, vec2(.5), tile(data, 64), color2);
217
217
  }
218
218
 
219
- // draw a grey square at top to cover up incomming tiles
219
+ // draw a grey square at top to cover up incoming tiles
220
220
  drawRect(cameraPos.subtract(cameraOffset).add(vec2(0,levelSize.y)), levelSize, backgroundColor);
221
221
  }
222
222
 
@@ -294,7 +294,7 @@ function clearMatches()
294
294
  const color2 = color1.lerp(hsl(), .5);
295
295
  new ParticleEmitter(
296
296
  pos.add(vec2(.5)), 0, // pos, angle
297
- .5, .1, 200, PI, // emitSize, emitTime, emitRate, emiteCone
297
+ .5, .1, 200, PI, // emitSize, emitTime, emitRate, emitCone
298
298
  0, // tileInfo
299
299
  color1, color2, // colorStartA, colorStartB
300
300
  color1.scale(1,0), color2.scale(1,0),// colorEndA, colorEndB
@@ -7,6 +7,8 @@
7
7
 
8
8
  'use strict';
9
9
 
10
+ // show the LittleJS splash screen
11
+ setShowSplashScreen(true);
10
12
 
11
13
  // fix texture bleeding by shrinking tile slightly
12
14
  tileFixBleedScale = .5;
@@ -64,7 +66,7 @@ function gameInit()
64
66
  // create particle emitter
65
67
  particleEmitter = new ParticleEmitter(
66
68
  vec2(16,9), 0, // emitPos, emitAngle
67
- 0, 0, 0, PI, // emitSize, emitTime, emitRate, emiteCone
69
+ 0, 0, 500, PI, // emitSize, emitTime, emitRate, emitCone
68
70
  tile(0, 16), // tileIndex, tileSize
69
71
  hsl(1,1,1), hsl(0,0,0), // colorStartA, colorStartB
70
72
  hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
@@ -109,55 +111,19 @@ function gameUpdatePost()
109
111
  function gameRender()
110
112
  {
111
113
  // draw a grey square in the background without using webgl
112
- drawRect(vec2(16,8), vec2(202,214), hsl(0,0,.6), 0, false);
114
+ drawRect(vec2(16,8), vec2(20,14), hsl(0,0,.6), 0, false);
113
115
 
116
+ // draw the logo as a tile
117
+ drawTile(vec2(21,5), vec2(4.5), tile(3,128));
114
118
  }
115
119
 
116
120
  ///////////////////////////////////////////////////////////////////////////////
117
121
  function gameRenderPost()
118
122
  {
119
- drawNineSlice(vec2(10,10), vec2(4,4), tile(1))
120
- }
121
-
122
- function drawNineSlice(pos, size, tileInfo, context=overlayContext)
123
- {
124
- // calculate the size of a slice
125
- const s = tileInfo.size.x / 3;
126
-
127
- // define the 9 parts as [x, y, width, height]
128
- const part1 = [0, 0, s, s];
129
- const part2 = [s, 0, s, s];
130
- const part3 = [s * 2, 0, s, s];
131
- const part4 = [0, s, s, s];
132
- const part5 = [s, s, s, s];
133
- const part6 = [s * 2, s, s, s];
134
- const part7 = [0, s * 2, s, s];
135
- const part8 = [s, s * 2, s, s];
136
- const part9 = [s * 2, s * 2, s, s];
137
-
138
- // target width/height (try different values!)
139
- const width = 16 * size.x;
140
- const height = 16 * size.y;
141
-
142
- const img = tileInfo.getTextureInfo().image;
143
-
144
- const originPos = pos.subtract(size.divide(vec2(2))).add(vec2( - 0.5));
145
-
146
- // draw the corners
147
- //context.imageSmoothingEnabled = false
148
- context.drawImage(img, ...part1, originPos.x + 0, originPos.y + 0, s + 1, s + 1); // top left
149
- context.drawImage(img, ...part3, originPos.x + width - s, originPos.y + 0, s + 1, s + 1); // top right
150
- context.drawImage(img, ...part7, originPos.x + 0, originPos.y + height - s, s + 1, s + 1); // bottom left
151
- context.drawImage(img, ...part9, originPos.x + width - s, originPos.y + height - s, s + 1, s + 1); // bottom right
152
-
153
- // draw the edges
154
- context.drawImage(img, ...part2, originPos.x + s, originPos.y + 0, width - 2 * s + 1, s + 1); // top
155
- context.drawImage(img, ...part8, originPos.x + s, originPos.y + height - s, width - 2 * s + 1, s + 1); // bottom
156
- context.drawImage(img, ...part4, originPos.x + 0, originPos.y + s, s + 1, height - 2 * s + 1); // left
157
- context.drawImage(img, ...part6, originPos.x + width - s, originPos.y + s, s + 1, height - 2 * s + 1); // right
158
-
159
- // draw the center
160
- context.drawImage(img, ...part5, originPos.x + s, originPos.y + s, width - 2 * s + 1, height - 2 * s + 1);
123
+ // draw to overlay canvas for hud rendering
124
+ drawTextScreen('LittleJS Demo',
125
+ vec2(mainCanvasSize.x/2, 70), 80, // position, size
126
+ hsl(0,0,1), 6, hsl(0,0,0)); // color, outline size and color
161
127
  }
162
128
 
163
129
  ///////////////////////////////////////////////////////////////////////////////
Binary file
package/jsconfig.json CHANGED
@@ -5,6 +5,7 @@
5
5
  "./src/*.js",
6
6
  "./plugins/*.js",
7
7
  "./examples/**/*.js",
8
+ "./shortExamples/**/*.js",
8
9
  ],
9
10
  "exclude": [
10
11
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.11.2",
3
+ "version": "1.11.4",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
5
  "main": "dist/littlejs.esm.js",
6
6
  "types": "dist/littlejs.d.ts",
package/plugins/box2d.js CHANGED
@@ -69,7 +69,7 @@ class Box2dObject extends EngineObject
69
69
  {
70
70
  const isAsleep = !this.getIsAwake();
71
71
  const isStatic = this.getIsStatic();
72
- const color = rgb(isAsleep,isAsleep,isStatic,.5);
72
+ const color = rgb(isAsleep?1:0 ,isAsleep?1:0, isStatic?1:0, .5);
73
73
  this.box2dDrawFixtures(color);
74
74
  }
75
75
 
@@ -353,7 +353,7 @@ function box2dBoxCastAll(pos, size)
353
353
 
354
354
  let queryObjects = [];
355
355
  box2dWorld.QueryAABB(queryCallback, aabb);
356
- debugRaycast && debugRect(pos, size, raycstResult ? '#f00' : '#00f', .02);
356
+ debugRaycast && debugRect(pos, size, queryObjects.length ? '#f00' : '#00f', .02);
357
357
  return queryObjects;
358
358
  }
359
359
 
@@ -374,7 +374,7 @@ function box2dBoxCast(pos, size)
374
374
 
375
375
  let queryObject;
376
376
  box2dWorld.QueryAABB(queryCallback, aabb);
377
- debugRaycast && debugRect(pos, size, raycstResult ? '#f00' : '#00f', .02);
377
+ debugRaycast && debugRect(pos, size, queryObject ? '#f00' : '#00f', .02);
378
378
  return queryObject;
379
379
  }
380
380
 
@@ -416,7 +416,7 @@ function box2dPointCast(pos, dynamicOnly=true)
416
416
  return true; // continue getting results
417
417
  if (!fixture.TestPoint(pos.getBox2d()))
418
418
  return true; // continue getting results
419
- queryResult = fixture.GetBody().object;
419
+ queryObject = fixture.GetBody().object;
420
420
  return false; // stop getting results
421
421
  };
422
422
 
@@ -424,10 +424,10 @@ function box2dPointCast(pos, dynamicOnly=true)
424
424
  aabb.set_lowerBound(pos.getBox2d());
425
425
  aabb.set_upperBound(pos.getBox2d());
426
426
 
427
- let queryResult;
428
- debugRaycast && debugRect(pos, vec2(), queryResult ? '#f00' : '#00f', .02);
427
+ let queryObject;
428
+ debugRaycast && debugRect(pos, vec2(), queryObject ? '#f00' : '#00f', .02);
429
429
  box2dWorld.QueryAABB(queryCallback, aabb);
430
- return queryResult;
430
+ return queryObject;
431
431
  }
432
432
 
433
433
  // box aabb cast and return all the fixtures
@@ -437,8 +437,8 @@ function box2dBoxCastAllFixtures(pos, size)
437
437
  queryCallback.ReportFixture = function(fixturePointer)
438
438
  {
439
439
  const fixture = box2d.wrapPointer(fixturePointer, box2d.b2Fixture);
440
- if (!queryObjects.includes(fixture))
441
- queryObjects.push(fixture); // add if not already in list
440
+ if (!queryFixtures.includes(fixture))
441
+ queryFixtures.push(fixture); // add if not already in list
442
442
  return true; // continue getting results
443
443
  };
444
444
 
@@ -448,7 +448,7 @@ function box2dBoxCastAllFixtures(pos, size)
448
448
 
449
449
  let queryFixtures = [];
450
450
  box2dWorld.QueryAABB(queryCallback, aabb);
451
- debugRaycast && debugRect(pos, size, raycstResult ? '#f00' : '#00f', .02);
451
+ debugRaycast && debugRect(pos, size, queryFixtures.length ? '#f00' : '#00f', .02);
452
452
  return queryFixtures;
453
453
  }
454
454
 
@@ -12,7 +12,7 @@
12
12
 
13
13
  ///////////////////////////////////////////////////////////////////////////////
14
14
 
15
- /** Newgrounds medal auto unlocks in newgronds API */
15
+ /** Newgrounds medal auto unlocks in newgrounds API */
16
16
  class NewgroundsMedal extends Medal
17
17
  {
18
18
  /** Create a medal object and adds it to the list of medals */
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.11.2';
33
+ const engineVersion = '1.11.4';
34
34
 
35
35
  /** Frames per second to update
36
36
  * @type {Number}
@@ -113,6 +113,7 @@ function engineAddPlugin(updateFunction, renderFunction)
113
113
  * @memberof Engine */
114
114
  function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
115
115
  {
116
+ ASSERT(!mainContext, 'engine already initialized');
116
117
  ASSERT(Array.isArray(imageSources), 'pass in images as array');
117
118
 
118
119
  // Called automatically by engine to setup render system
@@ -279,7 +280,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
279
280
  (canvasPixelated ? 'image-rendering:pixelated;' : '') + // pixel art
280
281
  'user-select:none;' + // prevent hold to select
281
282
  '-webkit-user-select:none;' + // compatibility for ios
282
- (!touchInputEnable ? '' : // no touch css setttings
283
+ (!touchInputEnable ? '' : // no touch css settings
283
284
  'touch-action:none;' + // prevent mobile pinch to resize
284
285
  '-webkit-touch-callout:none');// compatibility for ios
285
286
  rootElement.style.cssText = styleRoot;
@@ -308,6 +309,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
308
309
  new Promise(resolve =>
309
310
  {
310
311
  const image = new Image;
312
+ image.crossOrigin = 'anonymous';
311
313
  image.onerror = image.onload = ()=>
312
314
  {
313
315
  textureInfos[textureIndex] = new TextureInfo(image);
@@ -352,7 +354,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
352
354
  * @memberof Engine */
353
355
  function engineObjectsUpdate()
354
356
  {
355
- // get list of solid objects for physics optimzation
357
+ // get list of solid objects for physics optimization
356
358
  engineObjectsCollide = engineObjects.filter(o=>o.collideSolidObjects);
357
359
 
358
360
  // recursive object update
@@ -25,7 +25,7 @@ function audioInit()
25
25
  {
26
26
  if (!soundEnable || headlessMode) return;
27
27
 
28
- // (createGain is more widely spported then GainNode construtor)
28
+ // (createGain is more widely supported then GainNode constructor)
29
29
  audioGainNode = audioContext.createGain();
30
30
  audioGainNode.connect(audioContext.destination);
31
31
  audioGainNode.gain.value = soundVolume; // set starting value
@@ -375,7 +375,7 @@ const zzfxR = 44100;
375
375
  * @param {Number} [sustain] - Sustain time, how long sound holds (seconds)
376
376
  * @param {Number} [release] - Release time, how fast sound fades out (seconds)
377
377
  * @param {Number} [shape] - Shape of the sound wave
378
- * @param {Number} [shapeCurve] - Squarenes of wave (0=square, 1=normal, 2=pointy)
378
+ * @param {Number} [shapeCurve] - Squareness of wave (0=square, 1=normal, 2=pointy)
379
379
  * @param {Number} [slide] - How much to slide frequency (kHz/s)
380
380
  * @param {Number} [deltaSlide] - How much to change slide (kHz/s/s)
381
381
  * @param {Number} [pitchJump] - Frequency of pitch jump (Hz)
@@ -387,7 +387,7 @@ const zzfxR = 44100;
387
387
  * @param {Number} [delay] - Overlap sound with itself for reverb and flanger effects (seconds)
388
388
  * @param {Number} [sustainVolume] - Volume level for sustain (percent)
389
389
  * @param {Number} [decay] - Decay time, how long to reach sustain after attack (seconds)
390
- * @param {Number} [tremolo] - Trembling effect, rate controlled by repeat time (precent)
390
+ * @param {Number} [tremolo] - Trembling effect, rate controlled by repeat time (percent)
391
391
  * @param {Number} [filter] - Filter cutoff frequency, positive for HPF, negative for LPF (Hz)
392
392
  * @return {Array} - Array of audio samples
393
393
  * @memberof Audio
@@ -491,7 +491,7 @@ function zzfxG
491
491
  // ZzFX Music Renderer v2.0.3 by Keith Clark and Frank Force
492
492
 
493
493
  /** Generate samples for a ZzFM song with given parameters
494
- * @param {Array} instruments - Array of ZzFX sound paramaters
494
+ * @param {Array} instruments - Array of ZzFX sound parameters
495
495
  * @param {Array} patterns - Array of pattern data
496
496
  * @param {Array} sequence - Array of pattern indexes
497
497
  * @param {Number} [BPM] - Playback speed of the song in BPM
@@ -16,7 +16,7 @@
16
16
  * @memberof Debug */
17
17
  const debug = true;
18
18
 
19
- /** True if asserts are enaled
19
+ /** True if asserts are enabled
20
20
  * @type {Boolean}
21
21
  * @default
22
22
  * @memberof Debug */
@@ -244,12 +244,8 @@ function debugRender()
244
244
 
245
245
  if (debugTakeScreenshot)
246
246
  {
247
- // composite canvas
248
- glCopyToContext(mainContext, true);
249
- mainContext.drawImage(overlayCanvas, 0, 0);
250
- overlayCanvas.width |= 0;
251
-
252
- // remove alpha and save
247
+ // combine canvases, remove alpha and save
248
+ combineCanvases();
253
249
  const w = mainCanvas.width, h = mainCanvas.height;
254
250
  overlayContext.fillRect(0,0,w,h);
255
251
  overlayContext.drawImage(mainCanvas, 0, 0);
package/src/engineDraw.js CHANGED
@@ -48,7 +48,7 @@ let overlayContext;
48
48
  let mainCanvasSize = vec2();
49
49
 
50
50
  /** Array containing texture info for batch rendering system
51
- * @type {Array}
51
+ * @type {Array<TextureInfo>}
52
52
  * @memberof Draw */
53
53
  let textureInfos = [];
54
54
 
@@ -87,11 +87,13 @@ function tile(pos=vec2(), size=tileSizeDefault, textureIndex=0, padding=0)
87
87
 
88
88
  // use pos as a tile index
89
89
  const textureInfo = textureInfos[textureIndex];
90
- ASSERT(textureInfo, 'Texture not loaded');
90
+ ASSERT(!!textureInfo, 'Texture not loaded');
91
91
  const sizePadded = size.add(vec2(padding*2));
92
- const cols = textureInfo.size.x / sizePadded.x |0;
93
92
  if (typeof pos === 'number')
94
- pos = vec2(pos%cols, pos/cols|0);
93
+ {
94
+ const cols = textureInfo.size.x / sizePadded.x |0;
95
+ pos = cols>0 ? vec2(pos%cols, pos/cols|0) : vec2();
96
+ }
95
97
  pos = vec2(pos.x*sizePadded.x+padding, pos.y*sizePadded.y+padding);
96
98
 
97
99
  // return a tile info object
@@ -397,24 +399,6 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, conte
397
399
  context.restore();
398
400
  }
399
401
 
400
- /** Enable normal or additive blend mode
401
- * @param {Boolean} [additive]
402
- * @param {Boolean} [useWebGL=glEnable]
403
- * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
404
- * @memberof Draw */
405
- function setBlendMode(additive, useWebGL=glEnable, context)
406
- {
407
- ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
408
- if (useWebGL)
409
- glAdditive = additive;
410
- else
411
- {
412
- if (!context)
413
- context = mainContext;
414
- context.globalCompositeOperation = additive ? 'lighter' : 'source-over';
415
- }
416
- }
417
-
418
402
  /** Draw text on main canvas in world space
419
403
  * Automatically splits new lines into rows
420
404
  * @param {String} text
@@ -482,6 +466,38 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
482
466
  });
483
467
  }
484
468
 
469
+ /** Enable normal or additive blend mode
470
+ * @param {Boolean} [additive]
471
+ * @param {Boolean} [useWebGL=glEnable]
472
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
473
+ * @memberof Draw */
474
+ function setBlendMode(additive, useWebGL=glEnable, context)
475
+ {
476
+ ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
477
+ if (useWebGL)
478
+ glAdditive = additive;
479
+ else
480
+ {
481
+ if (!context)
482
+ context = mainContext;
483
+ context.globalCompositeOperation = additive ? 'lighter' : 'source-over';
484
+ }
485
+ }
486
+
487
+ /** Combines all LittleJS canvases onto the main canvas and clears them
488
+ * This is necessary for things like saving a screenshot
489
+ * @memberof Draw */
490
+ function combineCanvases()
491
+ {
492
+ // combine canvases
493
+ glCopyToContext(mainContext, true);
494
+ mainContext.drawImage(overlayCanvas, 0, 0);
495
+
496
+ // clear canvases
497
+ glClearCanvas();
498
+ overlayCanvas.width |= 0;
499
+ }
500
+
485
501
  ///////////////////////////////////////////////////////////////////////////////
486
502
 
487
503
  let engineFontImage;
@@ -493,7 +509,7 @@ let engineFontImage;
493
509
  * - You can also use fonts from the main tile sheet
494
510
  * @example
495
511
  * // use built in font
496
- * const font = new ImageFont;
512
+ * const font = new FontImage;
497
513
  *
498
514
  * // draw text
499
515
  * font.drawTextScreen("LittleJS\nHello World!", vec2(200, 50));
@@ -568,14 +584,14 @@ class FontImage
568
584
  }
569
585
 
570
586
  ///////////////////////////////////////////////////////////////////////////////
571
- // Fullscreen mode
587
+ // Display functions
572
588
 
573
589
  /** Returns true if fullscreen mode is active
574
590
  * @return {Boolean}
575
591
  * @memberof Draw */
576
592
  function isFullscreen() { return !!document.fullscreenElement; }
577
593
 
578
- /** Toggle fullsceen mode
594
+ /** Toggle fullscreen mode
579
595
  * @memberof Draw */
580
596
  function toggleFullscreen()
581
597
  {
@@ -587,4 +603,13 @@ function toggleFullscreen()
587
603
  }
588
604
  else if (rootElement.requestFullscreen)
589
605
  rootElement.requestFullscreen();
606
+ }
607
+
608
+ /** Set the cursor style
609
+ * @param {String} cursorStyle - CSS cursor style (auto, none, crosshair, etc)
610
+ * @memberof Draw */
611
+ function setCursor(cursorStyle = 'auto')
612
+ {
613
+ const rootElement = mainCanvas.parentElement;
614
+ rootElement.style.cursor = cursorStyle;
590
615
  }