littlejsengine 1.14.4 → 1.14.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 (42) hide show
  1. package/README.md +3 -3
  2. package/dist/littlejs.d.ts +40 -14
  3. package/dist/littlejs.esm.js +119 -59
  4. package/dist/littlejs.esm.min.js +1 -1
  5. package/dist/littlejs.js +115 -57
  6. package/dist/littlejs.min.js +1 -1
  7. package/dist/littlejs.release.js +108 -50
  8. package/examples/box2d/game.js +1 -3
  9. package/examples/box2d/gameObjects.js +2 -2
  10. package/examples/htmlMenu/game.js +1 -1
  11. package/examples/index.html +85 -49
  12. package/examples/puzzle/game.js +1 -2
  13. package/examples/shorts/animation.js +2 -2
  14. package/examples/shorts/box2d.js +1 -0
  15. package/examples/shorts/box2dCar.js +1 -0
  16. package/examples/shorts/flappyGame.js +2 -1
  17. package/examples/shorts/helloWorld.js +2 -2
  18. package/examples/shorts/hillGlideGame.js +6 -3
  19. package/examples/shorts/maze.js +1 -0
  20. package/examples/shorts/medals.js +3 -0
  21. package/examples/shorts/music.js +6 -8
  22. package/examples/shorts/platformer.js +1 -0
  23. package/examples/shorts/shapes.js +6 -6
  24. package/examples/shorts/sound.js +1 -0
  25. package/examples/shorts/spriteAtlas.js +1 -2
  26. package/examples/shorts/tileLayer.js +1 -0
  27. package/examples/shorts/tiltedView.js +1 -1
  28. package/examples/shorts/timers.js +34 -31
  29. package/examples/shorts/topDown.js +2 -1
  30. package/examples/shorts/uiSystem.js +3 -5
  31. package/examples/stress/index.html +1 -1
  32. package/examples/uiSystem/game.js +1 -1
  33. package/package.json +1 -1
  34. package/plugins/uiSystem.js +35 -17
  35. package/reference.md +1 -1
  36. package/src/engine.js +23 -6
  37. package/src/engineDebug.js +7 -7
  38. package/src/engineDraw.js +18 -11
  39. package/src/engineExport.js +4 -2
  40. package/src/engineSettings.js +10 -0
  41. package/src/engineUtilities.js +4 -0
  42. package/src/engineWebGL.js +18 -16
@@ -61,58 +61,62 @@ class ExampleInfo
61
61
  this.filename = filename;
62
62
  this.description = description;
63
63
  this.largeExample = largeExample;
64
+ this.isHeading = !filename;
65
+ this.text = this.name;
66
+ if (this.description)
67
+ this.text += ' - ' + this.description;
64
68
  }
65
69
  }
66
70
 
67
71
  const exampleList =
68
72
  [
69
73
  new ExampleInfo('--- SHORT EXAMPLES ---'),
70
- new ExampleInfo('Hello World', 'helloWorld.js', 'Minimal starter example - [basic, beginner]'),
71
- new ExampleInfo('Shapes', 'shapes.js', 'Draw geometric shapes - [graphics, primitives, basic]'),
72
- new ExampleInfo('Colors', 'colors.js', 'Color object and HSL usage - [graphics, color, basic]'),
73
- new ExampleInfo('Blending', 'blending.js', 'Blending modes and transparency - [graphics, effects]'),
74
- new ExampleInfo('Timers', 'timers.js', 'Timer object and timing functions - [utilities, time]'),
75
- new ExampleInfo('Texture', 'texture.js', 'Display and manipulate textures - [graphics, sprites]'),
76
- new ExampleInfo('Particles', 'particles.js', 'Particle system basics - [effects, particles]'),
77
- new ExampleInfo('Sound Effects', 'sound.js', 'Example sound effects with ZzFX - [audio, sound]'),
78
- new ExampleInfo('Music', 'music.js', 'Example sound loading, play, pause, seek, and stop - [audio, music]'),
79
- new ExampleInfo('System Font', 'systemFont.js', 'Built-in bitmap font rendering - [text, font]'),
80
- new ExampleInfo('Sprite Atlas', 'spriteAtlas.js', 'Sprite atlas and tile rendering - [graphics, sprites]'),
81
- new ExampleInfo('Animation', 'animation.js', 'Sprite animation techniques - [animation, sprites]'),
82
- new ExampleInfo('Clock', 'clock.js', 'Real-time clock display - [time, ui, utilities]'),
83
- new ExampleInfo('Medals', 'medals.js', 'Achievement system demo - [ui, achievements]'),
84
- new ExampleInfo('Tile Layer', 'tileLayer.js', 'Tile layer rendering system - [tiles, levels]'),
85
- new ExampleInfo('Piano', 'piano.js', 'Interactive piano keyboard - [audio, input, ui]'),
86
- new ExampleInfo('Maze Generator', 'maze.js', 'Procedural maze generation - [algorithm, generation]'),
87
- new ExampleInfo('Starfield', 'starfield.js', 'Animated starfield - [effects, space]'),
88
- new ExampleInfo('Parallax', 'parallax.js', 'Parallax mountains - [graphics, effects]'),
74
+ new ExampleInfo('Hello World', 'helloWorld.js', 'Minimal starter example'),
75
+ new ExampleInfo('Starfield', 'starfield.js', 'Animated parallax starfield'),
76
+ new ExampleInfo('Shapes', 'shapes.js', 'Draw geometric shapes and primitives'),
77
+ new ExampleInfo('Colors', 'colors.js', 'Color manipulation and HSL'),
78
+ new ExampleInfo('Texture', 'texture.js', 'Texture display and manipulation'),
79
+ new ExampleInfo('Sprite Atlas', 'spriteAtlas.js', 'Sprite atlas and tile rendering'),
80
+ new ExampleInfo('Animation', 'animation.js', 'Sprite animation system'),
81
+ new ExampleInfo('Blending', 'blending.js', 'Additive blending and transparency'),
82
+ new ExampleInfo('Tile Layer', 'tileLayer.js', 'Tile layer rendering system'),
83
+ new ExampleInfo('Particles', 'particles.js', 'Particle system'),
84
+ new ExampleInfo('Timers', 'timers.js', 'Timer objects and UI'),
85
+ new ExampleInfo('Sound Effects', 'sound.js', 'ZzFX sound effect generator'),
86
+ new ExampleInfo('Music', 'music.js', 'Music playback and controls'),
87
+ new ExampleInfo('Font Image', 'systemFont.js', 'Bitmap font system with built-in system font'),
88
+ new ExampleInfo('Parallax', 'parallax.js', 'Parallax scrolling mountains'),
89
+ new ExampleInfo('Maze Generator', 'maze.js', 'Procedural maze generation'),
90
+ new ExampleInfo('Medals', 'medals.js', 'Achievement system'),
91
+ new ExampleInfo('Piano', 'piano.js', 'Interactive piano keyboard'),
92
+ new ExampleInfo('Clock', 'clock.js', 'Animated analog clock'),
89
93
  new ExampleInfo('--- MINI GAMES ---'),
90
- new ExampleInfo('Platformer Game', 'platformer.js', 'Jump and run platformer - [game, platformer, physics]'),
91
- new ExampleInfo('Top Down Game', 'topDown.js', 'Adventure with collision - [game, topdown, rpg]'),
92
- new ExampleInfo('Tilted View', 'tiltedView.js', 'Pseudo 3D tilted perspective - [3d, camera, perspective]'),
93
- new ExampleInfo('Space Game', 'spaceGame.js', 'Spaceship with parallax starfield - [game, space, shooter]'),
94
- new ExampleInfo('Lander Game', 'landerGame.js', 'Lunar lander physics game - [game, physics, thrust]'),
95
- new ExampleInfo('Flappy Game', 'flappyGame.js', 'Flappy bird clone - [game, arcade, flying]'),
96
- new ExampleInfo('Hill Glide Game', 'hillGlideGame.js', 'Tiny wings style glider - [game, physics, flying]'),
97
- new ExampleInfo('Pong Game', 'pongGame.js', 'Classic paddle ball game - [game, classic, arcade]'),
98
- new ExampleInfo('Sliding Puzzle', 'slidingPuzzle.js', 'Tile sliding puzzle game - [game, puzzle, logic]'),
99
- new ExampleInfo('Raycasting Game', 'raycasting.js', 'Pseudo 3D raycasting demo - [3d, raycasting, wolfenstein]'),
94
+ new ExampleInfo('Pong Game', 'pongGame.js', 'Classic paddle ball bouncing'),
95
+ new ExampleInfo('Platformer Game', 'platformer.js', 'Jump and run side view'),
96
+ new ExampleInfo('Top Down Game', 'topDown.js', 'Top-down style camera'),
97
+ new ExampleInfo('Tilted View Game', 'tiltedView.js', 'Pseudo-3D oblique view'),
98
+ new ExampleInfo('Flappy Game', 'flappyGame.js', 'Flappy bird style game'),
99
+ new ExampleInfo('Lander Game', 'landerGame.js', 'Lunar lander style game'),
100
+ new ExampleInfo('Hill Glide Game', 'hillGlideGame.js', 'Tiny wings style sliding game'),
101
+ new ExampleInfo('Sliding Puzzle', 'slidingPuzzle.js', '15 tile sliding puzzle'),
102
+ new ExampleInfo('Space Game', 'spaceGame.js', 'Spaceship shooter with parallax'),
103
+ new ExampleInfo('Raycasting 3D Game', 'raycasting.js', 'Wolfenstein-style raycasting'),
100
104
  new ExampleInfo('--- PLUGINS ---'),
101
- new ExampleInfo('Box2d Demo', 'box2d.js', 'Box2D physics plugin demo - [physics, box2d, plugin]'),
102
- new ExampleInfo('Box2d Car', 'box2dCar.js', 'Drivable car with Box2D - [physics, box2d, vehicle]'),
103
- new ExampleInfo('Post Processing', 'postProcess.js', 'Shader effects and filters - [graphics, shaders, effects]'),
104
- new ExampleInfo('UI System Plugin', 'uiSystem.js', 'UI elements and widgets - [ui, plugin, interface]'),
105
- new ExampleInfo('Nine Slice', 'nineSlice.js', 'Scalable UI panel rendering - [ui, graphics, scaling]'),
105
+ new ExampleInfo('Box2d Demo', 'box2d.js', 'Box2D physics plugin'),
106
+ new ExampleInfo('Box2d Car', 'box2dCar.js', 'Drivable car with Box2D physics'),
107
+ new ExampleInfo('Post Processing', 'postProcess.js', 'Shader effects and filters'),
108
+ new ExampleInfo('UI System Plugin', 'uiSystem.js', 'Buttons, sliders, and checkboxes'),
109
+ new ExampleInfo('Nine Slice', 'nineSlice.js', 'Scalable UI panels'),
106
110
  new ExampleInfo('--- FULL EXAMPLES ---'),
107
- new ExampleInfo('Starter', 'starter', 'Clean project template - [template, beginner]', true),
108
- new ExampleInfo('Breakout Tutorial', 'breakoutTutorial', 'Step-by-step breakout guide - [tutorial, breakout]', true),
109
- new ExampleInfo('Breakout Game', 'breakout', 'Complete breakout with effects - [game, breakout, complete]', true),
110
- new ExampleInfo('Platforming Game', 'platformer', 'Full platformer with levels - [game, platformer, complete]', true),
111
- new ExampleInfo('Puzzle Game', 'puzzle', 'Match-3 puzzle with HD graphics - [game, puzzle, match3]', true),
112
- new ExampleInfo('Stress Test', 'stress', 'Performance test with music - [performance, test, music]', true),
113
- new ExampleInfo('Box2D Plugin', 'box2d', 'Complete Box2D physics demo - [physics, box2d, complete]', true),
114
- new ExampleInfo('HTML Menus', 'htmlMenu', 'HTML integration example - [html, ui, integration]', true),
115
- new ExampleInfo('UI System Plugin', 'uiSystem', 'Complete UI system demo - [ui, plugin, complete]', true),
111
+ new ExampleInfo('Starter', 'starter', 'Clean project template', true),
112
+ new ExampleInfo('Breakout Tutorial', 'breakoutTutorial', 'Step-by-step breakout tutorial', true),
113
+ new ExampleInfo('Breakout Game', 'breakout', 'Complete breakout game', true),
114
+ new ExampleInfo('Platforming Game', 'platformer', 'Full platformer with levels', true),
115
+ new ExampleInfo('Puzzle Game', 'puzzle', 'Match-3 puzzle game', true),
116
+ new ExampleInfo('Stress Test', 'stress', 'Performance and music test', true),
117
+ new ExampleInfo('Box2D Plugin', 'box2d', 'Full Box2D physics demo', true),
118
+ new ExampleInfo('HTML Menus', 'htmlMenu', 'HTML UI integration', true),
119
+ new ExampleInfo('UI System Plugin', 'uiSystem', 'Complete UI system demo', true),
116
120
  ];
117
121
 
118
122
  ///////////////////////////////////////////////////////////////////////////////
@@ -222,7 +226,7 @@ function setExample()
222
226
 
223
227
  // load the example
224
228
  const example = exampleList[exampleIndex];
225
- exampleInfo.innerText = example.name + (example.description ? ' - ' + example.description : '');
229
+ exampleInfo.innerText = example.text;
226
230
  const filename = 'examples/' + example.filename;
227
231
  exampleLink.href = 'https://github.com/KilledByAPixel/LittleJS/tree/main/' + filename;
228
232
  exampleLink.innerText = 'View code on GitHub';
@@ -300,16 +304,48 @@ function filterExamples(reset=0)
300
304
 
301
305
  // filter and add matching examples
302
306
  const searchTerm = inputSearch.value.toLowerCase().trim();
307
+
308
+ // first pass: find which examples match
309
+ const matchingIndices = [];
303
310
  for (let i = 0; i < exampleList.length; i++)
304
311
  {
305
- // check if search term matches name or description
306
312
  const example = exampleList[i];
307
- const text = example.name + (example.description ? ` - ${example.description}` : '');
313
+ if (!example.filename)
314
+ continue;
315
+
316
+ // Check if search term matches name or description
308
317
  if (example.name.toLowerCase().includes(searchTerm) ||
309
318
  example.description.toLowerCase().includes(searchTerm))
319
+ matchingIndices.push(i);
320
+ }
321
+
322
+ // second pass: add headings and matching examples
323
+ let lastHeadingIndex = -1;
324
+ for (let i = 0; i < exampleList.length; i++)
325
+ {
326
+ const example = exampleList[i];
327
+ if (example.isHeading)
328
+ {
329
+ // check if there are any matches between this and the next
330
+ for (let j = i + 1; j < exampleList.length; j++)
331
+ {
332
+ if (exampleList[j].isHeading)
333
+ break; // hit next heading
334
+ if (matchingIndices.includes(j))
335
+ {
336
+ // only add heading if there are matches under it
337
+ lastHeadingIndex = i;
338
+ const o = new Option(example.text);
339
+ o.disabled = true;
340
+ selectExample.add(o);
341
+ break;
342
+ }
343
+ }
344
+ }
345
+ else if (matchingIndices.includes(i))
310
346
  {
311
- const o = new Option(text);
312
- o.disabled = !example.filename;
347
+ // add matching example
348
+ const o = new Option(example.text);
313
349
  o.originalIndex = i;
314
350
  selectExample.add(o);
315
351
  }
@@ -317,7 +353,7 @@ function filterExamples(reset=0)
317
353
 
318
354
  if (!selectExample.options.length)
319
355
  {
320
- // show a message if no matches
356
+ // show a message if no matches were found
321
357
  const o = new Option(`No examples found matching '${searchTerm}'`);
322
358
  o.disabled = true;
323
359
  selectExample.add(o);
@@ -69,8 +69,7 @@ function gameInit()
69
69
  {
70
70
  // setup canvas
71
71
  LJS.setCanvasFixedSize(vec2(1920, 1080)); // 1080p
72
- LJS.mainCanvas.style.background = backgroundColor;
73
-
72
+ LJS.setCanvasClearColor(backgroundColor);
74
73
  // load high score
75
74
  bestScore = localStorage[highScoreKey] || 0;
76
75
 
@@ -1,7 +1,7 @@
1
+ canvasClearColor = GRAY;
2
+
1
3
  function gameRender()
2
4
  {
3
- drawRect(vec2(0,0), vec2(100), GRAY); // draw background
4
-
5
5
  {
6
6
  // animate using multiple frames
7
7
  const pos = vec2(-5, 2*abs(Math.sin(time*2*PI)));
@@ -4,6 +4,7 @@ async function gameInit()
4
4
  await box2dInit();
5
5
  mouseJoint = 0;
6
6
  gravity.y = -50;
7
+ canvasClearColor = hsl(0,0,.9);
7
8
 
8
9
  // create ground object
9
10
  groundObject = new Box2dObject(vec2(-8), vec2(), 0, 0, GRAY, box2d.bodyTypeStatic);
@@ -6,6 +6,7 @@ async function gameInit()
6
6
  groundObject = new Box2dObject(vec2(-8), vec2(), 0, 0, GRAY, box2d.bodyTypeStatic);
7
7
  groundObject.addBox(vec2(100,6));
8
8
  new CarObject(vec2(0,-2));
9
+ canvasClearColor = hsl(0,0,.9);
9
10
  }
10
11
 
11
12
  class CarObject extends Box2dObject
@@ -2,7 +2,7 @@ class Wall extends EngineObject
2
2
  {
3
3
  constructor(pos, size)
4
4
  {
5
- super(pos, size, 0, 0, hsl(.4,.5,.4));
5
+ super(pos, size, 0, 0, hsl(.3,.5,.3));
6
6
  this.setCollision(); // make object collide
7
7
  }
8
8
  update()
@@ -50,4 +50,5 @@ function gameInit()
50
50
  new Wall(vec2(14 + i*spacing,y), vec2(3,h));
51
51
  }
52
52
  new Player(vec2(-7,6));
53
+ canvasClearColor = hsl(.55,1,.8);
53
54
  }
@@ -1,7 +1,7 @@
1
1
  function gameRender()
2
2
  {
3
- // draw background rect
4
- drawRect(cameraPos, vec2(50), hsl(0,0,.2));
3
+ // draw background gradient
4
+ drawRectGradient(cameraPos, getCameraSize(), BLACK, WHITE);
5
5
 
6
6
  // draw text to the overlay canvas
7
7
  drawTextOverlay('Hello World', vec2(0,3), 3);
@@ -40,17 +40,20 @@ function gameInit()
40
40
  {
41
41
  gravity.y = -.01;
42
42
  new Player(vec2(0,5));
43
+ canvasClearColor = hsl(.7,1,.8);
43
44
  }
44
45
 
45
46
  function gameRender()
46
47
  {
47
48
  const h = 100, w = 20;
48
- const pos = vec2(), size = vec2(.2,h), color = WHITE;
49
+ const pos = vec2(), sizeTop = vec2(.4), size = vec2(.2,h), color = WHITE;
49
50
  for (let x=cameraPos.x-w; x<cameraPos.x+w; x+=.1)
50
51
  {
51
52
  pos.x = x;
52
- pos.y = getGroundHeight(x)-h/2;
53
- color.setHSLA(.2+.2*wave(.2,1,x), .5, .5);
53
+ pos.y = getGroundHeight(x);
54
+ drawRect(pos, sizeTop, BLACK);
55
+ pos.y -= h/2;
56
+ color.setHSLA(.2+.2*wave(.2,1,x), .7, .5);
54
57
  drawRect(pos, size, color);
55
58
  }
56
59
  }
@@ -44,4 +44,5 @@ function gameInit()
44
44
  }
45
45
  tileLayer.redraw(); // redraw tile layer with new data
46
46
  cameraPos = mazeSize.scale(.5); // center camera
47
+ canvasClearColor = hsl(rand(),.3,.2); // random background color
47
48
  }
@@ -12,6 +12,9 @@ medalsInit(saveName);
12
12
  medalsForEach(medal=> medal.unlocked = false);
13
13
  medal_openedExample.unlock();
14
14
 
15
+ // set background color
16
+ canvasClearColor = hsl(.5,.3,.2);
17
+
15
18
  function gameUpdate()
16
19
  {
17
20
  if (mouseWasPressed(0))
@@ -1,18 +1,16 @@
1
- // Music player variables
1
+ let playButton, stopButton, progressBar;
2
2
  let musicSound = new SoundWave('song.mp3');
3
- let musicVolume = .8;
3
+ let musicVolume = 1;
4
4
  let musicInstance;
5
5
 
6
- // UI elements
7
- let playButton, stopButton, progressBar;
8
-
9
6
  function gameInit()
10
7
  {
11
- // load ui system plugin
8
+ // setup ui system plugin
12
9
  new UISystemPlugin;
13
- uiSystem.defaultSoundPress = new Sound([.3,0,220]);
14
- uiSystem.defaultSoundClick = new Sound([.3,0,440]);
10
+ uiSystem.defaultSoundPress = new Sound([.5,0,220]);
11
+ uiSystem.defaultSoundClick = new Sound([.5,0,440]);
15
12
  uiSystem.defaultCornerRadius = 20;
13
+ canvasClearColor = hsl(.9,.3,.2); // background color
16
14
 
17
15
  // setup music player UI
18
16
  const musicPlayer = new UIObject(mainCanvasSize.scale(.5), vec2(500, 300));
@@ -26,6 +26,7 @@ function gameInit()
26
26
  // setup level
27
27
  gravity.y = -.05;
28
28
  new Player(vec2(5,6));
29
+ canvasClearColor = hsl(.6,.3,.5);
29
30
 
30
31
  // create tile layer
31
32
  const pos = vec2();
@@ -1,18 +1,18 @@
1
1
  function gameRender()
2
2
  {
3
3
  // circles and ellipses
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)
4
+ drawEllipse(vec2(-6,5), vec2(3,2), YELLOW, .5);
5
+ drawCircle(vec2(0,5), 2+wave(.5), RED);
6
+ drawEllipse(vec2(6,5), vec2(2,4), CLEAR_BLACK, .3, .5, CYAN)
7
7
 
8
8
  // polygon shapes
9
9
  drawRectGradient(vec2(-6,0), vec2(5,4), RED, BLUE)
10
- drawRegularPoly(vec2(0,0), vec2(2), 3, PURPLE, .2, WHITE, time);
10
+ drawRegularPoly(vec2(0,0), vec2(4), 3, PURPLE, .2, WHITE, time);
11
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));
12
+ drawLineList(starPath, .2, GREEN, true, vec2(6, 0));
13
13
 
14
14
  // rects and lines
15
15
  drawRect(vec2(0,-5), vec2(4,3), ORANGE, time);
16
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);
17
+ drawLineList([vec2(5,-3), vec2(-5,-3), vec2(5,-7), vec2(-5,-7)], .2, MAGENTA);
18
18
  }
@@ -34,4 +34,5 @@ function gameInit()
34
34
  new SoundButton(vec2(-6,-5),'🌊', new Sound([,.2,40,.5,,1.5,,11,,,,,,199]));
35
35
  new SoundButton(vec2( 0,-5),'🛰️', new Sound([,.5,847,.02,.3,.9,1,1.67,,,-294,.04,.13,,,,.1]));
36
36
  new SoundButton(vec2( 6,-5),'⚡', new Sound([,,471,,.09,.47,4,1.06,-6.7,,,,,.9,61,.1,,.82,.1]));
37
+ canvasClearColor = hsl(.6,.3,.2); // background color
37
38
  }
@@ -1,4 +1,5 @@
1
1
  let spriteAtlas;
2
+ canvasClearColor = GRAY;
2
3
 
3
4
  function gameInit()
4
5
  {
@@ -16,8 +17,6 @@ function gameInit()
16
17
 
17
18
  function gameRender()
18
19
  {
19
- drawRect(vec2(0,0), vec2(100), GRAY); // draw background
20
-
21
20
  // draw a sprite from the atlas
22
21
  let pos = vec2(Math.sin(time)*5,-3);// world position to draw
23
22
  let angle = 0; // world space angle to draw the tile
@@ -2,6 +2,7 @@ function gameInit()
2
2
  {
3
3
  cameraPos = vec2(16); // setup camera
4
4
  gravity.y = -.01; // enable gravity
5
+ canvasClearColor = hsl(0,0,.2); // background color
5
6
 
6
7
  // create tile layer
7
8
  const pos = vec2();
@@ -37,7 +37,7 @@ function gameInit()
37
37
 
38
38
  // create background objects
39
39
  for (let i=1; i<300; ++i)
40
- new EngineObject(randInCircle(90), vec2(rand(59),rand(59)), 0, 0, hsl(.4,.3,rand(.1,.2),.8), -1e5);
40
+ new EngineObject(randInCircle(90), vec2(rand(59),rand(59)), 0, 0, hsl(.4,.2,rand(.4,.5),.8), -1e5);
41
41
 
42
42
  // create world objects
43
43
  for (let i=1; i<1e3; ++i)
@@ -1,40 +1,43 @@
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
- }
1
+ let timerButton, timerSlider;
9
2
 
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
- }
3
+ function gameInit()
4
+ {
5
+ // setup ui system plugin
6
+ new UISystemPlugin();
7
+ uiSystem.defaultCornerRadius = 10;
8
+ canvasClearColor = hsl(.3,.3,.2);
16
9
 
17
- render()
10
+ // create timer button
11
+ const pos = mainCanvasSize.scale(.5).add(vec2(0, -40));
12
+ timerButton = new UIButton(pos, vec2(200, 90), 'Start');
13
+ timerButton.timer = new Timer;
14
+ timerButton.onClick = ()=>
18
15
  {
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())
16
+ if (timerButton.timer.isSet())
25
17
  {
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);
18
+ timerButton.timer.unset();
19
+ timerButton.text = 'Start';
29
20
  }
30
21
  else
31
- drawTextOverlay('Click\nto set', this.pos, 2);
22
+ {
23
+ timerButton.timer.set(3);
24
+ timerButton.text = 'Stop';
25
+ }
32
26
  }
33
- }
34
27
 
35
- function gameInit()
36
- {
37
- // create some timer buttons
38
- new TimerButton(vec2(-5, 0), 3);
39
- new TimerButton(vec2( 5, 0), 0);
28
+ // create non-interactive slider to display timer
29
+ timerSlider = new UIScrollbar(vec2(0, 100), vec2(400, 50));
30
+ timerSlider.interactive = false;
31
+ timerSlider.update = ()=>
32
+ {
33
+ // update the timer display
34
+ const t = timerButton.timer.get();
35
+ const timeText = t.toFixed(2) + 's';
36
+ const isSet = timerButton.timer.isSet();
37
+ const setTime = timerButton.timer.getSetTime();
38
+ timerSlider.text = timeText;
39
+ timerSlider.value = setTime ? 1+t/setTime : 1;
40
+ timerSlider.color = isSet ? t < 0 ? CYAN : RED : GRAY;
41
+ }
42
+ timerButton.addChild(timerSlider);
40
43
  }
@@ -23,13 +23,14 @@ class Player extends EngineObject
23
23
  function gameInit()
24
24
  {
25
25
  // setup level
26
+ canvasClearColor = hsl(.3,.2,.6);
26
27
  objectDefaultDamping = .7;
27
28
  new Player;
28
29
 
29
30
  // create collision objects
30
31
  for (let i=300; i--;)
31
32
  {
32
- const o = new EngineObject(randInCircle(15+i,7), vec2(rand(4,9),rand(4,9)), 0, 0, hsl(0,0,rand(.8,1)));
33
+ const o = new EngineObject(randInCircle(15+i,7), vec2(rand(4,9),rand(4,9)), 0, 0, hsl(0,0,rand(.1,.3)));
33
34
  o.setCollision(); // make object collide
34
35
  o.mass = 0; // make object have static physics
35
36
  }
@@ -4,17 +4,15 @@ let uiMenu;
4
4
 
5
5
  function gameInit()
6
6
  {
7
- // load ui system plugin
7
+ // setup ui system plugin
8
8
  new UISystemPlugin;
9
9
  uiSystem.defaultSoundPress = new Sound([1,0,220]);
10
10
  uiSystem.defaultSoundClick = new Sound([1,0,440]);
11
11
  uiSystem.defaultCornerRadius = 8;
12
12
 
13
13
  // setup example menu
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);
14
+ const uiMenu = new UIObject(mainCanvasSize.scale(.5), vec2(450));
15
+ canvasClearColor = hsl(0,0,.8);
18
16
 
19
17
  // example text
20
18
  const textTitle = new UIText(vec2(0,-120), vec2(400, 60), 'LittleJS UI\nSystem Demo');
@@ -47,7 +47,7 @@ function gameInit()
47
47
  LJS.setCanvasFixedSize(vec2(1920, 1080)); // 1080p
48
48
  LJS.setCameraScale(20);
49
49
  LJS.setCameraPos(tileLayer.size.scale(.5));
50
- LJS.mainCanvas.style.background = '#555';
50
+ LJS.setCanvasClearColor(rgb(.4,.4,.4));
51
51
  LJS.setGravity(vec2(0,-.005));
52
52
  sprites = [];
53
53
 
@@ -85,6 +85,7 @@ function gameInit()
85
85
  {
86
86
  new LJS.UISystemPlugin;
87
87
  createUI();
88
+ LJS.setCanvasClearColor(hsl(0,0,.2));
88
89
  }
89
90
 
90
91
  ///////////////////////////////////////////////////////////////////////////////
@@ -110,7 +111,6 @@ function gameUpdatePost()
110
111
  function gameRender()
111
112
  {
112
113
  // test game rendering
113
- LJS.drawRect(vec2(), vec2(1e3), hsl(0,0,.2));
114
114
  for (let i=0; i<1e3; ++i)
115
115
  {
116
116
  const pos = vec2(30*Math.sin(i+LJS.time/9),20*Math.sin(i*i+LJS.time/9));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.14.4",
3
+ "version": "1.14.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",