update racing physics

This commit is contained in:
fnicon 2026-03-21 00:28:21 +09:00
parent 20b0b26e29
commit d284853f24
3 changed files with 75 additions and 27 deletions

View File

@ -13,13 +13,47 @@ local function accelerate(dt, gas_input, speed, max_speed, accel, min_speed)
return new_speed return new_speed
end end
local function drift(dt, pos_x, speed, max_speed, curve, centrifugal) local function centrifugal_force(dt, speed, max_speed)
local speed_percent = (speed/max_speed)
local dx = dt * 2 * speed_percent
local dy = dt * 2 * speed_percent
-- assume mass is 1
return 1 * dy * speed * speed
end
local function drift(dt, pos_x, pos_y, speed, max_speed, angle, centrifugal)
local speed_percent = (speed/max_speed) local speed_percent = (speed/max_speed)
local dx = dt * 2 * speed_percent -- at top speed, should be able to cross from left to right (-1 to 1) in 1 second local dx = dt * 2 * speed_percent -- at top speed, should be able to cross from left to right (-1 to 1) in 1 second
return pos_x - (dx * speed_percent * curve * centrifugal); local dy = dt * 2 * speed_percent
cos = math.cos(angle)
sin = math.sin(angle)
return pos_x + (dx * speed_percent * cos * centrifugal),
pos_y + (dy * speed_percent * sin * centrifugal)
end
local function gas(accel, drag)
return accel - drag
end
local function brake(decel, drag, grip)
return - decel - drag - grip
end
local function roam(decel, drag)
return - decel - drag
end
local function steer(_steer, grip, drag, velocity)
return _steer + grip + drag - velocity
end end
return { return {
accelerate = accelerate, accelerate = accelerate,
drift = drift drift = drift,
gas = gas,
brake = brake,
steer = steer,
roam = roam,
centrifugal_force = centrifugal_force
} }

View File

@ -31,13 +31,13 @@ function wrapper:load(_args)
{ {
assemblage = racer.assemble, assemblage = racer.assemble,
data = { data = {
accel = 10.0, accel = 20.0,
brake = 10.0, brake = 10.0,
grip = 10.0, grip = 2.0,
max_speed = 100.0, max_speed = 100.0,
steer = 10.0, steer = 2.0,
velocity = 10.0, velocity = 10.0,
decel = 2.0, decel = 10.0,
drag = 2.0 drag = 2.0
} }
} }

View File

@ -92,6 +92,30 @@ function system:load()
end end
end end
local function get_velocity(dt, up, down, accel, drag, decel, grip, velocity, max_speed)
local new_accel
local new_min_speed = 0
if (up) then
new_accel = racing_phy.gas(accel, drag)
elseif(down) then
new_accel = racing_phy.brake(decel, drag, grip)
new_min_speed = -max_speed
else
new_accel = racing_phy.roam(decel, drag)
end
return racing_phy.accelerate(dt, 1, velocity, max_speed, new_accel, new_min_speed)
end
local function get_angle(dt, left, right, steer, grip, drag, velocity, max_speed)
local new_angle = 0
if (left) then
new_angle = - 1 * racing_phy.steer(steer, grip, drag, velocity / max_speed) * dt
elseif (right) then
new_angle = 1 * racing_phy.steer(steer, grip, drag, velocity / max_speed) * dt
end
return new_angle
end
function system:update(dt) function system:update(dt)
for _, e in ipairs(self.pool) do for _, e in ipairs(self.pool) do
local accel, brake, grip, max_speed, steer, velocity, drag, decel = get(e) local accel, brake, grip, max_speed, steer, velocity, drag, decel = get(e)
@ -101,31 +125,21 @@ function system:update(dt)
local left = love.keyboard.isDown("left") local left = love.keyboard.isDown("left")
local right = love.keyboard.isDown("right") local right = love.keyboard.isDown("right")
if (up) then e[race.dict.velocity].data = get_velocity(dt, up, down, accel, drag, decel, grip, velocity, max_speed)
e[race.dict.velocity].data = racing_phy.accelerate(dt, 1, velocity, max_speed, accel - drag)
elseif(down) then
e[race.dict.velocity].data = racing_phy.accelerate(dt, -1, velocity, max_speed, accel - drag, -max_speed)
else
e[race.dict.velocity].data = racing_phy.accelerate(dt, 1, velocity, max_speed, -drag -decel)
end
local pos_x, pos_y = e["race.pos"].data[1], e["race.pos"].data[2]
local angle = e["race.angle"].data local angle = e["race.angle"].data
if (left) then local new_angle = get_angle(dt, left, right, steer, grip, drag,velocity, max_speed)
e["race.angle"].data = angle - 1 * dt e["race.angle"].data = angle + new_angle
end
if (right) then
e["race.angle"].data = angle + 1 * dt
end
angle = e["race.angle"].data
cos = math.cos(angle)
sin = math.sin(angle)
velocity = e[race.dict.velocity].data velocity = e[race.dict.velocity].data
angle = e["race.angle"].data
e["race.pos"].data[1] = e["race.pos"].data[1] + velocity * cos local centrifugal = racing_phy.centrifugal_force(dt, velocity, max_speed)
e["race.pos"].data[2] = e["race.pos"].data[2] + velocity * sin local goal_x, goal_y = racing_phy.drift(dt, pos_x, pos_y, velocity, max_speed, angle, centrifugal)
-- print(racing_phy.drift(dt, 1, velocity, max_speed, 2, 10))
e["race.pos"].data[1] = goal_x
e["race.pos"].data[2] = goal_y
end end
end end