diff --git a/game/love_src/src/new/components/actor.lua b/game/love_src/src/new/components/actor.lua new file mode 100644 index 0000000..bded46c --- /dev/null +++ b/game/love_src/src/new/components/actor.lua @@ -0,0 +1,52 @@ +local main_wrapper = require "love_src.wrapper.lappy.world" +local vm = require "lib.vornmath" +---@class wrappers.Concord.world : lappy.world +local world = main_wrapper:extend() + +local reap = require("lib.reap") +local BASE = reap.base_path(...) + +function world:new() + world.super.new(self, BASE, "actor") +end + +local default = { + forward = 0.0, + steer = 0.0 +} + +function world:load(entity, data) + self.e = entity + self.data = data or default +end + +local function handle_input(v2, accel, brake, steer) + local desire_forward = 0 + local desire_steer = 0 + if (v2[1] > 0) then + desire_forward = accel + elseif (v2[1] < 0) then + desire_forward = - brake + end + if (v2[2] < 0) then + desire_steer = steer + elseif (v2[2] > 0) then + desire_steer = - steer + end + return desire_forward, desire_steer +end + +local function plan() + return vm.vec2(1.0, 1.0) +end + +function world:update(dt) + local accel, brake, steer = self.e.components.racer.data.accel, self.e.components.racer.data.brake, self.e.components.racer.data.steer + local plan_v = plan() + local desire_forward, desire_steer = handle_input(plan_v, accel, brake, steer) + + self.data.forward = desire_forward + self.data.steer = desire_steer +end + +return world diff --git a/game/love_src/src/new/components/map.lua b/game/love_src/src/new/components/map.lua new file mode 100644 index 0000000..6c752d1 --- /dev/null +++ b/game/love_src/src/new/components/map.lua @@ -0,0 +1,37 @@ +local vm = require"lib.vornmath" + +local main_wrapper = require "love_src.wrapper.lappy.world" +---@class wrappers.Concord.world : lappy.world +local world = main_wrapper:extend() + +local reap = require("lib.reap") +local BASE = reap.base_path(...) + +function world:new() + world.super.new(self, BASE, "map") +end + +local default = { + drag_movement = 0.0, + friction = 1.0, + drag = vm.vec2(1.0, 0.0) +} + +function world:load(entity, data) + self.e = entity + self.data = data or default +end + +local function debug_data(x, y, r, g, b, to_debug) + local font_ix = test.draw_font_start() + test.draw_font_set_base_color(r, g, b) + for k, v in pairs(to_debug) do + y = y + test.draw_font(font_ix, string.format("%s : %s", k, v), x, y) + end +end + +function world:ui_draw() + debug_data(650, 800, 1.0, 0.0, 1.0, self.data) +end + +return world diff --git a/game/love_src/src/new/components/player.lua b/game/love_src/src/new/components/player.lua new file mode 100644 index 0000000..41d761a --- /dev/null +++ b/game/love_src/src/new/components/player.lua @@ -0,0 +1,51 @@ +local main_wrapper = require "love_src.wrapper.lappy.world" +---@class wrappers.Concord.world : lappy.world +local world = main_wrapper:extend() + +local reap = require("lib.reap") +local BASE = reap.base_path(...) + +function world:new() + world.super.new(self, BASE, "player") +end + +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 + +local default = { + forward = 0.0, + steer = 0.0 +} + +function world:load(entity, data) + self.e = entity + self.data = data or default +end + +function world:update(dt) + local accel, brake, steer = self.e.components.racer.data.accel, self.e.components.racer.data.brake, self.e.components.racer.data.steer + local desire_forward, desire_steer = handle_input(accel, brake, steer) + + self.data.forward = desire_forward + self.data.steer = desire_steer +end + +return world diff --git a/game/love_src/src/new/components/racer.lua b/game/love_src/src/new/components/racer.lua new file mode 100644 index 0000000..52e3bef --- /dev/null +++ b/game/love_src/src/new/components/racer.lua @@ -0,0 +1,171 @@ +local vm = require"lib.vornmath" +local racing_force = require("love_src.src.system.racing_force") + +local main_wrapper = require "love_src.wrapper.lappy.world" +---@class wrappers.Concord.world : lappy.world +local world = main_wrapper:extend() + +local reap = require("lib.reap") +local BASE = reap.base_path(...) + +function world:new() + world.super.new(self, BASE, "racer") +end + +local default = { + pos = vm.vec2(44.64, 10.87), + + orientation = vm.vec2(0.0, 0.0), + orientation_speed = vm.vec2(0.0, 0.0), + min_orientation_speed = -1.0, + max_orientation_speed = 1.0, + + velocity = vm.vec2(0.0, 0.0), + max_speed = 0.1, + min_speed = -0.1, + inertia = vm.vec2(0.0, 0.0), + + accel = 0.1, + brake = 0.1, + grip = 0.1, + steer = 0.1, + mass = 0.1, + streamline = 0.1 +} + +local magic_w = { + tire = 0.01, + floor = 0.1, + forward = 0.01, + steer = 0.01, + drag_boost = 0.01, + drag_halt = 0.1, + inertia = 0.0, + centrifugal = 0.1, + dampening = 0.1 +} + +function world:load(entity, data) + self.e = entity + self.data = data or default + self.map = {} +end + +function get(s) + return + s.data.max_speed, + s.data.min_speed, + s.data.velocity, + s.data.accel, + s.data.brake, + s.data.grip, + s.data.steer, + s.data.inertia, + s.data.mass, + s.data.streamline +end + +local function rotate_vector(x0, y0, theta) + local x1 = x0 * math.cos(theta) - y0 * math.sin(theta) + local y1 = x0 * math.sin(theta) + y0 * math.cos(theta) + return vm.vec2(x1, y1) +end + +local function forward_velocity(dt, force, mass, velocity, max_speed, min_speed, dampening) + if (mass == 0) then + mass = 1 + end + local a = force[1] * dt / mass + local new_velocity = velocity[1] + a + if (a == 0 and new_velocity > 0.1) then + new_velocity = velocity[1] - dampening * dt / mass + elseif (a == 0 and new_velocity < -0.1) then + new_velocity = velocity[1] + dampening * dt / mass + elseif (a == 0) then + new_velocity = 0 + end + new_velocity = vm.clamp(new_velocity, min_speed, max_speed) + return new_velocity +end + +local function orientation_velocity(dt, force, mass, orientation_speed, orientation, max_orientation, min_orientation) + if (mass == 0) then + mass = 1 + end + local a = force[2] / mass + local new_speed = orientation_speed + a + new_speed = vm.clamp(new_speed, min_orientation, max_orientation) + local new_orientation = rotate_vector(orientation[1], orientation[2], new_speed) + return new_orientation, new_speed +end + +function world:update_race(dt) + local x, y = self.data.pos[1], self.data.pos[2] + local or_x, or_y = self.data.orientation[1], self.data.orientation[2] + + local max_speed, min_speed, velocity, accel, brake, grip, steer, inertia, mass, streamline = get(self) + local friction, drag, drag_movement = self.map.data.friction, self.map.data.drag, self.map.data.drag_movement + + local desire_forward, desire_steer = self.e.components.actor.data.forward, self.e.components.actor.data.steer + + local force = racing_force( + desire_forward, desire_steer, + grip, friction, + drag, 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 + ) + local f_v = forward_velocity(dt, force, mass, velocity, max_speed, min_speed, magic_w.dampening) + local o, o_v = orientation_velocity(dt, force, mass, self.data.orientation_speed, self.data.orientation, self.data.max_orientation_speed, self.data.min_orientation_speed) + + self.data.velocity[1] = f_v + -- self.data.orientation_speed = o_v + self.data.orientation = o + -- if (self.data.velocity[1] ~= 0) then + self.data.pos = self.data.pos + o * f_v + -- end + + self.data.inertia = force +end + +function world:update(dt) + self:update_race(dt) +end + +function world:draw() + local x, y = self.data.pos[1], self.data.pos[2] + local or_x, or_y = self.data.orientation[1], self.data.orientation[2] + local vx, vy = self.data.orientation[1] * self.data.velocity[1], self.data.orientation[2] * self.data.velocity[1] + + test.set_sphere(x, y, vx, vy) +end + +local function debug_data(x, y, r, g, b, to_debug) + local font_ix = test.draw_font_start() + test.draw_font_set_base_color(r, g, b) + for k, v in pairs(to_debug) do + y = y + test.draw_font(font_ix, string.format("%s : %s", k, v), x, y) + end +end + +local function debug_vector(vx, vy) + local lw, lh = love.graphics.getDimensions() + + test.draw_line_quad_start() + test.draw_set_color(1.0, 0.0, 0.0) -- r, g, b (0.0 to 1.0) + test.draw_line(lw/2, lh/2, lw/vx, lh/vy) -- x1, y1, x2, y2 +end + +function world:ui_draw() + debug_data(650, 0, 1.0, 0.0, 1.0, self.data) + debug_data(650, 400, 1.0, 0.0, 1.0, magic_w) + + local vx, vy = self.data.orientation[1], self.data.orientation[2] + debug_vector(vx, vy) +end + +return world diff --git a/game/love_src/src/new/world/race.lua b/game/love_src/src/new/world/race.lua new file mode 100644 index 0000000..8a53bbc --- /dev/null +++ b/game/love_src/src/new/world/race.lua @@ -0,0 +1,131 @@ +local vm = require"lib.vornmath" + +local main_wrapper = require "love_src.wrapper.lappy.world" +---@class wrappers.Concord.world : lappy.world +local world = main_wrapper:extend() + +local reap = require("lib.reap") +local BASE = reap.base_path(...) + +local default = { + racers = { + base = require "love_src.src.new.components.racer" + } +} + +local entities_default = { + { + components = { + racer = require("love_src.src.new.components.racer"), + actor = require("love_src.src.new.components.actor"), + }, + type = "racer", + name = "racer 1", + data = { + racer = { + pos = vm.vec2(44.64, 10.87), + + orientation = vm.vec2(1.0, 0.0), + orientation_speed = 0.0, + min_orientation_speed = -1.0, + max_orientation_speed = 1.0, + + velocity = vm.vec2(0.0, 0.0), + max_speed = 0.3, + min_speed = -0.3, + inertia = vm.vec2(0.0, 0.0), + + accel = 0.1, + brake = 0.1, + grip = 0.1, + steer = 0.01, + mass = 0.1, + streamline = 0.1 + }, + actor = { + forward = 0.0, + steer = 0.0, + } + } + }, + { + components = { + map = require"love_src.src.new.components.map" + }, + type = "map", + name = "map 1", + data = { + map = { + drag_movement = 0.1, + friction = 0.1, + drag = vm.vec2(0.1, 0.0) + } + } + } +} + +function world:new() + world.super.new(self, BASE, "race") + self.is_loaded = false + self.entities = {} +end + +function world:load(data, entities_data) + self.data = data or default + self.is_loaded = true + + self.entities_data = entities_data or entities_default + + local map + for _, d in pairs(self.entities_data) do + local e = { + type = d.type, + name = d.name, + components = {} + } + for t, c in pairs(d.components) do + e.components[t] = c() + e.components[t]:load(e, d.data[t]) + end + table.insert(self.entities, e) + if (e.type == "map") then + map = e + end + end + for _, e in ipairs(self.entities) do + if (e.type == "racer") then + for t, c in pairs(e.components) do + if (c.name == "racer") then + c.map = map.components.map + end + end + end + end + +end + +function world:update(dt) + for _, e in ipairs(self.entities) do + for t, c in pairs(e.components) do + c:update(dt) + end + end +end + +function world:draw() + for _, e in ipairs(self.entities) do + for t, c in pairs(e.components) do + c:draw() + end + end +end + +function world:ui_draw() + for _, e in ipairs(self.entities) do + for t, c in pairs(e.components) do + c:ui_draw() + end + end +end + +return world