littlejsengine 1.18.28 → 1.19.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.
@@ -582,7 +582,7 @@ function inputInit()
582
582
  const rect = mainCanvas.getBoundingClientRect();
583
583
  const px = percent(mousePos.x, rect.left, rect.right);
584
584
  const py = percent(mousePos.y, rect.top, rect.bottom);
585
- return vec2(px*mainCanvas.width, py*mainCanvas.height);
585
+ return vec2(px*mainCanvasSize.x, py*mainCanvasSize.y);
586
586
  }
587
587
  }
588
588
 
package/src/engineLogo.js CHANGED
@@ -13,10 +13,11 @@ function drawEngineLogo(t)
13
13
  const showName = 1;
14
14
 
15
15
  // LittleJS Logo and Splash Screen
16
+ // the splash runs before the engine loop so size the canvas here too
17
+ engineUpdateCanvas();
16
18
  const x = mainContext;
17
- const dpr = canvasPixelRatio ?? (devicePixelRatio || 1);
18
- const w = mainCanvas.width = innerWidth * dpr;
19
- const h = mainCanvas.height = innerHeight * dpr;
19
+ const w = mainCanvasSize.x;
20
+ const h = mainCanvasSize.y;
20
21
  {
21
22
  // background
22
23
  const p3 = percent(t, 1, .8);
package/src/engineMath.js CHANGED
@@ -261,6 +261,74 @@ function isIntersecting(start, end, pos, size)
261
261
  return true;
262
262
  }
263
263
 
264
+ ///////////////////////////////////////////////////////////////////////////////
265
+ // Collision helpers, none of them change anything that is passed in
266
+ // Boxes are axis aligned and centered on pos with a full size, like drawRect
267
+ // Each returns how far to move the first shape to get it clear, or undefined when they are not touching
268
+ // isOverlapping answers whether two boxes touch, these answer how far out
269
+
270
+ /** Returns the vector to move circle A by so it no longer overlaps circle B, or undefined
271
+ * @param {Vector2} posA - Center of circle A
272
+ * @param {number} radiusA
273
+ * @param {Vector2} posB - Center of circle B
274
+ * @param {number} radiusB
275
+ * @return {Vector2|undefined}
276
+ * @memberof Math */
277
+ function collideCircleCircle(posA, radiusA, posB, radiusB)
278
+ {
279
+ const d = posA.subtract(posB);
280
+ const r = radiusA + radiusB;
281
+ const dist = d.length();
282
+ if (dist >= r)
283
+ return undefined;
284
+ return d.normalize(r - dist); // coincident centers normalize to straight up
285
+ }
286
+
287
+ /** Returns the vector to move a circle out of an axis aligned box, or undefined
288
+ * @param {Vector2} pos - Center of the circle
289
+ * @param {number} radius
290
+ * @param {Vector2} boxPos - Center of the box
291
+ * @param {Vector2} boxSize - Full size of the box
292
+ * @return {Vector2|undefined}
293
+ * @memberof Math */
294
+ function collideCircleBox(pos, radius, boxPos, boxSize)
295
+ {
296
+ const h = boxSize.scale(.5);
297
+ const closest = vec2(clamp(pos.x, boxPos.x - h.x, boxPos.x + h.x), clamp(pos.y, boxPos.y - h.y, boxPos.y + h.y));
298
+ const d = pos.subtract(closest), distSq = d.lengthSquared();
299
+ if (distSq)
300
+ return distSq >= radius*radius ? undefined : d.normalize(radius - distSq**.5);
301
+
302
+ // center is inside the box, push out along the axis of least penetration
303
+ const offset = pos.subtract(boxPos);
304
+ return pushOutAxis(offset, h.x - abs(offset.x), h.y - abs(offset.y), radius);
305
+ }
306
+
307
+ /** Returns the vector to move box A by so it no longer overlaps box B, the shortest way out, or undefined
308
+ * - isOverlapping is the yes or no version of this
309
+ * @param {Vector2} posA - Center of box A
310
+ * @param {Vector2} sizeA - Full size of box A
311
+ * @param {Vector2} posB - Center of box B
312
+ * @param {Vector2} sizeB - Full size of box B
313
+ * @return {Vector2|undefined}
314
+ * @memberof Math */
315
+ function collideBoxBox(posA, sizeA, posB, sizeB)
316
+ {
317
+ const d = posA.subtract(posB);
318
+ const overlapX = (sizeA.x + sizeB.x)/2 - abs(d.x);
319
+ const overlapY = (sizeA.y + sizeB.y)/2 - abs(d.y);
320
+ if (overlapX <= 0 || overlapY <= 0)
321
+ return undefined;
322
+ return pushOutAxis(d, overlapX, overlapY);
323
+ }
324
+
325
+ // the axis with the smallest penetration, pointing the way d does, with extra distance added
326
+ function pushOutAxis(d, penX, penY, extra=0)
327
+ {
328
+ const s = (v)=> v >= 0 ? 1 : -1; // sign() gives 0 on a tie, which would be no push
329
+ return penX <= penY ? vec2(s(d.x)*(penX + extra), 0) : vec2(0, s(d.y)*(penY + extra));
330
+ }
331
+
264
332
  /** Returns an oscillating wave between 0 and amplitude with frequency of 1 Hz by default
265
333
  * @param {number} [frequency] - Frequency of the wave in Hz
266
334
  * @param {number} [amplitude] - Amplitude (max height) of the wave
@@ -693,6 +761,7 @@ class Vector2
693
761
  distanceSquared(v) { return (this.x - v.x)**2 + (this.y - v.y)**2; }
694
762
 
695
763
  /** Returns a new vector in same direction as this one with the length passed in
764
+ * - A zero vector has no direction, so it normalizes to straight up
696
765
  * @param {number} [length]
697
766
  * @return {Vector2} */
698
767
  normalize(length=1)