aboutsummaryrefslogtreecommitdiff
path: root/src/player.odin
diff options
context:
space:
mode:
authorXander Swan <no email>2025-12-05 21:31:14 -0500
committerXander Swan <no email>2025-12-05 21:31:14 -0500
commitcb11496752ede6dab15d7ae60e0005e78b77e5bb (patch)
tree5c731a250274bf570a604dfecb6b7ee0209d34cd /src/player.odin
parent3375d712e40cce1d17198ba20839f58a2a77d202 (diff)
actual physics system
Diffstat (limited to 'src/player.odin')
-rw-r--r--src/player.odin91
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) {