Use dtime to calculate player position in motion (#1)

Makes movement uniform and independent of framerates / step delays.
master
x2048 2021-08-22 00:44:31 +02:00 committed by GitHub
parent 7ed4276607
commit 0195d5f1cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 62 additions and 33 deletions

View File

@ -124,9 +124,9 @@ cinematic = {
-- Update loop -- Update loop
minetest.register_globalstep(function() minetest.register_globalstep(function(dtime)
for _, entry in pairs(cinematic.players) do for _, entry in pairs(cinematic.players) do
cinematic.motions[entry.motion].tick(entry.player, entry.state) cinematic.motions[entry.motion].tick(entry.player, entry.state, dtime)
end end
end) end)
@ -142,16 +142,23 @@ cinematic.register_motion("360", {
angle = minetest.dir_to_yaw(vector.subtract(player_pos, center)) + math.pi / 2, angle = minetest.dir_to_yaw(vector.subtract(player_pos, center)) + math.pi / 2,
height = player_pos.y - center.y, height = player_pos.y - center.y,
speed = params:get_speed({"l", "left"}, "right"), speed = params:get_speed({"l", "left"}, "right"),
time = 0,
} }
end, end,
tick = function(player, state) tick = function(player, state, dtime)
state.angle = state.angle + state.speed * math.pi / 3600 state.time = state.time + dtime
if state.angle < 0 then state.angle = state.angle + 2 * math.pi end local delta_angle = state.speed * state.time * math.pi * 1 / 180
if state.angle > 2 * math.pi then state.angle = state.angle - 2 * math.pi end if math.abs(delta_angle) > 1.0 then
state.angle = state.angle + delta_angle
delta_angle = 0.0
state.time = 0.0
if state.angle < 0 then state.angle = state.angle + 2 * math.pi end
if state.angle > 2 * math.pi then state.angle = state.angle - 2 * math.pi end
end
player_pos = vector.add(state.center, vector.new(state.distance * math.cos(state.angle), state.height, state.distance * math.sin(state.angle))) player_pos = vector.add(state.center, vector.new(state.distance * math.cos(state.angle + delta_angle), state.height, state.distance * math.sin(state.angle + delta_angle)))
player:set_pos(player_pos) player:set_pos(player_pos)
player:set_look_horizontal(state.angle + math.pi / 2) player:set_look_horizontal(state.angle + delta_angle + math.pi / 2)
end end
}) })
@ -160,12 +167,14 @@ cinematic.register_motion("dolly", {
return { return {
speed = params:get_speed({"b", "back", "backwards", "out"}, "forward"), speed = params:get_speed({"b", "back", "backwards", "out"}, "forward"),
direction = vector.normalize(vector.new(player:get_look_dir().x, 0, player:get_look_dir().z)), direction = vector.normalize(vector.new(player:get_look_dir().x, 0, player:get_look_dir().z)),
origin = player:get_pos(),
time = 0,
} }
end, end,
tick = function(player, state) tick = function(player, state, dtime)
local player_pos = player:get_pos() state.time = state.time + dtime
player_pos = vector.add(player_pos, vector.multiply(state.direction, state.speed * 0.05)) player_pos = vector.add(state.origin, vector.multiply(state.direction, state.time * state.speed))
player:set_pos(player_pos) player:set_pos(player_pos)
end end
}) })
@ -175,12 +184,14 @@ cinematic.register_motion("truck", {
return { return {
speed = params:get_speed({"l", "left"}, "right"), speed = params:get_speed({"l", "left"}, "right"),
direction = vector.normalize(vector.cross(vector.new(0,1,0), player:get_look_dir())), direction = vector.normalize(vector.cross(vector.new(0,1,0), player:get_look_dir())),
origin = player:get_pos(),
time = 0,
} }
end, end,
tick = function(player, state) tick = function(player, state, dtime)
local player_pos = player:get_pos() state.time = state.time + dtime
player_pos = vector.add(player_pos, vector.multiply(state.direction, state.speed * 0.05)) player_pos = vector.add(state.origin, vector.multiply(state.direction, state.time * state.speed))
player:set_pos(player_pos) player:set_pos(player_pos)
end end
}) })
@ -189,13 +200,15 @@ cinematic.register_motion("pedestal", {
initialize = function(player, params) initialize = function(player, params)
return { return {
speed = params:get_speed({"d", "down"}, "up"), speed = params:get_speed({"d", "down"}, "up"),
direction = vector.new(0,1,0) direction = vector.new(0,1,0),
origin = player:get_pos(),
time = 0,
} }
end, end,
tick = function(player, state) tick = function(player, state, dtime)
local player_pos = player:get_pos() state.time = state.time + dtime
player_pos = vector.add(player_pos, vector.multiply(state.direction, state.speed * 0.05)) player_pos = vector.add(state.origin, vector.multiply(state.direction, state.time * state.speed))
player:set_pos(player_pos) player:set_pos(player_pos)
end end
}) })
@ -203,30 +216,46 @@ cinematic.register_motion("pedestal", {
cinematic.register_motion("pan", { cinematic.register_motion("pan", {
initialize = function(player, params) initialize = function(player, params)
return { return {
speed = params:get_speed({"l", "left"}, "right"), speed = -params:get_speed({"l", "left"}, "right"),
angle = player:get_look_horizontal() angle = player:get_look_horizontal(),
time = 0,
} }
end, end,
tick = function(player, state) tick = function(player, state, dtime)
state.angle = state.angle - state.speed * math.pi / 3600 state.time = state.time + dtime
if state.angle < 0 then state.angle = state.angle + 2 * math.pi end local delta_angle = state.speed * state.time * math.pi * 1 / 180
if state.angle > 2 * math.pi then state.angle = state.angle - 2 * math.pi end if math.abs(delta_angle) > 1.0 then
player:set_look_horizontal(state.angle) state.angle = state.angle + delta_angle
delta_angle = 0.0
state.time = 0.0
if state.angle < 0 then state.angle = state.angle + 2 * math.pi end
if state.angle > 2 * math.pi then state.angle = state.angle - 2 * math.pi end
end
player:set_look_horizontal(state.angle + delta_angle)
end end
}) })
cinematic.register_motion("tilt", { cinematic.register_motion("tilt", {
initialize = function(player, params) initialize = function(player, params)
return { return {
speed = params:get_speed({"d", "down"}, "up"), speed = -params:get_speed({"d", "down"}, "up"),
angle = player:get_look_vertical() angle = player:get_look_vertical(),
time = 0,
} }
end, end,
tick = function(player, state) tick = function(player, state, dtime)
state.angle = state.angle - state.speed * math.pi / 3600 state.time = state.time + dtime
if state.angle < 0 then state.angle = state.angle + 2 * math.pi end local delta_angle = state.speed * state.time * math.pi * 1 / 180
if state.angle > 2 * math.pi then state.angle = state.angle - 2 * math.pi end if math.abs(delta_angle) > 1.0 then
player:set_look_vertical(state.angle) state.angle = state.angle + delta_angle
delta_angle = 0.0
state.time = 0.0
if state.angle < 0 then state.angle = state.angle + 2 * math.pi end
if state.angle > 2 * math.pi then state.angle = state.angle - 2 * math.pi end
end
player:set_look_vertical(state.angle + delta_angle)
end end
}) })
@ -274,7 +303,7 @@ cinematic.register_command("pos", {
minetest.chat_send_player(player:get_player_name(), slot) minetest.chat_send_player(player:get_player_name(), slot)
end end
else else
return false, "Unknown subcommand"..args[1] return false, "Unknown subcommand"..(args[1] or "")
end end
end end
}) })