package main import ( "git.zb-server.de/ZB-Server/EscapeFromTeacher/pkg/config" "git.zb-server.de/ZB-Server/EscapeFromTeacher/pkg/game" ) // ApplyInput wendet einen Input auf den vorhergesagten Zustand an func (g *Game) ApplyInput(input InputState) { // Horizontale Bewegung moveX := 0.0 if input.Left { moveX = -1.0 } else if input.Right { moveX = 1.0 } speed := config.RunSpeed + (moveX * 4.0) g.predictedX += speed // Gravitation g.predictedVY += config.Gravity if g.predictedVY > config.MaxFall { g.predictedVY = config.MaxFall } // Fast Fall if input.Down { g.predictedVY = 15.0 } // Sprung if input.Jump && g.predictedGround { g.predictedVY = -14.0 g.predictedGround = false } // Vertikale Bewegung g.predictedY += g.predictedVY // Einfache Boden-Kollision (hardcoded für jetzt) if g.predictedY >= 540 { g.predictedY = 540 g.predictedVY = 0 g.predictedGround = true } else { g.predictedGround = false } } // ReconcileWithServer gleicht lokale Prediction mit Server-State ab func (g *Game) ReconcileWithServer(serverState game.PlayerState) { g.predictionMutex.Lock() defer g.predictionMutex.Unlock() // Server-bestätigte Sequenz g.lastServerSeq = serverState.LastInputSeq // Entferne alle bestätigten Inputs for seq := range g.pendingInputs { if seq <= g.lastServerSeq { delete(g.pendingInputs, seq) } } // Setze vorhergesagte Position auf Server-Position g.predictedX = serverState.X g.predictedY = serverState.Y g.predictedVX = serverState.VX g.predictedVY = serverState.VY g.predictedGround = serverState.OnGround // Replay alle noch nicht bestätigten Inputs // (Sortiert nach Sequenz) if len(g.pendingInputs) > 0 { for seq := g.lastServerSeq + 1; seq <= g.inputSequence; seq++ { if input, ok := g.pendingInputs[seq]; ok { g.ApplyInput(input) } } } }