Sprites and Animations

This commit is contained in:
2026-02-15 16:55:22 -06:00
parent 997aa3f16b
commit 7b19fbcf53
4 changed files with 241 additions and 12 deletions

134
src/sprite.odin Normal file
View File

@@ -0,0 +1,134 @@
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)
src_width := widthf
src_height := heightf
src_x := frame_pos.x * widthf
src_y := frame_pos.y * heightf
if flipX {
src_width = -src_width
src_x += widthf
}
if flipY {
src_height = -src_height
src_y += heightf
}
source_rect := raylib.Rectangle {
x = src_x,
y = src_y,
width = src_width,
height = src_height,
}
dest_rect := raylib.Rectangle {
x = draw_pos.x,
y = draw_pos.y,
width = widthf,
height = heightf,
}
// origin := raylib.Vector2{widthf * 0.5, heightf * 0.5}
// dest_rect.x = draw_pos.x + widthf * 0.5
// dest_rect.y = draw_pos.y + heightf * 0.5
origin := raylib.Vector2{0, 0}
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)}
}