From d06472f57b2d89f9be10724a706ec770e1f6294b Mon Sep 17 00:00:00 2001 From: Rokas Puzonas Date: Mon, 27 Jun 2022 13:42:26 +0000 Subject: [PATCH] basic character controller with aiming --- src/data/controls.lua | 12 ++++++++ src/states/main.lua | 43 ++++++++++++++++++++++++++- src/systems/physics.lua | 13 +++++++++ src/systems/player.lua | 65 +++++++++++++++++++++++++++++++++++++++++ src/systems/sprite.lua | 10 +++++++ 5 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 src/data/controls.lua create mode 100644 src/systems/physics.lua create mode 100644 src/systems/player.lua create mode 100644 src/systems/sprite.lua diff --git a/src/data/controls.lua b/src/data/controls.lua new file mode 100644 index 0000000..118e4cc --- /dev/null +++ b/src/data/controls.lua @@ -0,0 +1,12 @@ + +return { + move_up = "w", + move_down = "s", + move_left = "a", + move_right = "d", + + aim_up = "up", + aim_down = "down", + aim_left = "left", + aim_right = "right", +} diff --git a/src/states/main.lua b/src/states/main.lua index e7e9c0f..9e58cc4 100644 --- a/src/states/main.lua +++ b/src/states/main.lua @@ -1,7 +1,48 @@ local MainState = {} +local pprint = require("lib.pprint") +local nata = require("lib.nata") +local Vec = require("lib.brinevector") + +function MainState:enter() + self.ecs = nata.new{ + groups = { + physical = {filter = {"pos", "vel"}}, + player = {filter = {"pos", "acc", "speed", "score"}}, + sprite = {filter = {"sprite"}} + }, + systems = { + require("systems.physics"), + require("systems.player"), + require("systems.sprite"), + }, + data = {} + } + + self.ecs:queue{ + pos = Vec(100, 100), + vel = Vec(0, 0), + acc = Vec(), + score = 0, + sprite = {}, + speed = 100 + } +end + +function MainState:update(dt) + self.ecs:flush() + self.ecs:emit("update", dt) + + if love.keyboard.isDown("escape") then + love.event.quit() + end +end + +function MainState:mousemoved(...) + self.ecs:emit("mousemoved", ...) +end function MainState:draw() - love.graphics.rectangle("fill", 20, 20, 100, 100) + self.ecs:emit("draw") end return MainState diff --git a/src/systems/physics.lua b/src/systems/physics.lua new file mode 100644 index 0000000..f63df4e --- /dev/null +++ b/src/systems/physics.lua @@ -0,0 +1,13 @@ +local Physics = {} + +function Physics:update(dt) + for _, e in ipairs(self.pool.groups.physical.entities) do + if e.acc then + e.vel = e.vel + e.acc * dt + end + + e.pos = e.pos + e.vel * dt + end +end + +return Physics diff --git a/src/systems/player.lua b/src/systems/player.lua new file mode 100644 index 0000000..5e20e6e --- /dev/null +++ b/src/systems/player.lua @@ -0,0 +1,65 @@ +local Player = {} +local pprint = require("lib.pprint") +local data = require("data") +local Vec = require("lib.brinevector") + +local controls = data.controls + +local function getDirection(up_key, down_key, left_key, right_key) + local dx = (love.keyboard.isDown(right_key) and 1 or 0) + - (love.keyboard.isDown(left_key) and 1 or 0) + local dy = (love.keyboard.isDown(down_key) and 1 or 0) + - (love.keyboard.isDown(up_key) and 1 or 0) + return Vec(dx, dy).normalized +end + +function Player:getMoveDirection() + return getDirection( + controls.move_up, + controls.move_down, + controls.move_left, + controls.move_right + ) +end + +function Player:getAimDirection(player) + if self.use_mouse_aim then + return (Vec(love.mouse.getPosition()) - player.pos).normalized + else + return getDirection( + controls.aim_up, + controls.aim_down, + controls.aim_left, + controls.aim_right + ) + end +end + +function Player:update(dt) + local move_direction = self:getMoveDirection() + + if love.keyboard.isDown(controls.aim_up, controls.aim_down, controls.aim_left, controls.aim_right) then + self.use_mouse_aim = false + end + + for _, e in ipairs(self.pool.groups.player.entities) do + e.aim_dir = self:getAimDirection(e) + e.acc = move_direction * e.speed + end +end + +function Player:mousemoved() + self.use_mouse_aim = true +end + +function Player:draw() + for _, e in ipairs(self.pool.groups.player.entities) do + if e.aim_dir.x ~= 0 or e.aim_dir.y ~= 0 then + love.graphics.setColor(0.8, 0.2, 0.2) + local aim_pos = e.pos + e.aim_dir * 25 + love.graphics.circle("fill", aim_pos.x, aim_pos.y, 10) + end + end +end + +return Player diff --git a/src/systems/sprite.lua b/src/systems/sprite.lua new file mode 100644 index 0000000..9336b23 --- /dev/null +++ b/src/systems/sprite.lua @@ -0,0 +1,10 @@ +local Sprite = {} + +function Sprite:draw() + for _, e in ipairs(self.pool.groups.sprite.entities) do + love.graphics.setColor(1, 1, 1) + love.graphics.circle("fill", e.pos.x, e.pos.y, 20) + end +end + +return Sprite