package main import rl "vendor:raylib" Graphics :: union { GfxNone, GfxCircle, GfxRect, GfxRing, GfxCircleLines, GfxAnimatedSprite, GfxTexture, } GfxNone :: struct {} GfxCircle :: struct { pos: rl.Vector2, radius: f32, color: rl.Color, } GfxRect :: struct { pos: rl.Vector2, size: rl.Vector2, color: rl.Color, } GfxRing :: struct { pos: rl.Vector2, inner_radius: f32, outer_radius: f32, color: rl.Color, } GfxCircleLines :: struct { pos: rl.Vector2, radius: f32, color: rl.Color, } GfxTexture :: struct {} GfxAnimatedSprite :: struct { pos: rl.Vector2, atlas: ^Atlas, frame: i32, speed: f32, current_time: f32, update: proc(g: ^GfxAnimatedSprite, dt: f32), } PlayerTexFiles :: enum { IDLE, RUN, RUN_ATTACK, WALK, WALK_ATTACK, ATTACK, } Atlas :: struct { tex: rl.Texture2D, frame_size: rl.Vector2, cols: i32, rows: i32, frames: i32, get_offset: proc(a: ^Atlas, f: i32) -> rl.Vector2, } GraphicsAssetStore :: struct { playerTex: map[PlayerTexFiles]Atlas, } player_atlas_get :: proc(g: ^GraphicsAssetStore, f: PlayerTexFiles) -> ^Atlas { return &g.playerTex[f] } gfx_init :: proc() -> GraphicsAssetStore { st := GraphicsAssetStore{} st.playerTex = make(map[PlayerTexFiles]Atlas) st.playerTex[.IDLE] = init_atlas( texture_path = "assets/3rdparty/player_idle.png", size = rl.Vector2{64, 64}, ) return st } init_atlas :: proc(texture_path: cstring, size: rl.Vector2) -> Atlas { atlas := Atlas { tex = rl.LoadTexture(texture_path), frame_size = size, get_offset = get_offset, } atlas.rows = atlas.tex.height / (i32(size.y)) atlas.cols = atlas.tex.width / i32(size.x) atlas.frames = atlas.cols * atlas.rows return atlas } get_offset :: proc(a: ^Atlas, f: i32) -> rl.Vector2 { col := f % a.cols row := f / a.cols return rl.Vector2{f32(col) * a.frame_size.x, f32(row) * a.frame_size.y} } gfx_free :: proc(g: GraphicsAssetStore) { for _, tex in g.playerTex { rl.UnloadTexture(tex.tex) } delete(g.playerTex) } gfx_draw :: proc(pos: rl.Vector2, g: ^Graphics) { #partial switch v in g { case GfxCircle: rl.DrawCircleV(pos + v.pos, v.radius, v.color) case GfxRect: rl.DrawRectangleV(pos - v.size / 2 + v.pos, v.size, v.color) case GfxRing: rl.DrawRing(pos + v.pos, v.inner_radius, v.outer_radius, 0, 360, 0, v.color) case GfxCircleLines: rl.DrawCircleLinesV(pos + v.pos, v.radius, v.color) case GfxAnimatedSprite: //TODO: Count from L to R row-wize frame_offset := v.atlas->get_offset(v.frame) rl.DrawTexturePro( v.atlas^.tex, rl.Rectangle { frame_offset.x, frame_offset.y, v.atlas.frame_size.x, v.atlas.frame_size.y, }, rl.Rectangle { pos.x - v.atlas.frame_size.x * 3 / 2, pos.y - v.atlas.frame_size.y * 3 / 2, v.atlas.frame_size.x * 3, v.atlas.frame_size.y * 3, }, rl.Vector2{0, 0}, 0, rl.WHITE, ) // v.current_time += rl.GetFrameTime() // if v.current_time > v.speed { // v.current_time = v.current_time - v.speed // v.frame += 1 // } } }