From 7860c7e7295770d20fbe2704869f339ccec9a04e Mon Sep 17 00:00:00 2001 From: Andre Padez Date: Tue, 4 Nov 2025 17:45:36 +0000 Subject: [PATCH] feat: add dynamic ship tracking for sentences mode - Ship now moves to center of each character as you type - Calculate and store X position of current character during rendering - Ship smoothly tracks typing progress across both lines - Handles line transitions seamlessly - Creates engaging targeting effect as ship 'shoots' each letter --- src/types.ts | 2 ++ src/useBoard/useBoard.ts | 4 ++++ src/useGame/useGame.ts | 15 +++++++++++---- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/types.ts b/src/types.ts index 5b4412e..286f073 100755 --- a/src/types.ts +++ b/src/types.ts @@ -37,6 +37,8 @@ export type FallingLetter = { // For line transitions in sentences/paragraphs lineTransition?: boolean; lineTransitionTime?: number; + // For ship tracking in sentences + currentCharX?: number; // X position of current character to type }; // ============================================================================ diff --git a/src/useBoard/useBoard.ts b/src/useBoard/useBoard.ts index 28cc586..5d869dd 100644 --- a/src/useBoard/useBoard.ts +++ b/src/useBoard/useBoard.ts @@ -359,6 +359,8 @@ export function useBoard() { ctx.fillStyle = `rgba(0, 255, 0, ${topOpacity})`; // Green - completed } else if (charIdx === charIndex) { ctx.fillStyle = `rgba(255, 255, 0, ${topOpacity})`; // Yellow - current + // Store position of current character for ship tracking + letter.currentCharX = line2X + ctx.measureText(char).width / 2; } else { ctx.fillStyle = `rgba(255, 255, 255, ${topOpacity})`; // White - remaining } @@ -380,6 +382,8 @@ export function useBoard() { ctx.fillStyle = "#00ff00"; // Green - completed } else if (i === charIndex) { ctx.fillStyle = "#ffff00"; // Yellow - current + // Store position of current character for ship tracking + letter.currentCharX = line1X + ctx.measureText(char).width / 2; } else { ctx.fillStyle = "#ffffff"; // White - remaining } diff --git a/src/useGame/useGame.ts b/src/useGame/useGame.ts index 4a8c474..7ca6bd3 100755 --- a/src/useGame/useGame.ts +++ b/src/useGame/useGame.ts @@ -28,7 +28,7 @@ export function useGame( gameStatusManager.updatePlayerX(playerPos.x); // For words/letters, auto-track to falling letters - // For sentences/paragraphs, keep ship centered + // For sentences/paragraphs, track to current character position if (gameModeRef.current !== 'sentences' && gameModeRef.current !== 'paragraphs') { if (letters.length > 0) { const letter = letters[0]; @@ -37,9 +37,16 @@ export function useGame( cursorManager.moveTowardTarget(deltaTime); } else { - // Keep ship centered for sentence/paragraph mode - cursorManager.setTargetX(400); // Canvas center - cursorManager.moveTowardTarget(deltaTime); // Move to center but don't track letters + // For sentences: track to current character position + if (letters.length > 0) { + const letter = letters[0]; + // Use the stored character position or default to center + const targetX = letter.currentCharX || 400; + cursorManager.setTargetX(targetX); + } else { + cursorManager.setTargetX(400); // Default to center when no letters + } + cursorManager.moveTowardTarget(deltaTime); } renderBoardWrapped(letters);