update spirit
This commit is contained in:
@@ -109,21 +109,45 @@ export function clamp(v: number, min: number, max: number): number {
|
||||
return v < min ? min : v > max ? max : v;
|
||||
}
|
||||
|
||||
/** Hit-test tolerance (design px). Touches this far outside the visual
|
||||
* bounding box still register as a hit. This compensates for finger
|
||||
* imprecision on small touch targets (req 1.3, 20.3).
|
||||
* Increased from 10→15 to better accommodate finger-pad size on mobile. */
|
||||
export const HIT_TOLERANCE = 15;
|
||||
|
||||
/**
|
||||
* Returns true if `(x, y)` lies inside `rect`. Origin is bottom-left.
|
||||
* Used by both `isInside` and the touch router.
|
||||
* Used for the joystick which is rendered as a full rectangle.
|
||||
*/
|
||||
export function isInsideRect(rect: IHitRect, x: number, y: number): boolean {
|
||||
const halfW = rect.w / 2;
|
||||
const halfH = rect.h / 2;
|
||||
return Math.abs(x - rect.cx) <= halfW && Math.abs(y - rect.cy) <= halfH;
|
||||
return Math.abs(x - rect.cx) <= halfW + HIT_TOLERANCE && Math.abs(y - rect.cy) <= halfH + HIT_TOLERANCE;
|
||||
}
|
||||
|
||||
/** Which control (if any) is hit at `(x, y)`. Priority: attack > jump > joystick. */
|
||||
/**
|
||||
* Returns true if `(x, y)` lies inside the **circle** inscribed by `rect`.
|
||||
* Buttons are rendered as circles via `Graphics.circle`; using a circular
|
||||
* hit-test ensures the visual shape and the touch area match — no "dead
|
||||
* zones" in the corners of a rectangular hit rect that visually lie outside
|
||||
* the circle, and no missing the upper/lower arc of the circle.
|
||||
*
|
||||
* The effective radius is `min(w, h) / 2 + HIT_TOLERANCE`.
|
||||
*/
|
||||
export function isInsideCircle(rect: IHitRect, x: number, y: number): boolean {
|
||||
const radius = Math.min(rect.w, rect.h) / 2;
|
||||
const dx = x - rect.cx;
|
||||
const dy = y - rect.cy;
|
||||
return (dx * dx + dy * dy) <= (radius + HIT_TOLERANCE) * (radius + HIT_TOLERANCE);
|
||||
}
|
||||
|
||||
/** Which control (if any) is hit at `(x, y)`. Priority: attack > jump > joystick.
|
||||
* Buttons (jump, shuriken, ninjaSword) use circular hit-test to match their
|
||||
* visual shape. The joystick retains rectangular hit-test for full-area coverage. */
|
||||
export function hitTest(layout: IFloatingLayout, x: number, y: number): ControlId | null {
|
||||
if (isInsideRect(layout.ninjaSword, x, y)) return ControlId.NinjaSword;
|
||||
if (isInsideRect(layout.shuriken, x, y)) return ControlId.Shuriken;
|
||||
if (isInsideRect(layout.jump, x, y)) return ControlId.Jump;
|
||||
if (isInsideCircle(layout.ninjaSword, x, y)) return ControlId.NinjaSword;
|
||||
if (isInsideCircle(layout.shuriken, x, y)) return ControlId.Shuriken;
|
||||
if (isInsideCircle(layout.jump, x, y)) return ControlId.Jump;
|
||||
if (isInsideRect(layout.joystick, x, y)) return ControlId.Joystick;
|
||||
return null;
|
||||
}
|
||||
@@ -268,6 +292,11 @@ export class MultiTouchRouter {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Check whether a specific touchId still has an active slot in the router. */
|
||||
public isPressedById(id: number): boolean {
|
||||
return this.slots.has(id);
|
||||
}
|
||||
|
||||
/** Returns how many simultaneous fingers are currently tracked. */
|
||||
public get activeTouchCount(): number {
|
||||
return this.slots.size;
|
||||
|
||||
Reference in New Issue
Block a user