littlejsengine 1.14.8 → 1.14.10

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.
@@ -33,7 +33,7 @@ const engineName = 'LittleJS';
33
33
  * @type {string}
34
34
  * @default
35
35
  * @memberof Engine */
36
- const engineVersion = '1.14.8';
36
+ const engineVersion = '1.14.10';
37
37
 
38
38
  /** Frames per second to update
39
39
  * @type {number}
@@ -1127,7 +1127,8 @@ function debugRender()
1127
1127
  {
1128
1128
  overlayContext.fillText(`${engineName} v${engineVersion}`, x, y += h/2 );
1129
1129
  overlayContext.fillText('Time: ' + formatTime(time), x, y += h);
1130
- overlayContext.fillText('FPS: ' + averageFPS.toFixed(1), x, y += h);
1130
+ overlayContext.fillText('FPS: ' + averageFPS.toFixed(1) + (glEnable?' WebGL':' Canvas2D'),
1131
+ x, y += h);
1131
1132
  overlayContext.fillText('Objects: ' + engineObjects.length, x, y += h);
1132
1133
  overlayContext.fillText('Draw Count: ' + drawCount, x, y += h);
1133
1134
  overlayContext.fillText('---------', x, y += h);
@@ -1146,12 +1147,18 @@ function debugRender()
1146
1147
  overlayContext.fillText('6: Toggle Video Capture', x, y += h);
1147
1148
 
1148
1149
  let keysPressed = '';
1150
+ let mousePressed = '';
1149
1151
  for (const i in inputData[0])
1150
1152
  {
1151
- if (keyIsDown(i, 0))
1153
+ if (!keyIsDown(i, 0))
1154
+ continue;
1155
+ if (parseInt(i) < 3)
1156
+ mousePressed += i + ' ' ;
1157
+ else if (keyIsDown(i, 0))
1152
1158
  keysPressed += i + ' ' ;
1153
1159
  }
1154
- keysPressed && overlayContext.fillText('Keys Down: ' + keysPressed, x, y += h);
1160
+ mousePressed && overlayContext.fillText('Mouse: ' + mousePressed, x, y += h);
1161
+ keysPressed && overlayContext.fillText('Keys: ' + keysPressed, x, y += h);
1155
1162
 
1156
1163
  let buttonsPressed = '';
1157
1164
  if (inputData[1])
@@ -2485,6 +2492,12 @@ let touchGamepadEnable = false;
2485
2492
  * @memberof Settings */
2486
2493
  let touchGamepadAnalog = true;
2487
2494
 
2495
+ /** Number of buttons on touch gamepad
2496
+ * @type {number}
2497
+ * @default
2498
+ * @memberof Settings */
2499
+ let touchGamepadButtonCount = 4;
2500
+
2488
2501
  /** Size of virtual gamepad for touch devices in pixels
2489
2502
  * @type {number}
2490
2503
  * @default
@@ -4515,7 +4528,7 @@ function inputInit()
4515
4528
  function onMouseLeave()
4516
4529
  {
4517
4530
  // set mouse position and delta when leaving canvas
4518
- mousePosScreen = vec2(Infinity);
4531
+ mousePosScreen = vec2(-1);
4519
4532
  mouseDeltaScreen = vec2(0);
4520
4533
  }
4521
4534
  }
@@ -4570,10 +4583,12 @@ function gamepadsUpdate()
4570
4583
  const data = inputData[1] || (inputData[1] = []);
4571
4584
  for (let i=10; i--;)
4572
4585
  {
4573
- const j = i === 3 ? 2 : i === 2 ? 3 : i; // fix button locations
4574
- const wasDown = gamepadIsDown(j,0);
4575
- data[j] = touchGamepadButtons[i] ? wasDown ? 1 : 3 : wasDown ? 4 : 0;
4586
+ const wasDown = gamepadIsDown(i,0);
4587
+ data[i] = touchGamepadButtons[i] ? wasDown ? 1 : 3 : wasDown ? 4 : 0;
4576
4588
  }
4589
+
4590
+ // disable normal gamepads when touch gamepad is active
4591
+ return;
4577
4592
  }
4578
4593
 
4579
4594
  // return if gamepads are disabled or not supported
@@ -4648,6 +4663,15 @@ const isTouchDevice = !headlessMode && window.ontouchstart !== undefined;
4648
4663
  // touch gamepad internal variables
4649
4664
  let touchGamepadTimer = new Timer, touchGamepadButtons = [], touchGamepadStick = vec2();
4650
4665
 
4666
+ function touchGamepadButtonCenter()
4667
+ {
4668
+ // draw right face buttons
4669
+ let center = vec2(mainCanvasSize.x-touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
4670
+ if (touchGamepadButtonCount <= 2)
4671
+ center.x += touchGamepadSize/2;
4672
+ return center;
4673
+ }
4674
+
4651
4675
  // enable touch input mouse passthrough
4652
4676
  function touchInputInit()
4653
4677
  {
@@ -4695,8 +4719,8 @@ function touchInputInit()
4695
4719
  // set was touching
4696
4720
  wasTouching = touching;
4697
4721
 
4698
- // prevent default handling like copy and magnifier lens
4699
- if (inputPreventDefault && document.hasFocus()) // allow document to get focus
4722
+ // prevent default handling like copy, magnifier lens, and scrolling
4723
+ if (inputPreventDefault && document.hasFocus() && e.cancelable)
4700
4724
  e.preventDefault();
4701
4725
 
4702
4726
  // must return true so the document will get focus
@@ -4725,25 +4749,36 @@ function touchInputInit()
4725
4749
 
4726
4750
  // get center of left and right sides
4727
4751
  const stickCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
4728
- const buttonCenter = mainCanvasSize.subtract(vec2(touchGamepadSize, touchGamepadSize));
4752
+ const buttonCenter = touchGamepadButtonCenter();
4729
4753
  const startCenter = mainCanvasSize.scale(.5);
4730
4754
 
4731
4755
  // check each touch point
4732
4756
  for (const touch of e.touches)
4733
4757
  {
4734
4758
  const touchPos = mouseEventToScreen(vec2(touch.clientX, touch.clientY));
4735
- if (touchPos.distance(stickCenter) < touchGamepadSize)
4759
+ if (stickCenter.distance(touchPos) < touchGamepadSize)
4736
4760
  {
4737
4761
  // virtual analog stick
4738
4762
  touchGamepadStick = touchPos.subtract(stickCenter).scale(2/touchGamepadSize).clampLength();
4739
4763
  }
4740
- else if (touchPos.distance(buttonCenter) < touchGamepadSize)
4764
+ else if (buttonCenter.distance(touchPos) < touchGamepadSize)
4741
4765
  {
4742
4766
  // virtual face buttons
4743
- const button = touchPos.subtract(buttonCenter).direction();
4744
- touchGamepadButtons[button] = 1;
4767
+ let button = buttonCenter.subtract(touchPos).direction();
4768
+ button = mod(button+2, 4);
4769
+ if (touchGamepadButtonCount === 1)
4770
+ button = 0;
4771
+ else if (touchGamepadButtonCount === 2)
4772
+ {
4773
+ const delta = buttonCenter.subtract(touchPos);
4774
+ button = -delta.x < delta.y ? 1 : 0;
4775
+ }
4776
+ // fix button locations (swap 2 and 3 to match gamepad layout)
4777
+ button = button === 3 ? 2 : button === 2 ? 3 : button;
4778
+ if (button < touchGamepadButtonCount)
4779
+ touchGamepadButtons[button] = 1;
4745
4780
  }
4746
- else if (touchPos.distance(startCenter) < touchGamepadSize && !wasTouching)
4781
+ else if (startCenter.distance(touchPos) < touchGamepadSize && !wasTouching)
4747
4782
  {
4748
4783
  // virtual start button in center
4749
4784
  touchGamepadButtons[9] = 1;
@@ -4774,11 +4809,10 @@ function touchGamepadRender()
4774
4809
  // draw left analog stick
4775
4810
  context.fillStyle = touchGamepadStick.lengthSquared() > 0 ? '#fff' : '#000';
4776
4811
  context.beginPath();
4777
-
4778
- const leftCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
4812
+ const stickCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
4779
4813
  if (touchGamepadAnalog) // draw circle shaped gamepad
4780
4814
  {
4781
- context.arc(leftCenter.x, leftCenter.y, touchGamepadSize/2, 0, 9);
4815
+ context.arc(stickCenter.x, stickCenter.y, touchGamepadSize/2, 0, 9);
4782
4816
  context.fill();
4783
4817
  context.stroke();
4784
4818
  }
@@ -4787,21 +4821,27 @@ function touchGamepadRender()
4787
4821
  for (let i=10; i--;)
4788
4822
  {
4789
4823
  const angle = i*PI/4;
4790
- context.arc(leftCenter.x, leftCenter.y,touchGamepadSize*.6, angle + PI/8, angle + PI/8);
4791
- i%2 && context.arc(leftCenter.x, leftCenter.y, touchGamepadSize*.33, angle, angle);
4824
+ context.arc(stickCenter.x, stickCenter.y,touchGamepadSize*.6, angle + PI/8, angle + PI/8);
4825
+ i%2 && context.arc(stickCenter.x, stickCenter.y, touchGamepadSize*.33, angle, angle);
4792
4826
  i===1 && context.fill();
4793
4827
  }
4794
4828
  context.stroke();
4795
4829
  }
4796
4830
 
4797
4831
  // draw right face buttons
4798
- const rightCenter = vec2(mainCanvasSize.x-touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
4799
- for (let i=4; i--;)
4800
- {
4801
- const pos = rightCenter.add(vec2().setDirection(i, touchGamepadSize/2));
4802
- context.fillStyle = touchGamepadButtons[i] ? '#fff' : '#000';
4832
+ const buttonCenter = touchGamepadButtonCenter();
4833
+ const buttonSize = touchGamepadButtonCount > 1 ? touchGamepadSize/4 : touchGamepadSize/2;
4834
+ for (let i=0; i<touchGamepadButtonCount; i++)
4835
+ {
4836
+ let j = mod(i-1, 4);
4837
+ let button = touchGamepadButtonCount > 2 ?
4838
+ j : min(j, touchGamepadButtonCount-1);
4839
+ // fix button locations (swap 2 and 3 to match gamepad layout)
4840
+ button = button === 3 ? 2 : button === 2 ? 3 : button;
4841
+ const pos = buttonCenter.add(vec2().setDirection(j, touchGamepadSize/2));
4842
+ context.fillStyle = touchGamepadButtons[button] ? '#fff' : '#000';
4803
4843
  context.beginPath();
4804
- context.arc(pos.x, pos.y, touchGamepadSize/4, 0,9);
4844
+ context.arc(pos.x, pos.y, buttonSize, 0,9);
4805
4845
  context.fill();
4806
4846
  context.stroke();
4807
4847
  }
@@ -8157,7 +8197,7 @@ class UIObject
8157
8197
  const mouseDown = mouseIsDown(0);
8158
8198
  const mousePress = this.dragActivate ? mouseDown : mouseWasPressed(0);
8159
8199
  if (!uiSystem.hoverObject)
8160
- if (mousePress || !mouseDown || isActive)
8200
+ if (mousePress || isActive || (!mouseDown && !isTouchDevice))
8161
8201
  {
8162
8202
  const size = this.size.add(vec2(isTouchDevice && this.extraTouchSize || 0));
8163
8203
  if (isOverlapping(this.pos, size, mousePosScreen))
@@ -8189,7 +8229,8 @@ class UIObject
8189
8229
  }
8190
8230
  }
8191
8231
  }
8192
- if (isActive && (!mouseDown || !this.isHoverObject()))
8232
+ if (isActive)
8233
+ if (!mouseDown || (this.dragActivate && !this.isHoverObject()))
8193
8234
  {
8194
8235
  this.onRelease();
8195
8236
  if (this.soundRelease)