aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriamcheeseman <[email protected]>2026-03-13 20:07:31 -0400
committeriamcheeseman <[email protected]>2026-03-13 20:07:31 -0400
commitcc679988babf47d5752c609ee90444db22d2d1fe (patch)
tree46d1e8abd7ae56535afdf4910f9ba41ad65d40d9
parente09caf3cf41ac3e3ea7ec252a21a7ac5b7fbb52c (diff)
Player can dash
-rw-r--r--main.lua2
-rw-r--r--src/init.lua2
-rw-r--r--src/objs/player.lua70
-rw-r--r--src/phys.lua12
-rw-r--r--src/state_machine.lua24
-rw-r--r--src/utils.lua6
6 files changed, 100 insertions, 16 deletions
diff --git a/main.lua b/main.lua
index 4c943e3..2b2e380 100644
--- a/main.lua
+++ b/main.lua
@@ -7,7 +7,7 @@ function love.load()
main_init()
local scn = new_scene()
event_bind(scn.on_update, "Body", body_sys)
- event_bind(scn.on_update, "Player", player_movement_sys)
+ event_bind(scn.on_update, "State_Machine", state_update_sys)
event_bind(scn.on_update, "Sprite", sprite_anim_sys)
event_bind(scn.on_draw, "Sprite", sprite_draw_sys)
diff --git a/src/init.lua b/src/init.lua
index 18299fd..ec71521 100644
--- a/src/init.lua
+++ b/src/init.lua
@@ -5,6 +5,7 @@ require "src.input"
require "src.textures"
require "src.phys"
require "src.sprite"
+require "src.state_machine"
require "src.im"
require "src.room_editor"
@@ -17,6 +18,7 @@ WindowScale = 1
register_input("Left", {{"key", "left"}, {"key", "a"}})
register_input("Right", {{"key", "right"}, {"key", "d"}})
register_input("Jump", {{"key", "space"}})
+register_input("Dash", {{"key", "lshift"}})
register_input("Right_Click", {{"mouse", 2}})
register_input("Left_Click", {{"mouse", 1}})
diff --git a/src/objs/player.lua b/src/objs/player.lua
index 1d89f8a..2893321 100644
--- a/src/objs/player.lua
+++ b/src/objs/player.lua
@@ -1,22 +1,17 @@
-PLAYER_SPEED = 100
-PLAYER_ACCEL = 30
-PLAYER_JUMP_FORCE = 350
-
-register_comp("Body", function (ent, x, y, w, h, opts)
- ent.vx = 0
- ent.vy = 0
- ent.box = phys.Box.new(x, y, w, h, opts)
-end)
+local PLAYER_SPEED = 100
+local PLAYER_DASH_SPEED = 500
+local PLAYER_ACCEL = 30
+local PLAYER_JUMP_FORCE = 350
+local PLAYER_DASH_TIMER = 0.15
+local PLAYER_DASH_COOLDOWN = 0.5
register_comp("Player", TAGCOMP)
-function body_sys(ent, dt)
- ent.vx, ent.vy = ent.box:update(ent.vx, ent.vy, dt)
- ent.x = ent.box.x
- ent.y = ent.box.y
+local function player_normal_state_init(state)
+ state.dash_cooldown = 0
end
-function player_movement_sys(player, dt)
+local function player_normal_state_update(player, state, dt)
local inputx = bton(is_input_pressed("Right")) - bton(is_input_pressed("Left"))
player.vx = dlerp(player.vx, inputx * PLAYER_SPEED, PLAYER_ACCEL * dt)
@@ -25,21 +20,66 @@ function player_movement_sys(player, dt)
if player.box:touching_down() and is_input_just_pressed("Jump") then
player.vy = -PLAYER_JUMP_FORCE
end
+
+ if state.dash_cooldown <= 0 and is_input_just_pressed("Dash") then
+ set_state(player, "Dash")
+ state.dash_cooldown = PLAYER_DASH_COOLDOWN
+ end
+
+ state.dash_cooldown = state.dash_cooldown - dt
+end
+
+local function player_dash_state_enter(player, state)
+ local inputx = bton(is_input_pressed("Right")) - bton(is_input_pressed("Left"))
+ if inputx == 0 then
+ inputx = 1 --TODO: Change this to be the direction that the player is facing
+ end
+ player.vx = PLAYER_DASH_SPEED * inputx
+ player.vy = 0
+
+ state.dash_timer = PLAYER_DASH_TIMER
+end
+
+local function player_dash_state_update(player, state, dt)
+ state.dash_timer = state.dash_timer - dt
+ if state.dash_timer <= 0 then
+ set_state(player, "Normal")
+ end
+end
+
+local function player_dash_state_exit(player, state, entering)
+ player.vx = player.vx / 2
end
function new_player(x, y)
local ent = new_entity()
+
+ add_comp(ent, "Player")
+
add_comp(ent, "Body", x, y, 8, 14, {
offsetx = -4,
offsety = -6,
layers = {},
mask = {"hard"},
})
- add_comp(ent, "Player")
+
add_comp(ent, "Sprite", "res/img/player.ase", {
offsetx = 0.5,
offsety = 0.5,
})
+
+ add_comp(ent, "State_Machine", "Normal", {
+ Normal = {
+ init = player_normal_state_init,
+ update = player_normal_state_update,
+ },
+ Dash = {
+ enter = player_dash_state_enter,
+ update = player_dash_state_update,
+ exit = player_dash_state_exit,
+ },
+ })
+
return ent
end
diff --git a/src/phys.lua b/src/phys.lua
index 9adb915..08a610a 100644
--- a/src/phys.lua
+++ b/src/phys.lua
@@ -233,3 +233,15 @@ function phys.Box:draw()
local x, y, w, h = self:get_rect()
lg.rectangle("line", x, y, w, h)
end
+
+register_comp("Body", function (ent, x, y, w, h, opts)
+ ent.vx = 0
+ ent.vy = 0
+ ent.box = phys.Box.new(x, y, w, h, opts)
+end)
+
+function body_sys(ent, dt)
+ ent.vx, ent.vy = ent.box:update(ent.vx, ent.vy, dt)
+ ent.x = ent.box.x
+ ent.y = ent.box.y
+end
diff --git a/src/state_machine.lua b/src/state_machine.lua
new file mode 100644
index 0000000..7aac1bc
--- /dev/null
+++ b/src/state_machine.lua
@@ -0,0 +1,24 @@
+register_comp("State_Machine", function(ent, default, states)
+ assert(states[default], "Entity does not have state '" .. default .. "'.")
+
+ ent.states = states
+ ent.state = default
+
+ for _, state in pairs(states) do
+ state.data = {}
+ try(state.init, state.data)
+ end
+end)
+
+function state_update_sys(ent, dt)
+ try(ent.states[ent.state].update, ent, ent.states[ent.state].data, dt)
+end
+
+function set_state(ent, to)
+ assert(has_comp(ent, "State_Machine"), "Entity must have a state machine.")
+ assert(ent.states[to], "Entity does not have state '" .. to .. "'.")
+
+ try(ent.states[ent.state].exit, ent, ent.states[ent.state].data, to)
+ ent.state = to
+ try(ent.states[ent.state].enter, ent, ent.states[ent.state].data)
+end
diff --git a/src/utils.lua b/src/utils.lua
index 55a9d35..02ca522 100644
--- a/src/utils.lua
+++ b/src/utils.lua
@@ -11,6 +11,12 @@ function bton(bool)
return bool and 1 or 0
end
+function try(fn, ...)
+ if fn then
+ fn(...)
+ end
+end
+
function min(a, b)
if a < b then
return a