package demonchime import "core:log" import "core:math/linalg" import "fw" Sprite :: struct { image: fw.Texture, anim_id: Animation_Id, current_tag: Tag_Resource, frame_time: f32, current_frame: i32, width: i32, height: i32, pos: Vec2, offset: Vec2, rotation: f32, scale: Vec2, just_finished_loop: bool, } init_sprite :: proc( sprite: ^Sprite, image_id: Image_Id, anim_id: Maybe(Animation_Id) = nil, ) -> bool { sprite.image = get_image(image_id) switch id in anim_id { case Animation_Id: sprite.anim_id = id case nil: sprite.anim_id = images[image_id].anim } anim := animations[sprite.anim_id] sprite.width = i32(f32(sprite.image.size.x) / f32(anim.frame_count)) sprite.height = i32(sprite.image.size.y) sprite.scale = Vec2{1, 1} return true } set_sprite_active_tag :: proc(sprite: ^Sprite, tag_name: string) { anim := animations[sprite.anim_id] sprite.current_tag = anim.tags[tag_name] } set_sprite_offset_percentage :: proc(sprite: ^Sprite, offset: Vec2) { sprite.offset = linalg.round( Vec2{f32(sprite.width), f32(sprite.height)} * offset, ) } update_sprite :: proc(sprite: ^Sprite, dt: f32) { sprite.just_finished_loop = false sprite.frame_time += dt anim := animations[sprite.anim_id] duration := f32(anim.frame_durations[sprite.current_frame]) / 1000 if sprite.frame_time > duration { sprite.frame_time -= duration sprite.current_frame += 1 } tag := &sprite.current_tag if sprite.current_frame < tag.from { sprite.current_frame = tag.to sprite.just_finished_loop = true } if sprite.current_frame > tag.to { sprite.current_frame = tag.from sprite.just_finished_loop = true } } draw_sprite :: proc(sprite: Sprite) { rect := Rect { {f32(sprite.width * sprite.current_frame), 0}, {f32(sprite.width), f32(sprite.height)}, } log.debug(sprite.width, sprite.height) fw.draw_tex_ex( sprite.image, sprite.pos, rect = rect, offset = sprite.offset, rot = sprite.rotation, scale = sprite.scale, ) }