littlejsengine 1.14.11 → 1.14.19

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 (80) hide show
  1. package/dist/littlejs.d.ts +303 -137
  2. package/dist/littlejs.esm.js +936 -463
  3. package/dist/littlejs.esm.min.js +1 -1
  4. package/dist/littlejs.js +934 -462
  5. package/dist/littlejs.min.js +1 -1
  6. package/dist/littlejs.release.js +859 -417
  7. package/examples/box2d/game.js +3 -2
  8. package/examples/box2d/gameObjects.js +2 -2
  9. package/examples/box2d/tiles.png +0 -0
  10. package/examples/breakout/game.js +5 -5
  11. package/examples/breakout/gameObjects.js +2 -2
  12. package/examples/breakoutTutorial/README.md +32 -32
  13. package/examples/breakoutTutorial/game.js +1 -1
  14. package/examples/electron/game.js +4 -4
  15. package/examples/electron/index.html +2 -2
  16. package/examples/electron/package.json +1 -8
  17. package/examples/index.html +67 -56
  18. package/examples/module/game.js +4 -4
  19. package/examples/platformer/gameEffects.js +5 -5
  20. package/examples/platformer/gameLevel.js +1 -1
  21. package/examples/platformer/gameObjects.js +4 -4
  22. package/examples/puzzle/game.js +1 -1
  23. package/examples/shorts/animation.js +1 -1
  24. package/examples/shorts/base.html +1 -1
  25. package/examples/shorts/blending.js +8 -14
  26. package/examples/shorts/box2d.js +7 -3
  27. package/examples/shorts/box2dCar.js +2 -1
  28. package/examples/shorts/empty.js +30 -0
  29. package/examples/shorts/helloWorld.js +1 -1
  30. package/examples/shorts/hillGlideGame.js +10 -4
  31. package/examples/shorts/landerGame.js +11 -8
  32. package/examples/shorts/medals.js +4 -4
  33. package/examples/shorts/music.js +29 -56
  34. package/examples/shorts/musicPlayer.js +135 -0
  35. package/examples/shorts/nineSlice.js +34 -15
  36. package/examples/shorts/parallax.js +5 -4
  37. package/examples/shorts/particles.js +15 -15
  38. package/examples/shorts/piano.js +15 -21
  39. package/examples/shorts/pongGame.js +6 -4
  40. package/examples/shorts/raycasting.js +9 -4
  41. package/examples/shorts/sequencer.js +122 -0
  42. package/examples/shorts/shader.js +29 -0
  43. package/examples/shorts/shapes.js +7 -4
  44. package/examples/shorts/slidingPuzzle.js +4 -2
  45. package/examples/shorts/sound.js +18 -9
  46. package/examples/shorts/spaceGame.js +12 -8
  47. package/examples/shorts/spriteAtlas.js +7 -7
  48. package/examples/shorts/starfield.js +1 -1
  49. package/examples/shorts/systemFont.js +2 -2
  50. package/examples/shorts/texture.js +2 -2
  51. package/examples/shorts/tileLayer.js +10 -10
  52. package/examples/shorts/tiltedView.js +24 -5
  53. package/examples/shorts/timers.js +10 -0
  54. package/examples/shorts/topDown.js +4 -1
  55. package/examples/shorts/uiSystem.js +8 -5
  56. package/examples/starter/game.js +4 -4
  57. package/examples/starter/index.html +2 -2
  58. package/examples/style.css +1 -0
  59. package/examples/typescript/game.js +4 -4
  60. package/examples/typescript/game.ts +4 -4
  61. package/examples/uiSystem/game.js +4 -3
  62. package/package.json +4 -2
  63. package/plugins/box2d.js +17 -2
  64. package/plugins/newgrounds.js +7 -5
  65. package/plugins/postProcess.js +76 -53
  66. package/plugins/uiSystem.js +192 -53
  67. package/plugins/zzfxm.js +5 -1
  68. package/reference.md +1 -1
  69. package/src/engine.js +60 -23
  70. package/src/engineAudio.js +44 -17
  71. package/src/engineDebug.js +75 -45
  72. package/src/engineDraw.js +94 -59
  73. package/src/engineExport.js +2 -1
  74. package/src/engineMedals.js +10 -2
  75. package/src/engineObject.js +14 -10
  76. package/src/engineParticles.js +60 -47
  77. package/src/engineSettings.js +7 -7
  78. package/src/engineTileLayer.js +73 -56
  79. package/src/engineUtilities.js +67 -20
  80. package/src/engineWebGL.js +134 -63
@@ -3,19 +3,38 @@ function gameRender()
3
3
  const nineSliceTile = tile(16);
4
4
  const threeSliceTile = tile(19);
5
5
 
6
- // draw nine slice with thin border and color
7
- drawNineSlice(vec2(-7,4), vec2(11+wave(.5,2), 6), nineSliceTile, hsl(.1,.5,.9), .5);
8
- drawTextOverlay('Nine Slice\nThin Border', vec2(-7,4), 1, BLACK);
9
-
10
- // draw nine slice in screen space with thick border and rotation
11
- drawNineSliceScreen(vec2(700,150), vec2(250), nineSliceTile, 32, 2, time/2);
12
- drawTextScreen('Nine Slice\nScreen Space', vec2(700,150), 30, BLACK);
13
-
14
- // draw three slice with variable border and additive color
15
- drawThreeSlice(vec2(-7,-4), vec2(9, 7), threeSliceTile, WHITE, 2+wave(.2)*2, hsl(time/30,.5,.5));
16
- drawTextOverlay('Three Slice\nVariable\n Border', vec2(-7,-4), 1, BLACK);
17
-
18
- // draw three slice in screen space with changing size
19
- drawThreeSliceScreen(vec2(700,420), vec2(350-wave(.3,90),120+wave(.3,60)), threeSliceTile);
20
- drawTextScreen('Three Slice\nScreen Space', vec2(700,420), 30, BLACK);
6
+ {
7
+ // draw nine slice with thin border and color
8
+ const pos = vec2(-7,4);
9
+ const size = vec2(11+wave(.5,2), 6);
10
+ const color = hsl(.1,.5,.9);
11
+ const border = .5;
12
+ drawNineSlice(pos, size, nineSliceTile, color, border);
13
+ drawTextOverlay('Nine Slice\nThin Border', pos, 1, BLACK);
14
+ }
15
+ {
16
+ // draw nine slice in screen space with thick border and rotation
17
+ const pos = vec2(700,150);
18
+ const size = vec2(250);
19
+ const border = 32;
20
+ const angle = time/2;
21
+ drawNineSliceScreen(pos, size, nineSliceTile, border, 2, angle);
22
+ drawTextScreen('Nine Slice\nScreen Space', pos, 30, BLACK);
23
+ }
24
+ {
25
+ // draw three slice with variable border and additive color
26
+ const pos = vec2(-7,-4);
27
+ const size = vec2(9, 7);
28
+ const border = 2 + wave(.2)*2;
29
+ const additive = hsl(time/30,.5,.5);
30
+ drawThreeSlice(pos, size, threeSliceTile, WHITE, border, additive);
31
+ drawTextOverlay('Three Slice\nVariable\nBorder', pos, 1, BLACK);
32
+ }
33
+ {
34
+ // draw three slice in screen space with changing size
35
+ const pos = vec2(700,420);
36
+ const size = vec2(350-wave(.3,90),120+wave(.3,60));
37
+ drawThreeSliceScreen(pos, size, threeSliceTile);
38
+ drawTextScreen('Three Slice\nScreen Space', pos, 30, BLACK);
39
+ }
21
40
  }
@@ -23,7 +23,7 @@ class ParallaxLayer extends CanvasLayer
23
23
  const w = canvasSize.x, h = canvasSize.y;
24
24
  for (let i = h; i--;)
25
25
  {
26
- // draw a 1 pixel gradient line on the left side of the canvas
26
+ // draw a 1 pixel gradient line on the left side
27
27
  const p = i/h;
28
28
  this.context.fillStyle = topColor.lerp(bottomColor, p);
29
29
  this.context.fillRect(0, i, 1, 1);
@@ -34,7 +34,8 @@ class ParallaxLayer extends CanvasLayer
34
34
  const levelness = .005; // how much the mountains level out
35
35
  const slopeRange = 1; // max slope of the mountains
36
36
  const startGroundLevel = h/2;
37
- let y = startGroundLevel, groundSlope = rand(-slopeRange, slopeRange);
37
+ let y = startGroundLevel;
38
+ let groundSlope = rand(-slopeRange, slopeRange);
38
39
  for (let x=w; x--;)
39
40
  {
40
41
  // pull slope towards start ground level
@@ -45,14 +46,14 @@ class ParallaxLayer extends CanvasLayer
45
46
  groundSlope = rand(-slopeRange, slopeRange);
46
47
 
47
48
  // draw 1 pixel wide vertical slice of mountain
48
- this.context.drawImage(this.canvas, 0, 0, 1, h, x, y, 1, h - y);
49
+ this.context.drawImage(this.canvas, 0,0,1,h,x,y,1,h-y);
49
50
  }
50
51
 
51
52
  // remove gradient sliver from left side
52
53
  this.context.clearRect(0,0,1,h);
53
54
 
54
55
  // make WebGL texture
55
- this.useWebGL(glEnable);
56
+ this.useWebGL();
56
57
  }
57
58
 
58
59
  render()
@@ -4,25 +4,25 @@ function gameInit()
4
4
 
5
5
  // fire
6
6
  new ParticleEmitter(
7
- vec2(-5,-2), 0, // pos, angle
8
- 2, 0, 200, PI, // emitSize, emitTime, emitRate, emitCone
9
- tile(0), // tileInfo
10
- rgb(1,.5,.1), rgb(1,.1,.1), // colorStartA, colorStartB
11
- rgb(1,.5,.1,0), rgb(1,.1,.1,0), // colorEndA, colorEndB
12
- .7, 2, 0, .2, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
13
- .9, 1, -1, PI, .05, // damp, angleDamp, gravity, particleCone, fade
14
- .5, 0, 1, 0 // randomness, collide, additive, colorLinear
7
+ vec2(-5,-2), 0, // pos, angle
8
+ 2, 0, 200, PI, // emitSize, emitTime, rate, cone
9
+ tile(0), // tileInfo
10
+ rgb(1,.5,.1), rgb(1,.1,.1), // colorStartA, colorStartB
11
+ rgb(1,.5,.1,0), rgb(1,.1,.1,0),// colorEndA, colorEndB
12
+ .7, 2, 0, .2, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
13
+ .9, 1, -1, PI, .05,// damp, angleDamp, gravity, particleCone, fade
14
+ .5, 0, 1, 0 // randomness, collide, additive, colorLinear
15
15
  );
16
16
 
17
17
  // smoke
18
18
  new ParticleEmitter(
19
19
  vec2(5,-2), 0, // pos, angle
20
- 3, 0, 100, PI, // emitSize, emitTime, emitRate, emitCone
21
- tile(0), // tileInfo
22
- hsl(0,0,0,.5), hsl(0,0,1,.5), // colorStartA, colorStartB
23
- hsl(0,0,0,0), hsl(0,0,1,0), // colorEndA, colorEndB
24
- 1, 1, 5, .2, .01, // time, sizeStart, sizeEnd, speed, angleSpeed
25
- .85, 1, -1, PI, .3, // damp, angleDamp, gravity, particleCone, fade
26
- .5, 0, 0, 1 // randomness, collide, additive, colorLinear
20
+ 3, 0, 100, PI, // emitSize, emitTime, rate, cone
21
+ tile(0), // tileInfo
22
+ hsl(0,0,0,.5), hsl(0,0,1,.5),// colorStartA, colorStartB
23
+ hsl(0,0,0,0), hsl(0,0,1,0), // colorEndA, colorEndB
24
+ 1, 1, 5, .2, .01, // time, sizeStart, sizeEnd, speed, angleSpeed
25
+ .85, 1, -1, PI, .3,// damp, angleDamp, gravity, particleCone, fade
26
+ .5, 0, 0, 1 // randomness, collide, additive, colorLinear
27
27
  );
28
28
  }
@@ -2,29 +2,21 @@ const pianoSound = new Sound([,0,220,,9]);
2
2
 
3
3
  class PianoKey extends UIButton
4
4
  {
5
- constructor(pos, size, semitone, isWhite)
5
+ constructor(pos, size, semitone, color, hoverColor)
6
6
  {
7
7
  const keySize = 65;
8
8
  size = size.scale(keySize);
9
9
  pos = pos.scale(keySize).add(vec2(0,size.y/2-keySize*2));
10
10
  pos = pos.add(mainCanvasSize.scale(.5));
11
- super(pos, size, '', hsl(0,0,isWhite ? 1 : .3));
12
- this.semitone = semitone;
11
+ super(pos, size, '', color);
12
+
13
13
  this.dragActivate = true;
14
- this.hoverColor = hsl(0,1,isWhite ? .9 : .3);
14
+ this.semitone = semitone;
15
+ this.hoverColor = hoverColor;
15
16
  this.activeColor = RED;
16
17
  }
17
- onPress()
18
- {
19
- if (!this.soundInstance)
20
- this.soundInstance = pianoSound.playNote(this.semitone);
21
- }
22
- onRelease()
23
- {
24
- if (this.soundInstance)
25
- this.soundInstance.stop(.2);
26
- this.soundInstance = 0;
27
- }
18
+ onPress() { this.sound = pianoSound.playNote(this.semitone); }
19
+ onRelease() { this.sound.stop(.2); }
28
20
  }
29
21
 
30
22
  function gameInit()
@@ -35,16 +27,18 @@ function gameInit()
35
27
  // create piano keyboard
36
28
  for (let i=15; i--;)
37
29
  {
38
- const pos = vec2(i-7,0);
39
- const size = vec2(1,4);
30
+ // white keys
31
+ const pos = vec2(i-7, 0);
32
+ const size = vec2(1, 4);
40
33
  const semitone = [0,2,4,5,7,9,11][i%7]+(i/7|0)*12;
41
- new PianoKey(pos, size, semitone, true);
34
+ new PianoKey(pos, size, semitone, WHITE, hsl(0,1,.9));
42
35
  }
43
36
  for (let i=10; i--;)
44
37
  {
45
- const pos = vec2([1,2,4,5,6][i%5]+(i/5|0)*7-7.5,0)
46
- const size = vec2(1,2);
38
+ // black keys
39
+ const pos = vec2([1,2,4,5,6][i%5]+(i/5|0)*7-7.5, 0)
40
+ const size = vec2(1, 2);
47
41
  const semitone = [1,3,6,8,10][i%5]+(i/5|0)*12;
48
- new PianoKey(pos, size, semitone);
42
+ new PianoKey(pos, size, semitone, hsl(0,0,.3), hsl(0,1,.3));
49
43
  }
50
44
  }
@@ -18,10 +18,12 @@ function gameInit()
18
18
  canvasFixedSize = vec2(1280, 720); // use a 720p fixed size canvas
19
19
 
20
20
  // create objects
21
- paddle = new PhysicsObject(vec2(0,1), vec2(6,1)); // create player's paddle
22
- new PhysicsObject(vec2(-.5,levelSize.y/2), vec2(1,100)); // left wall
23
- new PhysicsObject(vec2(levelSize.x+.5,levelSize.y/2), vec2(1,100)); // right wall
24
- new PhysicsObject(vec2(levelSize.x/2,levelSize.y+.5), vec2(100,1)); // top wall
21
+ paddle = new PhysicsObject(vec2(0,1), vec2(6,1)); // player
22
+
23
+ const w = levelSize.x, h = levelSize.y;
24
+ new PhysicsObject(vec2(-.5,h/2), vec2(1,100)); // left wall
25
+ new PhysicsObject(vec2(w+.5,h/2), vec2(1,100)); // right wall
26
+ new PhysicsObject(vec2(w/2,h+.5), vec2(100,1)); // top wall
25
27
  }
26
28
 
27
29
  function gameUpdate()
@@ -45,7 +45,7 @@ function gameRender()
45
45
  {
46
46
  // draw horizontal slizes to create floor and ceiling
47
47
  const h = 9;
48
- let pos = vec2(), size = vec2(39, .15), color = WHITE;
48
+ let pos = vec2(), size = vec2(39, .15), color = rgb();
49
49
  for (let y=-h; y<h; y+=.1)
50
50
  {
51
51
  const p = 1.01-abs(y/h)
@@ -57,7 +57,7 @@ function gameRender()
57
57
  {
58
58
  // draw vertical slices to create the walls
59
59
  const w = 20;
60
- const pos = vec2(), size = vec2(.15), color = WHITE;
60
+ const pos = vec2(), size = vec2(.15), color = rgb();
61
61
  for (let x=-w; x<w; x+=.1)
62
62
  {
63
63
  const p = raycast(playerPos, playerAngle + x/w);
@@ -68,7 +68,12 @@ function gameRender()
68
68
  }
69
69
  }
70
70
  // draw instructions and pointer lock status
71
- const instructions = pointerLockIsActive() ? 'Mouse Control Active - ESC To Exit' : 'Click To Enable Mouse Control';
71
+ const instructions = pointerLockIsActive() ?
72
+ 'Mouse Control Active - ESC To Exit' :
73
+ 'Click To Enable Mouse Control';
74
+ const textPos = vec2(mainCanvasSize.x/2, 50);
75
+ const textSize = 24;
76
+ const textColor = pointerLockIsActive() ? GREEN : WHITE;
72
77
  if (!isTouchDevice)
73
- drawTextScreen(instructions, vec2(mainCanvasSize.x/2, 50), 24, pointerLockIsActive() ? GREEN : WHITE);
78
+ drawTextScreen(instructions, textPos, textSize, textColor);
74
79
  }
@@ -0,0 +1,122 @@
1
+ const stepCount = 8, trackCount = 12, sequencer = [];
2
+ let currentStep = 0, stepTime = 0, tempo = 240;
3
+ let isPlaying = false, eraseMode = false;
4
+
5
+ // sound sequencer instruments
6
+ const sound_piano = new Sound([.3,0,220,,.1]);
7
+ const sound_drumKick = new Sound([,,99,,,.02,,,,,,,,2]);
8
+ const sound_drumHat = new Sound([,,1e3,,,.01,4,,,,,,,,,,,,,,4e3]);
9
+
10
+ // musical note scales
11
+ const majorScale = [0,2,4,5,7,9,11];
12
+ const minorScale = [0,2,3,5,7,8,10];
13
+ const pentatonicScale = [0,3,5,7,10];
14
+ const scale = majorScale;
15
+
16
+ class UISequencerButton extends UIButton
17
+ {
18
+ constructor(step, track)
19
+ {
20
+ const size = vec2(68, 35);
21
+ let pos = vec2(step, trackCount-1-track);
22
+ pos = pos.multiply(size);
23
+ pos = pos.add(vec2(240, 40));
24
+ super(pos, size);
25
+
26
+ this.step = step;
27
+ this.track = track;
28
+ this.cornerRadius = 0;
29
+ this.dragActivate = true;
30
+ this.isOn = false;
31
+
32
+ // set instrument and color based on track
33
+ const pianoStart = 2;
34
+ this.hue = track*.15;
35
+ if (track >= pianoStart)
36
+ {
37
+ const octave = Math.floor((track-pianoStart) / scale.length);
38
+ const scaleNote = (track-pianoStart) % scale.length;
39
+ this.semitone = scale[scaleNote] + 12*octave;
40
+ this.sound = sound_piano;
41
+ this.hue = .6 - scaleNote/40 + octave*.2;
42
+ }
43
+ else
44
+ this.sound = [sound_drumKick, sound_drumHat][track];
45
+ }
46
+ onPress()
47
+ {
48
+ // set the button on/off and update sequencer table
49
+ if (mouseWasPressed(0))
50
+ eraseMode = this.isOn;
51
+ this.isOn = !eraseMode;
52
+ eraseMode || this.playSound();
53
+ const index = this.step + this.track*stepCount;
54
+ sequencer[index] = eraseMode ? 0 : this;
55
+ }
56
+ render()
57
+ {
58
+ this.activeColor = eraseMode ? RED : WHITE;
59
+ this.color = this.isActiveObject() ? BLACK :
60
+ hsl(this.hue, this.isOn ? 1 : .5, this.isOn ? .5 : .15);
61
+ if (isPlaying && this.step == currentStep)
62
+ this.color = this.color.lerp(WHITE, .5);
63
+ super.render();
64
+ }
65
+ playSound() { this.sound.playNote(this.semitone); }
66
+ }
67
+
68
+ function gameInit()
69
+ {
70
+ // initialize UI system
71
+ new UISystemPlugin;
72
+ uiSystem.defaultCornerRadius = 8;
73
+ canvasClearColor = hsl(0,0,.3);
74
+
75
+ // create sequencer buttons
76
+ for (let step=stepCount; step--;)
77
+ for (let track=trackCount; track--;)
78
+ new UISequencerButton(step, track);
79
+
80
+ // create play/stop button
81
+ const playButton = new UIButton(vec2(660,500), vec2(180,60), 'PLAY');
82
+ playButton.onClick = ()=>
83
+ {
84
+ isPlaying = !isPlaying;
85
+ currentStep = stepTime = 0;
86
+ playButton.text = isPlaying ? 'STOP' : 'PLAY';
87
+ };
88
+
89
+ // create tempo slider
90
+ const minTempo = 120, maxTempo = 480;
91
+ const tempoPercent = percent(tempo, minTempo, maxTempo);
92
+ const tempoSlider = new UIScrollbar(vec2(380,500), vec2(340,40), tempoPercent);
93
+ tempoSlider.onChange = ()=>
94
+ {
95
+ tempo = lerp(minTempo, maxTempo, tempoSlider.value);
96
+ tempo = Math.floor(tempo/10) * 10; // round to nearest 10th
97
+ tempoSlider.text = `${tempo} BPM`;
98
+ };
99
+ tempoSlider.onChange();
100
+ }
101
+
102
+ function gameUpdate()
103
+ {
104
+ if (!isPlaying)
105
+ return;
106
+
107
+ // update step time based on tempo
108
+ const lastStepTime = stepTime;
109
+ const lastStep = currentStep;
110
+ stepTime += timeDelta*tempo/60;
111
+ currentStep = Math.floor(stepTime) % stepCount;
112
+ if (currentStep == lastStep && lastStepTime)
113
+ return;
114
+
115
+ // play sounds when step changes
116
+ for (let i=trackCount; i--;)
117
+ {
118
+ const index = currentStep + i*stepCount;
119
+ const noteButton = sequencer[index];
120
+ noteButton && noteButton.playSound();
121
+ }
122
+ }
@@ -0,0 +1,29 @@
1
+ const shader = `
2
+ void mainImage(out vec4 c, vec2 p)
3
+ {
4
+ // normalize coordinates
5
+ vec2 uv = (p - iResolution.xy * .5) / iResolution.y;
6
+
7
+ // get distance and angle from center
8
+ float distance = length(uv);
9
+ float angle = atan(uv.y, uv.x);
10
+
11
+ // color based on angle and distance
12
+ c.rgb = vec3(
13
+ .5 + .5 * sin(angle + iTime),
14
+ .5 + .5 * sin(angle + iTime * 2.),
15
+ .5 + .5 * sin(distance * 5. - iTime)
16
+ );
17
+
18
+ // apply glow in center
19
+ c += .1 / (distance + .1);
20
+
21
+ // apply sine wave brightness
22
+ c *= .5 + .5 * sin(distance * 20. - iTime * 3.);
23
+ }
24
+ `;
25
+
26
+ function gameInit()
27
+ {
28
+ new PostProcessPlugin(shader);
29
+ }
@@ -7,12 +7,15 @@ function gameRender()
7
7
 
8
8
  // polygon shapes
9
9
  drawRectGradient(vec2(-6,0), vec2(5,4), RED, BLUE)
10
- drawRegularPoly(vec2(0,0), vec2(4), 3, PURPLE, .2, WHITE, time);
11
- const starPath = [vec2(0,2), vec2(2,-2), vec2(-3,.5), vec2(3,.5), vec2(-2,-2), vec2(0,2)];
12
- drawLineList(starPath, .2, GREEN, true, vec2(6, 0));
10
+ drawRegularPoly(vec2(0,0), vec2(4), 3, PURPLE, .3, WHITE, time);
11
+ let starPath = []
12
+ for (let i=10; i--;)
13
+ starPath.push(vec2(0,2*(i%2?.4:1)).rotate(i/10*PI*2));
14
+ drawPoly(starPath, BLUE, .1, GREEN, vec2(6, 0));
13
15
 
14
16
  // rects and lines
15
17
  drawRect(vec2(0,-5), vec2(4,3), ORANGE, time);
16
18
  drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1,.5));
17
- drawLineList([vec2(5,-3), vec2(-5,-3), vec2(5,-7), vec2(-5,-7)], .2, MAGENTA);
19
+ const zPath = [vec2(5,-3), vec2(-5,-3), vec2(5,-7), vec2(-5,-7)];
20
+ drawLineList(zPath, .4, MAGENTA);
18
21
  }
@@ -19,7 +19,8 @@ class PuzzlePiece extends EngineObject
19
19
  {
20
20
  const deltaX = emptyGridPos.x - this.gridPos.x;
21
21
  const deltaY = emptyGridPos.y - this.gridPos.y;
22
- if (mouseWasPressed(0) && isOverlapping(this.pos, this.size, mousePos))
22
+ if (mouseWasPressed(0))
23
+ if (isOverlapping(this.pos, this.size, mousePos))
23
24
  if (abs(deltaX) + abs(deltaY) === 1)
24
25
  {
25
26
  // swap with empty space when clicked on
@@ -32,7 +33,8 @@ class PuzzlePiece extends EngineObject
32
33
 
33
34
  render()
34
35
  {
35
- const pos = this.lastPos.lerp(this.pos, this.moveTimer.getPercent());
36
+ const movePercent = this.moveTimer.getPercent();
37
+ const pos = this.lastPos.lerp(this.pos, movePercent);
36
38
  drawRect(pos, this.size, this.color);
37
39
  drawTextOverlay(this.text, pos, 2.5, BLACK);
38
40
  }
@@ -14,13 +14,22 @@ function gameInit()
14
14
  button.textHeight = 100;
15
15
  button.onClick = ()=> sound.play();
16
16
  }
17
- makeSoundButton(vec2(-1, 1),'💰', new Sound([,,1675,,.06,.24,1,1.82,,,837,.06]));
18
- makeSoundButton(vec2( 0, 1),'🥊', new Sound([,,925,.04,.3,.6,1,.3,,6.27,-184,.09,.17]));
19
- makeSoundButton(vec2( 1, 1),'✨', new Sound([,,539,0,.04,.29,1,1.92,,,567,.02,.02,,,,.04]));
20
- makeSoundButton(vec2(-1, 0),'🐁', new Sound([,.2,1e3,.02,,.01,2,,18,,475,.01,.01]));
21
- makeSoundButton(vec2( 0, 0),'🎹', new Sound([1.5,.5,270,,.1,,1,1.5,,,,,,,,.1,.01]));
22
- makeSoundButton(vec2( 1, 0),'🏌️', new Sound([,,150,.05,,.05,,1.3,,,,,,3]));
23
- makeSoundButton(vec2(-1,-1),'🌊', new Sound([,.2,40,.5,,1.5,,11,,,,,,199]));
24
- makeSoundButton(vec2( 0,-1),'🛰️', new Sound([,.5,847,.02,.3,.9,1,1.67,,,-294,.04,.13,,,,.1]));
25
- makeSoundButton(vec2( 1,-1),'⚡', new Sound([,,471,,.09,.47,4,1.06,-6.7,,,,,.9,61,.1,,.82,.1]));
17
+ makeSoundButton(vec2(-1, 1),'💰',
18
+ new Sound([,,1675,,.06,.24,1,1.82,,,837,.06]));
19
+ makeSoundButton(vec2( 0, 1),'🥊',
20
+ new Sound([,,925,.04,.3,.6,1,.3,,6.27,-184,.09,.17]));
21
+ makeSoundButton(vec2( 1, 1),'✨',
22
+ new Sound([,,539,0,.04,.29,1,1.92,,,567,.02,.02,,,,.04]));
23
+ makeSoundButton(vec2(-1, 0),'🐁',
24
+ new Sound([,.2,1e3,.02,,.01,2,,18,,475,.01,.01]));
25
+ makeSoundButton(vec2( 0, 0),'🎹',
26
+ new Sound([1.5,.5,270,,.1,,1,1.5,,,,,,,,.1,.01]));
27
+ makeSoundButton(vec2( 1, 0),'🏌️',
28
+ new Sound([,,150,.05,,.05,,1.3,,,,,,3]));
29
+ makeSoundButton(vec2(-1,-1),'🌊',
30
+ new Sound([,.2,40,.5,,1.5,,11,,,,,,199]));
31
+ makeSoundButton(vec2( 0,-1),'🛰️',
32
+ new Sound([,.5,847,.02,.3,.9,1,1.67,,,-294,.04,.13,,,,.1]));
33
+ makeSoundButton(vec2( 1,-1),'⚡',
34
+ new Sound([,,471,,.09,.47,4,1.06,-6.7,,,,,.9,61,.1,,.82,.1]));
26
35
  }
@@ -15,13 +15,16 @@ class Player extends EngineObject
15
15
  // space ship controls
16
16
  const moveInput = keyDirection();
17
17
  this.applyAngularAcceleration(moveInput.x * .005);
18
- this.applyAcceleration(vec2().setAngle(this.angle, moveInput.y*.02));
19
- if (!this.shootTimer.active() && (keyIsDown('Space') || mouseIsDown(0)))
18
+ const accel = vec2().setAngle(this.angle, moveInput.y*.02);
19
+ this.applyAcceleration(accel);
20
+ if (!this.shootTimer.active())
21
+ if (keyIsDown('Space') || mouseIsDown(0))
20
22
  {
21
23
  // shoot bullet
22
24
  const pos = this.pos.add(vec2(0,1).rotate(cameraAngle));
23
- const bullet = new EngineObject(pos, vec2(.2,.5), 0, this.angle, YELLOW);
24
- bullet.velocity = this.velocity.add(vec2(0,.5).rotate(this.angle));
25
+ const bullet = new EngineObject(pos, vec2(.2,.5), 0, this.angle);
26
+ bullet.velocity = vec2(0,.5).rotate(this.angle);
27
+ bullet.velocity = bullet.velocity.add(this.velocity);
25
28
  this.shootTimer.set(.1);
26
29
  }
27
30
 
@@ -42,14 +45,15 @@ function gameRender()
42
45
  const range = 32, halfRange = range/2;
43
46
 
44
47
  // precreate variables to avoid overhead
45
- const pos = vec2(), size = vec2(), color = WHITE;
48
+ const pos = vec2(), size = vec2(), color = rgb();
49
+ const x = cameraPos.x, y = cameraPos.y;
46
50
  for (let i=1e3; i--;)
47
51
  {
48
52
  // use math to generate random star positions
49
53
  const parallax = i%.13-1;
50
- pos.x = mod(i**2.1 + cameraPos.x*parallax, range) + cameraPos.x - halfRange;
51
- pos.y = mod(i**3.1 + cameraPos.y*parallax, range) + cameraPos.y - halfRange;
52
- size.x = size.y = i%.07+.03;
54
+ pos.x = mod(i**2.1 + x*parallax, range) + x - halfRange;
55
+ pos.y = mod(i**3.1 + y*parallax, range) + y - halfRange;
56
+ size.x = size.y = i%.07 + .03;
53
57
  color.a = .1+i%.9;
54
58
  drawRect(pos, size, color);
55
59
  }
@@ -1,5 +1,4 @@
1
1
  let spriteAtlas;
2
- canvasClearColor = GRAY;
3
2
 
4
3
  function gameInit()
5
4
  {
@@ -13,18 +12,19 @@ function gameInit()
13
12
  circleBig: gameTile(2, 128),
14
13
  iconBig: gameTile(3, 128),
15
14
  };
15
+ canvasClearColor = GRAY;
16
16
  }
17
17
 
18
18
  function gameRender()
19
19
  {
20
20
  // draw a sprite from the atlas
21
- let pos = vec2(Math.sin(time)*5,-3);// world position to draw
22
- let angle = 0; // world space angle to draw the tile
23
- let size = vec2(9); // world size of the tile
21
+ let pos = vec2(Math.sin(time)*5,-3);// world position
22
+ let angle = 0; // world space angle
23
+ let size = vec2(9); // world space size
24
24
  let mirror = 0; // should tile be mirrored?
25
- let color = hsl(0,0,1); // color to multiply the tile by
26
- let additiveColor = hsl(0,0,0,0); // color to add to
27
- drawTile(pos, size, spriteAtlas.iconBig, color, angle, mirror, additiveColor);
25
+ let color = hsl(0,0,1); // color to multiply by
26
+ let additive = hsl(0,0,0,0); // color to add to
27
+ drawTile(pos, size, spriteAtlas.iconBig, color, angle, mirror, additive);
28
28
 
29
29
  // draw more sprites from the atlas
30
30
  drawTile(vec2(-7,4), vec2(5), spriteAtlas.crate);
@@ -1,7 +1,7 @@
1
1
  function gameRender()
2
2
  {
3
3
  // precreate variables to avoid overhead
4
- const pos = vec2(), size = vec2(), color = new Color;
4
+ const pos = vec2(), size = vec2(), color = rgb();
5
5
  for (let i=2e3; i--;)
6
6
  {
7
7
  // use math to generate random star positions
@@ -2,7 +2,7 @@ function gameRender()
2
2
  {
3
3
  // draw text with built in font image system font
4
4
  const font = new FontImage;
5
- font.drawText('System Font Test', cameraPos.add(vec2(0,3)), .2, true);
5
+ font.drawText('System Font Test', cameraPos.add(vec2(0,3)), .2);
6
6
 
7
7
  // show every character in the system font
8
8
  let s = '';
@@ -12,5 +12,5 @@ function gameRender()
12
12
  s += '\n';
13
13
  s += String.fromCharCode(i);
14
14
  }
15
- font.drawText(s, cameraPos, .1, true);
15
+ font.drawText(s, cameraPos, .1);
16
16
  }
@@ -4,8 +4,8 @@ function gameRender()
4
4
  let pos = vec2(0,0); // world position to draw
5
5
  let size = vec2(15); // world size of the tile
6
6
  let color = hsl(0,0,1); // color to multiply the tile by
7
- let tilePos = vec2(0,0); // top left corner of tile in pixels
8
- let tileSize = vec2(256); // size of tile in pixels
7
+ let tilePos = vec2(0,0); // top left corner in pixels
8
+ let tileSize = vec2(256); // source size in pixels
9
9
  let tileInfo = new TileInfo(tilePos, tileSize); // tile info
10
10
  drawRect(pos, size, GRAY); // draw background
11
11
  drawTile(pos, size, tileInfo, color);
@@ -30,19 +30,19 @@ function gameUpdate()
30
30
  {
31
31
  if (mouseWasPressed(0))
32
32
  {
33
- // create particle emitter
33
+ // create particle emitter to test the collision
34
34
  const hue = rand();
35
35
  const particleEmitter = new ParticleEmitter(
36
- mousePos, 0, // emitPos, emitAngle
37
- 0, 0.1, 500, PI, // emitSize, emitTime, emitRate, emitCone
38
- tile(0, 16), // tileIndex, tileSize
39
- hsl(hue,1,.5), hsl(hue,1,1), // colorStartA, colorStartB
40
- hsl(hue,1,.5,0), hsl(hue,1,1,0), // colorEndA, colorEndB
41
- 2, .2, .2, .2, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
42
- .99, 1, 1, PI, // damping, angleDamping, gravityScale, cone
43
- .05, .8, true, false // fadeRate, randomness, collide, additive
36
+ mousePos, 0,
37
+ 0, 0.1, 500, PI,
38
+ tile(0, 16),
39
+ hsl(hue,1,.5), hsl(hue,1,1),
40
+ hsl(hue,1,.5,0), hsl(hue,1,1,0),
41
+ 2, .2, .2, .2, .05,
42
+ .99, 1, 1, PI,
43
+ .05, .8, true
44
44
  );
45
45
  particleEmitter.restitution = .5; // bounce when it collides
46
- particleEmitter.trailScale = 2; // stretch in direction of motion
46
+ particleEmitter.trailScale = 2; // stretch as it moves
47
47
  }
48
48
  }