Compare commits
4 Commits
3cd0a1f8ae
...
08521535fe
| Author | SHA1 | Date | |
|---|---|---|---|
| 08521535fe | |||
| 8f67a4de8b | |||
| f85339131a | |||
| e032650030 |
152
game/love_src/src/system/racing_force.lua
Normal file
152
game/love_src/src/system/racing_force.lua
Normal file
@ -0,0 +1,152 @@
|
||||
local vm = require("lib.vornmath")
|
||||
|
||||
|
||||
---calculate real desire forward after weight
|
||||
---@param forward number gas_input
|
||||
---@param weight number? magic weight constant
|
||||
---@return number forward actual desire
|
||||
local function add_forward(forward, weight)
|
||||
return forward * (weight or 1.0)
|
||||
end
|
||||
|
||||
---calculate real desire lateral steer after weight
|
||||
---@param steer number steer_input
|
||||
---@param weight number? magic weight constant
|
||||
---@return number lateral
|
||||
local function add_lateral(steer, weight)
|
||||
return steer * (weight or 1.0)
|
||||
end
|
||||
|
||||
---calculate friction impact based on grip
|
||||
---@param friction number outside friction
|
||||
---@param grip number car's grip
|
||||
---@return number friction
|
||||
local function grip_force(friction, grip)
|
||||
return friction * grip
|
||||
end
|
||||
|
||||
---add friction
|
||||
---@param f vec2 vec2 input
|
||||
---@param grip number car's grip
|
||||
---@param friction number floor's friction
|
||||
---@param weight_tire number? magic weight tire
|
||||
---@param weight_floor number? magic weight floor
|
||||
---@return vec2 f vec2 output
|
||||
local function add_friction(f, grip, friction, weight_tire, weight_floor)
|
||||
local f_grip = grip_force(grip, friction)
|
||||
-- tire - floor
|
||||
return f + f_grip * ((weight_tire or 1.0) - (weight_floor or 0.0))
|
||||
end
|
||||
|
||||
---calculate drag's impact based on streamline
|
||||
---@param drag number|vec2 drag
|
||||
---@param streamline number car's streamline
|
||||
---@return number drag
|
||||
local function drag_force(drag, streamline)
|
||||
return streamline * drag
|
||||
end
|
||||
|
||||
---add drag into f
|
||||
---@param f vec2 input
|
||||
---@param drag number|vec2 drag
|
||||
---@param streamline number car's streamline
|
||||
---@param weight_drag number? magic weight
|
||||
---@return vec2 f
|
||||
local function add_drag(v, drag, streamline, weight_drag)
|
||||
local f_drag = drag_force(drag, streamline)
|
||||
return v + f_drag * (weight_drag or 1.0)
|
||||
end
|
||||
|
||||
---add inertia into f
|
||||
---@param f vec2 input
|
||||
---@param inertia_force vec2 inertia
|
||||
---@param inertia_weight number? magic weight
|
||||
---@return vec2 f
|
||||
local function add_inertia(f, inertia_force, inertia_weight)
|
||||
return f + inertia_force * (inertia_weight or 1.0)
|
||||
end
|
||||
|
||||
---centrifugal_force
|
||||
---@param mass number car's mass
|
||||
---@param angular_v number velocity on angular
|
||||
---@param perpendicular number r
|
||||
---@return number f
|
||||
local function centrifugal_force(mass, angular_v, perpendicular)
|
||||
return mass * angular_v ^ 2 * perpendicular
|
||||
end
|
||||
|
||||
---add centrifugal
|
||||
---@param f vec2
|
||||
---@param mass number
|
||||
---@param inertia_force vec2
|
||||
---@param weight_centrifugal number?
|
||||
---@return vec2 f
|
||||
local function add_centrifugal(v, mass, inertia_force, weight_centrifugal)
|
||||
local centrifugal = centrifugal_force(mass, inertia_force[1], inertia_force[2])
|
||||
|
||||
local new_v
|
||||
if (v[2] > 0) then
|
||||
new_v = v - vm.vec2(0.0, 1.0) * centrifugal * (weight_centrifugal or 1.0)
|
||||
elseif (v[2] < 0) then
|
||||
new_v = v + vm.vec2(0.0, 1.0) * centrifugal * (weight_centrifugal or 1.0)
|
||||
end
|
||||
return new_v
|
||||
end
|
||||
|
||||
---create desire f
|
||||
---@param desire_forward number forward
|
||||
---@param desire_steer number lateral
|
||||
---@param weight_forward number? weight forward
|
||||
---@param weight_steer number? weight lateral
|
||||
---@return vec2 desire f
|
||||
local function add_desire(desire_forward, desire_steer, weight_forward, weight_steer)
|
||||
local forward = add_forward(desire_forward)
|
||||
local lateral = add_lateral(desire_steer)
|
||||
local val = vm.vec2(forward, lateral)
|
||||
return val
|
||||
end
|
||||
|
||||
---@param desire_forward number engine's force
|
||||
---@param desire_steer number axle's steer
|
||||
---@param grip number car's grip
|
||||
---@param friction number outside's friction
|
||||
---@param drag number|vec2 outside's drag
|
||||
---@param drag_movement number drag from moving
|
||||
---@param streamline number car's streamline
|
||||
---@param inertia_force vec2 last's force
|
||||
---@param mass number car's mass
|
||||
---@param weight_forward number? magic weight
|
||||
---@param weight_steer number? magic weight
|
||||
---@param weight_tire number? magic weight
|
||||
---@param weight_floor number? magic weight
|
||||
---@param weight_drag_boost number? magic weight
|
||||
---@param weight_drag_halt number? magic weight
|
||||
---@param weight_inertia number? magic weight
|
||||
---@param weight_centrifugal number? magic weight
|
||||
local function force_workflow(
|
||||
desire_forward, desire_steer,
|
||||
-- friction
|
||||
grip, friction,
|
||||
-- drag
|
||||
drag, drag_movement, streamline,
|
||||
-- inertia
|
||||
inertia_force,
|
||||
-- centrifugal
|
||||
mass,
|
||||
weight_forward, weight_steer,
|
||||
weight_tire, weight_floor,
|
||||
weight_drag_boost, weight_drag_halt,
|
||||
weight_inertia,
|
||||
weight_centrifugal
|
||||
)
|
||||
local val = add_desire(desire_forward, desire_steer, weight_forward, weight_steer)
|
||||
val = add_friction(val, grip, friction, weight_tire, weight_floor)
|
||||
val = add_drag(val, drag, streamline, weight_drag_boost)
|
||||
val = add_drag(val, drag_movement, streamline, weight_drag_halt)
|
||||
val = add_inertia(val, inertia_force, weight_inertia)
|
||||
val = add_centrifugal(val, mass, inertia_force, weight_centrifugal)
|
||||
|
||||
return val
|
||||
end
|
||||
|
||||
return force_workflow
|
||||
@ -1,3 +1,5 @@
|
||||
local vm = require("lib.vornmath")
|
||||
|
||||
local components = {}
|
||||
|
||||
components.dict = {
|
||||
@ -7,14 +9,13 @@ components.dict = {
|
||||
grip = "race.grip",
|
||||
steer = "race.steer",
|
||||
brake = "race.brake",
|
||||
decel = "race.decel",
|
||||
drag = "race.drag",
|
||||
mass = "race.mass",
|
||||
inertia = "race.inertia"
|
||||
inertia = "race.inertia",
|
||||
streamline = "race.streamline",
|
||||
}
|
||||
|
||||
function components.velocity (c, x)
|
||||
c.data = x
|
||||
function components.velocity (c, x, y)
|
||||
c.data = vm.vec2(x, y)
|
||||
end
|
||||
|
||||
function components.max_speed (c, x)
|
||||
@ -37,20 +38,16 @@ function components.brake (c, x)
|
||||
c.data = x
|
||||
end
|
||||
|
||||
function components.decel (c, x)
|
||||
c.data = x
|
||||
end
|
||||
|
||||
function components.drag (c, x)
|
||||
c.data = x
|
||||
end
|
||||
|
||||
function components.mass (c, x)
|
||||
c.data = x
|
||||
end
|
||||
|
||||
function components.inertia (c, x, y)
|
||||
c.data = {x, y}
|
||||
c.data = vm.vec2(x, y)
|
||||
end
|
||||
|
||||
function components.streamline (c, x)
|
||||
c.data = x
|
||||
end
|
||||
|
||||
return components
|
||||
|
||||
@ -31,15 +31,16 @@ function wrapper:load(_args)
|
||||
{
|
||||
assemblage = racer.assemble,
|
||||
data = {
|
||||
accel = 200.0,
|
||||
brake = 100.0,
|
||||
grip = 1.0,
|
||||
max_speed = 50.0,
|
||||
steer = 5.0,
|
||||
velocity = 0.0,
|
||||
velocity = {0.0, 0.0},
|
||||
max_speed = 10.0,
|
||||
|
||||
accel = 10.0,
|
||||
brake = 10.0,
|
||||
grip = 10.0,
|
||||
steer = 10.0,
|
||||
inertia = {0.0, 0.0},
|
||||
drag = 1.0,
|
||||
mass = 1.0
|
||||
mass = 10.0,
|
||||
streamline = 1.0
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
local system_constructor = require("love_src.wrapper.Concord.system")
|
||||
local race = require("love_src.src.world.top_down_race.component.race")
|
||||
local racing_phy = require("love_src.src.system.racing_phy")
|
||||
local racing_force = require("love_src.src.system.racing_force")
|
||||
|
||||
local component = require("love_src.wrapper.Concord.component")
|
||||
|
||||
@ -12,28 +13,29 @@ system.__index = system
|
||||
|
||||
system.pool = {
|
||||
pool = {
|
||||
race.dict.max_speed,
|
||||
race.dict.velocity,
|
||||
race.dict.accel,
|
||||
race.dict.brake,
|
||||
race.dict.grip,
|
||||
race.dict.max_speed,
|
||||
race.dict.steer,
|
||||
race.dict.velocity,
|
||||
race.dict.inertia,
|
||||
race.dict.drag,
|
||||
race.dict.mass
|
||||
race.dict.mass,
|
||||
race.dict.streamline
|
||||
}
|
||||
}
|
||||
|
||||
system.components = {
|
||||
[race.dict.max_speed] = race.max_speed,
|
||||
[race.dict.velocity] = race.velocity,
|
||||
|
||||
[race.dict.accel] = race.accel,
|
||||
[race.dict.brake] = race.brake,
|
||||
[race.dict.grip] = race.grip,
|
||||
[race.dict.max_speed] = race.max_speed,
|
||||
[race.dict.steer] = race.steer,
|
||||
[race.dict.velocity] = race.velocity,
|
||||
[race.dict.inertia] = race.inertia,
|
||||
[race.dict.drag] = race.drag,
|
||||
[race.dict.mass] = race.mass
|
||||
[race.dict.mass] = race.mass,
|
||||
[race.dict.streamline] = race.streamline
|
||||
}
|
||||
|
||||
function system.new()
|
||||
@ -50,15 +52,15 @@ end
|
||||
|
||||
local function get(e)
|
||||
return
|
||||
e[race.dict.max_speed].data,
|
||||
e[race.dict.velocity].data,
|
||||
e[race.dict.accel].data,
|
||||
e[race.dict.brake].data,
|
||||
e[race.dict.grip].data,
|
||||
e[race.dict.max_speed].data,
|
||||
e[race.dict.steer].data,
|
||||
e[race.dict.velocity].data,
|
||||
e[race.dict.drag].data,
|
||||
e[race.dict.inertia].data,
|
||||
e[race.dict.mass].data
|
||||
e[race.dict.mass].data,
|
||||
e[race.dict.streamline].data
|
||||
end
|
||||
|
||||
local function draw(text, x, y, sx, sy, angle, image, origin)
|
||||
@ -117,97 +119,11 @@ local frictions = {
|
||||
}
|
||||
}
|
||||
|
||||
local function accel_force(up, down, accel, brake, inertia)
|
||||
local force
|
||||
if (up) then
|
||||
force = accel - inertia
|
||||
elseif(down) then
|
||||
force = - brake + inertia
|
||||
else
|
||||
force = inertia
|
||||
end
|
||||
return force
|
||||
end
|
||||
|
||||
local function steer_force(left, right, steer, inertia)
|
||||
if (left) then
|
||||
force = -steer + inertia
|
||||
elseif(right) then
|
||||
force = steer - inertia
|
||||
else
|
||||
force = inertia
|
||||
end
|
||||
return force
|
||||
end
|
||||
|
||||
local function grip_force(grip, friction)
|
||||
return friction * grip
|
||||
end
|
||||
|
||||
local function add_friction(force, friction_direction, grip, friction, tire_c, floor_c)
|
||||
local f_grip = grip_force(grip, friction)
|
||||
if (force > 0) then
|
||||
-- tire - floor
|
||||
force = force + friction_direction * tire_c * f_grip - friction_direction * floor_c * f_grip
|
||||
elseif (force < 0) then
|
||||
force = force + friction_direction * tire_c * f_grip - friction_direction * floor_c * f_grip
|
||||
else
|
||||
force = force
|
||||
end
|
||||
return force
|
||||
end
|
||||
|
||||
local function add_friction_lateral(force, grip, friction, tire_c, floor_c)
|
||||
local f_grip = grip_force(grip, friction)
|
||||
if (force > 0) then
|
||||
-- tire - floor
|
||||
force = force + tire_c * f_grip - floor_c * f_grip
|
||||
if (force < 0) then
|
||||
force = 0.1
|
||||
end
|
||||
elseif (force < 0) then
|
||||
force = force - tire_c * f_grip + floor_c * f_grip
|
||||
if (force > 0) then
|
||||
force = -0.1
|
||||
end
|
||||
else
|
||||
force = force
|
||||
end
|
||||
return force
|
||||
end
|
||||
|
||||
local function add_drag(force, drag_direction, drag)
|
||||
if (force > 0) then
|
||||
force = force + drag_direction * drag
|
||||
elseif (force < 0) then
|
||||
force = force + drag_direction * drag
|
||||
else
|
||||
force = force
|
||||
end
|
||||
return force
|
||||
end
|
||||
|
||||
local function add_drag_lateral(force, drag)
|
||||
if (force > 0) then
|
||||
force = force - drag
|
||||
elseif (force < 0) then
|
||||
force = force + drag
|
||||
else
|
||||
force = force
|
||||
end
|
||||
return force
|
||||
end
|
||||
|
||||
local function add_centrifugal(force, centrifugal)
|
||||
if (force > 0) then
|
||||
force = force - centrifugal
|
||||
elseif (force < 0) then
|
||||
force = force + centrifugal
|
||||
else
|
||||
force = force
|
||||
end
|
||||
return force
|
||||
end
|
||||
local drags = {
|
||||
{
|
||||
drag = vm.vec2(1.0, 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
-- x1 y1 -- (x1 + w1) y1
|
||||
-- x2 y2
|
||||
@ -231,86 +147,105 @@ local function get_friction(pos_x, pos_y, floors)
|
||||
return friction
|
||||
end
|
||||
|
||||
local magic_n = {
|
||||
tire_c = 1.0,
|
||||
floor_c = 1.5,
|
||||
scale_x = 1000.0,
|
||||
scale_y = 1000.0,
|
||||
centrifugal_r = 1.0,
|
||||
magic_slowdown = 10.0,
|
||||
magic_boost = 10000.0,
|
||||
magic_slow_drift = 10.0
|
||||
local magic_w = {
|
||||
tire = 1.0,
|
||||
floor = 1.5,
|
||||
forward = 1.0,
|
||||
steer = 1.0,
|
||||
drag_boost = 1.0,
|
||||
drag_halt = 1.5,
|
||||
inertia = 1.0,
|
||||
centrifugal = 1.0,
|
||||
drag_movement = 1.0
|
||||
-- magic_slowdown = 10.0,
|
||||
-- magic_boost = 10000.0,
|
||||
-- magic_slow_drift = 10.0
|
||||
}
|
||||
|
||||
function system:update(dt)
|
||||
for _, e in ipairs(self.pool) do
|
||||
local accel, brake, grip, max_speed, steer, velocity, drag, inertia, mass = get(e)
|
||||
|
||||
local function handle_input(accel, brake, steer)
|
||||
local up = love.keyboard.isDown("up")
|
||||
local down = love.keyboard.isDown("down")
|
||||
local left = love.keyboard.isDown("left")
|
||||
local right = love.keyboard.isDown("right")
|
||||
|
||||
local desire_forward = 0
|
||||
local desire_steer = 0
|
||||
if (up) then
|
||||
desire_forward = accel
|
||||
elseif (down) then
|
||||
desire_forward = - brake
|
||||
end
|
||||
if (left) then
|
||||
desire_steer = - steer
|
||||
elseif (right) then
|
||||
desire_steer = steer
|
||||
end
|
||||
return desire_forward, desire_steer
|
||||
end
|
||||
|
||||
function system:update(dt)
|
||||
for _, e in ipairs(self.pool) do
|
||||
local max_speed, velocity, accel, brake, grip, steer, inertia, mass, streamline = get(e)
|
||||
|
||||
local pos_x, pos_y = e["race.pos"].data[1], e["race.pos"].data[2]
|
||||
|
||||
local friction = get_friction(pos_x, pos_y, frictions)
|
||||
local drag = drags[1].drag
|
||||
|
||||
local f_forward = accel_force(up, down, accel, brake, inertia[1])
|
||||
local f_lateral = steer_force(left, right, steer, inertia[2])
|
||||
local desire_forward, desire_steer = handle_input(accel, brake, steer)
|
||||
|
||||
if (not up) then
|
||||
f_forward = f_forward - magic_n.magic_slowdown
|
||||
elseif (up and velocity == 0) then
|
||||
f_forward = f_forward + magic_n.magic_boost
|
||||
end
|
||||
local force = racing_force(
|
||||
desire_forward, desire_steer,
|
||||
grip, friction,
|
||||
drag, magic_w.drag_movement, streamline,
|
||||
inertia,
|
||||
mass,
|
||||
magic_w.forward, magic_w.steer,
|
||||
magic_w.tire, magic_w.floor,
|
||||
magic_w.drag_boost, magic_w.drag_halt,
|
||||
magic_w.inertia, magic_w.centrifugal
|
||||
)
|
||||
|
||||
if (velocity > 0) then
|
||||
f_forward = add_friction(f_forward, 1.0, grip, friction, magic_n.tire_c, magic_n.floor_c)
|
||||
elseif (velocity < 0) then
|
||||
f_forward = add_friction(f_forward, -1.0, grip, friction, magic_n.tire_c, magic_n.floor_c)
|
||||
end
|
||||
f_lateral = add_friction_lateral(f_lateral, grip, friction, magic_n.tire_c, magic_n.floor_c)
|
||||
|
||||
if (velocity > 0) then
|
||||
f_forward = add_drag(f_forward, -1.0, drag)
|
||||
elseif (velocity < 0) then
|
||||
f_forward = add_drag(f_forward, 1.0, drag)
|
||||
end
|
||||
f_lateral = add_drag_lateral(f_lateral, drag)
|
||||
-- if (not up) then
|
||||
-- force = force - magic_n.magic_slowdown
|
||||
-- elseif (up and velocity == 0) then
|
||||
-- force = force + magic_n.magic_boost
|
||||
-- end
|
||||
|
||||
if (mass == 0) then
|
||||
mass = 1
|
||||
end
|
||||
local a = force * dt / mass
|
||||
|
||||
local new_velocity = racing_phy.accelerate(dt, 1, velocity, max_speed, f_forward*dt/mass, 0)
|
||||
local centrifugal = racing_phy.centrifugal_force(dt, mass, new_velocity * magic_n.centrifugal_r, max_speed)
|
||||
f_lateral = add_centrifugal(f_lateral, centrifugal)
|
||||
e[race.dict.velocity].data = e[race.dict.velocity].data + a
|
||||
|
||||
if (not left and not right) then
|
||||
if (not (left) and f_lateral > 0) then
|
||||
f_lateral = f_lateral - (magic_n.magic_slow_drift)
|
||||
if (f_lateral < 0) then
|
||||
f_lateral = 0
|
||||
end
|
||||
elseif (not right and f_lateral < 0) then
|
||||
f_lateral = f_lateral + (magic_n.magic_slow_drift)
|
||||
if (f_lateral > 0) then
|
||||
f_lateral = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
-- local new_velocity = racing_phy.accelerate(dt, 1, velocity, max_speed, f_forward*dt/mass, 0)
|
||||
|
||||
e[race.dict.inertia].data = {f_forward * dt, f_lateral * dt}
|
||||
-- if (not left and not right) then
|
||||
-- if (not (left) and f_lateral > 0) then
|
||||
-- f_lateral = f_lateral - (magic_n.magic_slow_drift)
|
||||
-- if (f_lateral < 0) then
|
||||
-- f_lateral = 0
|
||||
-- end
|
||||
-- elseif (not right and f_lateral < 0) then
|
||||
-- f_lateral = f_lateral + (magic_n.magic_slow_drift)
|
||||
-- if (f_lateral > 0) then
|
||||
-- f_lateral = 0
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
local new_angle = e["race.angle"].data + f_lateral * dt/mass
|
||||
e["race.angle"].data = new_angle
|
||||
e[race.dict.velocity].data = new_velocity
|
||||
e[race.dict.inertia].data = force
|
||||
|
||||
local goal_x, goal_y = racing_phy.drift(dt, pos_x, pos_y, new_velocity, max_speed, new_angle, magic_n.scale_x, magic_n.scale_y)
|
||||
-- local new_angle = e["race.angle"].data + f_lateral * dt/mass
|
||||
-- e["race.angle"].data = new_angle
|
||||
-- e[race.dict.velocity].data = new_velocity
|
||||
|
||||
-- local goal_x, goal_y = racing_phy.drift(dt, pos_x, pos_y, new_velocity, max_speed, new_angle, magic_n.scale_x, magic_n.scale_y)
|
||||
-- print("force_forward", f_forward, "f_lateral", f_lateral, "velocity", new_velocity, "angle", new_angle, "goal_x", goal_x, "goal_y", goal_y)
|
||||
|
||||
e["race.pos"].data[1] = goal_x
|
||||
e["race.pos"].data[2] = goal_y
|
||||
-- e["race.pos"].data[1] = goal_x
|
||||
-- e["race.pos"].data[2] = goal_y
|
||||
end
|
||||
end
|
||||
|
||||
@ -328,8 +263,8 @@ function system:draw()
|
||||
local image = e["race.image"].data.image
|
||||
local origin = e["race.image"].data.origin
|
||||
--draw(velocity, x, y, sx, sy, angle, image, origin)
|
||||
local vx = 0
|
||||
local vy = 0
|
||||
local vx = e[race.dict.velocity].data[1]
|
||||
local vy = e[race.dict.velocity].data[2]
|
||||
test.set_sphere(x, y, vx, vy)
|
||||
end
|
||||
end
|
||||
|
||||
@ -3,26 +3,28 @@ local race = require("love_src.src.world.top_down_race.component.race")
|
||||
local template = {}
|
||||
|
||||
template.default_data = {
|
||||
velocity = {0.0, 0.0},
|
||||
max_speed = 10.0,
|
||||
|
||||
accel = 10.0,
|
||||
brake = 10.0,
|
||||
grip = 10.0,
|
||||
max_speed = 10.0,
|
||||
steer = 10.0,
|
||||
velocity = 0.0,
|
||||
inertia = {0.0, 0.0},
|
||||
drag = 2.0,
|
||||
mass = 10.0
|
||||
mass = 10.0,
|
||||
streamline = 1.0
|
||||
}
|
||||
function template.assemble(e, data)
|
||||
e:give(race.dict.max_speed, data.max_speed)
|
||||
e:give(race.dict.velocity, data.velocity[1], data.velocity[2])
|
||||
|
||||
e:give(race.dict.accel, data.accel)
|
||||
e:give(race.dict.brake, data.brake)
|
||||
e:give(race.dict.grip, data.grip)
|
||||
e:give(race.dict.max_speed, data.max_speed)
|
||||
e:give(race.dict.steer, data.steer)
|
||||
e:give(race.dict.velocity, data.velocity)
|
||||
e:give(race.dict.inertia, data.inertia[1], data.inertia[2])
|
||||
e:give(race.dict.drag, data.drag)
|
||||
e:give(race.dict.mass, data.mass)
|
||||
e:give(race.dict.streamline, data.streamline)
|
||||
end
|
||||
|
||||
return template
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user