Spaces:
Sleeping
Sleeping
| import { useGameStore } from '@/stores/gameStore' | |
| import { useWorldStore } from '@/stores/worldStore' | |
| import { usePlayerStore } from '@/stores/playerStore' | |
| import { TICK_DURATION_MS, MAX_TICKS } from '@/engine/constants' | |
| let lastTime = 0 | |
| let accumulatedTime = 0 | |
| let frameTime = 0 | |
| let tickTime = 0 | |
| let tickCount = 0 | |
| let frameCount = 0 | |
| let lastSecondTime = 0 | |
| /** | |
| * Main game loop that handles fixed timestep updates and rendering | |
| * @param timestamp Current timestamp from requestAnimationFrame | |
| */ | |
| function gameLoop(timestamp: number) { | |
| // Initialize time on first frame | |
| if (!lastTime) { | |
| lastTime = timestamp | |
| } | |
| // Calculate time differences | |
| const delta = timestamp - lastTime | |
| lastTime = timestamp | |
| accumulatedTime += delta | |
| // Update frame counter for FPS calculation | |
| frameCount++ | |
| frameTime += delta | |
| // Process game ticks at fixed intervals | |
| while (accumulatedTime >= TICK_DURATION_MS) { | |
| // Update game state | |
| updateGame() | |
| // Update tick counter for TPS calculation | |
| tickCount++ | |
| tickTime += TICK_DURATION_MS | |
| accumulatedTime -= TICK_DURATION_MS | |
| } | |
| // Calculate and update performance metrics | |
| updatePerformanceMetrics(timestamp) | |
| // Render the game | |
| renderGame() | |
| // Schedule next frame | |
| requestAnimationFrame(gameLoop) | |
| } | |
| /** | |
| * Update game state (fixed timestep) | |
| */ | |
| function updateGame() { | |
| const gameStore = useGameStore.getState() | |
| const worldStore = useWorldStore.getState() | |
| const playerStore = usePlayerStore.getState() | |
| // Skip updates if game is paused | |
| if (gameStore.paused) return | |
| // Update game tick counter | |
| gameStore.actions.incrementTick() | |
| // Update world time | |
| worldStore.actions.updateWorldTime() | |
| // Update player position and physics | |
| updatePlayerPhysics() | |
| // Update entities | |
| updateEntities() | |
| // Update scheduled block ticks | |
| updateScheduledTicks() | |
| // Update random block ticks | |
| updateRandomTicks() | |
| } | |
| /** | |
| * Update player physics and movement | |
| */ | |
| function updatePlayerPhysics() { | |
| const playerStore = usePlayerStore.getState() | |
| const player = playerStore.player | |
| if (!player) return | |
| // Apply gravity | |
| player.velocity[1] += -32 * (TICK_DURATION_MS / 1000) | |
| // Apply movement | |
| // This is a simplified version - actual implementation would handle input and collision detection | |
| player.position[0] += player.velocity[0] * (TICK_DURATION_MS / 1000) | |
| player.position[1] += player.velocity[1] * (TICK_DURATION_MS / 1000) | |
| player.position[2] += player.velocity[2] * (TICK_DURATION_MS / 1000) | |
| // Update player state | |
| playerStore.actions.updatePosition(player.position) | |
| } | |
| /** | |
| * Update all entities in the world | |
| */ | |
| function updateEntities() { | |
| // Implementation would iterate through all entities and update their state | |
| // including AI, physics, and animations | |
| } | |
| /** | |
| * Process scheduled block ticks | |
| */ | |
| function updateScheduledTicks() { | |
| // Implementation would handle scheduled block updates like redstone ticks | |
| } | |
| /** | |
| * Process random block ticks (like plant growth) | |
| */ | |
| function updateRandomTicks() { | |
| // Implementation would handle random block updates based on world's randomTickSpeed | |
| } | |
| /** | |
| * Render the game scene | |
| */ | |
| function renderGame() { | |
| // Implementation would handle rendering with Three.js | |
| // including camera updates, chunk rendering, and UI | |
| } | |
| /** | |
| * Update performance metrics (FPS, TPS) | |
| * @param timestamp Current timestamp | |
| */ | |
| function updatePerformanceMetrics(timestamp: number) { | |
| // Calculate FPS and TPS | |
| if (timestamp - lastSecondTime >= 1000) { | |
| const fps = frameCount / (frameTime / 1000) | |
| const tps = tickCount / (tickTime / 1000) | |
| useGameStore.getState().actions.updatePerformance({ | |
| averageFPS: fps, | |
| averageTPS: tps, | |
| }) | |
| // Update debug UI | |
| useUIStore.getState().actions.updateDebugInfo({ | |
| fps: Math.round(fps), | |
| tps: Math.round(tps), | |
| }) | |
| // Reset counters | |
| frameCount = 0 | |
| frameTime = 0 | |
| tickCount = 0 | |
| tickTime = 0 | |
| lastSecondTime = timestamp | |
| } | |
| } | |
| /** | |
| * Start the game loop | |
| */ | |
| export function startGameLoop() { | |
| requestAnimationFrame(gameLoop) | |
| } |