Spaces:
Sleeping
Sleeping
File size: 4,102 Bytes
caa5fe0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | 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)
} |