littlejsengine 1.1.2 → 1.1.3

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 (94) hide show
  1. package/README.md +55 -0
  2. package/build.bat +2 -1
  3. package/engine/engine.all.js +1320 -930
  4. package/engine/engine.all.min.js +1 -1
  5. package/engine/engine.all.release.js +965 -601
  6. package/engine/engine.js +71 -60
  7. package/engine/engineAudio.js +80 -22
  8. package/engine/engineBuild.bat +2 -2
  9. package/engine/engineDebug.js +65 -36
  10. package/engine/engineDraw.js +71 -56
  11. package/engine/engineInput.js +178 -28
  12. package/engine/engineMedals.js +66 -58
  13. package/engine/engineObject.js +86 -71
  14. package/engine/engineParticles.js +101 -63
  15. package/engine/engineRelease.js +4 -1
  16. package/engine/engineSettings.js +62 -53
  17. package/engine/engineTileLayer.js +99 -83
  18. package/engine/engineUtilities.js +95 -59
  19. package/engine/engineWebGL.js +53 -48
  20. package/examples/breakout/game.js +1 -1
  21. package/examples/breakout/gameObjects.js +2 -2
  22. package/examples/breakout/index.html +7 -5
  23. package/examples/platformer/game.js +7 -4
  24. package/examples/platformer/gameEffects.js +8 -11
  25. package/examples/platformer/gameLevel.js +15 -8
  26. package/examples/platformer/gameObjects.js +2 -2
  27. package/examples/platformer/gamePlayer.js +6 -6
  28. package/examples/platformer/index.html +10 -8
  29. package/examples/puzzle/game.js +3 -3
  30. package/examples/puzzle/index.html +6 -4
  31. package/examples/stress/index.html +7 -5
  32. package/game.js +10 -10
  33. package/index.html +17 -15
  34. package/package.json +4 -7
  35. package/tiles.png +0 -0
  36. package/LittleJS.zip +0 -0
  37. package/docs/Audio.html +0 -2264
  38. package/docs/Color.html +0 -2506
  39. package/docs/Debug.html +0 -2929
  40. package/docs/Draw.html +0 -3854
  41. package/docs/EngineObject.html +0 -2506
  42. package/docs/Input.html +0 -2478
  43. package/docs/Medal.html +0 -992
  44. package/docs/Medals.html +0 -624
  45. package/docs/Music.html +0 -569
  46. package/docs/Newgrounds.html +0 -1384
  47. package/docs/Particle.html +0 -567
  48. package/docs/ParticleEmitter.html +0 -1537
  49. package/docs/Random.html +0 -1770
  50. package/docs/Settings.html +0 -2885
  51. package/docs/Sound.html +0 -998
  52. package/docs/TileLayer.html +0 -3211
  53. package/docs/TileLayerData.html +0 -569
  54. package/docs/Timer.html +0 -1168
  55. package/docs/Utilities.html +0 -3266
  56. package/docs/Vector2.html +0 -3956
  57. package/docs/WebGL.html +0 -1842
  58. package/docs/engine.js.html +0 -428
  59. package/docs/engineAudio.js.html +0 -567
  60. package/docs/engineDebug.js.html +0 -721
  61. package/docs/engineDraw.js.html +0 -409
  62. package/docs/engineInput.js.html +0 -397
  63. package/docs/engineMedals.js.html +0 -445
  64. package/docs/engineObject.js.html +0 -492
  65. package/docs/engineParticles.js.html +0 -399
  66. package/docs/engineSettings.js.html +0 -358
  67. package/docs/engineTileLayer.js.html +0 -482
  68. package/docs/engineUtilities.js.html +0 -600
  69. package/docs/engineWebGL.js.html +0 -507
  70. package/docs/fonts/MavenPro-Regular.ttf +0 -0
  71. package/docs/fonts/Montserrat-Regular.ttf +0 -0
  72. package/docs/fonts/Muli-Black.ttf +0 -0
  73. package/docs/fonts/OFL-hind.txt +0 -93
  74. package/docs/fonts/OFL-montserrat.txt +0 -93
  75. package/docs/global.html +0 -1635
  76. package/docs/index.html +0 -243
  77. package/docs/scripts/fix-code-block.js +0 -53
  78. package/docs/scripts/fix-navbar.js +0 -25
  79. package/docs/scripts/linenumber.js +0 -25
  80. package/docs/scripts/misc.js +0 -217
  81. package/docs/scripts/resize.js +0 -85
  82. package/docs/scripts/search.js +0 -83
  83. package/docs/scripts/third-party/Apache-License-2.0.txt +0 -202
  84. package/docs/scripts/third-party/fuse.js +0 -9
  85. package/docs/scripts/third-party/lang-css.js +0 -2
  86. package/docs/scripts/third-party/prettify.js +0 -28
  87. package/docs/static/favicon.png +0 -0
  88. package/docs/styles/clean-jsdoc-theme-base.css +0 -393
  89. package/docs/styles/clean-jsdoc-theme-dark.css +0 -324
  90. package/docs/styles/clean-jsdoc-theme-light.css +0 -319
  91. package/docs/styles/reset.css +0 -346
  92. package/docs/styles/third-party/ionicons.min.css +0 -11
  93. package/docs/styles/third-party/prettify-jsdoc.css +0 -111
  94. package/docs/styles/third-party/prettify-tomorrow.css +0 -5
@@ -1,12 +1,12 @@
1
1
  /**
2
- * LittleJS WebGL Interface
3
- * <br> - All webgl used by the engine is wrapped up here
4
- * <br> - Can be disabled with glEnable to revert to 2D canvas rendering
5
- * <br> - Batches sprite rendering on GPU for incredibly fast performance
6
- * <br> - Sprite transform math is done in the shader where possible
7
- * <br> - For normal stuff you won't need to call any functions in this file
8
- * <br> - For advanced stuff there are helper functions to create shaders, textures, etc
9
- * @namespace WebGL
2
+ * LittleJS WebGL Interface
3
+ * <br> - All webgl used by the engine is wrapped up here
4
+ * <br> - For normal stuff you won't need to see or call anything in this file
5
+ * <br> - For advanced stuff there are helper functions to create shaders, textures, etc
6
+ * <br> - Can be disabled with glEnable to revert to 2D canvas rendering
7
+ * <br> - Batches sprite rendering on GPU for incredibly fast performance
8
+ * <br> - Sprite transform math is done in the shader where possible
9
+ * @namespace WebGL
10
10
  */
11
11
 
12
12
  'use strict';
@@ -27,7 +27,7 @@ let glContext;
27
27
  let glTileTexture;
28
28
 
29
29
  // WebGL internal variables not exposed to documentation
30
- let glActiveTexture, glShader, glPositionData, glColorData, glBatchCount, glDirty, glAdditive;
30
+ let glActiveTexture, glShader, glPositionData, glColorData, glBatchCount, glBatchAdditive, glAdditive;
31
31
 
32
32
  ///////////////////////////////////////////////////////////////////////////////
33
33
 
@@ -38,19 +38,16 @@ function glInit()
38
38
 
39
39
  // create the canvas and tile texture
40
40
  glCanvas = document.createElement('canvas');
41
- glContext = glCanvas.getContext('webgl', {antialias:!pixelated});
41
+ glContext = glCanvas.getContext('webgl');
42
+ glCanvas.style = styleCanvas;
42
43
  glTileTexture = glCreateTexture(tileImage);
43
44
 
44
- if (glOverlay)
45
- {
46
- // firefox is much faster without copying the gl buffer so we just overlay it with some tradeoffs
47
- document.body.appendChild(glCanvas);
48
- glCanvas.style = mainCanvas.style.cssText;
49
- }
45
+ // some browsers are much faster without copying the gl buffer so we just overlay it instead
46
+ glOverlay && document.body.appendChild(glCanvas);
50
47
 
51
48
  // setup vertex and fragment shaders
52
49
  glShader = glCreateProgram(
53
- 'precision lowp float;'+ // use lowp for better performance
50
+ 'precision highp float;'+ // use highp for better accuracy, lowp for better perf
54
51
  'uniform mat4 m;'+ // transform matrix
55
52
  'attribute float a;'+ // angle
56
53
  'attribute vec2 p,s,t;'+ // position, size, uv
@@ -62,7 +59,7 @@ function glInit()
62
59
  'v=t;d=c;e=b;'+ // pass stuff to fragment shader
63
60
  '}' // end of shader
64
61
  ,
65
- 'precision lowp float;'+ // use lowp for better performance
62
+ 'precision highp float;'+ // use highp for better accuracy, lowp for better perf
66
63
  'varying vec2 v;'+ // uv
67
64
  'varying vec4 d,e;'+ // color, additiveColor
68
65
  'uniform sampler2D j;'+ // texture
@@ -78,6 +75,7 @@ function glInit()
78
75
  glColorData = new Uint32Array(glVertexData);
79
76
 
80
77
  // setup the vertex data array
78
+ let offset = glBatchCount = 0;
81
79
  const initVertexAttribArray = (name, type, typeSize, size, normalize=0)=>
82
80
  {
83
81
  const location = glContext.getAttribLocation(glShader, name);
@@ -85,7 +83,6 @@ function glInit()
85
83
  glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
86
84
  offset += size*typeSize;
87
85
  }
88
- let offset = glDirty = glBatchCount = 0;
89
86
  initVertexAttribArray('a', gl_FLOAT, 4, 1); // angle
90
87
  initVertexAttribArray('p', gl_FLOAT, 4, 2); // position
91
88
  initVertexAttribArray('s', gl_FLOAT, 4, 2); // size
@@ -101,14 +98,8 @@ function glSetBlendMode(additive)
101
98
  {
102
99
  if (!glEnable) return;
103
100
 
104
- if (additive != glAdditive)
105
- glFlush();
106
-
107
101
  // setup blending
108
102
  glAdditive = additive;
109
- const destBlend = additive ? gl_ONE : gl_ONE_MINUS_SRC_ALPHA;
110
- glContext.blendFuncSeparate(gl_SRC_ALPHA, destBlend, gl_ONE, destBlend);
111
- glContext.enable(gl_BLEND);
112
103
  }
113
104
 
114
105
  /** Set the WebGl texture, not normally necessary unless multiple tile sheets are used
@@ -118,7 +109,8 @@ function glSetBlendMode(additive)
118
109
  function glSetTexture(texture=glTileTexture)
119
110
  {
120
111
  if (!glEnable) return;
121
-
112
+
113
+ // must flush cache with the old texture to set a new one
122
114
  if (texture != glActiveTexture)
123
115
  glFlush();
124
116
 
@@ -183,36 +175,35 @@ function glCreateBuffer(bufferType, size, usage)
183
175
  return buffer;
184
176
  }
185
177
 
186
- /** Create WebGL texture from an image
178
+ /** Create WebGL texture from an image and set the texture settings
187
179
  * @param {Image} image
188
180
  * @return {WebGLTexture}
189
181
  * @memberof WebGL */
190
182
  function glCreateTexture(image)
191
183
  {
192
- if (!glEnable) return;
184
+ if (!glEnable || !image || !image.width) return;
193
185
 
194
186
  // build the texture
195
187
  const texture = glContext.createTexture();
196
188
  glContext.bindTexture(gl_TEXTURE_2D, texture);
197
189
  glContext.texImage2D(gl_TEXTURE_2D, 0, gl_RGBA, gl_RGBA, gl_UNSIGNED_BYTE, image);
198
-
190
+
199
191
  // use point filtering for pixelated rendering
200
- glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, pixelated ? gl_NEAREST : gl_LINEAR);
201
- glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, pixelated ? gl_NEAREST : gl_LINEAR);
192
+ glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, cavasPixelated ? gl_NEAREST : gl_LINEAR);
193
+ glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, cavasPixelated ? gl_NEAREST : gl_LINEAR);
202
194
  glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE);
203
195
  glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE);
204
196
  return texture;
205
197
  }
206
198
 
207
199
  // called automatically by engine before render
208
- function glPreRender(width, height)
200
+ function glPreRender(width, height, cameraX, cameraY, cameraScale)
209
201
  {
210
202
  if (!glEnable) return;
211
203
 
212
204
  // clear and set to same size as main canvas
213
- glCanvas.width = width;
214
- glCanvas.height = height;
215
- glContext.viewport(0, 0, width, height);
205
+ glContext.viewport(0, 0, glCanvas.width = width, glCanvas.height = height);
206
+ glContext.clear(gl_COLOR_BUFFER_BIT);
216
207
 
217
208
  // set up the shader
218
209
  glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = glTileTexture);
@@ -227,7 +218,7 @@ function glPreRender(width, height)
227
218
  sx, 0, 0, 0,
228
219
  0, sy, 0, 0,
229
220
  1, 1, -1, 1,
230
- -1-sx*cameraPos.x, -1-sy*cameraPos.y, 0, 0
221
+ -1-sx*cameraX, -1-sy*cameraY, 0, 0
231
222
  ])
232
223
  );
233
224
  }
@@ -238,11 +229,16 @@ function glFlush()
238
229
  {
239
230
  if (!glEnable || !glBatchCount) return;
240
231
 
232
+ const destBlend = glBatchAdditive ? gl_ONE : gl_ONE_MINUS_SRC_ALPHA;
233
+ glContext.blendFuncSeparate(gl_SRC_ALPHA, destBlend, gl_ONE, destBlend);
234
+ glContext.enable(gl_BLEND);
235
+
241
236
  // draw all the sprites in the batch and reset the buffer
242
237
  glContext.bufferSubData(gl_ARRAY_BUFFER, 0,
243
238
  glPositionData.subarray(0, glBatchCount * gl_VERTICES_PER_QUAD * gl_INDICIES_PER_VERT));
244
239
  glContext.drawArrays(gl_TRIANGLES, 0, glBatchCount * gl_VERTICES_PER_QUAD);
245
240
  glBatchCount = 0;
241
+ glBatchAdditive = glAdditive;
246
242
  }
247
243
 
248
244
  /** Draw any sprites still in the buffer, copy to main canvas and clear
@@ -251,29 +247,38 @@ function glFlush()
251
247
  * @memberof WebGL */
252
248
  function glCopyToContext(context, forceDraw)
253
249
  {
254
- if (!glEnable || !glDirty) return;
250
+ if (!glEnable || !glBatchCount) return;
255
251
 
256
252
  glFlush();
253
+
254
+ // do not draw in overlay mode because the canvas is visible
257
255
  if (!glOverlay || forceDraw)
258
- {
259
- // do not draw/clear in overlay mode because the canvas is visible
260
- context.drawImage(glCanvas, 0, glAdditive = glDirty = 0);
261
- glContext.clear(gl_COLOR_BUFFER_BIT);
262
- }
256
+ context.drawImage(glCanvas, 0, 0);
263
257
  }
264
258
 
265
- // Draw a sprite with the given parameters, used internally by draw functions
266
- function glDraw(x, y, sizeX, sizeY, angle=0, uv0X=0, uv0Y=0, uv1X=1, uv1Y=1, rgba=0xffffffff, rgbaAdditive=0x00000000)
259
+ /** Add a sprite to the gl draw list, used by all gl draw functions
260
+ * @param x
261
+ * @param y
262
+ * @param sizeX
263
+ * @param sizeY
264
+ * @param angle
265
+ * @param uv0X
266
+ * @param uv0Y
267
+ * @param uv1X
268
+ * @param uv1Y
269
+ * @param [rgba=0xffffffff]
270
+ * @param [rgbaAdditive=0]
271
+ * @memberof WebGL */
272
+ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba=0xffffffff, rgbaAdditive=0)
267
273
  {
268
274
  if (!glEnable) return;
269
-
270
- // flush if there is no room for more verts
271
- if (glBatchCount == gl_MAX_BATCH)
275
+
276
+ // flush if there is no room for more verts or if different blend mode
277
+ if (glBatchCount == gl_MAX_BATCH || glBatchAdditive != glAdditive)
272
278
  glFlush();
273
279
 
274
280
  // setup 2 triangles to form a quad
275
281
  let offset = glBatchCount++ * gl_VERTICES_PER_QUAD * gl_INDICIES_PER_VERT;
276
- glDirty = 1;
277
282
 
278
283
  // vertex 0
279
284
  glPositionData[offset++] = angle;
@@ -14,7 +14,7 @@ const sound_bounce = new Sound([,,1e3,,.03,.02,1,2,,,940,.03,,,,,.2,.6,,.06]
14
14
  ///////////////////////////////////////////////////////////////////////////////
15
15
  function gameInit()
16
16
  {
17
- fixedWidth = 1280, fixedHeight = 720; // 720p
17
+ canvasFixedSize = vec2(1280, 720); // 720p
18
18
  levelSize = vec2(72, 40);
19
19
  cameraPos = levelSize.scale(.5);
20
20
  paddle = new Paddle(vec2(levelSize.x/2-12,2));
@@ -18,7 +18,7 @@ class Paddle extends EngineObject
18
18
 
19
19
  update()
20
20
  {
21
- if (usingGamepad)
21
+ if (isUsingGamepad)
22
22
  {
23
23
  // control with gamepad
24
24
  this.pos.x += gamepadStick(0).x;
@@ -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
 
@@ -1,8 +1,10 @@
1
- <html><head><title>LittleJS Breakout Example</title>
2
- <meta name=viewport content=width=device-width,initial-scale=1,maximum-scale=1>
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>
3
5
  <link rel=icon type=image/png href=../../favicon.png>
4
6
  </head><body>
5
7
 
6
- <script src=../../engine/engine.all.min.js?56></script>
7
- <script src=game.js?56></script>
8
- <script src=gameObjects.js?56></script>
8
+ <script src=../../engine/engine.all.js?93></script>
9
+ <script src=game.js?93></script>
10
+ <script src=gameObjects.js?93></script>
@@ -10,6 +10,9 @@ let score, deaths;
10
10
  ///////////////////////////////////////////////////////////////////////////////
11
11
  function gameInit()
12
12
  {
13
+ // enable touch gamepad on touch devices
14
+ touchGamepadEnable = 1;
15
+
13
16
  // setup game
14
17
  score = deaths = 0;
15
18
  gravity = -.01;
@@ -30,7 +33,7 @@ function gameUpdate()
30
33
  }
31
34
 
32
35
  // mouse wheel = zoom
33
- cameraScale = clamp(cameraScale*(1-mouseWheel/10), 1e3, 1);
36
+ cameraScale = clamp(cameraScale*(1-mouseWheel/10), 1, 1e3);
34
37
 
35
38
  // T = drop test crate
36
39
  if (keyWasPressed(84))
@@ -70,7 +73,7 @@ function gameRender()
70
73
  function gameRenderPost()
71
74
  {
72
75
  // draw to overlay canvas for hud rendering
73
- const drawOverlayText = (text, x, y, size=70) =>
76
+ const drawText = (text, x, y, size=70) =>
74
77
  {
75
78
  overlayContext.textAlign = 'center';
76
79
  overlayContext.textBaseline = 'top';
@@ -80,8 +83,8 @@ function gameRenderPost()
80
83
  overlayContext.strokeText(text, x, y);
81
84
  overlayContext.fillText(text, x, y);
82
85
  }
83
- drawOverlayText('Score: ' + score, overlayCanvas.width*1/3, 20);
84
- drawOverlayText('Deaths: ' + deaths, overlayCanvas.width*2/3, 20);
86
+ drawText('Score: ' + score, overlayCanvas.width*1/3, 20);
87
+ drawText('Deaths: ' + deaths, overlayCanvas.width*2/3, 20);
85
88
  }
86
89
 
87
90
  ///////////////////////////////////////////////////////////////////////////////
@@ -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())
@@ -157,6 +157,9 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
157
157
 
158
158
  function decorateBackgroundTile(pos)
159
159
  {
160
+ if (!tileBackgroundLayer)
161
+ return;
162
+
160
163
  const tileData = getTileBackgroundData(pos);
161
164
  if (tileData <= 0)
162
165
  return;
@@ -254,17 +257,11 @@ function drawStars()
254
257
  (randSeeded(w)+time*speed)%w-extraSpace,
255
258
  (randSeeded(h)+time*speed*randSeeded())%h-extraSpace);
256
259
 
257
- if (glOverlay)
258
- {
259
- // drawing stars with gl is too slow in low graphics mode, just draw rects
260
- mainContext.fillStyle = color.rgba();
261
- if (size < 9)
262
- mainContext.fillRect(screenPos.x, screenPos.y, size, size);
263
- else
264
- mainContext.beginPath(mainContext.fill(mainContext.arc(screenPos.x, screenPos.y, size, 0, 9)));
265
- }
260
+ mainContext.fillStyle = color.rgba();
261
+ if (size < 9)
262
+ mainContext.fillRect(screenPos.x, screenPos.y, size, size);
266
263
  else
267
- drawTileScreenSpace(screenPos, vec2(size), 0, vec2(16), color);
264
+ mainContext.beginPath(mainContext.fill(mainContext.arc(screenPos.x, screenPos.y, size, 0, 9)));
268
265
  }
269
266
  }
270
267
 
@@ -28,7 +28,7 @@ function buildTerrain(size)
28
28
  {
29
29
  tileBackground = [];
30
30
  initTileCollision(size);
31
- let startGroundLevel = 80;
31
+ let startGroundLevel = 40;
32
32
  let groundLevel = startGroundLevel;
33
33
  let groundSlope = rand(-1,1);
34
34
  let backgroundDelta = 0, backgroundDeltaSlope = 0;
@@ -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, 99, 30);
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);
@@ -90,7 +90,7 @@ function buildTerrain(size)
90
90
  }
91
91
 
92
92
  // add ladders
93
- for (let ladderCount=50; ladderCount--;)
93
+ for (let ladderCount = 40; ladderCount--;)
94
94
  {
95
95
  // pick random pos
96
96
  const pos = vec2(randInt(levelSize.x), randInt(levelSize.y))
@@ -122,7 +122,7 @@ function buildTerrain(size)
122
122
  new Crate(vec2((randInt(levelSize.x))+.5, randInt(levelSize.y)));
123
123
 
124
124
  // spawn enemies
125
- for (let enemyCount=20; enemyCount--;)
125
+ for (let enemyCount=10; enemyCount--;)
126
126
  new Enemy(vec2(rand(levelSize.x), rand(levelSize.y)));
127
127
  }
128
128
 
@@ -181,11 +181,18 @@ function makeTileLayers()
181
181
  }
182
182
  tileLayer.redraw();
183
183
  tileBackgroundLayer.redraw();
184
+
185
+ if (!glEnable)
186
+ {
187
+ // get rid of background if webgl is not enabled
188
+ tileBackgroundLayer.destroy();
189
+ tileBackgroundLayer = 0;
190
+ }
184
191
  }
185
192
 
186
193
  function buildLevel()
187
194
  {
188
- levelSize = vec2(300,200);
195
+ levelSize = vec2(256);
189
196
  levelColor = randColor(new Color(.2,.2,.2), new Color(.8,.8,.8));
190
197
  levelGroundColor = levelColor.mutate().add(new Color(.4,.4,.4)).clamp();
191
198
 
@@ -205,7 +212,7 @@ function buildLevel()
205
212
 
206
213
  // warm up level
207
214
  warmup = 1;
208
- for (let i=5*FPS; i--;)
215
+ for (let i=5*frameRate; i--;)
209
216
  engineObjectsUpdate();
210
217
  warmup = 0;
211
218
 
@@ -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
@@ -66,7 +66,7 @@ class Crate extends GameObject
66
66
  {
67
67
  constructor(pos, typeOverride)
68
68
  {
69
- super(pos, defaultObjectSize, 2, vec2(16), (randInt(4))*PI/2);
69
+ super(pos, objectDefaultSize, 2, vec2(16), (randInt(4))*PI/2);
70
70
 
71
71
  this.color = (new Color).setHSLA(rand(),1,.8);
72
72
  this.health = 5;
@@ -24,7 +24,7 @@ class Character extends GameObject
24
24
  this.deadTimer = new Timer;
25
25
  this.grendeThrowTimer = new Timer;
26
26
  this.drawSize = vec2(1);
27
- this.color = (new Color).setHSLA(rand(),1,.5);
27
+ this.color = (new Color).setHSLA(rand(),1,.7);
28
28
  this.renderOrder = 10;
29
29
  this.walkCyclePercent = 0;
30
30
  this.health = 1;
@@ -169,7 +169,7 @@ class Character extends GameObject
169
169
 
170
170
  // apply movement acceleration and clamp
171
171
  const maxCharacterSpeed = .2;
172
- this.velocity.x = clamp(this.velocity.x + moveInput.x * .042, maxCharacterSpeed, -maxCharacterSpeed);
172
+ this.velocity.x = clamp(this.velocity.x + moveInput.x * .042, -maxCharacterSpeed, maxCharacterSpeed);
173
173
 
174
174
  // track last pos for ladder collision code
175
175
  this.lastPos = this.pos.copy();
@@ -182,7 +182,7 @@ class Character extends GameObject
182
182
  if (this.climbingLadder || this.groundTimer.active() && !this.dodgeTimer.active())
183
183
  {
184
184
  this.walkCyclePercent += speed * .5;
185
- this.walkCyclePercent = speed > .01 ? mod(this.walkCyclePercent, 1) : 0;
185
+ this.walkCyclePercent = speed > .01 ? mod(this.walkCyclePercent) : 0;
186
186
  }
187
187
  else
188
188
  this.walkCyclePercent = 0;
@@ -292,11 +292,11 @@ class Player extends Character
292
292
  // player controls
293
293
  this.holdingJump = keyIsDown(38) || gamepadIsDown(0);
294
294
  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);
295
+ this.pressingThrow = mouseIsDown(1) || keyIsDown(67) || gamepadIsDown(1);
296
+ this.pressedDodge = mouseIsDown(2) || keyIsDown(88) || gamepadIsDown(3);
297
297
 
298
298
  // movement control
299
- this.moveInput = usingGamepad ? gamepadStick(0) :
299
+ this.moveInput = isUsingGamepad ? gamepadStick(0) :
300
300
  vec2(keyIsDown(39) - keyIsDown(37), keyIsDown(38) - keyIsDown(40));
301
301
 
302
302
  super.update();
@@ -1,11 +1,13 @@
1
- <html><head><title>LittleJS Platformer Example</title>
2
- <meta name=viewport content=width=device-width,initial-scale=1,maximum-scale=1>
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>
3
5
  <link rel=icon type=image/png href=../../favicon.png>
4
6
  </head><body>
5
7
 
6
- <script src=../../engine/engine.all.min.js?56></script>
7
- <script src=gameObjects.js?56></script>
8
- <script src=gamePlayer.js?56></script>
9
- <script src=gameEffects.js?56></script>
10
- <script src=gameLevel.js?56></script>
11
- <script src=game.js?56></script>
8
+ <script src=../../engine/engine.all.js?93></script>
9
+ <script src=gameObjects.js?93></script>
10
+ <script src=gamePlayer.js?93></script>
11
+ <script src=gameEffects.js?93></script>
12
+ <script src=gameLevel.js?93></script>
13
+ <script src=game.js?93></script>
@@ -6,7 +6,7 @@
6
6
 
7
7
  'use strict';
8
8
 
9
- pixelated = 0; // do not use pixelated rendering
9
+ cavasPixelated = 0; // do not use pixelated rendering
10
10
 
11
11
  const fallTime = .2;
12
12
  const cameraOffset = vec2(0,-.5);
@@ -42,7 +42,7 @@ const setTile = (pos, data) => level[pos.x + pos.y * levelSize.x] = data;
42
42
  function gameInit()
43
43
  {
44
44
  // setup canvas
45
- fixedWidth = 1920, fixedHeight = 1080; // 1080p
45
+ canvasFixedSize = vec2(1920, 1080); // 1080p
46
46
  mainCanvas.style.background = backgroundColor.rgba();
47
47
 
48
48
  // load high score
@@ -100,7 +100,7 @@ function gameUpdate()
100
100
 
101
101
  if (keepFalling)
102
102
  {
103
- const p = percent(comboCount, 0, 9);
103
+ const p = percent(comboCount, 9, 0);
104
104
  fallTimer.set(fallTime*p);
105
105
  sound_fall.play();
106
106
  }
@@ -1,7 +1,9 @@
1
- <html><head><title>LittleJS Puzzle Example</title>
2
- <meta name=viewport content=width=device-width,initial-scale=1,maximum-scale=1>
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>
3
5
  <link rel=icon type=image/png href=../../favicon.png>
4
6
  </head><body>
5
7
 
6
- <script src=../../engine/engine.all.min.js?56></script>
7
- <script src=game.js?56></script>
8
+ <script src=../../engine/engine.all.js?93></script>
9
+ <script src=game.js?93></script>
@@ -1,9 +1,11 @@
1
- <html><head><title>LittleJS Stress Test</title>
2
- <meta name=viewport content=width=device-width,initial-scale=1,maximum-scale=1>
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>
3
5
  <link rel=icon type=image/png href=../../favicon.png>
4
6
  </head><body>
5
7
 
6
- <script src=../../engine/engine.all.min.js?56></script>
8
+ <script src=../../engine/engine.all.min.js?93></script>
7
9
  <script>
8
10
 
9
11
  /*
@@ -81,7 +83,7 @@ function gameUpdate()
81
83
  });
82
84
 
83
85
  // mouse wheel = zoom
84
- cameraScale = clamp(cameraScale*(1-mouseWheel/10), 1e3, 1);
86
+ cameraScale = clamp(cameraScale*(1-mouseWheel/10), 1, 1e3);
85
87
  }
86
88
 
87
89
  ///////////////////////////////////////////////////////////////////////////////
@@ -94,7 +96,7 @@ function gameRender()
94
96
  {
95
97
  // track fps and update stats
96
98
  const frameTimeMS = Date.now();
97
- showFPS = lerp(.05, 1e3/(frameTimeMS - timeMS||1), showFPS);
99
+ showFPS = lerp(.05, showFPS, 1e3/(frameTimeMS - timeMS||1));
98
100
  timeMS = frameTimeMS;
99
101
 
100
102
  const spriteCount = sprites.length
package/game.js CHANGED
@@ -4,6 +4,10 @@
4
4
 
5
5
  'use strict';
6
6
 
7
+ // popup errors if there are any (help diagnose issues on mobile devices)
8
+ if (debug)
9
+ onerror = (...parameters)=> alert(parameters);
10
+
7
11
  // game variables
8
12
  let particleEmiter, clickCount = 0;
9
13
 
@@ -11,7 +15,7 @@ let particleEmiter, clickCount = 0;
11
15
  const sound_click = new Sound([.5,.5]);
12
16
 
13
17
  // medals
14
- const medal_example = new Medal(0, 'Example Medal', 'More info about the medal goes here.');
18
+ const medal_example = new Medal(0, 'Example Medal', 'Medal description goes here.');
15
19
  const medal_tenClicks = new Medal(1, 'Ten Clicks!', 'You have clicked 10 times.', '🖱️');
16
20
  medalsInit('Hello World');
17
21
 
@@ -60,7 +64,7 @@ function gameInit()
60
64
  new Color(1,1,1,0), new Color(0,0,0,0), // colorEndA, colorEndB
61
65
  2, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
62
66
  .99, 1, 1, PI, .05, // damping, angleDamping, gravityScale, particleCone, fadeRate,
63
- .5, 1 // randomness, collide, additive, randomColorLinear, renderOrder
67
+ .5, 1, 1 // randomness, collide, additive, randomColorLinear, renderOrder
64
68
  );
65
69
  particleEmiter.elasticity = .3;
66
70
  particleEmiter.trailScale = 2;
@@ -100,19 +104,15 @@ function gameUpdatePost()
100
104
  ///////////////////////////////////////////////////////////////////////////////
101
105
  function gameRender()
102
106
  {
103
- // draw a grey square without using webgl
104
- drawCanvas2D(cameraPos, tileCollisionSize.add(vec2(5)), 0, 0, (context)=>
105
- {
106
- context.fillStyle='#333'
107
- context.fillRect(-.5,-.5,1,1);
108
- });
107
+ // draw a grey square in the background without using webgl
108
+ drawRect(cameraPos, tileCollisionSize.add(vec2(5)), new Color(.2,.2,.2), 0, 0);
109
109
  }
110
110
 
111
111
  ///////////////////////////////////////////////////////////////////////////////
112
112
  function gameRenderPost()
113
113
  {
114
114
  // draw to overlay canvas for hud rendering
115
- const drawOverlayText = (text, x, y, size=70) =>
115
+ const drawText = (text, x, y, size=70) =>
116
116
  {
117
117
  overlayContext.textAlign = 'center';
118
118
  overlayContext.textBaseline = 'top';
@@ -122,7 +122,7 @@ function gameRenderPost()
122
122
  overlayContext.strokeText(text, x, y);
123
123
  overlayContext.fillText(text, x, y);
124
124
  }
125
- drawOverlayText('Hello World', overlayCanvas.width/2, 40);
125
+ drawText('Hello World', overlayCanvas.width/2, 40);
126
126
  }
127
127
 
128
128
  ///////////////////////////////////////////////////////////////////////////////