diff options
| author | iamcheeseman <[email protected]> | 2026-03-03 21:13:32 -0500 |
|---|---|---|
| committer | iamcheeseman <[email protected]> | 2026-03-03 21:13:32 -0500 |
| commit | 86f95e0737ba082625c22d40057e66499cbc8ac1 (patch) | |
| tree | c86336bf0a21b7740d8b5416424b30c4bb3eee9e /src/player.odin | |
| parent | 11d72700ad9afd1d23bdae730edf5b160e99fde4 (diff) | |
Health and dying
Diffstat (limited to 'src/player.odin')
| -rw-r--r-- | src/player.odin | 73 |
1 files changed, 64 insertions, 9 deletions
diff --git a/src/player.odin b/src/player.odin index 4747e65..592552d 100644 --- a/src/player.odin +++ b/src/player.odin @@ -12,17 +12,15 @@ Player_State :: enum { Dash, Wall_Slide, Wall_Jump, + Dead, } // there will only ever be one player, so just make it a global :) player: struct { - body: phys.Body_Handle, - sprite: Sprite, - gun: struct { - sprite: Sprite, - kickback: f32, - }, - scarf: Tail(7), + health: i16, + max_health: i16, + + hit_timestamp: f32, jump_buffer: f32, coyote_time: f32, dash_cooldown: f32, @@ -33,6 +31,14 @@ player: struct { outside_room: bool, has_double_jumped: bool, fall_height: f32, + body: phys.Body_Handle, + + sprite: Sprite, + scarf: Tail(7), + gun: struct { + sprite: Sprite, + kickback: f32, + }, owns_double_jump: bool, owns_dash: bool, @@ -44,6 +50,7 @@ init_player :: proc() { layers = {.Player}, mask = {.Hard} ) + player.body = body init_sprite(&player.sprite, .Player) @@ -62,6 +69,9 @@ init_player :: proc() { color_start = Color {0.18, 0.13, 0.18, 1} * 0.5, color_end = {0.18, 0.13, 0.18, 1}, } + + player.max_health = 10 + player.health = 10 } deinit_player :: proc() { @@ -211,8 +221,12 @@ _default_state :: proc(dt: f32) { if .Down in new_collisions && .Down not_in collisions { // just landed height := phys.get_position(player.body).y - if height - player.fall_height > 16 * 16 { - log.info("DEAD") + + distance_fallen := height - player.fall_height + if distance_fallen > MAX_SAFE_FALL_HEIGHT { + distance_fallen -= MAX_SAFE_FALL_HEIGHT + damage := (distance_fallen / MAX_FALL_HEIGHT) * PLAYER_MAX_FALL_DAMAGE + player_take_damage(damage, {0, 0}) } } @@ -383,6 +397,7 @@ update_player :: proc(dt: f32) { case .Dash: _dash_state(dt) case .Wall_Slide: _wall_slide_state(dt) case .Wall_Jump: _wall_jump_state(dt) + case .Dead: } pos := phys.get_position(player.body) @@ -423,6 +438,46 @@ draw_player :: proc() { if player.state != .Dash { draw_sprite(player.gun.sprite) } + + health_bar_size := Vec2{16, 2} + + pos := player.sprite.pos + pos.x -= health_bar_size.x / 2 + pos.y -= 24 + + fw.draw_rect( + pos - {1, 1}, + health_bar_size + {2, 2}, + color = fw.WHITE, + ) + + fw.draw_progress_bar( + pos, + health_bar_size, + fw.RED, + fw.BLACK, + f32(player.health) / f32(player.max_health), + ) +} + +player_take_damage :: proc(#any_int amt: i16, kb_dir: Vec2) { + current_time := f32(fw.get_time()) + + if current_time - player.hit_timestamp < 0.2 { + return + } + + player.hit_timestamp = current_time + + player.health -= amt + player.health = math.clamp(player.health, 0, player.max_health) + + if player.health == 0 { + player.state = .Dead + } + + vel := phys.get_velocity(player.body) + kb_dir + phys.set_velocity(player.body, vel) } draw_player_fg :: proc() { |
