littlejsengine 1.1.26 → 1.2.9

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 (40) hide show
  1. package/README.md +7 -9
  2. package/build.bat +1 -1
  3. package/engine/engine.all.js +369 -377
  4. package/engine/engine.all.min.js +1 -1
  5. package/engine/engine.all.release.js +338 -147
  6. package/engine/engine.js +7 -7
  7. package/engine/engineAudio.js +2 -2
  8. package/engine/engineBuild.bat +9 -1
  9. package/engine/engineDebug.js +32 -231
  10. package/engine/engineDraw.js +130 -20
  11. package/engine/engineFont.png +0 -0
  12. package/engine/engineInput.js +32 -9
  13. package/engine/engineMedals.js +7 -4
  14. package/engine/engineObject.js +30 -11
  15. package/engine/engineParticles.js +5 -3
  16. package/engine/engineSettings.js +5 -0
  17. package/engine/engineTileLayer.js +17 -14
  18. package/engine/engineUtilities.js +50 -18
  19. package/engine/engineWebGL.js +53 -59
  20. package/engine/index.d.ts +1644 -0
  21. package/examples/breakout/game.js +9 -7
  22. package/examples/breakout/gameObjects.js +3 -3
  23. package/examples/breakout/index.html +3 -3
  24. package/examples/particles/index.html +366 -0
  25. package/examples/particles/tiles.png +0 -0
  26. package/examples/platformer/game.js +5 -5
  27. package/examples/platformer/gameEffects.js +10 -10
  28. package/examples/platformer/gameLevel.js +3 -3
  29. package/examples/platformer/gameObjects.js +3 -3
  30. package/examples/platformer/gamePlayer.js +11 -6
  31. package/examples/platformer/index.html +6 -6
  32. package/examples/platformer/tiles.png +0 -0
  33. package/examples/puzzle/game.js +3 -3
  34. package/examples/puzzle/index.html +2 -2
  35. package/examples/screenshot.jpg +0 -0
  36. package/examples/stress/index.html +4 -4
  37. package/game.js +4 -7
  38. package/index.html +13 -13
  39. package/package.json +8 -1
  40. package/engine/engineBuildSetup.bat +0 -6
@@ -47,21 +47,23 @@ function gameUpdatePost()
47
47
  ///////////////////////////////////////////////////////////////////////////////
48
48
  function gameRender()
49
49
  {
50
- // draw a grey square for the background
51
- drawRect(cameraPos, levelSize, new Color(.2,.2,.2));
50
+ // draw a the background
51
+ drawRect(cameraPos, levelSize.scale(2), new Color(.4,.4,.4));
52
+ drawRect(cameraPos, levelSize, new Color(.1,.1,.1));
52
53
  }
53
54
 
54
55
  ///////////////////////////////////////////////////////////////////////////////
55
56
  function gameRenderPost()
56
57
  {
57
- // draw text on top of everything
58
- drawText('Score: ' + score, cameraPos.add(vec2(0,21)), 2, new Color, .2);
58
+ // use built in image font for text
59
+ const font = new FontImage;
60
+ font.drawText('Score: ' + score, cameraPos.add(vec2(0,22)), .2, 1);
59
61
  if (!blockCount)
60
- drawText('You Win!', cameraPos.add(vec2(0,-5)), 2, new Color, .2);
62
+ font.drawText('You Win!', cameraPos.add(vec2(0,-5)), .25, 1);
61
63
  else if (!ball)
62
- drawText('Click to Play', cameraPos.add(vec2(0,-5)), 2, new Color, .2);
64
+ font.drawText('Click to Play', cameraPos.add(vec2(0,-5)), .25, 1);
63
65
  }
64
66
 
65
67
  ///////////////////////////////////////////////////////////////////////////////
66
68
  // Startup LittleJS Engine
67
- engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, 'tiles.png');
69
+ engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, 'tiles.png?1');
@@ -28,7 +28,7 @@ class Paddle extends EngineObject
28
28
  // move to mouse
29
29
  this.pos.x = mousePos.x;
30
30
  }
31
- this.pos.x = clamp(this.pos.x, levelSize.x - this.size.x/2, this.size.x/2);
31
+ this.pos.x = clamp(this.pos.x, this.size.x/2, levelSize.x - this.size.x/2);
32
32
  }
33
33
  }
34
34
 
@@ -56,11 +56,11 @@ class Block extends EngineObject
56
56
  const color1 = this.color;
57
57
  const color2 = color1.lerp(new Color, .5);
58
58
  new ParticleEmitter(
59
- this.pos, this.size, .1, 200, PI, // pos, emitSize, emitTime, emitRate, emiteCone
59
+ this.pos, 0, this.size, .1, 200, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
60
60
  0, vec2(16), // tileIndex, tileSize
61
61
  color1, color2, // colorStartA, colorStartB
62
62
  color1.scale(1,0), color2.scale(1,0), // colorEndA, colorEndB
63
- .2, 1, 1, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
63
+ .2, 1, 1, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
64
64
  .99, .95, .4, PI, .1, // damping, angleDamping, gravityScale, particleCone, fadeRate,
65
65
  1, 0, 1 // randomness, collide, additive, randomColorLinear, renderOrder
66
66
  );
@@ -5,6 +5,6 @@
5
5
  <link rel=icon type=image/png href=../../favicon.png>
6
6
  </head><body>
7
7
 
8
- <script src=../../engine/engine.all.js?92></script>
9
- <script src=game.js?92></script>
10
- <script src=gameObjects.js?92></script>
8
+ <script src=../../engine/engine.all.js?104></script>
9
+ <script src=game.js?104></script>
10
+ <script src=gameObjects.js?104></script>
@@ -0,0 +1,366 @@
1
+ <html><head><meta charset=utf-8>
2
+ <meta name=viewport content=width=device-width,height=device-height,initial-scale=1,maximum-scale=1>
3
+ <meta name=apple-mobile-web-app-capable content=yes>
4
+ <meta name=mobile-web-app-capable content=yes>
5
+ <link rel=icon type=image/png href=favicon.png>
6
+ <style>
7
+ input
8
+ {
9
+ width:99px;
10
+ }
11
+ button
12
+ {
13
+ margin:1px;
14
+ }
15
+ </style>
16
+ </head><body>
17
+
18
+ <script src=../../engine/engineDebug.js?104></script>
19
+ <script src=../../engine/engineUtilities.js?104></script>
20
+ <script src=../../engine/engineSettings.js?104></script>
21
+ <script src=../../engine/engineObject.js?104></script>
22
+ <script src=../../engine/engineDraw.js?104></script>
23
+ <script src=../../engine/engineInput.js?104></script>
24
+ <script src=../../engine/engineAudio.js?104></script>
25
+ <script src=../../engine/engineTileLayer.js?104></script>
26
+ <script src=../../engine/engineParticles.js?104></script>
27
+ <script src=../../engine/engineMedals.js?104></script>
28
+ <script src=../../engine/engineWebGL.js?104></script>
29
+ <script src=../../engine/engine.js?104></script>
30
+ <script>
31
+
32
+ 'use strict';
33
+
34
+ let particleEditor = 0, particleSystem, particleSystemDiv, particleSystemCode;
35
+ let inputCondense;
36
+ let restartTimer = new Timer();
37
+ const storagePrefix = 'particles_';
38
+
39
+ const particleSettings = [];
40
+ function addSetting(name, type, min, max, step, description)
41
+ {
42
+ particleSettings.push({name, type:type||'number', min, max, step, description});
43
+ }
44
+
45
+ addSetting('emitSize', '', 0, 1e9, .1);
46
+ addSetting('emitTime', '', 0, 1e9, .1);
47
+ addSetting('emitRate', '', 0, 1e9, 1);
48
+ addSetting('emitConeAngle', '', 0, 1e9, .01);
49
+ addSetting('tileIndex', '', -1, 1e9, 1);
50
+ addSetting('tileSizeX', '', 0, 1e9, 1);
51
+ addSetting('tileSizeY', '', 0, 1e9, 1);
52
+ addSetting('colorStartA', 'color');
53
+ addSetting('colorStartB', 'color');
54
+ addSetting('colorEndA', 'color');
55
+ addSetting('colorEndB', 'color');
56
+ addSetting('colorAlphaStartA', 'alpha', 0, 1, .01);
57
+ addSetting('colorAlphaStartB', 'alpha', 0, 1, .01);
58
+ addSetting('colorAlphaEndA', 'alpha', 0, 1, .01);
59
+ addSetting('colorAlphaEndB', 'alpha', 0, 1, .01);
60
+ addSetting('particleTime', '', 0, 1e9, .1);
61
+ addSetting('sizeStart', '', 0, 1e9, .01);
62
+ addSetting('sizeEnd', '', 0, 1e9, .01);
63
+ addSetting('speed', '', 0, 1e9, .01);
64
+ addSetting('angleSpeed', '', 0, 1e9, .01);
65
+ addSetting('damping', '', 0, 1, .01);
66
+ addSetting('angleDamping', '', 0, 1, .01);
67
+ addSetting('gravityScale', '', -1e9, 1e9, .1);
68
+ addSetting('particleConeAngle','', 0, 1e9, .1);
69
+ addSetting('fadeRate', '', 0, 1, .01);
70
+ addSetting('randomness', '', 0, 1, .01);
71
+ addSetting('collideTiles', 'checkbox');
72
+ addSetting('additive', 'checkbox');
73
+ addSetting('randomColorLinear','checkbox');
74
+
75
+ function makeEmitter()
76
+ {
77
+ particleSystem = new ParticleEmitter(cameraPos);
78
+ particleSystem.emitConeAngle =
79
+ particleSystem.particleConeAngle = 3.14;
80
+ }
81
+
82
+ ///////////////////////////////////////////////////////////////////////////////
83
+ function gameInit()
84
+ {
85
+ makeEmitter();
86
+ gravity = -.01;
87
+ cameraScale = 50;
88
+
89
+ const div = particleSystemDiv = document.createElement('div');
90
+ div.innerHTML = '<big><b>LittleJS Particle Tool';
91
+ div.style = 'position:absolute;top:10;left:10;color:#fff';
92
+ document.body.appendChild(div);
93
+
94
+ for (const setting of particleSettings)
95
+ {
96
+ const input = setting.input = document.createElement('input');
97
+ const name = setting.name;
98
+ input.oninput = (e)=> updateParticles();
99
+ input.type = setting.type == 'alpha' ? 'number' : setting.type;
100
+ if (setting.min !== undefined)
101
+ input.min = setting.min;
102
+ if (setting.max !== undefined)
103
+ input.max = setting.max;
104
+ if (setting.step !== undefined)
105
+ input.step = setting.step;
106
+ if (name == 'emitConeAngle' || name == 'particleConeAngle')
107
+ particleSystem[name] = 3.14; // simplify pi
108
+
109
+ div.appendChild(document.createElement('br'));
110
+ div.appendChild(input);
111
+ div.appendChild(document.createTextNode(' ' + name));
112
+ }
113
+
114
+ div.appendChild(document.createElement('br'));
115
+ div.appendChild(document.createElement('br'));
116
+
117
+ {
118
+ const button = document.createElement('button')
119
+ div.appendChild(button);
120
+ button.innerHTML = 'Copy To Clipboard';
121
+ button.onclick = (e)=> navigator.clipboard.writeText(particleSystemCode.value);
122
+ }
123
+ {
124
+ const button = document.createElement('button');
125
+ div.appendChild(button);
126
+ button.innerHTML = 'Reset';
127
+ button.onclick = (e)=>
128
+ {
129
+ if (!confirm('Reset to default?'))
130
+ return;
131
+ particleSystem.destroy();
132
+ makeEmitter();
133
+ updateInputs(0);
134
+ cameraScale = 50;
135
+ }
136
+ }
137
+ {
138
+ inputCondense = document.createElement('input');
139
+ div.appendChild(inputCondense);
140
+ inputCondense.checked = 'true';
141
+ inputCondense.type = 'checkbox';
142
+ inputCondense.style.width = 'initial';
143
+ inputCondense.oninput = (e)=> updateParticles();
144
+ div.appendChild(document.createTextNode(' Condense'));
145
+ }
146
+
147
+ //div.appendChild(document.createTextNode('JavaScript Code... '));
148
+ div.appendChild(document.createElement('br'));
149
+ div.appendChild(particleSystemCode = document.createElement('textarea'));
150
+ particleSystemCode.style.width = 500;
151
+ particleSystemCode.style.height = 100;
152
+ particleSystemCode.disabled = true;
153
+
154
+ updateInputs(0);
155
+
156
+ // load from storage
157
+ for (const setting of particleSettings)
158
+ {
159
+ const type = setting.type;
160
+ const storageName = storagePrefix + setting.name;
161
+ const savedValue = localStorage[storageName];
162
+ if (savedValue == undefined)
163
+ continue;
164
+
165
+ if (type == 'checkbox')
166
+ setting.input.checked = savedValue == 'true';
167
+ else
168
+ setting.input.value = savedValue;
169
+ }
170
+
171
+ updateParticles();
172
+ }
173
+
174
+ function updateParticles()
175
+ {
176
+ for (const setting of particleSettings)
177
+ {
178
+ const input = setting.input;
179
+ const name = setting.name;
180
+ const type = setting.type;
181
+ const inputFloat = parseFloat(input.value) || 0;
182
+ if (type == 'color')
183
+ {
184
+ const color = new Color().setHex(input.value);
185
+ particleSystem[name].r = color.r;
186
+ particleSystem[name].g = color.g;
187
+ particleSystem[name].b = color.b;
188
+ }
189
+ else if (type == 'alpha')
190
+ {
191
+ if (name == 'colorAlphaStartA')
192
+ particleSystem.colorStartA.a = clamp(inputFloat);
193
+ else if (name == 'colorAlphaStartB')
194
+ particleSystem.colorStartB.a = clamp(inputFloat);
195
+ else if (name == 'colorAlphaEndA')
196
+ particleSystem.colorEndA.a = clamp(inputFloat);
197
+ else if (name == 'colorAlphaEndB')
198
+ particleSystem.colorEndB.a = clamp(inputFloat);
199
+ }
200
+ else if (name == 'tileSizeX')
201
+ {
202
+ particleSystem.tileSize = vec2(parseInt(input.value), particleSystem.tileSize.y);
203
+ }
204
+ else if (name == 'tileSizeY')
205
+ {
206
+ particleSystem.tileSize = vec2(particleSystem.tileSize.x, parseInt(input.value));
207
+ }
208
+ else if (type == 'checkbox')
209
+ particleSystem[name] = input.checked ? 1 : 0;
210
+ else if (name == 'emitRate')
211
+ particleSystem[name] = min(inputFloat,1e3);
212
+ else
213
+ particleSystem[name] = clamp(inputFloat, setting.min, setting.max);
214
+ }
215
+ updateInputs();
216
+ }
217
+
218
+ function updateInputs(save=1)
219
+ {
220
+ for (const setting of particleSettings)
221
+ {
222
+ const input = setting.input;
223
+ const name = setting.name;
224
+ const type = setting.type;
225
+
226
+ if (type == 'color')
227
+ {
228
+ const color = particleSystem[name];
229
+ input.value = color.hex();
230
+ }
231
+ else if (type == 'alpha')
232
+ {
233
+ if (name == 'colorAlphaStartA')
234
+ input.value = particleSystem.colorStartA.a;
235
+ else if (name == 'colorAlphaStartB')
236
+ input.value = particleSystem.colorStartB.a;
237
+ else if (name == 'colorAlphaEndA')
238
+ input.value = particleSystem.colorEndA.a;
239
+ else if (name == 'colorAlphaEndB')
240
+ input.value = particleSystem.colorEndB.a;
241
+ }
242
+ else if (name == 'tileSizeX')
243
+ input.value = particleSystem.tileSize.x;
244
+ else if (name == 'tileSizeY')
245
+ input.value = particleSystem.tileSize.y;
246
+ else if (type == 'checkbox')
247
+ input.checked = particleSystem[name];
248
+ else
249
+ input.value = particleSystem[name] || '0';
250
+
251
+ if (save)
252
+ {
253
+ const storageName = storagePrefix + setting.name;
254
+ localStorage[storageName] = type == 'checkbox' ?
255
+ input.checked : input.value;
256
+ }
257
+ }
258
+ particleSystemCode.value = getCode();
259
+ }
260
+
261
+ function getCode()
262
+ {
263
+ const condense = inputCondense.checked;
264
+ let code = '';
265
+
266
+ // https://www.codingem.com/javascript-how-to-limit-decimal-places/
267
+ Number.prototype.round = function(n) {
268
+ const d = Math.pow(10, n);
269
+ return Math.round((this + Number.EPSILON) * d) / d;
270
+ }
271
+
272
+ code = 'new ParticleEmitter(';
273
+ if (condense)
274
+ code += 'vec2(), 0, ';
275
+ else
276
+ code += '\n vec2(), 0,\t//position, angle\n';
277
+
278
+ let count = 0;
279
+ for (const setting of particleSettings)
280
+ {
281
+ const name = setting.name;
282
+ const type = setting.type;
283
+ let value;
284
+ if (name == 'tileSizeX' || type == 'alpha')
285
+ continue;
286
+
287
+ if (name == 'tileSizeY')
288
+ value = `vec2(${particleSystem.tileSize.x}, ${particleSystem.tileSize.y})`;
289
+ else if (type == 'color')
290
+ {
291
+ const c = particleSystem[name];
292
+ const p = 3;
293
+ value = `new Color(${c.r.round(p)}, ${c.g.round(p)}, ${c.b.round(p)}, ${c.a.round(p)})`;
294
+ }
295
+ else if (type == 'checkbox')
296
+ value = particleSystem[name] ? 1 : 0;
297
+ else
298
+ value = particleSystem[name].round(3);
299
+ if (!condense)
300
+ code += ' ';
301
+ code += value;
302
+
303
+ const isEnd = name == 'randomColorLinear';
304
+ if (!condense)
305
+ {
306
+ code += ',\t// ' + name;
307
+ if (!isEnd)
308
+ code += '\n';
309
+ }
310
+ else if (!isEnd)
311
+ code += ', ';
312
+ }
313
+
314
+
315
+ if (condense)
316
+ code += ');';
317
+ else
318
+ code += '\n); // particle emitter';
319
+
320
+ return code;
321
+ }
322
+
323
+ ///////////////////////////////////////////////////////////////////////////////
324
+ function gameUpdate()
325
+ {
326
+ if (!restartTimer.isSet() && particleSystem.destroyed)
327
+ restartTimer.set(1);
328
+ else if (restartTimer.elapsed())
329
+ {
330
+ restartTimer.unset()
331
+ makeEmitter();
332
+ updateParticles();
333
+ }
334
+
335
+ if (document.activeElement == document.body)
336
+ {
337
+ particleSystem.pos = mouseIsDown(0) ? mousePos : vec2();
338
+ if (mouseWheel)
339
+ {
340
+ cameraScale -= sign(mouseWheel)*cameraScale/5;
341
+ cameraScale = clamp(cameraScale, 10, 300);
342
+ }
343
+ }
344
+ }
345
+
346
+ ///////////////////////////////////////////////////////////////////////////////
347
+ function gameUpdatePost()
348
+ {
349
+
350
+ }
351
+
352
+ ///////////////////////////////////////////////////////////////////////////////
353
+ function gameRender()
354
+ {
355
+ }
356
+
357
+ ///////////////////////////////////////////////////////////////////////////////
358
+ function gameRenderPost()
359
+ {
360
+ }
361
+
362
+ ///////////////////////////////////////////////////////////////////////////////
363
+ // Startup LittleJS Engine
364
+ engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, 'tiles.png');
365
+
366
+ </script>
Binary file
@@ -33,7 +33,7 @@ function gameUpdate()
33
33
  }
34
34
 
35
35
  // mouse wheel = zoom
36
- cameraScale = clamp(cameraScale*(1-mouseWheel/10), 1e3, 1);
36
+ cameraScale = clamp(cameraScale*(1-mouseWheel/10), 1, 1e3);
37
37
 
38
38
  // T = drop test crate
39
39
  if (keyWasPressed(84))
@@ -73,18 +73,18 @@ function gameRender()
73
73
  function gameRenderPost()
74
74
  {
75
75
  // draw to overlay canvas for hud rendering
76
- const drawText = (text, x, y, size=70) =>
76
+ const drawText = (text, x, y, size=50) =>
77
77
  {
78
78
  overlayContext.textAlign = 'center';
79
79
  overlayContext.textBaseline = 'top';
80
80
  overlayContext.font = size + 'px arial';
81
81
  overlayContext.fillStyle = '#fff';
82
- overlayContext.lineWidth = 3;
82
+ overlayContext.lineWidth = 2;
83
83
  overlayContext.strokeText(text, x, y);
84
84
  overlayContext.fillText(text, x, y);
85
85
  }
86
- drawText('Score: ' + score, overlayCanvas.width*1/3, 20);
87
- drawText('Deaths: ' + deaths, overlayCanvas.width*2/3, 20);
86
+ drawText('Score: ' + score, overlayCanvas.width*1/4, 20);
87
+ drawText('Deaths: ' + deaths, overlayCanvas.width*3/4, 20);
88
88
  }
89
89
 
90
90
  ///////////////////////////////////////////////////////////////////////////////
@@ -39,7 +39,7 @@ function makeDebris(pos, color = new Color, amount = 100, size=.2, elasticity =
39
39
  {
40
40
  const color2 = color.lerp(new Color, .5);
41
41
  const emitter = new ParticleEmitter(
42
- pos, 1, .1, 100, PI, // pos, emitSize, emitTime, emitRate, emiteCone
42
+ pos, 0, 1, .1, 100, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
43
43
  undefined, undefined, // tileIndex, tileSize
44
44
  color, color2, // colorStartA, colorStartB
45
45
  color, color2, // colorEndA, colorEndB
@@ -89,7 +89,7 @@ function explosion(pos, radius=3)
89
89
  }
90
90
 
91
91
  // push
92
- const p = percent(d, radius, 2*radius);
92
+ const p = percent(d, 2*radius, radius);
93
93
  const force = o.pos.subtract(pos).normalize(p*radius*.2);
94
94
  o.applyForce(force);
95
95
  if (o.isDead && o.isDead())
@@ -100,7 +100,7 @@ function explosion(pos, radius=3)
100
100
 
101
101
  // smoke
102
102
  new ParticleEmitter(
103
- pos, radius/2, .2, 50*radius, PI, // pos, emitSize, emitTime, emitRate, emiteCone
103
+ pos, 0, radius/2, .2, 50*radius, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
104
104
  0, undefined, // tileIndex, tileSize
105
105
  new Color(0,0,0), new Color(0,0,0), // colorStartA, colorStartB
106
106
  new Color(0,0,0,0), new Color(0,0,0,0), // colorEndA, colorEndB
@@ -111,7 +111,7 @@ function explosion(pos, radius=3)
111
111
 
112
112
  // fire
113
113
  new ParticleEmitter(
114
- pos, radius/2, .1, 100*radius, PI, // pos, emitSize, emitTime, emitRate, emiteCone
114
+ pos, 0, radius/2, .1, 100*radius, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
115
115
  0, undefined, // tileIndex, tileSize
116
116
  new Color(1,.5,.1), new Color(1,.1,.1), // colorStartA, colorStartB
117
117
  new Color(1,.5,.1,0), new Color(1,.1,.1,0), // colorEndA, colorEndB
@@ -203,7 +203,7 @@ function decorateTile(pos)
203
203
 
204
204
  // make pixel perfect outlines
205
205
  const size = i&1 ? vec2(2, 16) : vec2(16, 2);
206
- tileLayer.context.fillStyle = levelGroundColor.mutate(.1).rgba();
206
+ tileLayer.context.fillStyle = levelGroundColor.mutate(.1);
207
207
  const drawPos = pos.scale(16)
208
208
  .add(vec2(i==1?14:0,(i==0?14:0)))
209
209
  .subtract((i&1? vec2(0,8-size.y/2) : vec2(8-size.x/2,0)));
@@ -228,8 +228,8 @@ function drawSky()
228
228
  {
229
229
  // fill background with a gradient
230
230
  const gradient = mainContext.fillStyle = mainContext.createLinearGradient(0, 0, 0, mainCanvas.height);
231
- gradient.addColorStop(0, skyColor.rgba());
232
- gradient.addColorStop(1, horizonColor.rgba());
231
+ gradient.addColorStop(0, skyColor);
232
+ gradient.addColorStop(1, horizonColor);
233
233
  mainContext.fillRect(0, 0, mainCanvas.width, mainCanvas.height);
234
234
  }
235
235
 
@@ -257,7 +257,7 @@ function drawStars()
257
257
  (randSeeded(w)+time*speed)%w-extraSpace,
258
258
  (randSeeded(h)+time*speed*randSeeded())%h-extraSpace);
259
259
 
260
- mainContext.fillStyle = color.rgba();
260
+ mainContext.fillStyle = color;
261
261
  if (size < 9)
262
262
  mainContext.fillRect(screenPos.x, screenPos.y, size, size);
263
263
  else
@@ -285,8 +285,8 @@ function initParallaxLayers()
285
285
  const layerColor = levelColor.mutate(.2).lerp(skyColor,.95-i*.15);
286
286
  const gradient = tileParallaxLayer.context.fillStyle =
287
287
  tileParallaxLayer.context.createLinearGradient(0,0,0,tileParallaxLayer.canvas.height = parallaxSize.y);
288
- gradient.addColorStop(0,layerColor.rgba());
289
- gradient.addColorStop(1,layerColor.subtract(new Color(1,1,1,0)).mutate(.1).clamp().rgba());
288
+ gradient.addColorStop(0,layerColor);
289
+ gradient.addColorStop(1,layerColor.subtract(new Color(1,1,1,0)).mutate(.1).clamp());
290
290
 
291
291
  // draw mountains ranges
292
292
  let groundLevel = startGroundLevel, groundSlope = rand(-1,1);
@@ -46,7 +46,7 @@ function buildTerrain(size)
46
46
  {
47
47
  // big jump
48
48
  const jumpDelta = rand(19,-19);
49
- startGroundLevel = clamp(startGroundLevel + jumpDelta, 80, 20);
49
+ startGroundLevel = clamp(startGroundLevel + jumpDelta, 20, 80);
50
50
  groundLevel += jumpDelta;
51
51
  groundSlope = rand(-1,1);
52
52
  }
@@ -58,9 +58,9 @@ function buildTerrain(size)
58
58
  backgroundDelta = 0;
59
59
  if (rand() < .1)
60
60
  backgroundDeltaSlope = rand(-1,1);
61
- backgroundDelta = clamp(backgroundDelta, 3, -1)
61
+ backgroundDelta = clamp(backgroundDelta, -1, 3)
62
62
 
63
- groundLevel = clamp(groundLevel, levelSize.y-20, 20);
63
+ groundLevel = clamp(groundLevel, 20, levelSize.y-20);
64
64
  for (let y=0; y < size.y; y++)
65
65
  {
66
66
  const pos = vec2(x,y);
@@ -25,7 +25,7 @@ class GameObject extends EngineObject
25
25
  // flash white when damaged
26
26
  if (!this.isDead() && this.damageTimer.isSet())
27
27
  {
28
- const a = .5*percent(this.damageTimer.get(), 0, .15);
28
+ const a = .5*percent(this.damageTimer.get(), .15, 0);
29
29
  this.additiveColor = new Color(a,a,a,0);
30
30
  }
31
31
  else
@@ -210,7 +210,7 @@ class Weapon extends EngineObject
210
210
 
211
211
  // shell effect
212
212
  this.addChild(this.shellEmitter = new ParticleEmitter(
213
- vec2(), 0, 0, 0, .1, // pos, emitSize, emitTime, emitRate, emiteCone
213
+ vec2(), 0, 0, 0, 0, .1, // pos, angle, emitSize, emitTime, emitRate, emiteCone
214
214
  undefined, undefined, // tileIndex, tileSize
215
215
  new Color(1,.8,.5), new Color(.9,.7,.5), // colorStartA, colorStartB
216
216
  new Color(1,.8,.5), new Color(.9,.7,.5), // colorEndA, colorEndB
@@ -321,7 +321,7 @@ class Bullet extends EngineObject
321
321
 
322
322
  // spark effects
323
323
  const emitter = new ParticleEmitter(
324
- this.pos, 0, .1, 100, .5, // pos, emitSize, emitTime, emitRate, emiteCone
324
+ this.pos, 0, 0, .1, 100, .5, // pos, angle, emitSize, emitTime, emitRate, emiteCone
325
325
  undefined, undefined, // tileIndex, tileSize
326
326
  new Color(1,1,0), new Color(1,0,0), // colorStartA, colorStartB
327
327
  new Color(1,1,0), new Color(1,0,0), // colorEndA, colorEndB
@@ -126,7 +126,12 @@ class Character extends GameObject
126
126
  {
127
127
  // update jumping and ground check
128
128
  if (this.groundObject || this.climbingWall)
129
+ {
130
+ if (!this.groundTimer.isSet())
131
+ sound_walk.play(this.pos); // land sound
132
+
129
133
  this.groundTimer.set(.1);
134
+ }
130
135
 
131
136
  if (this.groundTimer.active() && !this.dodgeTimer.active())
132
137
  {
@@ -169,7 +174,7 @@ class Character extends GameObject
169
174
 
170
175
  // apply movement acceleration and clamp
171
176
  const maxCharacterSpeed = .2;
172
- this.velocity.x = clamp(this.velocity.x + moveInput.x * .042, maxCharacterSpeed, -maxCharacterSpeed);
177
+ this.velocity.x = clamp(this.velocity.x + moveInput.x * .042, -maxCharacterSpeed, maxCharacterSpeed);
173
178
 
174
179
  // track last pos for ladder collision code
175
180
  this.lastPos = this.pos.copy();
@@ -189,16 +194,16 @@ class Character extends GameObject
189
194
 
190
195
  // update walk sound
191
196
  this.walkSoundTime += speed;
192
- if (speed > .01 && ((this.climbingLadder || this.groundTimer.active()) && !this.dodgeTimer.active()))
197
+ if (speed > .001 && ((this.climbingLadder || this.groundTimer.active()) && !this.dodgeTimer.active()))
193
198
  {
194
199
  if (this.walkSoundTime > 1)
195
200
  {
196
- this.walkSoundTime = 0;
201
+ this.walkSoundTime = this.walkSoundTime%1;
197
202
  sound_walk.play(this.pos);
198
203
  }
199
204
  }
200
205
  else
201
- this.walkSoundTime = .5;
206
+ this.walkSoundTime = 0;
202
207
 
203
208
  // update mirror
204
209
  if (moveInput.x && !this.dodgeTimer.active())
@@ -292,8 +297,8 @@ class Player extends Character
292
297
  // player controls
293
298
  this.holdingJump = keyIsDown(38) || gamepadIsDown(0);
294
299
  this.holdingShoot = mouseIsDown(0) || keyIsDown(90) || gamepadIsDown(2);
295
- this.pressedDodge = mouseIsDown(1) || keyIsDown(88) || gamepadIsDown(3);
296
- this.pressingThrow = mouseIsDown(2) || keyIsDown(67) || gamepadIsDown(1);
300
+ this.pressingThrow = mouseIsDown(1) || keyIsDown(67) || gamepadIsDown(1);
301
+ this.pressedDodge = mouseIsDown(2) || keyIsDown(88) || gamepadIsDown(3);
297
302
 
298
303
  // movement control
299
304
  this.moveInput = isUsingGamepad ? gamepadStick(0) :
@@ -5,9 +5,9 @@
5
5
  <link rel=icon type=image/png href=../../favicon.png>
6
6
  </head><body>
7
7
 
8
- <script src=../../engine/engine.all.js?92></script>
9
- <script src=gameObjects.js?92></script>
10
- <script src=gamePlayer.js?92></script>
11
- <script src=gameEffects.js?92></script>
12
- <script src=gameLevel.js?92></script>
13
- <script src=game.js?92></script>
8
+ <script src=../../engine/engine.all.js?104></script>
9
+ <script src=gameObjects.js?104></script>
10
+ <script src=gamePlayer.js?104></script>
11
+ <script src=gameEffects.js?104></script>
12
+ <script src=gameLevel.js?104></script>
13
+ <script src=game.js?103></script>
Binary file