littlejsengine 1.9.8 → 1.9.11

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 +2 -0
  2. package/dist/littlejs.d.ts +38 -5
  3. package/dist/littlejs.esm.js +106 -58
  4. package/dist/littlejs.esm.min.js +1 -1
  5. package/dist/littlejs.js +98 -56
  6. package/dist/littlejs.min.js +1 -1
  7. package/dist/littlejs.release.js +81 -54
  8. package/examples/box2d/game.js +34 -16
  9. package/examples/box2d/gameObjects.js +485 -0
  10. package/examples/box2d/index.html +6 -18
  11. package/examples/box2d/scenes.js +32 -251
  12. package/examples/box2d/tiles.png +0 -0
  13. package/examples/breakout/index.html +3 -3
  14. package/examples/breakoutTutorial/index.html +2 -2
  15. package/examples/electron/build.js +1 -1
  16. package/examples/electron/index.html +2 -2
  17. package/examples/js13k/build.js +19 -1
  18. package/examples/js13k/index.html +13 -13
  19. package/examples/module/index.html +1 -1
  20. package/examples/particles/index.html +1 -1
  21. package/examples/platformer/gameCharacter.js +1 -0
  22. package/examples/platformer/gameEffects.js +0 -2
  23. package/examples/platformer/gameObjects.js +1 -1
  24. package/examples/platformer/index.html +8 -8
  25. package/examples/puzzle/index.html +2 -2
  26. package/examples/starter/build.js +1 -1
  27. package/examples/starter/game.js +1 -1
  28. package/examples/starter/index.html +13 -13
  29. package/examples/stress/index.html +1 -1
  30. package/examples/typescript/index.html +1 -1
  31. package/package.json +1 -1
  32. package/plugins/box2d.js +126 -47
  33. package/plugins/postProcess.js +3 -2
  34. package/src/engine.js +12 -11
  35. package/src/engineAudio.js +16 -16
  36. package/src/engineBuild.js +1 -1
  37. package/src/engineDebug.js +17 -2
  38. package/src/engineExport.js +7 -2
  39. package/src/engineInput.js +13 -6
  40. package/src/engineMedals.js +3 -2
  41. package/src/engineObject.js +25 -19
  42. package/src/engineSettings.js +12 -0
@@ -3,6 +3,7 @@
3
3
  * - Tracks keyboard down, pressed, and released
4
4
  * - Tracks mouse buttons, position, and wheel
5
5
  * - Tracks multiple analog gamepads
6
+ * - Touch input is handled as mouse input
6
7
  * - Virtual gamepad for touch devices
7
8
  * @namespace Input
8
9
  */
@@ -136,7 +137,8 @@ function inputUpdate()
136
137
  if (headlessMode) return;
137
138
 
138
139
  // clear input when lost focus (prevent stuck keys)
139
- isTouchDevice || document.hasFocus() || clearInput();
140
+ if(!(touchInputEnable && isTouchDevice) && !document.hasFocus())
141
+ clearInput();
140
142
 
141
143
  // update mouse world space position
142
144
  mousePos = screenToWorld(mousePosScreen);
@@ -197,6 +199,10 @@ function inputInit()
197
199
  // mouse event handlers
198
200
  onmousedown = (e)=>
199
201
  {
202
+ // fix stalled audio requiring user interaction
203
+ if (soundEnable && !headlessMode && audioContext && audioContext.state != 'running')
204
+ audioContext.resume();
205
+
200
206
  isUsingGamepad = false;
201
207
  inputData[0][e.button] = 3;
202
208
  mousePosScreen = mouseToScreen(e);
@@ -208,7 +214,7 @@ function inputInit()
208
214
  oncontextmenu = (e)=> false; // prevent right click menu
209
215
 
210
216
  // init touch input
211
- if (isTouchDevice)
217
+ if (isTouchDevice && touchInputEnable)
212
218
  touchInputInit();
213
219
  }
214
220
 
@@ -336,12 +342,12 @@ function vibrateStop() { vibrate(0); }
336
342
 
337
343
  /** True if a touch device has been detected
338
344
  * @memberof Input */
339
- const isTouchDevice = !headlessMode && window.ontouchstart !== undefined;
345
+ const isTouchDevice = window.ontouchstart !== undefined;
340
346
 
341
347
  // touch gamepad internal variables
342
348
  let touchGamepadTimer = new Timer, touchGamepadButtons, touchGamepadStick;
343
349
 
344
- // try to enable touch mouse
350
+ // enable touch input mouse passthrough
345
351
  function touchInputInit()
346
352
  {
347
353
  // add non passive touch event listeners
@@ -365,8 +371,8 @@ function touchInputInit()
365
371
  function handleTouchDefault(e)
366
372
  {
367
373
  // fix stalled audio requiring user interaction
368
- if (soundEnable && audioContext && audioContext.state != 'running')
369
- zzfx(0);
374
+ if (soundEnable && !headlessMode && audioContext && audioContext.state != 'running')
375
+ audioContext.resume();
370
376
 
371
377
  // check if touching and pass to mouse events
372
378
  const touching = e.touches.length;
@@ -450,6 +456,7 @@ function touchInputInit()
450
456
  // render the touch gamepad, called automatically by the engine
451
457
  function touchGamepadRender()
452
458
  {
459
+ if (!touchInputEnable || !isTouchDevice || headlessMode) return;
453
460
  if (!touchGamepadEnable || !touchGamepadTimer.isSet())
454
461
  return;
455
462
 
@@ -31,7 +31,8 @@ function medalsInit(saveName)
31
31
  medalsForEach(medal=> medal.unlocked = (localStorage[medal.storageKey()] | 0));
32
32
 
33
33
  // engine automatically renders medals
34
- addPluginRender(function()
34
+ engineAddPlugin(undefined, medalsRender);
35
+ function medalsRender()
35
36
  {
36
37
  if (!medalsDisplayQueue.length)
37
38
  return;
@@ -55,7 +56,7 @@ function medalsInit(saveName)
55
56
  time > slideOffTime ? (time - slideOffTime) / medalDisplaySlideTime : 0;
56
57
  medal.render(hidePercent);
57
58
  }
58
- });
59
+ }
59
60
  }
60
61
 
61
62
  /** Calls a function for each medal
@@ -153,9 +153,9 @@ class EngineObject
153
153
 
154
154
  // apply physics
155
155
  const oldPos = this.pos.copy();
156
- this.velocity.y += gravity * this.gravityScale;
157
156
  this.pos.x += this.velocity.x *= this.damping;
158
- this.pos.y += this.velocity.y *= this.damping;
157
+ this.pos.y += this.velocity.y = this.damping * this.velocity.y
158
+ + gravity * this.gravityScale;
159
159
  this.angle += this.angleVelocity *= this.angleDamping;
160
160
 
161
161
  // physics sanity checks
@@ -284,19 +284,22 @@ class EngineObject
284
284
  const isBlockedX = tileCollisionTest(vec2(this.pos.x, oldPos.y), this.size, this);
285
285
  if (isBlockedY || !isBlockedX)
286
286
  {
287
- // set if landed on ground
288
- this.groundObject = wasMovingDown;
289
-
290
287
  // bounce velocity
291
288
  this.velocity.y *= -this.elasticity;
292
289
 
293
- // adjust next velocity to settle on ground
294
- const o = (oldPos.y - this.size.y/2|0) - (oldPos.y - this.size.y/2);
295
- if (o < 0 && o > this.damping * this.velocity.y + gravity * this.gravityScale)
296
- this.velocity.y = this.damping ? (o - gravity * this.gravityScale) / this.damping : 0;
297
-
298
- // move to previous position
299
- this.pos.y = oldPos.y;
290
+ // set if landed on ground
291
+ if (this.groundObject = wasMovingDown)
292
+ {
293
+ // adjust position to slightly above nearest tile boundary
294
+ // this prevents gap between object and ground
295
+ const epsilon = .0001;
296
+ this.pos.y = (oldPos.y-this.size.y/2|0)+this.size.y/2+epsilon;
297
+ }
298
+ else
299
+ {
300
+ // move to previous position
301
+ this.pos.y = oldPos.y;
302
+ }
300
303
  }
301
304
  if (isBlockedX)
302
305
  {
@@ -434,12 +437,15 @@ class EngineObject
434
437
  /** Render debug info for this object */
435
438
  renderDebugInfo()
436
439
  {
437
- // show object info for debugging
438
- const size = vec2(max(this.size.x, .2), max(this.size.y, .2));
439
- const color1 = rgb(this.collideTiles?1:0, this.collideSolidObjects?1:0, this.isSolid?1:0, this.parent?.2:.5);
440
- const color2 = this.parent ? rgb(1,1,1,.5) : rgb(0,0,0,.8);
441
- drawRect(this.pos, size, color1, this.angle, false);
442
- drawRect(this.pos, size.scale(.8), color2, this.angle, false);
443
- this.parent && drawLine(this.pos, this.parent.pos, .1, rgb(0,0,1,.5), false);
440
+ if (debug)
441
+ {
442
+ // show object info for debugging
443
+ const size = vec2(max(this.size.x, .2), max(this.size.y, .2));
444
+ const color1 = rgb(this.collideTiles?1:0, this.collideSolidObjects?1:0, this.isSolid?1:0, this.parent?.2:.5);
445
+ const color2 = this.parent ? rgb(1,1,1,.5) : rgb(0,0,0,.8);
446
+ drawRect(this.pos, size, color1, this.angle, false);
447
+ drawRect(this.pos, size.scale(.8), color2, this.angle, false);
448
+ this.parent && drawLine(this.pos, this.parent.pos, .1, rgb(0,0,1,.5), false);
449
+ }
444
450
  }
445
451
  }
@@ -169,6 +169,13 @@ let gamepadDirectionEmulateStick = true;
169
169
  * @memberof Settings */
170
170
  let inputWASDEmulateDirection = true;
171
171
 
172
+ /** True if touch input is enabled for mobile devices
173
+ * - Touch events will be routed to mouse events
174
+ * @type {Boolean}
175
+ * @default
176
+ * @memberof Settings */
177
+ let touchInputEnable = true;
178
+
172
179
  /** True if touch gamepad should appear on mobile devices
173
180
  * - Supports left analog stick, 4 face buttons and start button (button 9)
174
181
  * - Must be set by end of gameInit to be activated
@@ -384,6 +391,11 @@ function setGamepadDirectionEmulateStick(enable) { gamepadDirectionEmulateStick
384
391
  * @memberof Settings */
385
392
  function setInputWASDEmulateDirection(enable) { inputWASDEmulateDirection = enable; }
386
393
 
394
+ /** Set if touch input is allowed
395
+ * @param {Boolean} enable
396
+ * @memberof Settings */
397
+ function setTouchInputEnable(enable) { touchInputEnable = enable; }
398
+
387
399
  /** Set if touch gamepad should appear on mobile devices
388
400
  * @param {Boolean} enable
389
401
  * @memberof Settings */