feat(spireclimb): replace straight targeting arrow with quadratic Bezier curve

- Curve the targeting arrow upward (150px control point) for smoother visual guidance
- Compute arrowhead angle from the last Bezier segment instead of direct card-to-cursor line
- Refactor arrow drawing variables for clarity and reuse
This commit is contained in:
Brian Fertig 2026-06-27 11:37:13 -06:00
parent 54b942f8ac
commit 0afcc167dd
1 changed files with 27 additions and 14 deletions

View File

@ -102,26 +102,39 @@ export default class SpireClimbGame extends Phaser.Scene {
const g = this._targetArrow; g.clear();
const sp = this._handSprites && this._handSprites[this.pendingCard.uid];
if (!sp) return;
const x0 = sp.x, y0 = sp.y;
const p = this.input.activePointer;
const x1 = p.x, y1 = p.y;
if (Math.hypot(x1 - x0, y1 - y0) < 8) return;
const ang = Math.atan2(y1 - y0, x1 - x0);
// Quadratic Bezier: P0=card, P1=control 150px above card, P2=mouse
const p0x = sp.x, p0y = sp.y;
const p1x = sp.x, p1y = sp.y - 150;
const ptr = this.input.activePointer;
const p2x = ptr.x, p2y = ptr.y;
if (Math.hypot(p2x - p0x, p2y - p0y) < 8) return;
const STEPS = 32;
const pts = [];
for (let i = 0; i <= STEPS; i++) {
const t = i / STEPS, mt = 1 - t;
pts.push([mt*mt*p0x + 2*mt*t*p1x + t*t*p2x, mt*mt*p0y + 2*mt*t*p1y + t*t*p2y]);
}
const [lx, ly] = pts[STEPS];
const [plx, ply] = pts[STEPS - 1];
const ang = Math.atan2(ly - ply, lx - plx);
const cos = Math.cos(ang), sin = Math.sin(ang);
const px = -sin, py = cos; // perpendicular unit
const drawArrow = (color, alpha, lineW, headLen, headW) => {
const bx = x1 - cos * headLen, by = y1 - sin * headLen; // arrowhead base center
const nx = -sin, ny = cos;
const draw = (color, alpha, lineW, headLen, headW) => {
g.lineStyle(lineW, color, alpha);
g.beginPath(); g.moveTo(x0, y0); g.lineTo(bx, by); g.strokePath();
g.beginPath();
g.moveTo(pts[0][0], pts[0][1]);
for (let i = 1; i <= STEPS; i++) g.lineTo(pts[i][0], pts[i][1]);
g.strokePath();
const hbx = lx - cos * headLen, hby = ly - sin * headLen;
g.fillStyle(color, alpha);
g.beginPath();
g.moveTo(x1, y1);
g.lineTo(bx + px * headW, by + py * headW);
g.lineTo(bx - px * headW, by - py * headW);
g.moveTo(lx, ly);
g.lineTo(hbx + nx * headW, hby + ny * headW);
g.lineTo(hbx - nx * headW, hby - ny * headW);
g.closePath(); g.fillPath();
};
drawArrow(0x241806, 0.85, 24, 54, 35); // dark outline
drawArrow(0xe7c14b, 0.97, 14, 50, 29); // gold core
draw(0x241806, 0.85, 24, 54, 35); // dark outline
draw(0xe7c14b, 0.97, 14, 50, 29); // gold core
}
// ════════════════════════════════════════════════════════ helpers ══════════