diff --git a/src/pages/GamePage.module.css b/src/pages/GamePage.module.css index 49058a3..7488bcc 100644 --- a/src/pages/GamePage.module.css +++ b/src/pages/GamePage.module.css @@ -18,6 +18,31 @@ color: #fff; text-shadow: 0 0 16px rgba(217, 70, 239, 0.6), 0 2px 4px rgba(0, 0, 0, 0.8); font-variant-numeric: tabular-nums; + display: inline-block; +} + +.scorePulse { + animation: score-beat 0.2s ease-out; +} + +@keyframes score-beat { + 0% { transform: scale(1.3); } + 100% { transform: scale(1); } +} + +.scoreDelta { + position: absolute; + font-size: 20px; + font-weight: 700; + color: #00ffcc; + text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8); + pointer-events: none; + animation: delta-float 0.8s ease-out forwards; +} + +@keyframes delta-float { + 0% { opacity: 1; transform: translateY(0); } + 100% { opacity: 0; transform: translateY(-30px); } } .menuBtn { diff --git a/src/pages/GamePage.tsx b/src/pages/GamePage.tsx index 0e62103..06cb662 100644 --- a/src/pages/GamePage.tsx +++ b/src/pages/GamePage.tsx @@ -56,20 +56,35 @@ export function GamePage() { const gameReady = calibrationStatus === 'ready' + // Score delta floater + const [scoreDelta, setScoreDelta] = useState<{ value: number; key: number; dx: number; dy: number } | null>(null) + const [scorePulse, setScorePulse] = useState(0) + // Scoring: base points + combo bonus (capped at 4x) const handleJudgment = useCallback( (j: 'perfect' | 'good' | 'miss', combo: number) => { + let delta = 0 if (j === 'perfect') { addPerfectHit() const multiplier = 1 + Math.min(combo, 30) / 10 - addScore(Math.round(1000 * multiplier)) + delta = Math.round(1000 * multiplier) } else if (j === 'good') { addGoodHit() const multiplier = 1 + Math.min(combo, 30) / 10 - addScore(Math.round(500 * multiplier)) + delta = Math.round(500 * multiplier) } else { addMiss() } + if (delta > 0) { + addScore(delta) + setScoreDelta({ + value: delta, + key: Date.now(), + dx: 20 + Math.random() * 80, + dy: -10 + Math.random() * 40, + }) + setScorePulse(Date.now()) + } }, [addPerfectHit, addGoodHit, addMiss, addScore], ) @@ -104,9 +119,22 @@ export function GamePage() { {error &&