diff options
| author | Xander Swan <no email> | 2025-12-05 21:31:14 -0500 |
|---|---|---|
| committer | Xander Swan <no email> | 2025-12-05 21:31:14 -0500 |
| commit | cb11496752ede6dab15d7ae60e0005e78b77e5bb (patch) | |
| tree | 5c731a250274bf570a604dfecb6b7ee0209d34cd /src/player.odin | |
| parent | 3375d712e40cce1d17198ba20839f58a2a77d202 (diff) | |
actual physics system
Diffstat (limited to 'src/player.odin')
| -rw-r--r-- | src/player.odin | 91 |
1 files changed, 40 insertions, 51 deletions
diff --git a/src/player.odin b/src/player.odin index 1dd79ae..f204126 100644 --- a/src/player.odin +++ b/src/player.odin @@ -6,22 +6,25 @@ import "core:math" import sapp "shared:sokol/app" import "draw" +import "phys" Player :: struct { - pos: Vec2, - vel: Vec2, + body_handle: phys.Body_Handle, anim: draw.Animation, sprite: draw.Sprite, - on_floor: bool + + jump_buffer: f32, + cyote_time: f32, } PLAYER_SPEED :: 100 PLAYER_ACCEL :: 10 PLAYER_JUMP_FORCE :: 350 -init_player :: proc(p: ^Player) { - p.pos = Vec2{50, 50} +JUMP_BUFFERING :: 0.07 +CYOTE_TIME :: 0.05 +init_player :: proc(p: ^Player) { anim_ok := draw.init_anim_data(&p.anim, "res/robot2.json") if !anim_ok { fmt.println("coult not load animation") @@ -29,6 +32,14 @@ init_player :: proc(p: ^Player) { return } + handle, body := phys.make_body( + &state.physics_world, + phys.Rect{{-8, -16}, {16, 16}}, + ) + p.body_handle = handle + + body.pos = Vec2{50, 50} + draw.init_sprite(&p.sprite, p.anim.image_path, p.anim) p.sprite.offset = Vec2{ @@ -38,6 +49,8 @@ init_player :: proc(p: ^Player) { } deinit_player :: proc(p: ^Player) { + phys.remove_body(&state.physics_world, p.body_handle) + draw.delete_anim_data(p.anim) } @@ -51,6 +64,10 @@ update_player :: proc(p: ^Player, dt: f32) { input += 1 } + if is_keybind_down(state.input, state.input.jump) { + p.jump_buffer = JUMP_BUFFERING + } + if input != 0 { draw.set_sprite_active_tag(&p.sprite, "down_run") p.sprite.scale.x = math.sign(input) @@ -58,60 +75,32 @@ update_player :: proc(p: ^Player, dt: f32) { draw.set_sprite_active_tag(&p.sprite, "down_idle") } - if is_keybind_down(state.input, state.input.jump) && p.on_floor { - p.vel.y = -PLAYER_JUMP_FORCE + body := phys.get_body(state.physics_world, p.body_handle) + + if .DOWN in body.collisions { + p.cyote_time = CYOTE_TIME + } + + if p.jump_buffer > 0 && p.cyote_time > 0 { + p.jump_buffer = 0 + p.cyote_time = 0 + body.vel.y = -PLAYER_JUMP_FORCE } - p.vel.x = math.lerp( - p.vel.x, + body.vel.x = math.lerp( + body.vel.x, input * PLAYER_SPEED, math.pow(0.5, dt * PLAYER_ACCEL), ) - p.vel.y = math.min(p.vel.y + GRAVITY * dt, TERMINAL_VELOCITY) - - res_pos := p.pos + p.vel * dt - - rect_size := Vec2{f32(p.sprite.width), f32(p.sprite.height)} - rect_offset := Vec2{-rect_size.x / 2, -rect_size.y} - - rect := Rect{ - res_pos + rect_offset, - rect_size, - } + body.vel.y = math.min(body.vel.y + GRAVITY * dt, TERMINAL_VELOCITY) - p.on_floor = false - - iter := iter_entity_list(state.platform_list) - for plat in entity_list_iter(&iter) { - if aabb(rect, plat.rect) { - prev_rect := Rect{ - p.pos + rect_offset, - rect_size, - } - if aabb_hori(prev_rect, plat.rect) { - if p.vel.y > 0 { - res_pos.y = plat.rect.start.y - rect.size.y - rect_offset.y - p.on_floor = true - } else { - res_pos.y = plat.rect.start.y + plat.rect.size.y - rect_offset.y - } - p.vel.y = 0 - } else if aabb_vert(prev_rect, plat.rect) { - if p.vel.x > 0 { - res_pos.x = plat.rect.start.x - rect.size.x - rect_offset.x - } else { - res_pos.x = plat.rect.start.x + plat.rect.size.x - rect_offset.x - } - p.vel.x = 0 - } - } - } - - p.pos = res_pos - - p.sprite.pos = p.pos + phys.update_body(&state.physics_world, p.body_handle) + p.sprite.pos = body.pos draw.update_sprite(&p.sprite, dt) + + p.jump_buffer -= dt + p.cyote_time -= dt } draw_player :: proc(p: Player) { |
