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)} }