119 lines
2.4 KiB
Odin
119 lines
2.4 KiB
Odin
package main
|
|
|
|
import "vendor:raylib"
|
|
|
|
Sprite :: struct {
|
|
texture: raylib.Texture2D,
|
|
width: i32,
|
|
height: i32,
|
|
framesX: i32,
|
|
framesY: i32,
|
|
}
|
|
|
|
SpriteAnimation :: struct {
|
|
start_frame: i32,
|
|
end_frame: i32,
|
|
fps: i32,
|
|
loop: bool,
|
|
}
|
|
|
|
SpriteAnimator :: struct {
|
|
anim: ^SpriteAnimation,
|
|
current_frame: i32,
|
|
timer: f32,
|
|
}
|
|
|
|
load_sprite :: proc(image_path: cstring, w: i32, h: i32) -> Sprite {
|
|
new_texture: raylib.Texture2D = raylib.LoadTexture(image_path)
|
|
|
|
new_sprite: Sprite = {
|
|
texture = new_texture,
|
|
width = w,
|
|
height = h,
|
|
framesX = new_texture.width / w,
|
|
framesY = new_texture.height / h,
|
|
}
|
|
|
|
return new_sprite
|
|
}
|
|
|
|
draw_sprite_frame :: proc(
|
|
sprite: ^Sprite,
|
|
frame_pos: raylib.Vector2,
|
|
draw_pos: raylib.Vector2,
|
|
flipX: bool,
|
|
flipY: bool,
|
|
color: raylib.Color,
|
|
) {
|
|
widthf := f32(sprite.width)
|
|
heightf := f32(sprite.height)
|
|
|
|
source_rect := raylib.Rectangle {
|
|
x = frame_pos.x * widthf,
|
|
y = frame_pos.y * heightf,
|
|
width = widthf,
|
|
height = heightf,
|
|
}
|
|
|
|
if flipX do source_rect.width *= -1
|
|
if flipY do source_rect.height *= -1
|
|
|
|
origin := raylib.Vector2{widthf / 2, heightf / 2}
|
|
|
|
dest_rect := raylib.Rectangle {
|
|
x = draw_pos.x + origin.x,
|
|
y = draw_pos.y + origin.y,
|
|
width = widthf,
|
|
height = heightf,
|
|
}
|
|
|
|
raylib.DrawTexturePro(sprite.texture, source_rect, dest_rect, origin, 0.0, color)
|
|
}
|
|
|
|
set_sprite_animation :: proc(animator: ^SpriteAnimator, new_anim: ^SpriteAnimation) {
|
|
if (animator.anim == new_anim) do return
|
|
|
|
animator.anim = new_anim
|
|
animator.timer = 0
|
|
animator.current_frame = new_anim.start_frame
|
|
}
|
|
|
|
draw_sprite_animated :: proc(
|
|
sprite: ^Sprite,
|
|
animator: ^SpriteAnimator,
|
|
draw_pos: raylib.Vector2,
|
|
flipX: bool,
|
|
flipY: bool,
|
|
color: raylib.Color,
|
|
) {
|
|
frame_pos := frame_to_xy(sprite, animator.current_frame)
|
|
draw_sprite_frame(sprite, frame_pos, draw_pos, flipX, flipY, color)
|
|
}
|
|
|
|
update_animator :: proc(a: ^SpriteAnimator, delta: f32) {
|
|
if a.anim == nil do return
|
|
|
|
frame_time := 1.0 / f32(a.anim.fps)
|
|
a.timer += delta
|
|
|
|
if (a.timer >= frame_time) {
|
|
a.timer -= frame_time
|
|
a.current_frame += 1
|
|
|
|
if (a.current_frame > a.anim.end_frame) {
|
|
if (a.anim.loop) {
|
|
a.current_frame = a.anim.start_frame
|
|
} else {
|
|
a.current_frame = a.anim.end_frame
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
frame_to_xy :: proc(sprite: ^Sprite, frame: i32) -> raylib.Vector2 {
|
|
x := frame % sprite.framesX
|
|
y := frame / sprite.framesX
|
|
return raylib.Vector2{f32(x), f32(y)}
|
|
}
|
|
|