diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 28870682..84164fc5 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -169,7 +169,8 @@ "Bash(open http://localhost:6006)", "Bash(open http://localhost:3002/games/matching)", "Bash(open http://localhost:3002/create)", - "Bash(open http://localhost:3002/games/complement-race/practice)" + "Bash(open http://localhost:3002/games/complement-race/practice)", + "Bash(open http://localhost:3002/games/complement-race)" ], "deny": [], "ask": [] diff --git a/apps/web/src/app/games/complement-race/components/RaceTrack/SteamTrainJourney.tsx b/apps/web/src/app/games/complement-race/components/RaceTrack/SteamTrainJourney.tsx index 10afaab6..38f82624 100644 --- a/apps/web/src/app/games/complement-race/components/RaceTrack/SteamTrainJourney.tsx +++ b/apps/web/src/app/games/complement-race/components/RaceTrack/SteamTrainJourney.tsx @@ -98,6 +98,13 @@ export function SteamTrainJourney({ momentum, trainPosition, pressure, elapsedTi const pathRef = useRef(null) const [trackGenerator] = useState(() => new RailroadTrackGenerator(800, 600)) + // Train transforms (extracted to hook) - called first to get maxCars and carSpacing + const { trainTransform, trainCars, locomotiveOpacity, maxCars, carSpacing } = useTrainTransforms({ + trainPosition, + trackGenerator, + pathRef + }) + // Track management (extracted to hook) const { trackData, tiesAndRails, stationPositions, landmarks, landmarkPositions, displayPassengers } = useTrackManagement({ currentRoute: state.currentRoute, @@ -105,14 +112,9 @@ export function SteamTrainJourney({ momentum, trainPosition, pressure, elapsedTi trackGenerator, pathRef, stations: state.stations, - passengers: state.passengers - }) - - // Train transforms (extracted to hook) - const { trainTransform, trainCars, locomotiveOpacity, maxCars, carSpacing } = useTrainTransforms({ - trainPosition, - trackGenerator, - pathRef + passengers: state.passengers, + maxCars, + carSpacing }) // Passenger animations (extracted to hook) diff --git a/apps/web/src/app/games/complement-race/hooks/useTrackManagement.ts b/apps/web/src/app/games/complement-race/hooks/useTrackManagement.ts index 21b089d2..e44e113f 100644 --- a/apps/web/src/app/games/complement-race/hooks/useTrackManagement.ts +++ b/apps/web/src/app/games/complement-race/hooks/useTrackManagement.ts @@ -10,6 +10,8 @@ interface UseTrackManagementParams { pathRef: React.RefObject stations: Station[] passengers: Passenger[] + maxCars?: number + carSpacing?: number } export function useTrackManagement({ @@ -18,7 +20,9 @@ export function useTrackManagement({ trackGenerator, pathRef, stations, - passengers + passengers, + maxCars = 5, + carSpacing = 7 }: UseTrackManagementParams) { const [trackData, setTrackData] = useState | null>(null) const [tiesAndRails, setTiesAndRails] = useState<{ @@ -68,23 +72,26 @@ export function useTrackManagement({ // Manage passenger display during route transitions useEffect(() => { - // If we're starting a new route (position < 0) or passengers haven't changed, update immediately - if (trainPosition < 0 || passengers === previousPassengersRef.current) { + // Calculate the position of the last train car + const lastCarPosition = trainPosition - maxCars * carSpacing + const fadeOutEnd = 97 // Position where cars are fully faded out + + // Only switch to new passengers when: + // 1. Train has reset to start position (< 0), OR + // 2. All cars (including the last one) have exited (last car position >= fadeOutEnd) + const allCarsExited = lastCarPosition >= fadeOutEnd + const trainReset = trainPosition < 0 + + if (trainReset || allCarsExited || passengers === previousPassengersRef.current) { setDisplayPassengers(passengers) previousPassengersRef.current = passengers } // Otherwise, if we're mid-route and passengers changed, keep showing old passengers - else if (trainPosition > 0 && passengers !== previousPassengersRef.current) { - // Keep displaying old passengers until train exits + else if (passengers !== previousPassengersRef.current) { + // Keep displaying old passengers until all cars exit // Don't update displayPassengers yet } - - // When train resets to beginning, switch to new passengers - if (trainPosition < 0 && passengers !== previousPassengersRef.current) { - setDisplayPassengers(passengers) - previousPassengersRef.current = passengers - } - }, [passengers, trainPosition]) + }, [passengers, trainPosition, maxCars, carSpacing]) // Update display passengers during gameplay (same route) useEffect(() => {