littlejsengine 1.13.4 → 1.14.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 (58) hide show
  1. package/README.md +4 -3
  2. package/dist/littlejs.d.ts +395 -249
  3. package/dist/littlejs.esm.js +1550 -754
  4. package/dist/littlejs.esm.min.js +1 -1
  5. package/dist/littlejs.js +1528 -744
  6. package/dist/littlejs.min.js +1 -1
  7. package/dist/littlejs.release.js +1504 -720
  8. package/examples/box2d/game.js +4 -4
  9. package/examples/box2d/gameObjects.js +1 -1
  10. package/examples/breakout/game.js +30 -25
  11. package/examples/breakoutTutorial/README.md +1 -1
  12. package/examples/breakoutTutorial/game.js +1 -1
  13. package/examples/electron/build.js +1 -1
  14. package/examples/electron/index.html +2 -2
  15. package/examples/empty/game.js +1 -1
  16. package/examples/htmlMenu/index.html +7 -7
  17. package/examples/index.html +208 -97
  18. package/examples/platformer/gameEffects.js +20 -25
  19. package/examples/platformer/gameLevel.js +6 -1
  20. package/examples/shorts/base.html +1 -1
  21. package/examples/shorts/flappyGame.js +2 -1
  22. package/examples/shorts/helloWorld.js +1 -1
  23. package/examples/shorts/music.js +106 -0
  24. package/examples/shorts/parallax.js +71 -0
  25. package/examples/shorts/piano.js +7 -8
  26. package/examples/shorts/postProcess.js +25 -8
  27. package/examples/shorts/shapes.js +12 -18
  28. package/examples/shorts/song.mp3 +0 -0
  29. package/examples/shorts/uiSystem.js +15 -8
  30. package/examples/starter/index.html +2 -2
  31. package/examples/stress/index.html +14 -7
  32. package/examples/style.css +14 -4
  33. package/examples/typescript/build.js +1 -1
  34. package/examples/uiSystem/game.js +11 -11
  35. package/package.json +1 -1
  36. package/plugins/box2d.js +12 -10
  37. package/plugins/drawUtilities.js +5 -5
  38. package/plugins/newgrounds.js +6 -6
  39. package/plugins/pluginExport.js +1 -1
  40. package/plugins/uiSystem.js +103 -79
  41. package/plugins/zzfxm.js +10 -10
  42. package/reference.md +94 -56
  43. package/src/engine.js +28 -24
  44. package/src/engineAudio.js +284 -109
  45. package/src/engineBuild.js +11 -11
  46. package/src/engineDebug.js +29 -29
  47. package/src/engineDraw.js +285 -112
  48. package/src/engineExport.js +28 -16
  49. package/src/engineInput.js +57 -67
  50. package/src/engineMedals.js +25 -25
  51. package/src/engineObject.js +28 -25
  52. package/src/engineParticles.js +59 -59
  53. package/src/engineRelease.js +1 -1
  54. package/src/engineSettings.js +20 -13
  55. package/src/engineTileLayer.js +34 -35
  56. package/src/engineUtilities.js +66 -59
  57. package/src/engineWebGL.js +466 -66
  58. /package/examples/shorts/{playSound.js → sound.js} +0 -0
@@ -28,6 +28,7 @@ class Player extends EngineObject
28
28
  if (mouseWasPressed(0) || keyWasPressed('Space'))
29
29
  this.velocity = vec2(0,.2);
30
30
  this.angle = -this.velocity.y*2;
31
+ this.pos.y = max(-50, this.pos.y);
31
32
  }
32
33
 
33
34
  collideWithObject(object)
@@ -44,7 +45,7 @@ function gameInit()
44
45
  gravity.y = -.01;
45
46
  for (let i=100; i--;)
46
47
  {
47
- const h=50, y=-h/2-6+rand(9), spacing=15, gap=5;
48
+ const h=100, y=-h/2-6+rand(9), spacing=15, gap=5;
48
49
  new Wall(vec2(14 + i*spacing,y+h + gap), vec2(3,h));
49
50
  new Wall(vec2(14 + i*spacing,y), vec2(3,h));
50
51
  }
@@ -1,7 +1,7 @@
1
1
  function gameRender()
2
2
  {
3
3
  // draw background rect
4
- drawRect(cameraPos, vec2(30), hsl(0,0,.2));
4
+ drawRect(cameraPos, vec2(50), hsl(0,0,.2));
5
5
 
6
6
  // draw text to the overlay canvas
7
7
  drawTextOverlay('Hello World', vec2(0,3), 3);
@@ -0,0 +1,106 @@
1
+ // Music player variables
2
+ let musicSound = new SoundWave('song.mp3');
3
+ let musicVolume = .8;
4
+ let musicInstance;
5
+
6
+ // UI elements
7
+ let playButton, stopButton, progressBar;
8
+
9
+ function gameInit()
10
+ {
11
+ // load ui system plugin
12
+ new UISystemPlugin;
13
+ uiSystem.defaultSoundPress = new Sound([.3,0,220]);
14
+ uiSystem.defaultSoundClick = new Sound([.3,0,440]);
15
+ uiSystem.defaultCornerRadius = 20;
16
+
17
+ // setup music player UI
18
+ const musicPlayer = new UIObject(mainCanvasSize.scale(.5), vec2(500, 300));
19
+
20
+ // title
21
+ const title = new UIText(vec2(0, -100), vec2(500, 40), 'LittleJS Music Player');
22
+ musicPlayer.addChild(title);
23
+
24
+ // volume slider
25
+ const volumeSlider = new UIScrollbar(vec2(0, -40), vec2(400, 30), musicVolume, 'Music Volume');
26
+ musicPlayer.addChild(volumeSlider);
27
+ volumeSlider.onChange = () =>
28
+ {
29
+ musicVolume = volumeSlider.value;
30
+ if (musicInstance)
31
+ musicInstance.setVolume(musicVolume);
32
+ };
33
+
34
+ // play button
35
+ playButton = new UIButton(vec2(-90, 30), vec2(140, 50), 'Play');
36
+ musicPlayer.addChild(playButton);
37
+ playButton.onClick = ()=>
38
+ {
39
+ if (!musicSound.isLoaded())
40
+ return;
41
+
42
+ // handle play/pause toggle
43
+ if (!musicInstance)
44
+ musicInstance = musicSound.playMusic(musicVolume);
45
+ else if (musicInstance.isPaused())
46
+ musicInstance.resume();
47
+ else
48
+ musicInstance.pause();
49
+ };
50
+
51
+ // stop button
52
+ stopButton = new UIButton(vec2(90, 30), vec2(140, 50), 'Stop');
53
+ musicPlayer.addChild(stopButton);
54
+ stopButton.onClick = ()=>
55
+ {
56
+ if (!musicInstance)
57
+ return;
58
+
59
+ // stop sound
60
+ musicInstance.stop();
61
+ };
62
+
63
+ // progress bar and scrollbar for seeking
64
+ progressBar = new UIScrollbar(vec2(0, 100), vec2(400, 30), 0, 'Progress');
65
+ musicPlayer.addChild(progressBar);
66
+ progressBar.onChange = ()=>
67
+ {
68
+ // control music seek position
69
+ const wasPlaying = musicInstance && musicInstance.isPlaying();
70
+ if (!musicInstance)
71
+ musicInstance = musicSound.playMusic(musicVolume, true, true);
72
+ progressBar.value = min(progressBar.value, .999); // prevent looping around
73
+ const seekTime = progressBar.value * musicSound.getDuration();
74
+ musicInstance.start(seekTime);
75
+ if (!wasPlaying)
76
+ musicInstance.pause();
77
+ };
78
+ }
79
+
80
+ function gameUpdate()
81
+ {
82
+ // disable buttons while loading or waiting for interaction
83
+ const isDisabled = !musicSound.isLoaded() || !audioIsRunning();
84
+ playButton.disabled = isDisabled
85
+ stopButton.disabled = isDisabled
86
+ progressBar.disabled = isDisabled
87
+
88
+ // update ui
89
+ if (!musicSound.isLoaded())
90
+ {
91
+ // update loading progress
92
+ const loadingPercent = musicSound.loadedPercent * 100;
93
+ progressBar.text = `Loading: ${(loadingPercent).toFixed(2)}%`;
94
+ }
95
+ else
96
+ {
97
+ // update ui text
98
+ playButton.text = !musicInstance || !musicInstance.isPlaying() ? 'Play' : 'Pause';
99
+ const currentTime = musicInstance ? musicInstance.getCurrentTime() : 0;
100
+ const duration = musicSound.getDuration();
101
+ if (!progressBar.mouseIsHeld)
102
+ progressBar.value = currentTime / duration;
103
+ const timeText = `${formatTime(currentTime)} / ${formatTime(duration)}`;
104
+ progressBar.text = audioIsRunning() ? timeText : 'Click to Enable Audio';
105
+ }
106
+ }
@@ -0,0 +1,71 @@
1
+ function gameInit()
2
+ {
3
+ // create parallax layers
4
+ const levelColor = hsl(rand(), .5, .5);
5
+ for (let i=3; i--;)
6
+ {
7
+ const topColor = levelColor.mutate(.3);
8
+ const bottomColor = levelColor.subtract(CLEAR_WHITE).mutate(.3);
9
+ new ParallaxLayer(topColor, bottomColor, i);
10
+ }
11
+ }
12
+
13
+ class ParallaxLayer extends CanvasLayer
14
+ {
15
+ constructor(topColor, bottomColor, depth)
16
+ {
17
+ const renderOrder = depth;
18
+ const canvasSize = vec2(512, 256);
19
+ super(vec2(), vec2(), 0, renderOrder, canvasSize);
20
+ this.depth = depth;
21
+
22
+ // create a gradient for the mountains
23
+ const w = canvasSize.x, h = canvasSize.y;
24
+ for (let i = h; i--;)
25
+ {
26
+ // draw a 1 pixel gradient line on the left side of the canvas
27
+ const p = i/h;
28
+ this.context.fillStyle = topColor.lerp(bottomColor, p);
29
+ this.context.fillRect(0, i, 1, 1);
30
+ }
31
+
32
+ // draw random mountains
33
+ const pointiness = .2; // how pointy the mountains are
34
+ const levelness = .005; // how much the mountains level out
35
+ const slopeRange = 1; // max slope of the mountains
36
+ const startGroundLevel = h/2;
37
+ let y = startGroundLevel, groundSlope = rand(-slopeRange, slopeRange);
38
+ for (let x=w; x--;)
39
+ {
40
+ // pull slope towards start ground level
41
+ y += groundSlope -= (y-startGroundLevel)*levelness;
42
+
43
+ // randomly change slope
44
+ if (rand() < pointiness)
45
+ groundSlope = rand(-slopeRange, slopeRange);
46
+
47
+ // draw 1 pixel wide vertical slice of mountain
48
+ this.context.drawImage(this.canvas, 0, 0, 1, h, x, y, 1, h - y);
49
+ }
50
+
51
+ // remove gradient sliver from left side
52
+ this.context.clearRect(0,0,1,h);
53
+
54
+ // make WebGL texture
55
+ this.useWebGL(glEnable);
56
+ }
57
+
58
+ render()
59
+ {
60
+ const canvasSize = vec2(this.canvas.width, this.canvas.height);
61
+ const viewerPos = mousePos;
62
+ const depth = this.depth
63
+ const distance = 3 + depth;
64
+ const parallax = vec2(.2, .05).scale(depth**2+1);
65
+ const cameraDeltaFromCenter = viewerPos.multiply(parallax);
66
+ const positonOffset = vec2(0, 4-depth*3);
67
+ this.pos = cameraDeltaFromCenter.add(positonOffset)
68
+ this.size = canvasSize.scale(distance/cameraScale);
69
+ super.render();
70
+ }
71
+ }
@@ -13,19 +13,18 @@ class PianoKey extends EngineObject
13
13
  }
14
14
  press()
15
15
  {
16
- if (!this.isDown)
17
- pianoSound.playNote(this.semitone);
18
- this.isDown = true;
16
+ if (!this.soundInstance)
17
+ this.soundInstance = pianoSound.playNote(this.semitone);
19
18
  }
20
19
  release()
21
20
  {
22
- if (this.isDown)
23
- pianoSound.stop(.2);
24
- this.isDown = false;
21
+ if (this.soundInstance)
22
+ this.soundInstance.stop(.2);
23
+ this.soundInstance = 0;
25
24
  }
26
25
  render()
27
26
  {
28
- const color = this.isDown ? RED : this.color;
27
+ const color = this.soundInstance ? RED : this.color;
29
28
  drawRect(this.pos, this.drawSize, color);
30
29
  }
31
30
  }
@@ -42,7 +41,7 @@ function gameInit()
42
41
  function gameUpdate()
43
42
  {
44
43
  // update state of piano keys
45
- const pressedKey = keys.find(k=>k.isDown);
44
+ const pressedKey = keys.find(k=>k.soundInstance);
46
45
  const newPressedKey = mouseIsDown(0) && keys.find(k=>isOverlapping(k.pos, k.size, mousePos));
47
46
  if (newPressedKey != pressedKey)
48
47
  {
@@ -6,7 +6,7 @@ function gameInit()
6
6
  function gameRender()
7
7
  {
8
8
  drawRect(vec2(), vec2(99), GRAY);
9
- drawTile(vec2(), vec2(12), tile(3,128));
9
+ drawTile(vec2(Math.sin(time)*3, 0), vec2(12), tile(3,128));
10
10
  }
11
11
 
12
12
  const tvShader = `
@@ -16,27 +16,44 @@ float hash(vec2 p)
16
16
  p=fract(p*.3197);
17
17
  return fract(1.+sin(51.*p.x+73.*p.y)*13753.3);
18
18
  }
19
- float noise(vec2 p)
20
- {
21
- vec2 i=floor(p),f=fract(p),u=f*f*(3.-2.*f);
22
- return mix(mix(hash(i),hash(i+vec2(1,0)),u.x),mix(hash(i+vec2(0,1)),hash(i+1.),u.x),u.y);
23
- }
19
+
24
20
  void mainImage(out vec4 c, vec2 p)
25
21
  {
26
22
  // setup the shader
23
+ vec2 uv = p;
27
24
  p /= iResolution.xy;
28
25
  c = texture(iChannel0, p);
29
26
 
30
27
  // static noise
31
28
  const float staticAlpha = .1;
32
- const float staticScale = .005;
29
+ const float staticScale = .002;
33
30
  c += staticAlpha * hash(floor(p/staticScale) + mod(iTime*500., 1e3));
34
31
 
35
32
  // scan lines
36
33
  const float scanlineScale = 2.;
37
- const float scanlineAlpha = .3;
34
+ const float scanlineAlpha = .5;
38
35
  c *= 1. - scanlineAlpha*cos(p.y*2.*iResolution.y/scanlineScale);
39
36
 
37
+ {
38
+ // bloom effect
39
+ const float blurSize = .002;
40
+ const float bloomIntensity = .2;
41
+
42
+ // 5-tap Gaussian blur
43
+ vec4 bloom = vec4(0);
44
+ bloom += texture(iChannel0, p + vec2(-2.*blurSize, 0)) * .12;
45
+ bloom += texture(iChannel0, p + vec2( -blurSize, 0)) * .24;
46
+ bloom += texture(iChannel0, p) * .28;
47
+ bloom += texture(iChannel0, p + vec2( blurSize, 0)) * .24;
48
+ bloom += texture(iChannel0, p + vec2( 2.*blurSize, 0)) * .12;
49
+ bloom += texture(iChannel0, p + vec2(0, -2.*blurSize)) * .12;
50
+ bloom += texture(iChannel0, p + vec2(0, -blurSize)) * .24;
51
+ bloom += texture(iChannel0, p) * .28;
52
+ bloom += texture(iChannel0, p + vec2(0, blurSize)) * .24;
53
+ bloom += texture(iChannel0, p + vec2(0, 2.*blurSize)) * .12;
54
+ c += bloom * bloomIntensity;
55
+ }
56
+
40
57
  // black vignette around edges
41
58
  const float vignette = 2.;
42
59
  const float vignettePow = 6.;
@@ -1,24 +1,18 @@
1
1
  function gameRender()
2
2
  {
3
- // polygon shapes
4
- for (let j=3; j<7; ++j)
5
- {
6
- let points = [];
7
- for (let i=0; i<j; ++i)
8
- {
9
- let angle = i * Math.PI * 2 / j;
10
- points.push(vec2(j*4-18,0).add(vec2(0,1).rotate(angle)));
11
- }
12
- drawPoly(points, hsl(j/4+time/9,1,.5)); // draw a regular polygon
13
- }
14
-
15
3
  // circles and ellipses
16
- drawCircle(vec2(0,5), 1+wave(.5), hsl(.15,1,.5));
17
- drawEllipse(vec2(-5,5), vec2(2,1), hsl(0,1,.5));
18
- drawEllipse(vec2(5,5), vec2(.5,2), hsl(.55,1,.5), .5);
4
+ drawCircle(vec2(0,5), 1+wave(.5), RED);
5
+ drawEllipse(vec2(-6,5), vec2(1,1), YELLOW, .5);
6
+ drawEllipse(vec2(6,5), vec2(1,2), CLEAR_BLACK, .3, .5, CYAN)
7
+
8
+ // polygon shapes
9
+ drawRectGradient(vec2(-6,0), vec2(5,4), RED, BLUE)
10
+ drawRegularPoly(vec2(0,0), vec2(2), 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, MAGENTA, true, vec2(6, 0));
19
13
 
20
14
  // rects and lines
21
- drawRect(vec2(0,-5), vec2(4,3), hsl(.6,1,.5), time);
22
- drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1, .5));
23
- drawLine(vec2(-5,-3), vec2(5,-7), .2, hsl(1,1,.5));
15
+ drawRect(vec2(0,-5), vec2(4,3), ORANGE, time);
16
+ 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, GREEN);
24
18
  }
Binary file
@@ -11,26 +11,33 @@ function gameInit()
11
11
  uiSystem.defaultCornerRadius = 8;
12
12
 
13
13
  // setup example menu
14
- uiMenu = new UIObject(mainCanvasSize.scale(.5));
15
- const uiBackground = new UIObject(vec2(), vec2(400));
16
- uiMenu.addChild(uiBackground);
14
+ uiBackground = new UIObject(mainCanvasSize.scale(.5), vec2(1e5));
15
+ uiBackground.color = hsl(0,0,.8);
16
+ const uiMenu = new UIObject(vec2(), vec2(450));
17
+ uiBackground.addChild(uiMenu);
17
18
 
18
19
  // example text
19
- const textTitle = new UIText(vec2(0,-100), vec2(400, 60), 'LittleJS UI\nSystem Demo');
20
+ const textTitle = new UIText(vec2(0,-120), vec2(400, 60), 'LittleJS UI\nSystem Demo');
20
21
  uiMenu.addChild(textTitle);
21
22
 
22
23
  // example button
23
- const button1 = new UIButton(vec2(70,40), vec2(100), 'Test');
24
- button1.textHeight = 40;
24
+ const button1 = new UIButton(vec2(70,0), vec2(140, 80), 'Test');
25
+ button1.textHeight = 60;
25
26
  uiMenu.addChild(button1);
26
27
  button1.onClick = ()=> uiBackground.color = randColor();
27
28
 
28
29
  // example checkbox
29
- const checkbox = new UICheckbox(vec2(-70,40), vec2(50));
30
+ const checkbox = new UICheckbox(vec2(-70,0), vec2(50));
31
+ checkbox.onChange = ()=> button1.disabled = checkbox.checked;
30
32
  uiMenu.addChild(checkbox);
31
33
 
34
+ // example scrollbar
35
+ const scrollbar = new UIScrollbar(vec2(0,90), vec2(300, 50), soundVolume, 'Volume');
36
+ uiMenu.addChild(scrollbar);
37
+ scrollbar.onChange = ()=> setSoundVolume(scrollbar.value);
38
+
32
39
  // exit button
33
- const button2 = new UIButton(vec2(0,140), vec2(300, 50), 'Exit Menu');
40
+ const button2 = new UIButton(vec2(0,170), vec2(300, 50), 'Exit Menu');
34
41
  button2.textHeight = 40;
35
42
  uiMenu.addChild(button2);
36
43
  button2.onClick = ()=> uiMenu.visible = false;
@@ -7,7 +7,7 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- LittleJS Engine -->
10
- <script src=../../dist/littlejs.js?1133></script>
10
+ <script src=../../dist/littlejs.js?1136></script>
11
11
 
12
12
  <!-- LittleJS Engine Source
13
13
  <script src=../../src/engineDebug.js></script>
@@ -31,4 +31,4 @@
31
31
  -->
32
32
 
33
33
  <!-- Add your game scripts here -->
34
- <script src=game.js?1133></script>
34
+ <script src=game.js?1136></script>
@@ -21,7 +21,7 @@ import * as LJS from '../../dist/littlejs.esm.min.js';
21
21
  const {vec2, rgb} = LJS;
22
22
 
23
23
  // keep our own list of simple sprites and track fps
24
- let sprites, tileLayer, timeMS, fpsDisplay, statsDisplay, spriteColor, spriteAdditiveColor;
24
+ let sprites, tileLayer, timeMS, fpsDisplay, statsDisplay, spriteColor, spriteAdditiveColor, musicInstance, hasClicked;
25
25
 
26
26
  ///////////////////////////////////////////////////////////////////////////////
27
27
 
@@ -59,16 +59,14 @@ function gameInit()
59
59
  ///////////////////////////////////////////////////////////////////////////////
60
60
  function gameUpdate()
61
61
  {
62
- if (LJS.mouseWasPressed(0) && !music.getSource())
63
- music.play();
64
-
65
62
  // mouse click = change color
66
63
  if (LJS.mouseWasPressed(0) || LJS.mouseIsDown(2))
67
64
  {
65
+ hasClicked = true;
68
66
  spriteColor = LJS.randColor();
69
67
  spriteAdditiveColor = LJS.randColor(rgb(.5,.5,.5, 0), rgb(0,0,0,0));
70
68
  }
71
-
69
+
72
70
  // right click = drop test object
73
71
  if (LJS.mouseIsDown(2))
74
72
  new TestObject(LJS.mousePos);
@@ -87,9 +85,18 @@ function gameUpdate()
87
85
  additiveColor:spriteAdditiveColor.rgbaInt()
88
86
  });
89
87
  }
90
-
88
+
91
89
  // mouse wheel = zoom
92
90
  LJS.setCameraScale(LJS.clamp(LJS.cameraScale*(1-LJS.mouseWheel/10), 1, 1e3));
91
+
92
+ // mouse click = play music
93
+ if (hasClicked)
94
+ {
95
+ if (!musicInstance)
96
+ musicInstance = music.play();
97
+ else if (!musicInstance.isPlaying())
98
+ musicInstance.start();
99
+ }
93
100
  }
94
101
 
95
102
  ///////////////////////////////////////////////////////////////////////////////
@@ -162,5 +169,5 @@ LJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost,
162
169
 
163
170
  ///////////////////////////////////////////////////////////////////////////////
164
171
  // music - Depp Loop
165
- const music = new LJS.ZzFXMusic([[[.6,0,43,,,1,1,.5,,,,,.1,,,.05,,.5,.4,.2],[,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]]);
172
+ const music = new LJS.ZzFXMusic([[[.6,0,77,,,1,1,.5,,,,,.1,,,.05,,.5,.4,.2],[,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]]);
166
173
  </script>
@@ -30,22 +30,27 @@ iframe
30
30
  #selectExample
31
31
  {
32
32
  flex-grow: 1;
33
+ min-height: 100px;
34
+ }
35
+ #divTextareas
36
+ {
37
+ flex-grow: 1;
38
+ display: flex;
39
+ flex-direction: column;
40
+ min-height: 300px;
33
41
  }
34
42
  .CodeMirror,
35
43
  #textareaCode
36
44
  {
37
45
  flex-grow: 1;
38
- padding: 5px;
39
46
  resize: none;
40
47
  color: #fff;
41
48
  background: #000;
42
- font-size: 20px;
43
49
  }
44
50
  #textareaConsole,
45
51
  #textareaError
46
52
  {
47
53
  flex-grow: .3;
48
- padding: 5px;
49
54
  resize: none;
50
55
  display: none;
51
56
  color:#f22;
@@ -79,9 +84,10 @@ iframe
79
84
  {
80
85
  margin: 0px;
81
86
  text-align: center;
82
- font-size: 20px;
87
+ font-size: 15px;
83
88
  display: inline-block;
84
89
  align-self: center;
90
+ font-style: italic;
85
91
  }
86
92
  select
87
93
  {
@@ -117,6 +123,10 @@ input[type='checkbox']:disabled
117
123
  {
118
124
  background-color: #f004 !important;
119
125
  }
126
+ .nowrap
127
+ {
128
+ white-space:nowrap;
129
+ }
120
130
 
121
131
  /* LittleJS CodeMirror Theme */
122
132
  .cm-s-littlejs.CodeMirror { background: #080808; color: #aef; }
@@ -23,7 +23,7 @@ fs.rmSync(BUILD_FOLDER, { recursive: true, force: true });
23
23
  console.log(`Compiling TypeScript...`);
24
24
  // Compile all TypeScript files at once
25
25
  const tsFiles = tsSourceFiles.join(' ');
26
- child_process.execSync(`npx tsc ${tsFiles} --outDir "./${BUILD_FOLDER}" --target es2020 --module es2020`, {stdio: 'inherit'});
26
+ child_process.execSync(`npx tsc ${tsFiles} --outDir './${BUILD_FOLDER}' --target es2020 --module es2020`, {stdio: 'inherit'});
27
27
  console.log(`TypeScript built in ${((Date.now() - startTime)/1e3).toFixed(2)} seconds!`);
28
28
 
29
29
  console.log(`Moving js files back to root...`);
@@ -54,26 +54,26 @@ function createUI()
54
54
  // example tile image
55
55
  const tileTest = new LJS.UITile(vec2(150,-130), vec2(110), tile(3,128))
56
56
  uiMenu.addChild(tileTest);
57
-
58
- // example checkbox
59
- const checkbox = new LJS.UICheckbox(vec2(-140,-20), vec2(40));
60
- uiMenu.addChild(checkbox);
61
- checkbox.onChange = ()=> console.log('Checkbox clicked');
62
-
63
- // text attached to checkbox
64
- const checkboxText = new LJS.UIText(vec2(170,0), vec2(300, 40), 'Test Checkbox');
65
- checkbox.addChild(checkboxText);
66
-
67
57
  // example scrollbar
68
58
  const scrollbar = new LJS.UIScrollbar(vec2(0,60), vec2(350, 50));
69
59
  uiMenu.addChild(scrollbar);
70
- scrollbar.onChange = ()=> console.log('New scrollbar value:', scrollbar.value);
60
+ scrollbar.onChange = ()=> scrollbar.text = scrollbar.value.toFixed(2)
61
+ scrollbar.onChange();
71
62
 
72
63
  // example button
73
64
  const button1 = new LJS.UIButton(vec2(0,140), vec2(350, 50), 'Test Button');
74
65
  uiMenu.addChild(button1);
75
66
  button1.onClick = ()=> console.log('Button 1 clicked');
76
67
 
68
+ // example checkbox
69
+ const checkbox = new LJS.UICheckbox(vec2(-140,-20), vec2(40));
70
+ uiMenu.addChild(checkbox);
71
+ checkbox.onChange = ()=> button1.disabled = checkbox.checked;
72
+
73
+ // text attached to checkbox
74
+ const checkboxText = new LJS.UIText(vec2(170,0), vec2(300, 40), 'Test Checkbox');
75
+ checkbox.addChild(checkboxText);
76
+
77
77
  // exit button
78
78
  const button2 = new LJS.UIButton(vec2(0,220), vec2(350, 50), 'Exit Menu');
79
79
  uiMenu.addChild(button2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.13.4",
3
+ "version": "1.14.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
@@ -88,14 +88,14 @@ class Box2dObject extends EngineObject
88
88
  if (this.tileInfo)
89
89
  super.render();
90
90
  else
91
- this.drawFixtures(this.color, this.lineColor, this.lineWidth, mainContext);
91
+ this.drawFixtures(this.color, this.lineColor, this.lineWidth);
92
92
  }
93
93
 
94
94
  /** Render debug info */
95
95
  renderDebugInfo()
96
96
  {
97
97
  const isAsleep = !this.getIsAwake();
98
- const isStatic = this.getBodyType() == box2d.bodyTypeStatic;
98
+ const isStatic = this.getBodyType() === box2d.bodyTypeStatic;
99
99
  const color = rgb(isAsleep?1:0, isAsleep?1:0, isStatic?1:0, .5);
100
100
  this.drawFixtures(color);
101
101
  }
@@ -1563,7 +1563,7 @@ class Box2dPlugin
1563
1563
  queryCallback.ReportFixture = function(fixturePointer)
1564
1564
  {
1565
1565
  const fixture = box2d.instance.wrapPointer(fixturePointer, box2d.instance.b2Fixture);
1566
- if (dynamicOnly && fixture.GetBody().GetType() != box2d.instance.b2_dynamicBody)
1566
+ if (dynamicOnly && fixture.GetBody().GetType() !== box2d.instance.b2_dynamicBody)
1567
1567
  return true; // continue getting results
1568
1568
  if (!fixture.TestPoint(box2d.vec2dTo(pos)))
1569
1569
  return true; // continue getting results
@@ -1592,7 +1592,7 @@ class Box2dPlugin
1592
1592
  * @param {Color} [lineColor]
1593
1593
  * @param {number} [lineWidth]
1594
1594
  * @param {CanvasRenderingContext2D} [context] */
1595
- drawFixture(fixture, pos, angle, color=WHITE, lineColor=BLACK, lineWidth=.1, context=drawContext)
1595
+ drawFixture(fixture, pos, angle, color=WHITE, lineColor=BLACK, lineWidth=.1, context)
1596
1596
  {
1597
1597
  const shape = box2d.castObjectType(fixture.GetShape());
1598
1598
  switch (shape.GetType())
@@ -1602,20 +1602,20 @@ class Box2dPlugin
1602
1602
  let points = [];
1603
1603
  for (let i=shape.GetVertexCount(); i--;)
1604
1604
  points.push(box2d.vec2From(shape.GetVertex(i)));
1605
- drawPoly(points, color, lineWidth, lineColor, pos, angle, false, false, context);
1605
+ drawPoly(points, color, lineWidth, lineColor, pos, angle);
1606
1606
  break;
1607
1607
  }
1608
1608
  case box2d.instance.b2Shape.e_circle:
1609
1609
  {
1610
1610
  const radius = shape.get_m_radius();
1611
- drawCircle(pos, radius, color, lineWidth, lineColor, false, false, context);
1611
+ drawCircle(pos, radius*2, color, lineWidth, lineColor);
1612
1612
  break;
1613
1613
  }
1614
1614
  case box2d.instance.b2Shape.e_edge:
1615
1615
  {
1616
1616
  const v1 = box2d.vec2From(shape.get_m_vertex1());
1617
1617
  const v2 = box2d.vec2From(shape.get_m_vertex2());
1618
- drawLine(v1, v2, lineWidth, lineColor, pos, angle, false, false, context);
1618
+ drawLine(v1, v2, lineWidth, lineColor, pos, angle);
1619
1619
  break;
1620
1620
  }
1621
1621
  }
@@ -1694,7 +1694,9 @@ class Box2dPlugin
1694
1694
  }
1695
1695
 
1696
1696
  ///////////////////////////////////////////////////////////////////////////////
1697
- /** Box2d Init - Call with await before starting LittleJS to init box2d
1697
+ /** Box2d Init - Call with await to init box2d
1698
+ * @example
1699
+ * await box2dInit();
1698
1700
  * @return {Promise<Box2dPlugin>}
1699
1701
  * @memberof Box2D */
1700
1702
  async function box2dInit()
@@ -1757,14 +1759,14 @@ async function box2dInit()
1757
1759
  {
1758
1760
  color = getDebugColor(color);
1759
1761
  center = box2d.vec2FromPointer(center);
1760
- drawCircle(center, radius, CLEAR_WHITE, debugLineWidth, color, false, false, overlayContext);
1762
+ drawCircle(center, radius*2, CLEAR_WHITE, debugLineWidth, color, false, false, overlayContext);
1761
1763
  };
1762
1764
  debugDraw.DrawSolidCircle = function(center, radius, axis, color)
1763
1765
  {
1764
1766
  color = getDebugColor(color);
1765
1767
  center = box2d.vec2FromPointer(center);
1766
1768
  axis = box2d.vec2FromPointer(axis).scale(radius);
1767
- drawCircle(center, radius, color, debugLineWidth, color, false, false, overlayContext);
1769
+ drawCircle(center, radius*2, color, debugLineWidth, color, false, false, overlayContext);
1768
1770
  drawLine(vec2(), axis, debugLineWidth, color, center, 0, false, false, overlayContext);
1769
1771
  };
1770
1772
  debugDraw.DrawTransform = function(transform)