Skip to content

Commit be87f00

Browse files
author
danil-nizamov
committed
updated opp cars movement tracking
1 parent 40a3cf3 commit be87f00

File tree

2 files changed

+48
-20
lines changed

2 files changed

+48
-20
lines changed

client/stats.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
Status: win
1+
Status: lose
22

33
Typing Statistics
44
==================
55

6-
Total Errors Made: 2
6+
Total Errors Made: 147
77
Errors Left (Unfixed): 0
8-
Total Time: 11.19 seconds
9-
Accuracy: 97.01%
10-
Speed: 64.35 words per minute
8+
Total Time: 23.27 seconds
9+
Accuracy: 10.37%
10+
Speed: 30.94 words per minute
1111

12-
Generated: 29/11/2025, 01:27:42
12+
Generated: 02/12/2025, 05:55:45

client/typing-simulator.js

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
// Game manager - handles different game types
3636
let currentGame = null;
3737
let gameUpdateInterval = null;
38+
let gameAnimationFrame = null;
3839

3940
function setStatus(msg) {
4041
const status = document.getElementById('status');
@@ -88,10 +89,14 @@
8889

8990
this.opponentPositions = [0, 0, 0];
9091
this.opponentSpeeds = config.racing?.opponentSpeeds || [0.3, 0.4, 0.5];
92+
// Convert speeds from pixels per frame (at 60fps) to pixels per second
93+
// Original speeds: 0.3, 0.4, 0.5 px/frame at 60fps = 18, 24, 30 px/s
94+
this.opponentSpeedsPxPerSec = this.opponentSpeeds.map(speed => speed * 60);
9195
// Current speeds with randomness (initialized to base speeds)
92-
this.currentOpponentSpeeds = [...this.opponentSpeeds];
93-
this.speedUpdateTimer = 0; // Timer for speed updates
96+
this.currentOpponentSpeeds = [...this.opponentSpeedsPxPerSec];
97+
this.speedUpdateTimer = 0; // Timer for speed updates (in milliseconds)
9498
this.speedUpdateInterval = 1500 + Math.random() * 1000; // Update speed every 1.5-2.5 seconds
99+
this.lastFrameTime = null; // For delta time calculation
95100
this.trackWidth = 0;
96101
this.finishLineTextPosition = 0; // Position in text coordinates
97102
this.isFinished = false;
@@ -126,10 +131,11 @@
126131
this.isFinished = false;
127132
this.finishLineTextPosition = 0;
128133
this.playerWon = null; // Reset win/loss status
129-
// Reset speeds to base speeds
130-
this.currentOpponentSpeeds = [...this.opponentSpeeds];
134+
// Reset speeds to base speeds (in px/s)
135+
this.currentOpponentSpeeds = [...this.opponentSpeedsPxPerSec];
131136
this.speedUpdateTimer = 0;
132137
this.speedUpdateInterval = 1500 + Math.random() * 1000; // Reset update interval
138+
this.lastFrameTime = null; // Reset frame time
133139

134140
if (this.playerCar) {
135141
this.playerCar.style.left = '20px';
@@ -151,7 +157,7 @@
151157
updateOpponentSpeeds() {
152158
// Update speeds with small random variations
153159
// Variations are ±20% of base speed to keep it realistic
154-
this.opponentSpeeds.forEach((baseSpeed, index) => {
160+
this.opponentSpeedsPxPerSec.forEach((baseSpeed, index) => {
155161
const variation = 0.2; // ±20% variation
156162
const randomFactor = 1 + (Math.random() * 2 - 1) * variation; // Random between 0.8 and 1.2
157163
this.currentOpponentSpeeds[index] = baseSpeed * randomFactor;
@@ -239,14 +245,26 @@
239245
// Finish line is positioned with right: 0 in CSS, so it automatically aligns with track edge
240246
}
241247

242-
updateOpponents() {
248+
updateOpponents(currentTime) {
243249
if (this.isFinished || !startTime) return;
244250

251+
// Calculate delta time (time since last frame) in seconds
252+
let deltaTime = 0;
253+
if (this.lastFrameTime !== null) {
254+
deltaTime = (currentTime - this.lastFrameTime) / 1000; // Convert to seconds
255+
// Clamp delta time to prevent large jumps (e.g., when tab regains focus)
256+
deltaTime = Math.min(deltaTime, 0.1); // Max 100ms delta (10fps minimum)
257+
}
258+
this.lastFrameTime = currentTime;
259+
260+
// Skip update if this is the first frame (no delta time yet)
261+
if (deltaTime === 0) return;
262+
245263
// Update finish line position first (in case text changed)
246264
this.updateFinishLinePosition();
247265

248266
// Update speeds periodically with randomness
249-
this.speedUpdateTimer += 16; // ~60fps, so 16ms per frame
267+
this.speedUpdateTimer += deltaTime * 1000; // Convert to milliseconds
250268
if (this.speedUpdateTimer >= this.speedUpdateInterval) {
251269
this.updateOpponentSpeeds();
252270
}
@@ -259,9 +277,11 @@
259277
this.opponentCars.forEach((car, index) => {
260278
if (!car) return;
261279

262-
// Use current speed (with randomness) instead of base speed
263-
const speed = this.currentOpponentSpeeds[index] || this.opponentSpeeds[index] || 0.3;
264-
this.opponentPositions[index] += speed;
280+
// Use current speed (with randomness) in pixels per second
281+
// Multiply by deltaTime to get frame-rate independent movement
282+
const speedPxPerSec = this.currentOpponentSpeeds[index] || this.opponentSpeedsPxPerSec[index] || 18;
283+
const movementThisFrame = speedPxPerSec * deltaTime; // pixels this frame
284+
this.opponentPositions[index] += movementThisFrame;
265285

266286
// Calculate car position
267287
// Car's left edge is at: 20px (start) + opponentPositions[index]
@@ -356,6 +376,10 @@
356376
clearInterval(gameUpdateInterval);
357377
gameUpdateInterval = null;
358378
}
379+
if (gameAnimationFrame !== null) {
380+
cancelAnimationFrame(gameAnimationFrame);
381+
gameAnimationFrame = null;
382+
}
359383
}
360384

361385
// Initialize based on game type
@@ -369,13 +393,17 @@
369393

370394
currentGame.initialize();
371395

372-
// Start game update loop for racing
396+
// Start game update loop for racing using requestAnimationFrame
373397
if (gameType === 'racing' && currentGame instanceof RacingGame) {
374-
gameUpdateInterval = setInterval(() => {
398+
function animate(currentTime) {
375399
if (currentGame && currentGame.updateOpponents) {
376-
currentGame.updateOpponents();
400+
currentGame.updateOpponents(currentTime);
377401
}
378-
}, 16); // ~60fps
402+
// Continue animation loop
403+
gameAnimationFrame = requestAnimationFrame(animate);
404+
}
405+
// Start the animation loop
406+
gameAnimationFrame = requestAnimationFrame(animate);
379407
}
380408

381409
// Re-render text if it's already loaded

0 commit comments

Comments
 (0)