aboutsummaryrefslogtreecommitdiff
path: root/src/player.odin
diff options
context:
space:
mode:
authorXander Swan <[hidden email]>2026-01-01 18:32:20 -0500
committerXander Swan <[hidden email]>2026-01-01 18:32:20 -0500
commit65a2ceda55198dab3bab75c06c0d50adeb0a1101 (patch)
tree2a08400520f60fcd86b381bc840bb5c739ff998a /src/player.odin
parentdc373b507ca68ada2cbf4c8e0d7949d6bc46ed9b (diff)
lots of changes + player dash
Diffstat (limited to 'src/player.odin')
-rw-r--r--src/player.odin180
1 files changed, 142 insertions, 38 deletions
diff --git a/src/player.odin b/src/player.odin
index 5d7ffb4..5c001da 100644
--- a/src/player.odin
+++ b/src/player.odin
@@ -7,25 +7,42 @@ import rl "vendor:raylib"
import "draw"
import "phys"
+import "tiled"
PLAYER_SPEED :: 100
PLAYER_ACCEL :: 10
PLAYER_JUMP_FORCE :: 350
-JUMP_BUFFERING :: 0.07
-COYOTE_TIME :: 0.05
-JUMP_RELEASE_CUT :: -100
+PLAYER_JUMP_BUFFERING :: 0.07
+PLAYER_COYOTE_TIME :: 0.05
+PLAYER_JUMP_RELEASE_CUT :: -100
-Player :: struct {
+PLAYER_DASH_SPEED :: 500
+PLAYER_DASH_TIME :: 0.15
+PLAYER_DASH_COOLDOWN :: 0.3
+
+Player_State :: enum {
+ DEFAULT,
+ DASH,
+}
+
+// there will only ever be one player, so just make it a global :)
+player: struct {
body_handle: phys.Body_Handle,
anim: draw.Animation,
sprite: draw.Sprite,
jump_buffer: f32,
coyote_time: f32,
+
+ dash_cooldown: f32,
+ dash_timer: f32,
+
+ state: Player_State,
+ outside_room: bool,
}
-init_player :: proc(p: ^Player) {
- anim_ok := draw.init_anim_data(&p.anim, "res/player.json")
+init_player :: proc() {
+ anim_ok := draw.init_anim_data(&player.anim, "res/player.json")
if !anim_ok {
log.warn("could not load animation")
rl.CloseWindow()
@@ -33,28 +50,29 @@ init_player :: proc(p: ^Player) {
}
handle, body := phys.make_body(
- phys.Rect{{8, 17}, {16, 16}},
+ phys.Rect{{-4, 17}, {8, 16}},
)
- p.body_handle = handle
+ player.body_handle = handle
phys.set_body_position(handle, Vec2{50, 100})
- draw.init_sprite(&p.sprite, p.anim.image_path, p.anim)
+ draw.init_sprite(&player.sprite, player.anim.image_path, player.anim)
- p.sprite.offset = Vec2{
- -math.floor(f32(p.sprite.width / 2)),
- -f32(p.sprite.height)
+ player.sprite.offset = Vec2{
+ math.floor(f32(player.sprite.width / 2)),
+ -f32(player.sprite.height)
}
}
-delete_player :: proc(p: Player) {
- phys.remove_body(p.body_handle)
+delete_player :: proc() {
+ phys.remove_body(player.body_handle)
- draw.destroy_sprite(p.sprite)
- draw.delete_anim_data(p.anim)
+ draw.destroy_sprite(player.sprite)
+ draw.delete_anim_data(player.anim)
}
-update_player :: proc(p: ^Player, dt: f32) {
+@(private="file")
+get_input_dir :: proc() -> f32 {
input: f32
if is_keybind_down(actions.move_left) {
@@ -64,33 +82,45 @@ update_player :: proc(p: ^Player, dt: f32) {
input += 1
}
- if is_keybind_just_down(actions.jump) {
- p.jump_buffer = JUMP_BUFFERING
- }
+ return input
+}
+
+@(private="file")
+default_state :: proc(dt: f32) {
+ input := get_input_dir()
if input != 0 {
- draw.set_sprite_active_tag(&p.sprite, "run")
- p.sprite.scale.x = math.sign(input)
+ draw.set_sprite_active_tag(&player.sprite, "run")
+ player.sprite.scale.x = math.sign(input)
} else {
- draw.set_sprite_active_tag(&p.sprite, "idle")
+ draw.set_sprite_active_tag(&player.sprite, "idle")
+ }
+
+ if is_keybind_just_down(actions.jump) {
+ player.jump_buffer = PLAYER_JUMP_BUFFERING
+ }
+
+ if is_keybind_just_down(actions.dash) && player.dash_cooldown <= 0 {
+ enter_dash()
+ return
}
- body := phys.get_body(p.body_handle)
-
+ body := phys.get_body(player.body_handle)
+
if .DOWN in body.collisions {
- p.coyote_time = COYOTE_TIME
+ player.coyote_time = PLAYER_COYOTE_TIME
}
- if p.jump_buffer > 0 && p.coyote_time > 0 {
- p.jump_buffer = 0
- p.coyote_time = 0
+ if player.jump_buffer > 0 && player.coyote_time > 0 {
+ player.jump_buffer = 0
+ player.coyote_time = 0
body.vel.y = -PLAYER_JUMP_FORCE
}
if .DOWN not_in body.collisions \
&& !is_keybind_down(actions.jump) \
- && body.vel.y < JUMP_RELEASE_CUT {
- body.vel.y = JUMP_RELEASE_CUT
+ && body.vel.y < PLAYER_JUMP_RELEASE_CUT {
+ body.vel.y = PLAYER_JUMP_RELEASE_CUT
}
body.vel.x = math.lerp(
@@ -100,16 +130,90 @@ update_player :: proc(p: ^Player, dt: f32) {
)
body.vel.y = math.min(body.vel.y + GRAVITY * dt, TERMINAL_VELOCITY)
- phys.update_body(p.body_handle)
+ phys.update_body(player.body_handle)
+}
+
+@(private="file")
+enter_dash :: proc() {
+ body := phys.get_body(player.body_handle)
+ // the sprite x scale is the direction the player is facing :)
+ body.vel = {math.sign(player.sprite.scale.x) * PLAYER_DASH_SPEED, 0}
+
+ player.dash_timer = PLAYER_DASH_TIME
+ player.state = .DASH
+}
+
+@(private="file")
+dash_state :: proc(dt: f32) {
+ phys.update_body(player.body_handle)
+
+ player.dash_timer -= dt
+ body := phys.get_body(player.body_handle)
+
+ if player.dash_timer <= 0 || body.collisions != {} {
+ exit_dash()
+ }
+}
+
+exit_dash :: proc() {
+ player.state = .DEFAULT
+
+ player.dash_cooldown = PLAYER_DASH_COOLDOWN
+
+ body := phys.get_body(player.body_handle)
+ body.vel /= 2
+}
+
+@(private="file")
+change_rooms :: proc() {
+ body := phys.get_body(player.body_handle)
- p.sprite.pos = body.pos
- draw.update_sprite(&p.sprite, dt)
+ width := f32(tiled.current_room.room.width)
+ height := f32(tiled.current_room.room.height)
- p.jump_buffer -= dt
- p.coyote_time -= dt
+ if body.pos.x < 0 || body.pos.x > width \
+ || body.pos.y < 0 || body.pos.y > height {
+ prev_room_pos := [2]f32{
+ f32(tiled.current_room.room.x),
+ f32(tiled.current_room.room.y),
+ }
+ changed := tiled.open_new_room_at({i32(body.pos.x), i32(body.pos.y)})
+
+ if changed {
+ new_room_pos := [2]f32{
+ f32(tiled.current_room.room.x),
+ f32(tiled.current_room.room.y),
+ }
+
+ diff := prev_room_pos - new_room_pos
+ new_pos := body.pos + diff - {0, 0}
+ phys.set_body_position(player.body_handle, new_pos)
+
+ setup_map_collisions()
+ }
+ }
}
-draw_player :: proc(p: Player) {
- draw.sprite(p.sprite)
+update_player :: proc(dt: f32) {
+ switch player.state {
+ case .DEFAULT:
+ default_state(dt)
+ case .DASH:
+ dash_state(dt)
+ }
+
+ body := phys.get_body(player.body_handle)
+
+ player.sprite.pos = body.pos
+ draw.update_sprite(&player.sprite, dt)
+
+ player.dash_cooldown -= dt
+ player.jump_buffer -= dt
+ player.coyote_time -= dt
+
+ change_rooms()
}
+draw_player :: proc() {
+ draw.sprite(player.sprite)
+}