minecraft-clone / src /engine /gameLoop.ts
TomatitoToho's picture
Upload src/engine/gameLoop.ts with huggingface_hub
caa5fe0 verified
Raw
History Blame Contribute Delete
4.1 kB
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)
}