1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
package demonchime
import "core:log"
import "core:math"
import rl "vendor:raylib"
import "draw"
import "phys"
PLAYER_SPEED :: 100
PLAYER_ACCEL :: 10
PLAYER_JUMP_FORCE :: 350
JUMP_BUFFERING :: 0.07
COYOTE_TIME :: 0.05
JUMP_RELEASE_CUT :: -100
Player :: struct {
body_handle: phys.Body_Handle,
anim: draw.Animation,
sprite: draw.Sprite,
jump_buffer: f32,
coyote_time: f32,
}
init_player :: proc(p: ^Player) {
anim_ok := draw.init_anim_data(&p.anim, "res/player.json")
if !anim_ok {
log.warn("could not load animation")
rl.CloseWindow()
return
}
handle, body := phys.make_body(
phys.Rect{{8, 17}, {16, 16}},
)
p.body_handle = handle
body.pos = Vec2{50, 0}
draw.init_sprite(&p.sprite, p.anim.image_path, p.anim)
p.sprite.offset = Vec2{
-math.floor(f32(p.sprite.width / 2)),
-f32(p.sprite.height)
}
}
deinit_player :: proc(p: ^Player) {
phys.remove_body(p.body_handle)
draw.destroy_sprite(p.sprite)
draw.delete_anim_data(p.anim)
}
update_player :: proc(p: ^Player, dt: f32) {
input: f32
if is_keybind_down(actions.move_left) {
input -= 1
}
if is_keybind_down(actions.move_right) {
input += 1
}
if is_keybind_just_down(actions.jump) {
p.jump_buffer = JUMP_BUFFERING
}
if input != 0 {
draw.set_sprite_active_tag(&p.sprite, "run")
p.sprite.scale.x = math.sign(input)
} else {
draw.set_sprite_active_tag(&p.sprite, "idle")
}
body := phys.get_body(p.body_handle)
if .DOWN in body.collisions {
p.coyote_time = COYOTE_TIME
}
if p.jump_buffer > 0 && p.coyote_time > 0 {
p.jump_buffer = 0
p.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.x = math.lerp(
body.vel.x,
input * PLAYER_SPEED,
math.pow(0.5, dt * PLAYER_ACCEL),
)
body.vel.y = math.min(body.vel.y + GRAVITY * dt, TERMINAL_VELOCITY)
phys.update_body(p.body_handle)
p.sprite.pos = body.pos
draw.update_sprite(&p.sprite, dt)
p.jump_buffer -= dt
p.coyote_time -= dt
}
draw_player :: proc(p: Player) {
draw.sprite(p.sprite)
}
|