littlejsengine 1.11.5 → 1.11.7

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 (66) hide show
  1. package/README.md +11 -16
  2. package/dist/littlejs.d.ts +14 -1
  3. package/dist/littlejs.esm.js +40 -26
  4. package/dist/littlejs.esm.min.js +1 -1
  5. package/dist/littlejs.js +37 -26
  6. package/dist/littlejs.min.js +1 -1
  7. package/dist/littlejs.release.js +33 -25
  8. package/examples/box2d/game.js +2 -2
  9. package/examples/box2d/index.html +5 -5
  10. package/examples/breakout/game.js +6 -5
  11. package/examples/breakout/gameObjects.js +1 -1
  12. package/examples/breakout/index.html +4 -4
  13. package/examples/breakoutTutorial/README.md +1 -1
  14. package/examples/breakoutTutorial/game.js +1 -1
  15. package/examples/breakoutTutorial/index.html +2 -2
  16. package/examples/htmlMenu/index.html +2 -2
  17. package/examples/index.html +300 -32
  18. package/examples/module/index.html +1 -1
  19. package/examples/particles/index.html +1 -1
  20. package/examples/platformer/gamePlayer.js +2 -7
  21. package/examples/platformer/index.html +8 -8
  22. package/examples/puzzle/index.html +2 -2
  23. package/examples/shorts/animation.js +18 -0
  24. package/examples/shorts/base.html +26 -0
  25. package/examples/shorts/blending.js +16 -0
  26. package/examples/shorts/clock.js +21 -0
  27. package/examples/shorts/colors.js +25 -0
  28. package/examples/shorts/helloWorld.js +8 -0
  29. package/examples/shorts/platformer.js +42 -0
  30. package/{shortExamples/code → examples/shorts}/playSound.js +4 -3
  31. package/{shortExamples/code → examples/shorts}/pong.js +3 -3
  32. package/{shortExamples/code → examples/shorts}/shapes.js +1 -1
  33. package/examples/shorts/spriteAtlas.js +34 -0
  34. package/examples/shorts/systemFont.js +16 -0
  35. package/{shortExamples/code → examples/shorts}/tileLayer.js +1 -1
  36. package/examples/shorts/tiles.png +0 -0
  37. package/examples/shorts/tiltedView.js +44 -0
  38. package/examples/shorts/timers.js +40 -0
  39. package/examples/shorts/topDown.js +44 -0
  40. package/examples/starter/game.js +3 -3
  41. package/examples/starter/index.html +13 -13
  42. package/examples/stress/index.html +2 -2
  43. package/examples/uiSystem/game.js +6 -1
  44. package/examples/uiSystem/index.html +3 -3
  45. package/package.json +1 -1
  46. package/plugins/Box2D_License.txt +17 -0
  47. package/plugins/uiSystem.js +2 -1
  48. package/reference.md +2 -1
  49. package/src/engine.js +1 -1
  50. package/src/engineDebug.js +5 -1
  51. package/src/engineDraw.js +4 -1
  52. package/src/engineExport.js +3 -0
  53. package/src/engineInput.js +19 -15
  54. package/src/engineObject.js +4 -4
  55. package/src/engineRelease.js +1 -0
  56. package/src/engineTileLayer.js +2 -2
  57. package/src/engineUtilities.js +2 -2
  58. package/shortExamples/base.html +0 -36
  59. package/shortExamples/code/blending.js +0 -12
  60. package/shortExamples/code/helloWorld.js +0 -7
  61. package/shortExamples/code/spriteAtlas.js +0 -27
  62. package/shortExamples/code/systemFont.js +0 -14
  63. package/shortExamples/index.html +0 -242
  64. package/shortExamples/tiles.png +0 -0
  65. /package/{shortExamples/code → examples/shorts}/particles.js +0 -0
  66. /package/{shortExamples/code → examples/shorts}/texture.js +0 -0
@@ -0,0 +1,42 @@
1
+ class PhysicsObject extends EngineObject
2
+ {
3
+ constructor(pos, size, color)
4
+ {
5
+ super(pos, size, 0, 0, color);
6
+ this.setCollision(); // make object collide
7
+ this.mass = 0; // make object have static physics
8
+ }
9
+ }
10
+
11
+ class Player extends PhysicsObject
12
+ {
13
+ constructor(pos)
14
+ {
15
+ super(pos, vec2(2,4), RED);
16
+ this.mass = 1; // make object have dynamic physics
17
+ }
18
+
19
+ update()
20
+ {
21
+ // apply movement controls
22
+ const moveInput = keyDirection();
23
+ this.velocity.x += moveInput.x * (this.groundObject ? .1: .01);
24
+ if (this.groundObject && moveInput.y > 0)
25
+ this.velocity.y = .9; // jump
26
+
27
+ super.update(); // call parent update function
28
+ cameraPos = vec2(this.pos.x, 9); // move camera with player
29
+ }
30
+ }
31
+
32
+ function gameInit()
33
+ {
34
+ // setup level
35
+ gravity = -.05;
36
+ new Player(vec2(0,4));
37
+
38
+ // create random objects
39
+ new PhysicsObject(vec2(), vec2(1e3,4), GRAY); // ground
40
+ for (let i = 1; i < 500; ++i)
41
+ new PhysicsObject(vec2(i*10+randInt(4), 0), vec2(2+randInt(20),4+randInt(8)), GREEN);
42
+ }
@@ -9,12 +9,14 @@ class SoundButton extends EngineObject
9
9
 
10
10
  update()
11
11
  {
12
+ // play sound when clicked
12
13
  if (mouseWasPressed(0) && isOverlapping(this.pos, this.size, mousePos))
13
14
  this.sound.play(this.pos);
14
15
  }
15
16
 
16
17
  render()
17
18
  {
19
+ // draw the button and icon
18
20
  drawRect(this.pos, this.size, hsl(0,0,.8));
19
21
  drawTextOverlay(this.icon, this.pos, 3);
20
22
  }
@@ -22,14 +24,13 @@ class SoundButton extends EngineObject
22
24
 
23
25
  function gameInit()
24
26
  {
27
+ // create a grid of buttons with different sounds
25
28
  new SoundButton(vec2(-6, 5),'💰', new Sound([,,1675,,.06,.24,1,1.82,,,837,.06]));
26
29
  new SoundButton(vec2( 0, 5),'🥊', new Sound([,,925,.04,.3,.6,1,.3,,6.27,-184,.09,.17]));
27
30
  new SoundButton(vec2( 6, 5),'✨', new Sound([,,539,0,.04,.29,1,1.92,,,567,.02,.02,,,,.04]));
28
-
29
31
  new SoundButton(vec2(-6, 0),'🐁', new Sound([,.2,1e3,.02,,.01,2,,18,,475,.01,.01]));
30
32
  new SoundButton(vec2( 0, 0),'🎹', new Sound([1.5,.5,270,,.1,,1,1.5,,,,,,,,.1,.01]));
31
- new SoundButton(vec2( 6, 0),'🏌️', new Sound([,,150,.05,,.05,,1.3,,,,,,3]));
32
-
33
+ new SoundButton(vec2( 6, 0),'🏌️', new Sound([,,150,.05,,.05,,1.3,,,,,,3]));
33
34
  new SoundButton(vec2(-6,-5),'🌊', new Sound([,.2,40,.5,,1.5,,11,,,,,,199]));
34
35
  new SoundButton(vec2( 0,-5),'🛰️', new Sound([,.5,847,.02,.3,.9,1,1.67,,,-294,.04,.13,,,,.1]));
35
36
  new SoundButton(vec2( 6,-5),'⚡', new Sound([,,471,,.09,.47,4,1.06,-6.7,,,,,.9,61,.1,,.82,.1]));
@@ -20,9 +20,9 @@ function gameInit()
20
20
 
21
21
  // create objects
22
22
  paddle = new PhysicsObject(vec2(0,1), vec2(6,1)); // create player's paddle
23
- new PhysicsObject(vec2(-.5,levelSize.y/2), vec2(1,100)) // top wall
24
- new PhysicsObject(vec2(levelSize.x+.5,levelSize.y/2), vec2(1,100)) // left wall
25
- new PhysicsObject(vec2(levelSize.x/2,levelSize.y+.5), vec2(100,1)) // right wall
23
+ new PhysicsObject(vec2(-.5,levelSize.y/2), vec2(1,100)); // left wall
24
+ new PhysicsObject(vec2(levelSize.x+.5,levelSize.y/2), vec2(1,100)); // right wall
25
+ new PhysicsObject(vec2(levelSize.x/2,levelSize.y+.5), vec2(100,1)); // top wall
26
26
  }
27
27
 
28
28
  function gameUpdate()
@@ -17,7 +17,7 @@ function gameRender()
17
17
  drawEllipse(vec2(-5,5), 2, 1, 0, hsl(0,1,.5));
18
18
  drawEllipse(vec2(5,5), 1, .5, 0, hsl(.55,1,.5));
19
19
 
20
- // lines and rects
20
+ // rects and lines
21
21
  drawRect(vec2(0,-5), vec2(13,2), hsl(.6,1,.5));
22
22
  drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1));
23
23
  drawLine(vec2(-5,-3), vec2(5,-7), .2, hsl(1,1,.5));
@@ -0,0 +1,34 @@
1
+ let spriteAtlas;
2
+
3
+ function gameInit()
4
+ {
5
+ // create a table of all sprites
6
+ const gameTile = (i, size=16)=> tile(i, size);
7
+ spriteAtlas =
8
+ {
9
+ circle: gameTile(0),
10
+ crate: gameTile(1),
11
+ icon: gameTile(2),
12
+ circleBig: gameTile(2, 128),
13
+ iconBig: gameTile(3, 128),
14
+ };
15
+ }
16
+
17
+ function gameRender()
18
+ {
19
+ drawRect(vec2(0,0), vec2(100), GRAY); // draw background
20
+
21
+ // draw a sprite from the atlas
22
+ let pos = vec2(Math.sin(time)*5,-3);// world position to draw
23
+ let angle = 0; // world space angle to draw the tile
24
+ let size = vec2(9); // world size of the tile
25
+ let mirror = 0; // should tile be mirrored?
26
+ let color = hsl(0,0,1); // color to multiply the tile by
27
+ let additiveColor = hsl(0,0,0,0); // color to add to
28
+ drawTile(pos, size, spriteAtlas.iconBig, color, angle, mirror, additiveColor);
29
+
30
+ // draw more sprites from the atlas
31
+ drawTile(vec2(-7,4), vec2(5), spriteAtlas.crate);
32
+ drawTile(vec2( 0,4), vec2(5), spriteAtlas.circle);
33
+ drawTile(vec2( 7,4), vec2(5), spriteAtlas.circleBig);
34
+ }
@@ -0,0 +1,16 @@
1
+ function gameRender()
2
+ {
3
+ // draw text with built in font image system font
4
+ const font = new FontImage;
5
+ font.drawText('System Font Test', cameraPos.add(vec2(0,3)), .2, true);
6
+
7
+ // show every character in the system font
8
+ let s = '';
9
+ for(let i=32; i<128; ++i)
10
+ {
11
+ if (i%32 == 0)
12
+ s += '\n';
13
+ s += String.fromCharCode(i);
14
+ }
15
+ font.drawText(s, cameraPos, .1, true);
16
+ }
@@ -34,7 +34,7 @@ function gameUpdate()
34
34
  {
35
35
  // create particle emitter
36
36
  const hue = rand();
37
- let particleEmitter = new ParticleEmitter(
37
+ const particleEmitter = new ParticleEmitter(
38
38
  mousePos, 0, // emitPos, emitAngle
39
39
  0, 0.1, 500, PI, // emitSize, emitTime, emitRate, emitCone
40
40
  tile(0, 16), // tileIndex, tileSize
Binary file
@@ -0,0 +1,44 @@
1
+ class GameObject extends EngineObject
2
+ {
3
+ update()
4
+ {
5
+ this.renderOrder = -this.pos.y; // sort by y position
6
+ super.update();
7
+ }
8
+
9
+ render()
10
+ {
11
+ // adjust draw postion to be at the bottom of the object
12
+ const pos = this.pos.add(vec2(0,this.size.y/2).rotate(this.angle));
13
+ drawTile(pos, this.size, this.tileInfo, this.color, this.angle);
14
+ }
15
+ }
16
+
17
+ class Player extends GameObject
18
+ {
19
+ update()
20
+ {
21
+ // apply movement controls
22
+ const moveInput = keyDirection().clampLength(1).scale(.2); // clamp and scale input
23
+ this.velocity = this.velocity.add(moveInput); // apply movement
24
+
25
+ super.update(); // call parent update function
26
+ cameraPos = this.pos.add(vec2(0,2)); // move camera with player
27
+ }
28
+ }
29
+
30
+
31
+ function gameInit()
32
+ {
33
+ // setup level
34
+ objectDefaultDamping = .7;
35
+ new Player(vec2(), vec2(3), tile(5), 0, RED);
36
+
37
+ // create background objects
38
+ for (let i = 1; i < 300; ++i)
39
+ new EngineObject(randInCircle(90), vec2(rand(59),rand(59)), 0, 0, hsl(.4,.3,rand(.1,.2),.8), -1e5);
40
+
41
+ // create world objects
42
+ for (let i = 1; i < 1e3; ++i)
43
+ new GameObject(randInCircle(7+i,7), vec2(rand(1,2),rand(4,9)), 0, 0, hsl(.1,.5,rand(.2,.3)));
44
+ }
@@ -0,0 +1,40 @@
1
+ class TimerButton extends EngineObject
2
+ {
3
+ constructor(pos, time)
4
+ {
5
+ super(pos, vec2(5.5));
6
+ this.time = time;
7
+ this.timer = new Timer;
8
+ }
9
+
10
+ update()
11
+ {
12
+ // start or stop the timer when clicked
13
+ if (mouseWasPressed(0) && isOverlapping(this.pos, this.size, mousePos))
14
+ this.timer.isSet() ? this.timer.unset() : this.timer.set(this.time);
15
+ }
16
+
17
+ render()
18
+ {
19
+ // get color based on timer state
20
+ this.color = this.timer.isSet() ? this.timer.active() ? BLUE : RED : GRAY;
21
+
22
+ // draw the button and timer text
23
+ drawRect(this.pos, this.size, this.color);
24
+ if (this.timer.isSet())
25
+ {
26
+ drawTextOverlay(this.timer.get().toFixed(1), this.pos.add(vec2(0,1)), 2);
27
+ const percent = this.timer.getPercent()*100|0;
28
+ drawTextOverlay(percent+'%', this.pos.add(vec2(0,-1)), 2);
29
+ }
30
+ else
31
+ drawTextOverlay('Click\nto set', this.pos, 2);
32
+ }
33
+ }
34
+
35
+ function gameInit()
36
+ {
37
+ // create some timer buttons
38
+ new TimerButton(vec2(-5, 0), 3);
39
+ new TimerButton(vec2( 5, 0), 0);
40
+ }
@@ -0,0 +1,44 @@
1
+ class PhysicsObject extends EngineObject
2
+ {
3
+ constructor(pos, size, color)
4
+ {
5
+ super(pos, size, 0, 0, color);
6
+ this.setCollision(); // make object collide
7
+ this.mass = 0; // make object have static physics
8
+ }
9
+ }
10
+
11
+ class Player extends PhysicsObject
12
+ {
13
+ constructor(pos)
14
+ {
15
+ super(pos, vec2(2), RED);
16
+ this.mass = 1; // make object have dynamic physics
17
+ this.renderOrder = 1; // render player on top of other objects
18
+ }
19
+
20
+ update()
21
+ {
22
+ // apply movement controls
23
+ const moveInput = keyDirection().clampLength(1).scale(.2); // clamp and scale input
24
+ this.velocity = this.velocity.add(moveInput); // apply movement
25
+
26
+ super.update(); // call parent update function
27
+ cameraPos = this.pos; // move camera with player
28
+ }
29
+ }
30
+
31
+ function gameInit()
32
+ {
33
+ // setup level
34
+ objectDefaultDamping = .7;
35
+ new Player();
36
+
37
+ // create background objects
38
+ for (let i = 1; i < 300; ++i)
39
+ new EngineObject(randInCircle(90), vec2(rand(59),rand(59)), 0, rand(), hsl(.4,.5,rand(.2)));
40
+
41
+ // create foreground objects
42
+ for (let i = 1; i < 300; ++i)
43
+ new PhysicsObject(randInCircle(7+i,7), vec2(rand(4,9),rand(4,9)), hsl(0,0,rand(.8,1)));
44
+ }
@@ -70,9 +70,9 @@ function gameInit()
70
70
  tile(0, 16), // tileIndex, tileSize
71
71
  hsl(1,1,1), hsl(0,0,0), // colorStartA, colorStartB
72
72
  hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
73
- 2, .2, .2, .1, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
74
- .99, 1, 1, PI, // damping, angleDamping, gravityScale, cone
75
- .05, .8, true, true // fadeRate, randomness, collide, additive
73
+ 2, .2, .2, .1, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
74
+ .99, 1, 1, PI, // damping, angleDamping, gravityScale, cone
75
+ .05, .5, true, true // fadeRate, randomness, collide, additive
76
76
  );
77
77
  particleEmitter.elasticity = .3; // bounce when it collides
78
78
  particleEmitter.trailScale = 2; // stretch in direction of motion
@@ -7,18 +7,18 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- LittleJS Engine -->
10
- <script src=../../src/engineDebug.js?1105></script>
11
- <script src=../../src/engineUtilities.js?1105></script>
12
- <script src=../../src/engineSettings.js?1105></script>
13
- <script src=../../src/engineObject.js?1105></script>
14
- <script src=../../src/engineDraw.js?1105></script>
15
- <script src=../../src/engineInput.js?1105></script>
16
- <script src=../../src/engineAudio.js?1105></script>
17
- <script src=../../src/engineTileLayer.js?1105></script>
18
- <script src=../../src/engineParticles.js?1105></script>
19
- <script src=../../src/engineMedals.js?1105></script>
20
- <script src=../../src/engineWebGL.js?1105></script>
21
- <script src=../../src/engine.js?1105></script>
10
+ <script src=../../src/engineDebug.js?1117></script>
11
+ <script src=../../src/engineUtilities.js?1117></script>
12
+ <script src=../../src/engineSettings.js?1117></script>
13
+ <script src=../../src/engineObject.js?1117></script>
14
+ <script src=../../src/engineDraw.js?1117></script>
15
+ <script src=../../src/engineInput.js?1117></script>
16
+ <script src=../../src/engineAudio.js?1117></script>
17
+ <script src=../../src/engineTileLayer.js?1117></script>
18
+ <script src=../../src/engineParticles.js?1117></script>
19
+ <script src=../../src/engineMedals.js?1117></script>
20
+ <script src=../../src/engineWebGL.js?1117></script>
21
+ <script src=../../src/engine.js?1117></script>
22
22
 
23
23
  <!-- Add your game scripts here -->
24
- <script src=game.js?1105></script>
24
+ <script src=game.js?1117></script>
@@ -7,7 +7,7 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- LittleJS Engine -->
10
- <script src=../../dist/littlejs.min.js?1105></script>
10
+ <script src=../../dist/littlejs.min.js?1117></script>
11
11
  <script>
12
12
 
13
13
  /*
@@ -161,6 +161,6 @@ engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, [ti
161
161
 
162
162
  ///////////////////////////////////////////////////////////////////////////////
163
163
  // music - Depp Loop
164
- const music = new Music([[[,0,77,,,.7,2,.41,,,,,,,,.06],[,0,43,.01,,.3,2,,,,,,,,,.02,.01],[,0,170,.003,,.008,,.97,-35,53,,,,,,.1],[.8,0,270,,,.12,3,1.65,-2,,,,,4.5,,.02],[,0,86,,,.1,,.7,,,,.5,,6.7,1,.05],[,0,41,,.05,.4,2,0,,,9,.01,,,,.08,.02],[,0,2200,,,.04,3,2,,,800,.02,,4.8,,.01,.1],[.3,0,16,,,.3,3]],[[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,22,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,24,,,,,,,,,,,,,,,,,,,,,,,,22,,22,,22,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,24,,,,,,,,27,,,,,,,,,,,,,,,,27,,,,24,,,,24,,,,,,,,27,,,,,,,,,,,,,,,,24,,24,,24,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[6,1,,,34,34,34,,,,,,34,34,,,,,34,,,,34,34,,,,,34,,,,34,,,,34,34,34,,,,,,34,,,,,,34,34,,,34,34,,,,,,,,,34,34],[4,1,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,23,23,35,23,23,36,23,23,35,23,23,36,23,23,35,35,23,23,35,23,23,35,23,23,36,23,23,35,23,23,36,36],[5,-1,21,,,19,,,21,,,,,,,,,,21,,,19,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,],[3,1,24,,,24,,,24,,,,,,,,,,24,,,24,,,24,,,,24.75,24.5,24.26,24.01,24.01,24.01,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[4,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,24.75,24.5,24.26,24.01,24.01,24.01,24.01,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,,21,23,,35,,23,,21,23,,35,,35,,23,,21,23,,35,,21,23,,35,,21,23,,,],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,36,34,,33,34,34,36,31,36,34,,31,34,32,,33,36,34,,31,34,34,36,33,36,33,,31,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,21,,19,21,,33,,21,,19,21,,33,,33,,21,,19,21,,33,,21,,19,21,,33,,33,,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29],[2,1,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,],[6,1,,,36,,,,,,36,,36,,,,,,,,36,,,,,,36,,36,,,,,,,,36,,,,,,,,,,,,,,,,36,,,,,,36,,36,,,,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,25,,,25,,,,,,,,25,,,,,,,,25,25,25,25]],[[1,-1,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,19,19,31,19,19,31,19,19,31,19,19,31,19,19,31,31],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,36,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,19,,19,19,31,19,19,31,19,,19,19,31,19,19,31],[2,1,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,,,,,,34,,34,,,,,,,,34,,,,,,34,,34,,,,,,]]],[0,1,1,2,3,4,4]]);
164
+ const music = new Music([[[.6,0,76,,,1,1,.5,,,,,.1,,,.06,,.5,.2,,-700],[,0,43,.01,,.2,2,,,,,,,,,,.01],[,0,170,.003,,.008,,.97,-35,53,,,,,,.1],[.8,0,270,,,.12,3,1.65,-2,,,,,4.5,,.02],[,0,86,,,.1,,.7,,,,.5,,6.7,1,.05],[,0,41,,.05,.4,2,0,,,9,.01,,,,.08,.02],[,0,2200,,,.04,3,2,,,800,.02,,4.8,,.01,.1],[.3,0,16,,,.3,3]],[[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,22,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,24,,,,,,,,,,,,,,,,,,,,,,,,22,,22,,22,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,24,,,,,,,,27,,,,,,,,,,,,,,,,27,,,,24,,,,24,,,,,,,,27,,,,,,,,,,,,,,,,24,,24,,24,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[6,1,,,34,34,34,,,,,,34,34,,,,,34,,,,34,34,,,,,34,,,,34,,,,34,34,34,,,,,,34,,,,,,34,34,,,34,34,,,,,,,,,34,34],[4,1,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,23,23,35,23,23,36,23,23,35,23,23,36,23,23,35,35,23,23,35,23,23,35,23,23,36,23,23,35,23,23,36,36],[5,-1,21,,,19,,,21,,,,,,,,,,21,,,19,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,],[3,1,24,,,24,,,24,,,,,,,,,,24,,,24,,,24,,,,24.75,24.5,24.26,24.01,24.01,24.01,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[4,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,24.75,24.5,24.26,24.01,24.01,24.01,24.01,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,,21,23,,35,,23,,21,23,,35,,35,,23,,21,23,,35,,21,23,,35,,21,23,,,],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,36,34,,33,34,34,36,31,36,34,,31,34,32,,33,36,34,,31,34,34,36,33,36,33,,31,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,21,,19,21,,33,,21,,19,21,,33,,33,,21,,19,21,,33,,21,,19,21,,33,,33,,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29],[2,1,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,],[6,1,,,36,,,,,,36,,36,,,,,,,,36,,,,,,36,,36,,,,,,,,36,,,,,,,,,,,,,,,,36,,,,,,36,,36,,,,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,25,,,25,,,,,,,,25,,,,,,,,25,25,25,25]],[[1,-1,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,19,19,31,19,19,31,19,19,31,19,19,31,19,19,31,31],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,36,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,19,,19,19,31,19,19,31,19,,19,19,31,19,19,31],[2,1,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,,,,,,34,,34,,,,,,,,34,,,,,,34,,34,,,,,,]]],[0,1,1,2,3,4,4]]);
165
165
 
166
166
  </script>
@@ -17,11 +17,15 @@ let uiRoot, uiMenu;
17
17
  const getMenuVisible =()=> uiMenu.visible;
18
18
  const setMenuVisible =(visible)=> uiMenu.visible = visible;
19
19
 
20
+ // use a fixed size canvas
21
+ canvasFixedSize = vec2(1920, 1080); // 1080p
22
+ canvasPixelated = false;
23
+
20
24
  function createUI()
21
25
  {
22
26
  // setup root to attach all ui elements to
23
27
  uiRoot = new UIObject();
24
- const uiInfo = new UIText(vec2(0,50), vec2(1e3, 70),
28
+ const uiInfo = new UIText(vec2(0,90), vec2(1e3, 70),
25
29
  'LittleJS UI System Example\nM = Toggle menu');
26
30
  uiInfo.textColor = WHITE;
27
31
  uiInfo.lineWidth = 8;
@@ -31,6 +35,7 @@ function createUI()
31
35
  uiMenu = new UIObject(vec2(0,450));
32
36
  uiRoot.addChild(uiMenu);
33
37
  const uiBackground = new UIObject(vec2(0,0), vec2(450,580));
38
+ uiBackground.lineWidth = 8;
34
39
  uiMenu.addChild(uiBackground);
35
40
 
36
41
  // example large text
@@ -7,8 +7,8 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- LittleJS Engine -->
10
- <script src=../../dist/littlejs.js?1105></script>
10
+ <script src=../../dist/littlejs.js?1117></script>
11
11
 
12
12
  <!-- Add your game scripts here -->
13
- <script src=../../plugins/uiSystem.js?1105></script>
14
- <script src=game.js?1105></script>
13
+ <script src=../../plugins/uiSystem.js?1117></script>
14
+ <script src=game.js?1117></script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.11.5",
3
+ "version": "1.11.7",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
5
  "main": "dist/littlejs.esm.js",
6
6
  "types": "dist/littlejs.d.ts",
@@ -0,0 +1,17 @@
1
+ Copyright (c) 2006-2010 Erin Catto http://www.gphysics.com
2
+
3
+ This software is provided 'as-is', without any express or implied
4
+ warranty. In no event will the authors be held liable for any damages
5
+ arising from the use of this software.
6
+
7
+ Permission is granted to anyone to use this software for any purpose,
8
+ including commercial applications, and to alter it and redistribute it
9
+ freely, subject to the following restrictions:
10
+
11
+ 1. The origin of this software must not be misrepresented; you must not
12
+ claim that you wrote the original software. If you use this software
13
+ in a product, an acknowledgment in the product documentation would be
14
+ appreciated but is not required.
15
+ 2. Altered source versions must be plainly marked as such, and must not be
16
+ misrepresented as being the original software.
17
+ 3. This notice may not be removed or altered from any source distribution.
@@ -246,7 +246,8 @@ class UICheckbox extends UIObject
246
246
  }
247
247
  render()
248
248
  {
249
- drawUIRect(this.pos, this.size, this.color, this.lineWidth, this.lineColor);
249
+ const color = this.mouseIsOver? this.hoverColor : this.color;
250
+ drawUIRect(this.pos, this.size, color, this.lineWidth, this.lineColor);
250
251
  if (this.checked)
251
252
  {
252
253
  // draw an X if checked
package/reference.md CHANGED
@@ -224,6 +224,7 @@ soundDefaultTaper = .7 // Default range percent to taper off sound (0-1)
224
224
  keyIsDown(key) // Is key down?
225
225
  keyWasPressed(key) // Was key pressed this frame?
226
226
  keyWasReleased(key) // Was key released this frame?
227
+ keyDirection() // Get input vector from arrow keys or wasd
227
228
 
228
229
  // Mouse / Touch
229
230
  mousePos // World space mouse position
@@ -406,4 +407,4 @@ showWatermark // True if watermark with FPS should be show
406
407
 
407
408
  [LittleJS Engine](https://github.com/KilledByAPixel/LittleJS) Copyright 2021 Frank Force
408
409
 
409
- ![LittleJS Logo](examples/favicon.png)
410
+ ![LittleJS Logo](examples/favicon.png)
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.5';
33
+ const engineVersion = '1.11.7';
34
34
 
35
35
  /** Frames per second to update
36
36
  * @type {Number}
@@ -162,6 +162,10 @@ function debugText(text, pos, size=1, color='#fff', time=0, angle=0, font='monos
162
162
  * @memberof Debug */
163
163
  function debugClear() { debugPrimitives = []; }
164
164
 
165
+ /** Trigger debug system to take a screenshot
166
+ * @memberof Debug */
167
+ function debugScreenshot() { debugTakeScreenshot = 1; }
168
+
165
169
  /** Save a canvas to disk
166
170
  * @param {HTMLCanvasElement} canvas
167
171
  * @param {String} [filename]
@@ -235,7 +239,7 @@ function debugUpdate()
235
239
  if (keyWasPressed('Digit4'))
236
240
  debugRaycast = !debugRaycast;
237
241
  if (keyWasPressed('Digit5'))
238
- debugTakeScreenshot = 1;
242
+ debugScreenshot();
239
243
  }
240
244
  }
241
245
 
package/src/engineDraw.js CHANGED
@@ -458,7 +458,10 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
458
458
  context.lineJoin = 'round';
459
459
 
460
460
  pos = pos.copy();
461
- (text+'').split('\n').forEach(line=>
461
+
462
+ const lines = (text+'').split('\n');
463
+ pos.y -= (lines.length-1) * size/2; // center text vertically
464
+ lines.forEach(line=>
462
465
  {
463
466
  lineWidth && context.strokeText(line, pos.x, pos.y, maxWidth);
464
467
  context.fillText(line, pos.x, pos.y, maxWidth);
@@ -19,6 +19,7 @@ export {
19
19
  engineInit,
20
20
  engineObjectsUpdate,
21
21
  engineObjectsDestroy,
22
+ engineObjectsCollect,
22
23
  engineObjectsCallback,
23
24
  engineObjectsRaycast,
24
25
  engineAddPlugin,
@@ -38,6 +39,7 @@ export {
38
39
  debugOverlap,
39
40
  debugText,
40
41
  debugClear,
42
+ debugScreenshot,
41
43
  debugSaveCanvas,
42
44
  debugSaveText,
43
45
  debugSaveDataURL,
@@ -236,6 +238,7 @@ export {
236
238
  keyIsDown,
237
239
  keyWasPressed,
238
240
  keyWasReleased,
241
+ keyDirection,
239
242
  clearInput,
240
243
  mouseIsDown,
241
244
  mouseWasPressed,
@@ -43,6 +43,15 @@ function keyWasReleased(key, device=0)
43
43
  return inputData[device] && !!(inputData[device][key] & 4);
44
44
  }
45
45
 
46
+ /** Returns input vector from arrow keys or WASD if enabled
47
+ * @return {Vector2}
48
+ * @memberof Input */
49
+ function keyDirection(up='ArrowUp', down='ArrowDown', left='ArrowLeft', right='ArrowRight')
50
+ {
51
+ const k = (key)=> keyIsDown(key) ? 1 : 0;
52
+ return vec2(k(right) - k(left), k(up) - k(down));
53
+ }
54
+
46
55
  /** Clears all input
47
56
  * @memberof Input */
48
57
  function clearInput() { inputData = [[]]; touchGamepadButtons = []; }
@@ -126,9 +135,9 @@ function gamepadStick(stick, gamepad=0)
126
135
  { return gamepadStickData[gamepad] ? gamepadStickData[gamepad][stick] || vec2() : vec2(); }
127
136
 
128
137
  ///////////////////////////////////////////////////////////////////////////////
129
- // Input update called by engine
138
+ // Input system functions called automatically by engine
130
139
 
131
- // store input as a bit field for each key: 1 = isDown, 2 = wasPressed, 4 = wasReleased
140
+ // input is stored as a bit field for each key: 1 = isDown, 2 = wasPressed, 4 = wasReleased
132
141
  // mouse and keyboard are stored together in device 0, gamepads are in devices > 0
133
142
  let inputData = [[]];
134
143
 
@@ -158,9 +167,6 @@ function inputUpdatePost()
158
167
  mouseWheel = 0;
159
168
  }
160
169
 
161
- ///////////////////////////////////////////////////////////////////////////////
162
- // Input event handlers
163
-
164
170
  function inputInit()
165
171
  {
166
172
  if (headlessMode) return;
@@ -203,11 +209,11 @@ function inputInit()
203
209
 
204
210
  isUsingGamepad = false;
205
211
  inputData[0][e.button] = 3;
206
- mousePosScreen = mouseToScreen(e);
212
+ mousePosScreen = mouseEventToScreen(e);
207
213
  e.button && e.preventDefault();
208
214
  }
209
215
  onmouseup = (e)=> inputData[0][e.button] = inputData[0][e.button] & 2 | 4;
210
- onmousemove = (e)=> mousePosScreen = mouseToScreen(e);
216
+ onmousemove = (e)=> mousePosScreen = mouseEventToScreen(e);
211
217
  onwheel = (e)=> mouseWheel = e.ctrlKey ? 0 : sign(e.deltaY);
212
218
  oncontextmenu = (e)=> false; // prevent right click menu
213
219
  onblur = (e) => clearInput(); // reset input when focus is lost
@@ -218,14 +224,12 @@ function inputInit()
218
224
  }
219
225
 
220
226
  // convert a mouse or touch event position to screen space
221
- function mouseToScreen(mousePos)
227
+ function mouseEventToScreen(mousePos)
222
228
  {
223
- if (!mainCanvas || headlessMode)
224
- return vec2(); // fix bug that can occur if user clicks before page loads
225
-
226
229
  const rect = mainCanvas.getBoundingClientRect();
227
- return vec2(mainCanvas.width, mainCanvas.height).multiply(
228
- vec2(percent(mousePos.x, rect.left, rect.right), percent(mousePos.y, rect.top, rect.bottom)));
230
+ const px = percent(mousePos.x, rect.left, rect.right);
231
+ const py = percent(mousePos.y, rect.top, rect.bottom);
232
+ return vec2(px*mainCanvas.width, py*mainCanvas.height);
229
233
  }
230
234
 
231
235
  ///////////////////////////////////////////////////////////////////////////////
@@ -380,7 +384,7 @@ function touchInputInit()
380
384
  {
381
385
  // set event pos and pass it along
382
386
  const p = vec2(e.touches[0].clientX, e.touches[0].clientY);
383
- mousePosScreen = mouseToScreen(p);
387
+ mousePosScreen = mouseEventToScreen(p);
384
388
  wasTouching ? isUsingGamepad = touchGamepadEnable : inputData[0][button] = 3;
385
389
  }
386
390
  else if (wasTouching)
@@ -428,7 +432,7 @@ function touchInputInit()
428
432
  // check each touch point
429
433
  for (const touch of e.touches)
430
434
  {
431
- const touchPos = mouseToScreen(vec2(touch.clientX, touch.clientY));
435
+ const touchPos = mouseEventToScreen(vec2(touch.clientX, touch.clientY));
432
436
  if (touchPos.distance(stickCenter) < touchGamepadSize)
433
437
  {
434
438
  // virtual analog stick
@@ -338,19 +338,19 @@ class EngineObject
338
338
 
339
339
  /** Convert from local space to world space
340
340
  * @param {Vector2} pos - local space point */
341
- localToWorld(pos) { return this.pos.add(pos.rotate(-this.angle)); }
341
+ localToWorld(pos) { return this.pos.add(pos.rotate(this.angle)); }
342
342
 
343
343
  /** Convert from world space to local space
344
344
  * @param {Vector2} pos - world space point */
345
- worldToLocal(pos) { return pos.subtract(this.pos).rotate(this.angle); }
345
+ worldToLocal(pos) { return pos.subtract(this.pos).rotate(-this.angle); }
346
346
 
347
347
  /** Convert from local space to world space for a vector (rotation only)
348
348
  * @param {Vector2} vec - local space vector */
349
- localToWorldVector(vec) { return vec.rotate(this.angle); }
349
+ localToWorldVector(vec) { return vec.rotate(-this.angle); }
350
350
 
351
351
  /** Convert from world space to local space for a vector (rotation only)
352
352
  * @param {Vector2} vec - world space vector */
353
- worldToLocalVector(vec) { return vec.rotate(-this.angle); }
353
+ worldToLocalVector(vec) { return vec.rotate(this.angle); }
354
354
 
355
355
  /** Called to check if a tile collision should be resolved
356
356
  * @param {Number} tileData - the value of the tile at the position