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
|
package draw
import "core:log"
import "core:math"
import "core:image"
import "core:image/qoi"
import sg "shared:sokol/gfx"
import stime "shared:sokol/time"
Sprite :: struct {
image: sg.Image,
anim: Animation,
active_anim: u32,
frame_time: f32,
current_frame: i32,
width: i32,
height: i32,
pos: Vec2,
offset: Vec2,
scale: Vec2,
}
init_sprite :: proc(
sprite: ^Sprite,
path: string,
anim: Animation = {},
) -> bool {
img, img_err := qoi.load_from_file(path)
if img_err != nil {
log.error("could not load image")
return false
}
defer image.destroy(img)
sprite.image = sg.make_image({
width = i32(img.width),
height = i32(img.height),
data = {
mip_levels = {
0 = {ptr=&img.pixels.buf[0], size=len(img.pixels.buf)},
},
},
})
sprite.anim = anim
sprite.width = i32(img.width / len(sprite.anim.frames))
sprite.height = i32(img.height)
sprite.scale = Vec2{1, 1}
log.debugf(
"loaded sprite '%v' %vx%v (%vx%v)",
path,
sprite.width, sprite.height,
img.width, img.height,
)
return true
}
set_sprite_active_tag :: proc(sprite: ^Sprite, tag_name: string) {
sprite.active_anim = sprite.anim.frame_tags_indices[tag_name]
}
update_sprite :: proc(sprite: ^Sprite, dt: f32) {
sprite.frame_time += dt
tag := sprite.anim.frame_tags[sprite.active_anim]
frame := sprite.anim.frames[sprite.current_frame]
duration := f32(frame.duration) / 1000
if sprite.frame_time > duration {
sprite.frame_time -= duration
sprite.current_frame += 1
}
if sprite.current_frame < tag.from {
sprite.current_frame = tag.to
}
if sprite.current_frame > tag.to {
sprite.current_frame = tag.from
}
}
draw_sprite :: proc(
r: ^Renderer,
sprite: Sprite,
) {
frame := sprite.anim.frames[sprite.current_frame]
draw_texture(
r,
sprite.image,
Rect {
Vec2{f32(frame.rect.x), f32(frame.rect.y)},
Vec2{f32(frame.rect.w), f32(frame.rect.h)},
},
sprite.pos,
sprite.offset,
sprite.scale,
)
}
|