Change game loop to use fixed time step

main
Tyler Scott 2022-02-05 14:21:31 +07:00
parent c3250c71fa
commit b472d390bb
1 changed files with 78 additions and 15 deletions

View File

@ -57,7 +57,7 @@ function love.load(arg)
game.bubble_diameter = 60
game.bubble_radius = game.bubble_diameter / 2
game.bubble_speed = 900 -- px/s
game.bubble_speed = 8 -- px/frame
-- vertical distance between bubble center points
game.row_gap = math.ceil(math.sqrt(
@ -150,10 +150,13 @@ function love.load(arg)
end
function love.update(dt)
if game.paused then return end
if game.paused then
return
end
if game.next_bubble.velocity_x ~= 0 or game.next_bubble.velocity_y ~= 0 then
local next_x = game.next_bubble.x + game.next_bubble.velocity_x * dt
local next_y = game.next_bubble.y + game.next_bubble.velocity_y * dt
local next_x = game.next_bubble.x + game.next_bubble.velocity_x
local next_y = game.next_bubble.y + game.next_bubble.velocity_y
local collision_detection_finished = false
-- collision with ceiling
@ -166,7 +169,7 @@ function love.update(dt)
collision_detection_finished = true
end
-- collision with wall
-- collision with walls
if not collision_detection_finished then
if next_x + game.bubble_radius >= game.level_right or
next_x - game.bubble_radius <= game.level_left then
@ -175,13 +178,13 @@ function love.update(dt)
impact_x = game.level_right - game.bubble_radius
end
local dx = impact_x - game.next_bubble.x
local ratio = dx / game.next_bubble.velocity_x * dt
local dy = game.next_bubble.velocity_y * dt * ratio
local ratio = dx / game.next_bubble.velocity_x
local dy = game.next_bubble.velocity_y * ratio
local impact_y = game.next_bubble.y + dy
local ratio_after_bounce = 1.0 - ratio
game.next_bubble.velocity_x = -game.next_bubble.velocity_x
next_x = impact_x + game.next_bubble.velocity_x * dt * ratio_after_bounce
next_y = impact_y + game.next_bubble.velocity_y * dt * ratio_after_bounce
next_x = impact_x + game.next_bubble.velocity_x * ratio_after_bounce
next_y = impact_y + game.next_bubble.velocity_y * ratio_after_bounce
end
end
@ -195,6 +198,7 @@ function love.update(dt)
local dist = math.sqrt(diff_x * diff_x + diff_y * diff_y)
if dist <= game.bubble_diameter then
local depth = game.bubble_diameter - dist
print('depth', depth)
local direction_x = diff_x / dist
local direction_y = diff_y / dist
next_x = next_x + direction_x * depth
@ -223,17 +227,21 @@ function love.update(dt)
end
end
function love.draw()
function love.draw(alpha)
if game.paused then
alpha = 0
end
-- draw background
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(game.background_image, 0, 0)
love.graphics.draw(game.background_image, game.background_width, 0)
-- draw stationary bubbles
love.graphics.setColor(1, 1, 1, 1)
for i = 1, #game.bubble_slots do
local slot = game.bubble_slots[i]
if slot.bubble_type >= 1 and slot.bubble_type <= #game.bubble_images then
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(
game.bubble_images[slot.bubble_type],
slot.x,
@ -243,7 +251,6 @@ function love.draw()
game.bubble_radius
)
else
love.graphics.setColor(0.4, 0, 0, 1)
love.graphics.circle(
'line',
slot.x,
@ -253,7 +260,7 @@ function love.draw()
end
end
-- draw level border
-- draw walls
love.graphics.setColor(0, 0, 0, 1)
love.graphics.rectangle(
'line',
@ -277,11 +284,12 @@ function love.draw()
)
-- draw next bubble
-- if moving, extrapolate position based on alpha value from love.run
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(
game.bubble_images[game.next_bubble.bubble_type],
game.next_bubble.x,
game.next_bubble.y,
game.next_bubble.x + game.next_bubble.velocity_x * alpha,
game.next_bubble.y + game.next_bubble.velocity_y * alpha,
0,
1,
1,
@ -314,6 +322,9 @@ function love.keypressed(key, scan_code, is_repeat)
game.next_bubble.y = game.launcher_y
game.next_bubble.velocity_x = 0
game.next_bubble.velocity_y = 0
game.next_bubble.bubble_type = get_next_bubble_type(
game.next_bubble_index, {1,2,3,4,5,6,7,8}
)
game.paused = false
elseif key == 'space' then
game.paused = not game.paused
@ -322,3 +333,55 @@ function love.keypressed(key, scan_code, is_repeat)
game.paused = false
end
end
function love.run()
if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
if love.timer then love.timer.step() end
local dt = 1/120 -- update 120 times per second
local accumulator = 0.0
return function()
if love.event then
love.event.pump()
for name, a,b,c,d,e,f in love.event.poll() do
if name == "quit" then
if not love.quit or not love.quit() then
return a or 0
end
end
love.handlers[name](a,b,c,d,e,f)
end
end
local frame_time = dt -- default in case love.timer is disabled
if love.timer then
frame_time = love.timer.step()
if frame_time > 0.25 then
frame_time = 0.25
end
end
accumulator = accumulator + frame_time
while (accumulator >= dt) do
if love.update then love.update(dt) end
accumulator = accumulator - dt
end
local alpha = accumulator / dt
if love.graphics and love.graphics.isActive() then
love.graphics.origin()
love.graphics.clear(love.graphics.getBackgroundColor())
if love.draw then love.draw(alpha) end
love.graphics.present()
end
if love.timer then love.timer.sleep(0.001) end
end
end