From d284853f24a511f4407ad40920e75953711670a5 Mon Sep 17 00:00:00 2001 From: fnicon Date: Sat, 21 Mar 2026 00:28:21 +0900 Subject: [PATCH] update racing physics --- game/love_src/src/system/racing_phy.lua | 40 ++++++++++++-- .../love_src/src/world/top_down_race/init.lua | 8 +-- .../world/top_down_race/system/velocity.lua | 54 ++++++++++++------- 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/game/love_src/src/system/racing_phy.lua b/game/love_src/src/system/racing_phy.lua index 970f94f..465fdde 100644 --- a/game/love_src/src/system/racing_phy.lua +++ b/game/love_src/src/system/racing_phy.lua @@ -13,13 +13,47 @@ local function accelerate(dt, gas_input, speed, max_speed, accel, min_speed) return new_speed 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 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 return { accelerate = accelerate, - drift = drift + drift = drift, + gas = gas, + brake = brake, + steer = steer, + roam = roam, + centrifugal_force = centrifugal_force } diff --git a/game/love_src/src/world/top_down_race/init.lua b/game/love_src/src/world/top_down_race/init.lua index aaac13b..34e4441 100644 --- a/game/love_src/src/world/top_down_race/init.lua +++ b/game/love_src/src/world/top_down_race/init.lua @@ -31,13 +31,13 @@ function wrapper:load(_args) { assemblage = racer.assemble, data = { - accel = 10.0, + accel = 20.0, brake = 10.0, - grip = 10.0, + grip = 2.0, max_speed = 100.0, - steer = 10.0, + steer = 2.0, velocity = 10.0, - decel = 2.0, + decel = 10.0, drag = 2.0 } } diff --git a/game/love_src/src/world/top_down_race/system/velocity.lua b/game/love_src/src/world/top_down_race/system/velocity.lua index 5b7c076..0da69fa 100644 --- a/game/love_src/src/world/top_down_race/system/velocity.lua +++ b/game/love_src/src/world/top_down_race/system/velocity.lua @@ -92,6 +92,30 @@ function system:load() 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) for _, e in ipairs(self.pool) do 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 right = love.keyboard.isDown("right") - if (up) then - 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 + e[race.dict.velocity].data = get_velocity(dt, up, down, accel, drag, decel, grip, velocity, max_speed) + local pos_x, pos_y = e["race.pos"].data[1], e["race.pos"].data[2] local angle = e["race.angle"].data - if (left) then - e["race.angle"].data = angle - 1 * dt - 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) + local new_angle = get_angle(dt, left, right, steer, grip, drag,velocity, max_speed) + e["race.angle"].data = angle + new_angle velocity = e[race.dict.velocity].data + angle = e["race.angle"].data - e["race.pos"].data[1] = e["race.pos"].data[1] + velocity * cos - e["race.pos"].data[2] = e["race.pos"].data[2] + velocity * sin - -- print(racing_phy.drift(dt, 1, velocity, max_speed, 2, 10)) + local centrifugal = racing_phy.centrifugal_force(dt, velocity, max_speed) + local goal_x, goal_y = racing_phy.drift(dt, pos_x, pos_y, velocity, max_speed, angle, centrifugal) + + e["race.pos"].data[1] = goal_x + e["race.pos"].data[2] = goal_y end end