Cześć. Próbuję zaimplementować game loop z artykułu "Fix Your Timestep!"
Nie jestem zadowolony z efektu. Podczas niektórych uruchomień animacja postaci zaczyna się jakoś dziwnie animować. Czy widzicie tu jakiś błąd? Jak podchodzicie do debugowania takich problemów? Na windowsie można próbować powtórzyć ten problem poprzez trzymanie paska aplikacji wtedy rl.GetFrameTime() zwróci dość sporą wartość, ale czasem trafiam w ten stan bez ingerencji w frame time.
//main.odin
for !rl.WindowShouldClose() {
frameTime: f32 = rl.GetFrameTime()
if frameTime > maxFrameTime {
frameTime = maxFrameTime
}
accumulator += frameTime
updateInputs(&inputs)
for accumulator >= FIXED_DT {
updatePlayerInput(&gameState, &inputs)
updateEntities(&gameState, FIXED_DT)
accumulator -= FIXED_DT
}
blendFactor: f32 = accumulator / FIXED_DT
clearRenderFrame(&renderFrame)
drawEntitiesToFrame(&renderFrame, &gameState, blendFactor)
// interpCameraPos := interpolateVector2(
// gameState.oldCameraPos,
// gameState.cameraPos,
// blendFactor
// )
camera.target.x = math.round_f32(gameState.cameraPos.x)
camera.target.y = math.round_f32(gameState.cameraPos.y)
rl.BeginDrawing()
rl.ClearBackground(rl.GRAY)
rl.BeginMode2D(camera)
drawTilemap(&tilemap, camera)
flushRenderFrame(&renderFrame)
rl.EndMode2D()
str := fmt.tprintf("%v\nvelocity: %v", gameState.hero.pos, gameState.hero.velocity)
text_cstr := strings.clone_to_cstring(str)
defer delete(text_cstr)
rl.DrawText(text_cstr, 0, 0, 18, rl.BLACK)
rl.EndDrawing()
}
//game_state.odin
drawEntitiesToFrame :: proc(rf: ^RenderFrame, state: ^GameState, blendFactor: f32) {
if state.hero != nil {
drawEntityToFrame(rf, state.hero.entity, blendFactor)
}
for i in 0..<state.entityCount {
drawEntityToFrame(rf, state.enemies[i], blendFactor)
}
}
//entity.odin
drawEntityToFrame :: proc(rf: ^RenderFrame, e: ^Entity, blendFactor: f32) {
if !e.active do return
// Interpolate position for smooth rendering
interpPos := rl.Vector2{
e.oldPos.x + (e.pos.x - e.oldPos.x) * blendFactor,
e.oldPos.y + (e.pos.y - e.oldPos.y) * blendFactor,
}
renderPos := interpPos
// renderPos := rl.Vector2{
// math.round(interpPos.x),
// math.round(interpPos.y),
// }
drawSpritePlayerToFrame(rf, &e.spritePlayer, renderPos, e.z)
collisionRect := rl.Rectangle{
x = e.pos.x,
y = e.pos.y,
width = e.size.x,
height = e.size.y,
}
pushDebugRectangle(rf, collisionRect)
}
Projekt można łatwo uruchomić, potrzebujemy kompilator odina.
Budowa projektu: odin build .
Budowa i uruchomienie odin run .