littlejsengine 1.11.6 → 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 (54) hide show
  1. package/README.md +11 -16
  2. package/dist/littlejs.d.ts +14 -1
  3. package/dist/littlejs.esm.js +30 -19
  4. package/dist/littlejs.esm.min.js +1 -1
  5. package/dist/littlejs.js +27 -19
  6. package/dist/littlejs.min.js +1 -1
  7. package/dist/littlejs.release.js +23 -18
  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/index.html +4 -4
  12. package/examples/breakoutTutorial/index.html +2 -2
  13. package/examples/htmlMenu/index.html +2 -2
  14. package/examples/index.html +300 -32
  15. package/examples/module/index.html +1 -1
  16. package/examples/particles/index.html +1 -1
  17. package/examples/platformer/gamePlayer.js +2 -7
  18. package/examples/platformer/index.html +8 -8
  19. package/examples/puzzle/index.html +2 -2
  20. package/examples/shorts/base.html +26 -0
  21. package/{shortExamples/code → examples/shorts}/blending.js +1 -1
  22. package/examples/shorts/platformer.js +42 -0
  23. package/{shortExamples/code → examples/shorts}/playSound.js +3 -0
  24. package/{shortExamples/code → examples/shorts}/pong.js +3 -3
  25. package/examples/shorts/tiltedView.js +44 -0
  26. package/{shortExamples/code → examples/shorts}/timers.js +7 -3
  27. package/examples/shorts/topDown.js +44 -0
  28. package/examples/starter/index.html +13 -13
  29. package/examples/stress/index.html +2 -2
  30. package/examples/uiSystem/game.js +6 -1
  31. package/examples/uiSystem/index.html +3 -3
  32. package/package.json +1 -1
  33. package/plugins/Box2D_License.txt +17 -0
  34. package/plugins/uiSystem.js +2 -1
  35. package/reference.md +2 -1
  36. package/src/engine.js +1 -1
  37. package/src/engineDebug.js +5 -1
  38. package/src/engineExport.js +3 -0
  39. package/src/engineInput.js +19 -15
  40. package/src/engineRelease.js +1 -0
  41. package/src/engineTileLayer.js +2 -2
  42. package/shortExamples/base.html +0 -39
  43. package/shortExamples/index.html +0 -246
  44. /package/{shortExamples/code → examples/shorts}/animation.js +0 -0
  45. /package/{shortExamples/code → examples/shorts}/clock.js +0 -0
  46. /package/{shortExamples/code → examples/shorts}/colors.js +0 -0
  47. /package/{shortExamples/code → examples/shorts}/helloWorld.js +0 -0
  48. /package/{shortExamples/code → examples/shorts}/particles.js +0 -0
  49. /package/{shortExamples/code → examples/shorts}/shapes.js +0 -0
  50. /package/{shortExamples/code → examples/shorts}/spriteAtlas.js +0 -0
  51. /package/{shortExamples/code → examples/shorts}/systemFont.js +0 -0
  52. /package/{shortExamples/code → examples/shorts}/texture.js +0 -0
  53. /package/{shortExamples/code → examples/shorts}/tileLayer.js +0 -0
  54. /package/{shortExamples → examples/shorts}/tiles.png +0 -0
@@ -1,34 +1,302 @@
1
- <head>
2
- <title>LittleJS Examples</title>
1
+ <!DOCTYPE html><head>
2
+ <title>LittleJS Example Browser</title>
3
+ <link rel=icon type=image/png href=favicon.png>
4
+ <meta charset=utf-8>
3
5
  <style>
4
- iframe {width:480px; height:270px;}
6
+ html, body
7
+ {
8
+ height: 100%;
9
+ display: flex;
10
+ flex-direction: column;
11
+ }
12
+ #container1
13
+ {
14
+ height: 100%;
15
+ display: flex;
16
+ }
17
+ #container2
18
+ {
19
+ display: flex;
20
+ flex-direction: column;
21
+ }
22
+ #iframeContainer
23
+ {
24
+ border: 2px solid;
25
+ background: #000;
26
+ }
27
+ iframe
28
+ {
29
+ width: 100%;
30
+ height: 100%;
31
+ border: none;
32
+ }
33
+ #selectExample
34
+ {
35
+ flex-grow: 1;
36
+ }
37
+ #textareaCode
38
+ {
39
+ flex-grow: 1;
40
+ padding: 5px;
41
+ resize: none;
42
+ color: #fff;
43
+ background: #000;
44
+ }
45
+ #textareaError
46
+ {
47
+ flex-grow: .3;
48
+ padding: 5px;
49
+ resize: none;
50
+ display: none;
51
+ color:#f22;
52
+ background: #111;
53
+ }
54
+ #container3
55
+ {
56
+ width: 100%;
57
+ height: 100%;
58
+ display: flex;
59
+ flex-direction: column;
60
+ }
61
+ #titleInfo
62
+ {
63
+ margin: 5px;
64
+ text-align: center;
65
+ font-size: 50px;
66
+ }
67
+ #exampleLink
68
+ {
69
+ margin: 0px;
70
+ text-align: center;
71
+ font-size: 30px;
72
+ }
73
+ #exampleInfo
74
+ {
75
+ margin: 0px;
76
+ text-align: center;
77
+ font-size: 22px;
78
+ }
79
+ select
80
+ {
81
+ color:#fff;
82
+ background-color: #111;
83
+ width:100%;
84
+ }
5
85
  </style>
6
- <link rel=icon type=image/png href=../favicon.png>
7
- <body>
8
- <h1>All LittleJS Engine Examples</h1>
9
- <img src=screenshot.jpg width=480>
10
- <h2>Main Demos</h2>
11
- <p>
12
- <a href="starter">Starter</a> - Clean example with only a few things to get you started<br>
13
- <a href="stress">Stress</a> - Max sprite/object test and music system demo<br>
14
- <a href="platformer">Platformer</a> - Platformer/shooter with level data from Tiled Editor<br>
15
- <a href="breakout">Breakout</a> - Block breaking game with post-processing effects<br>
16
- <a href="breakoutTutorial">Breakout Tutorial</a> - Tutorial Breakout example<br>
17
- <a href="puzzle">Puzzle</a> - Match 3 puzzle game with HD rendering and high score tracking<br>
18
- <a href="particles">Particle Designer</a> - Particle system editor and visualizer<br>
19
- <a href="empty">Empty</a> - A blank hello world project for LittleJS<br>
20
- <a href="module">LittleJS with Modules</a> - Loads LittleJS as a module<br>
21
- </p>
22
- <h2>Plugin Demos</h2>
23
- <p>
24
- <a href="box2d">Box2D</a> - Box2D plugin demonstration and testbed<br>
25
- <a href="uiSystem">UI System</a> - A simple hierarchical UI system using LittleJS rendering<br>
26
- <a href="htmlMenu">HTML UI Menu</a> - Example using html to create an overlay menu<br>
27
- </p>
28
- <h2>Live Demos</h2>
29
- <p>
30
- <iframe id=iframe src="breakout"></iframe>
31
- <iframe id=iframe src="platformer"></iframe>
32
- <iframe id=iframe src="puzzle"></iframe>
33
- </p>
34
- </body>
86
+ </head><body>
87
+ <div id=container1>
88
+ <div id=container3>
89
+ <p id=titleInfo>LittleJS Example Browser</p>
90
+ <a id=exampleLink target="_blank">Example LINK</a>
91
+ <p id=exampleInfo>Example Info</p>
92
+ <textarea id=textareaCode oninput=codeInput() spellcheck=false></textarea>
93
+ <textarea id=textareaError readonly spellcheck=false></textarea>
94
+ <div><input type=checkbox id=checkboxLiveEdit checked>Live Edit
95
+ <button id=buttonScreenshot>Screenshot</button>
96
+ </div>
97
+ </div>
98
+ <div id=container2>
99
+ <div id=iframeContainer></div>
100
+ <select id=selectExample autofocus onchange=setExample() size=2></select>
101
+ </div>
102
+ </div>
103
+ <script>
104
+ 'use strict';
105
+
106
+ class ExampleInfo
107
+ {
108
+ constructor(name, filename, description, fullExample=false)
109
+ {
110
+ if (filename && !fullExample)
111
+ filename = 'shorts/' + filename; // short examples folder
112
+ this.name = name;
113
+ this.filename = filename;
114
+ this.description = description;
115
+ this.fullExample = fullExample;
116
+ }
117
+ }
118
+
119
+ const exampleList =
120
+ [
121
+ new ExampleInfo('--- SHORT EXAMPLES ---'),
122
+ new ExampleInfo('Hello World', 'helloWorld.js', 'Simplest example'),
123
+ new ExampleInfo('Shapes', 'shapes.js', 'How to draw geometric shapes'),
124
+ new ExampleInfo('Colors', 'colors.js', 'How to use the color object'),
125
+ new ExampleInfo('Blending', 'blending.js', 'Shows different blending modes'),
126
+ new ExampleInfo('Timers', 'timers.js', 'How to use the timer object'),
127
+ new ExampleInfo('Texture', 'texture.js', 'How to display a full texture'),
128
+ new ExampleInfo('Particles', 'particles.js', 'How to use the particle system'),
129
+ new ExampleInfo('Play Sound', 'playSound.js', 'How to play sounds with zzfx'),
130
+ new ExampleInfo('System Font', 'systemFont.js', 'Demo of the included system font'),
131
+ new ExampleInfo('Sprite Atlas', 'spriteAtlas.js', 'How to set up a simple sprite atlas'),
132
+ new ExampleInfo('Animation', 'animation.js', 'How to animate sprites'),
133
+ new ExampleInfo('Clock', 'clock.js', 'A simple clock showing the time'),
134
+ new ExampleInfo('Tile Layer', 'tileLayer.js', 'How to use the tile layer object'),
135
+ new ExampleInfo('Platformer Game', 'platformer.js', 'A platformer jumping game'),
136
+ new ExampleInfo('Top Down Game', 'topDown.js', 'A top down adventure game'),
137
+ new ExampleInfo('Tilted View', 'tiltedView.js', 'Pseudo 3D view with tilted camera'),
138
+ new ExampleInfo('Pong Game', 'pong.js', 'A simple pong game'),
139
+
140
+ new ExampleInfo('--- FULL EXAMPLES ---'),
141
+ new ExampleInfo('Starter', 'starter', 'Clean starter project', true),
142
+ new ExampleInfo('Breakout Tutorial', 'breakoutTutorial', 'Tutorial Breakout example', true),
143
+ new ExampleInfo('Breakout Game', 'breakout', 'Block breaking game with post-processing effects', true),
144
+ new ExampleInfo('Platforming Game', 'platformer', 'Platformer/shooter with level data loading', true),
145
+ new ExampleInfo('Puzzle Game', 'puzzle', 'Match 3 puzzle game with HD rendering', true),
146
+ new ExampleInfo('Stress Test', 'stress', 'Max sprite/object test and music system demo', true),
147
+ new ExampleInfo('Box2D Plugin', 'box2d', 'Demo of the Box2D physics plugin', true),
148
+ new ExampleInfo('HTML Menus', 'htmlMenu', 'Shows how to combine HTML with LittleJS', true),
149
+ new ExampleInfo('UI System Plugin', 'uiSystem', 'Example of how to use LittleJS UI plugin', true),
150
+ // Add more examples here!
151
+ ];
152
+
153
+ ///////////////////////////////////////////////////////////////////////////////
154
+
155
+ let iframeExample, inputTimeout;
156
+
157
+ // load the examples into the list
158
+ for (const example of exampleList)
159
+ {
160
+ const text = example.name + (example.description?' - ' + example.description : '');
161
+ const o = new Option(text);
162
+ o.disabled = !example.filename;
163
+ selectExample.add(o);
164
+ }
165
+
166
+ // select first option
167
+ selectExample.selectedIndex = 1;
168
+ setExample();
169
+
170
+ onresize = () =>
171
+ {
172
+ // resize iframe to fit half the window
173
+ const aspect = 1920 / 1080;
174
+ let w = innerWidth / 2 | 0;
175
+ let h = w / aspect | 0;
176
+ iframeContainer.style.width = w + 'px';
177
+ iframeContainer.style.height = h + 'px';
178
+ }
179
+ onresize();
180
+
181
+ ///////////////////////////////////////////////////////////////////////////////
182
+
183
+ function setExample()
184
+ {
185
+ const example = exampleList[selectExample.selectedIndex];
186
+ exampleInfo.innerText = example.name + (example.description ? ' - ' + example.description : '');
187
+ const filename = 'examples/' + example.filename;
188
+ exampleLink.href = 'https://github.com/KilledByAPixel/LittleJS/tree/main/' + filename;
189
+ exampleLink.innerText = filename;
190
+ loadFile(example.filename, example.fullExample);
191
+ }
192
+
193
+ function codeInput()
194
+ {
195
+ if (!checkboxLiveEdit.checked)
196
+ return;
197
+
198
+ // debounce input
199
+ clearTimeout(inputTimeout);
200
+ inputTimeout = setTimeout(() => setCode(textareaCode.value), 500);
201
+ }
202
+
203
+ function loadFile(filename, fullExample)
204
+ {
205
+ textareaCode.disabled = fullExample;
206
+ if (fullExample)
207
+ {
208
+ if (iframeExample)
209
+ iframeContainer.removeChild(iframeExample);
210
+
211
+ setErrorMessage();
212
+ iframeExample = document.createElement('iframe');
213
+ iframeContainer.appendChild(iframeExample);
214
+ iframeExample.onload = () =>
215
+ {
216
+ const iframeContent = iframeExample.contentWindow;
217
+ const iframeDocument = iframeContent.document;
218
+ //textareaCode.value = iframeDocument.body.innerHTML;
219
+ textareaCode.value = 'Editor code view not available for large examples.\n';
220
+ }
221
+ iframeExample.src = filename;
222
+ return;
223
+ }
224
+
225
+ fetch(filename)
226
+ .then(response => {
227
+ if (!response.ok)
228
+ throw new Error('Could not load file: '+ filename);
229
+ return response.text();
230
+ })
231
+ .then(text => setCode(textareaCode.value = text, fullExample))
232
+ .catch(error => setErrorMessage(error.message));
233
+ }
234
+
235
+ function setCode(code, largeExample)
236
+ {
237
+ clearTimeout(inputTimeout);
238
+ if (iframeExample)
239
+ iframeContainer.removeChild(iframeExample);
240
+
241
+ setErrorMessage();
242
+ iframeExample = document.createElement('iframe');
243
+ iframeContainer.appendChild(iframeExample);
244
+ iframeExample.onload = () =>
245
+ {
246
+ const iframeContent = iframeExample.contentWindow;
247
+ const iframeDocument = iframeContent.document;
248
+
249
+ // create error event listeners
250
+ iframeContent.onerror = (message, source, lineno, colno, error) =>
251
+ {
252
+ let text = message;
253
+ if (lineno)
254
+ text += ` (Line:${lineno}, Column:${colno})`
255
+ if (error && error.stack)
256
+ text += `\n\n` + error.stack;
257
+ setErrorMessage(text);
258
+ }
259
+ iframeContent.onunhandledrejection = (event) =>
260
+ {
261
+ let text = event.reason;
262
+ if (event.reason.stack)
263
+ text += `\n\n` + event.reason.stack;
264
+ setErrorMessage(text);
265
+ };
266
+ const originalAssert = iframeContent.console.assert;
267
+ iframeContent.console.assert = function (condition, output)
268
+ {
269
+ if (!condition)
270
+ setErrorMessage('Assertion failed: ' + (output || ''));
271
+ originalAssert.apply(this, arguments);
272
+ };
273
+
274
+ // create a script element that overrides the default functions
275
+ const overrideScript = iframeDocument.createElement('script');
276
+ iframeDocument.body.appendChild(overrideScript);
277
+ overrideScript.text = code;
278
+
279
+ if (textareaError.style.display == 'block')
280
+ return; // stop if script error
281
+
282
+ // start LittleJS engine
283
+ iframeContent.engineInit(iframeContent.gameInit, iframeContent.gameUpdate, iframeContent.gameUpdatePost, iframeContent.gameRender, iframeContent.gameRenderPost, ['tiles.png?1']);
284
+
285
+ buttonScreenshot.onclick = () =>
286
+ {
287
+ if (iframeContent.debugScreenshot)
288
+ iframeContent.debugScreenshot();
289
+ }
290
+ }
291
+ iframeExample.src = 'shorts/base.html';
292
+ }
293
+
294
+ function setErrorMessage(message='')
295
+ {
296
+ textareaError.value = message
297
+ textareaError.style.display = message ? 'block' : 'none';
298
+ }
299
+
300
+ </script>
301
+ </body>
302
+ </html>
@@ -7,4 +7,4 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- Add your game scripts here -->
10
- <script src=game.js?1116 type=module></script>
10
+ <script src=game.js?1117 type=module></script>
@@ -10,7 +10,7 @@ button { margin:1px; }
10
10
  </style>
11
11
  </head><body>
12
12
 
13
- <script src=../../dist/littlejs.js?1116></script>
13
+ <script src=../../dist/littlejs.js?1117></script>
14
14
  <script>
15
15
 
16
16
  'use strict';
@@ -13,17 +13,12 @@ class Player extends Character
13
13
  {
14
14
  update()
15
15
  {
16
- // player controls
16
+ // movement control
17
+ this.moveInput = isUsingGamepad ? gamepadStick(0) : keyDirection();
17
18
  this.holdingJump = keyIsDown('ArrowUp') || gamepadIsDown(0);
18
19
  this.holdingShoot = !isUsingGamepad && mouseIsDown(0) || keyIsDown('KeyZ') || gamepadIsDown(2);
19
20
  this.pressingThrow = keyIsDown('KeyC') || mouseIsDown(1) || gamepadIsDown(1);
20
21
  this.pressedDodge = keyIsDown('KeyX') || mouseIsDown(2) || gamepadIsDown(3);
21
-
22
- // movement control
23
- this.moveInput = isUsingGamepad ? gamepadStick(0) :
24
- vec2(keyIsDown('ArrowRight') - keyIsDown('ArrowLeft'),
25
- keyIsDown('ArrowUp') - keyIsDown('ArrowDown'));
26
-
27
22
  super.update();
28
23
  }
29
24
 
@@ -7,11 +7,11 @@
7
7
  <link rel=icon type=image/png href=../favicon.png>
8
8
  </head><body>
9
9
 
10
- <script src=../../dist/littlejs.js?1116></script>
11
- <script src=gameObjects.js?1116></script>
12
- <script src=gameCharacter.js?1116></script>
13
- <script src=gamePlayer.js?1116></script>
14
- <script src=gameEffects.js?1116></script>
15
- <script src=gameLevel.js?1116></script>
16
- <script src=gameLevelData.js?1116></script>
17
- <script src=game.js?1116></script>
10
+ <script src=../../dist/littlejs.js?1117></script>
11
+ <script src=gameObjects.js?1117></script>
12
+ <script src=gameCharacter.js?1117></script>
13
+ <script src=gamePlayer.js?1117></script>
14
+ <script src=gameEffects.js?1117></script>
15
+ <script src=gameLevel.js?1117></script>
16
+ <script src=gameLevelData.js?1117></script>
17
+ <script src=game.js?1117></script>
@@ -6,5 +6,5 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../dist/littlejs.js?1116></script>
10
- <script src=game.js?1116></script>
9
+ <script src=../../dist/littlejs.js?1117></script>
10
+ <script src=game.js?1117></script>
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html><meta charset=utf-8><body>
2
+ <script src=../../dist/littlejs.js?1117></script>
3
+ <script>
4
+
5
+ 'use strict';
6
+
7
+ // use fixed size canvas for examples
8
+ canvasFixedSize = vec2(960, 540);
9
+
10
+ // fix bleeding from neighboring pixels
11
+ tileFixBleedScale = .5;
12
+
13
+ // allow improved scaling
14
+ canvasPixelated = false;
15
+
16
+ // disable watermark
17
+ showWatermark = false;
18
+
19
+ // these functions can be overridden for each example
20
+ function gameInit() {}
21
+ function gameUpdate() {}
22
+ function gameUpdatePost() {}
23
+ function gameRender() {}
24
+ function gameRenderPost() {}
25
+
26
+ </script>
@@ -1,6 +1,6 @@
1
1
  function gameRender()
2
2
  {
3
- const circleTile = tile(2, 128);
3
+ const circleTile = tile(2, 128); // get the circle tile
4
4
 
5
5
  // additive blend
6
6
  setBlendMode(1);
@@ -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,6 +24,7 @@ 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]));
@@ -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()
@@ -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
+ }
@@ -9,13 +9,17 @@ class TimerButton extends EngineObject
9
9
 
10
10
  update()
11
11
  {
12
+ // start or stop the timer when clicked
12
13
  if (mouseWasPressed(0) && isOverlapping(this.pos, this.size, mousePos))
13
14
  this.timer.isSet() ? this.timer.unset() : this.timer.set(this.time);
14
15
  }
15
16
 
16
17
  render()
17
18
  {
19
+ // get color based on timer state
18
20
  this.color = this.timer.isSet() ? this.timer.active() ? BLUE : RED : GRAY;
21
+
22
+ // draw the button and timer text
19
23
  drawRect(this.pos, this.size, this.color);
20
24
  if (this.timer.isSet())
21
25
  {
@@ -30,7 +34,7 @@ class TimerButton extends EngineObject
30
34
 
31
35
  function gameInit()
32
36
  {
33
- new TimerButton(vec2(-7, 0), 3);
34
- new TimerButton(vec2( 0, 0), 1);
35
- new TimerButton(vec2( 7, 0), 0);
37
+ // create some timer buttons
38
+ new TimerButton(vec2(-5, 0), 3);
39
+ new TimerButton(vec2( 5, 0), 0);
36
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
+ }
@@ -7,18 +7,18 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- LittleJS Engine -->
10
- <script src=../../src/engineDebug.js?1116></script>
11
- <script src=../../src/engineUtilities.js?1116></script>
12
- <script src=../../src/engineSettings.js?1116></script>
13
- <script src=../../src/engineObject.js?1116></script>
14
- <script src=../../src/engineDraw.js?1116></script>
15
- <script src=../../src/engineInput.js?1116></script>
16
- <script src=../../src/engineAudio.js?1116></script>
17
- <script src=../../src/engineTileLayer.js?1116></script>
18
- <script src=../../src/engineParticles.js?1116></script>
19
- <script src=../../src/engineMedals.js?1116></script>
20
- <script src=../../src/engineWebGL.js?1116></script>
21
- <script src=../../src/engine.js?1116></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?1116></script>
24
+ <script src=game.js?1117></script>