Skip to content

Scoreboard

Central timing and progression system that manages race statistics, lap tracking, and player/opponent results with millisecond precision.


🏁 Core Responsibilities

FunctionDescription
Lap TimingTracks split/lap/finish times
Checkpoint ValidationVerifies proper track navigation
Race State ManagementHandles start/finish logic
Results AggregationCompiles final rankings
UI CoordinationUpdates race progress displays

📊 Properties

Timing Data

PropertyTypeDescription
currentPlayerStartTimeDate | nullRace start timestamp
lapTimeList(Date | null)[]Array of lap timestamps (max 3)
currentLapTimenumberCurrent lap duration (ms)

Progress Tracking

PropertyTypeRangeDescription
_currentLapnumber1-3Active lap number
currentCheckpointnumber0-NNext checkpoint ID
clearCheckpointsCounternumber≥0Valid checkpoints passed

Results

PropertyTypeDescription
playerResultsArray<{nickname: string, time: number}>Final standings

⏱️ Timing Methods

currentTime

get currentTime(): number {
return this.currentPlayerStartTime
? new Date().getTime() - this.currentPlayerStartTime.getTime()
: 0;
}

Lap Management

MethodReturnsDescription
resetCurrentTime()voidClears all timing data
currentLapnumberGets/sets current lap
currentLapTimenumberCurrent lap duration

🎮 Core Game Loop

update(gameScene: GameScene)

graph TD
A[Check Position] --> B{Checkpoint Reached?}
B -->|Yes| C[Advance Checkpoint]
C --> D{Lap Complete?}
D -->|Yes| E[Increment Lap]
E --> F[Play Lap Sound]
D -->|No| G[Continue Tracking]
B -->|No| G
F --> H{Race Complete?}
H -->|Yes| I[Record Results]
I --> J[Transition to Results]

Key Behaviors:

  • Checkpoint validation radius: 150 units
  • Lap transition sound: audioLap
  • Race completion sound: audioFinish
  • Requires all opponents to finish before showing results

🏆 Results Management

Final Ranking Logic

  1. Stores player time in playerResults
  2. Sorts entries by fastest time
  3. Triggers podium animation
  4. Unlocks achievements if applicable

Data Structure:

interface RaceResult {
nickname: string; // Player/opponent name
time: number; // Milliseconds
vehicle?: string; // Optional vehicle type
}

🔊 Audio Feedback

EventSoundTrigger Condition
Lap CompleteaudioLapcurrentCheckpoint === 0
Race FinishaudioFinish_currentLap > totalLaps
New Best LapaudioBestLapIf lap time < stored best

🛠️ Usage Example

// Initialize
Scoreboard.instance.resetCurrentTime();
// Game loop
function updateRace() {
Scoreboard.instance.update(currentScene);
// Display lap time
hud.setLapTime(
Scoreboard.instance.currentLap,
formatTime(Scoreboard.instance.currentLapTime)
);
}
// Finish handling
if (Scoreboard.instance.currentLap > 3) {
showPodiumAnimation();
}

🧠 Design Considerations

Singleton Pattern

  • Ensures global race state access
  • Prevents timing conflicts
  • Simplifies UI coordination

Checkpoint System

  • Prevents lap skipping
  • Validates proper track navigation
  • Enables position tracking

Performance

  • Lightweight calculations
  • Event-driven audio triggers
  • Minimal object allocation