diff --git a/public/src/games/spireclimb/SpireClimbGame.js b/public/src/games/spireclimb/SpireClimbGame.js index fbbb07b..9f330bd 100644 --- a/public/src/games/spireclimb/SpireClimbGame.js +++ b/public/src/games/spireclimb/SpireClimbGame.js @@ -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 ══════════