From 46114a1dbbd1829be62ee332c2ccb6d3663bc15f Mon Sep 17 00:00:00 2001 From: codegirl-007 Date: Tue, 16 Jun 2026 20:09:56 -0700 Subject: [PATCH] I don't know what i did wrong --- game/app.odin | 7 +++-- game/hud.odin | 32 +++++++++++++++++++-- game/ui.odin | 42 +++++++++++++++++++++++++++ game/ui_render.odin | 69 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 game/ui.odin create mode 100644 game/ui_render.odin diff --git a/game/app.odin b/game/app.odin index a13e09d..519bc4c 100644 --- a/game/app.odin +++ b/game/app.odin @@ -7,23 +7,26 @@ run :: proc() { defer rl.CloseWindow() rl.SetTargetFPS(60) + init_ui() + defer destroy_ui() + world := init_world() for !rl.WindowShouldClose() { dt := rl.GetFrameTime() + ui_prepare_frame(&world, dt) update_world(&world, dt) rl.BeginDrawing() rl.ClearBackground(rl.Color{34, 139, 34, 255}) render_world(&world) + render_ui() rl.EndDrawing() } delete(world.path) delete(world.towers) delete(world.events) - } - diff --git a/game/hud.odin b/game/hud.odin index 5c4b6a3..ccf2f65 100644 --- a/game/hud.odin +++ b/game/hud.odin @@ -1,11 +1,38 @@ package game +import clay "../clay-odin" import "core:fmt" import rl "vendor:raylib" +UI_BAR_COLOR :: clay.Color{20, 40, 20, 200} +UI_TEXT_COLOR :: clay.Color{240, 240, 230, 255} +UI_GOLD_COLOR :: clay.Color{255, 215, 80, 255} + +build_hud :: proc(world: ^World) { + if clay.UI(clay.ID("HudBar"))({ + layout = { + layoutDirection = .LeftToRight, + sizing = { + width = clay.SizingGrow({}), + height = clay.SizingFixed(28), + }, + padding = clay.PaddingAll(6), + childGap = 8, + childAlignment = {y = .Center}, + }, + backgroundColor = UI_BAR_COLOR, + }) { + gold_text := fmt.tprintf("Gold: %d", world.gold) + clay.Text(gold_text, clay.TextElementConfig{ + textColor = UI_GOLD_COLOR, + fontId = UI_FONT_ID, + fontSize = 18, + }) + } +} + render_hud :: proc(world: ^World) { - rl.DrawText(fmt.ctprintf("Gold: %d", world.gold), 10, 10, 22, rl.BLACK) // Gold HUD - rl.DrawText(fmt.ctprintf("Base HP: %d", world.base_health), 10, 32, 22, rl.BLACK) // HP HUD + rl.DrawText(fmt.ctprintf("Base HP: %d", world.base_health), 10, 32, 22, rl.BLACK) rl.DrawText(fmt.ctprintf("Enemies: %d", active_enemy_count(world)), 10, 54, 22, rl.BLACK) rl.DrawText(fmt.ctprintf("Wave: %d / %d", world.wave, MAX_WAVES), 10, 76, 22, rl.BLACK) @@ -20,4 +47,3 @@ render_hud :: proc(world: ^World) { rl.DrawText("Victory!", 260, 280, 40, rl.GREEN) } } - diff --git a/game/ui.odin b/game/ui.odin new file mode 100644 index 0000000..e0b0ce0 --- /dev/null +++ b/game/ui.odin @@ -0,0 +1,42 @@ +package game + +import clay "../clay-odin" +import rl "vendor:raylib" + +ui_memory: [^]u8 +ui_arena: clay.Arena +ui_render_commands: clay.ClayArray(clay.RenderCommand) + +ui_error_handler :: proc "c" (data: clay.ErrorData) { + _ = data +} + +init_ui :: proc() { + ui_register_font() + clay.SetMeasureTextFunction(measure_text, nil) + + min_size := clay.MinMemorySize() + ui_memory = make([^]u8, min_size) + ui_arena = clay.CreateArenaWithCapacityAndMemory(uint(min_size), ui_memory) + clay.Initialize(ui_arena, {f32(SCREEN_W), f32(SCREEN_H)}, {handler = ui_error_handler}) +} + +destroy_ui :: proc() { + free(ui_memory) +} + +ui_prepare_frame :: proc(world: ^World, dt: f32) { + mouse := rl.GetMousePosition() + clay.SetLayoutDimensions({f32(SCREEN_W), f32(SCREEN_H)}) + clay.SetPointerState({mouse.x, mouse.y}, rl.IsMouseButtonDown(.LEFT)) + clay.UpdateScrollContainers(false, {}, dt) + + clay.BeginLayout() + build_hud(world) + ui_render_commands = clay.EndLayout(dt) +} + +render_ui :: proc() { + clay_raylib_render(&ui_render_commands) +} + diff --git a/game/ui_render.odin b/game/ui_render.odin new file mode 100644 index 0000000..d4fb20a --- /dev/null +++ b/game/ui_render.odin @@ -0,0 +1,69 @@ +package game + +import clay "../clay-odin" +import "core:math" +import "core:strings" +import rl "vendor:raylib" + +UI_FONT_ID :: 0 + +ui_font: rl.Font + +ui_register_font :: proc() { + ui_font = rl.GetFontDefault() +} + +clay_color_to_rl :: proc(c: clay.Color) -> rl.Color { + return {u8(c.r), u8(c.g), u8(c.b), u8(c.a)} +} + +measure_text :: proc "c" ( + text: clay.StringSlice, + config: ^clay.TextElementConfig, + _: rawptr, +) -> clay.Dimensions { + return {width = f32(text.length) * f32(config.fontSize) * 0.55, height = f32(config.fontSize)} +} + +clay_raylib_render :: proc(commands: ^clay.ClayArray(clay.RenderCommand)) { + for i in 0 ..< commands.length { + cmd := clay.RenderCommandArray_Get(commands, i) + bounds := cmd.boundingBox + + #partial switch cmd.commandType { + case .None: + case .Text: + cfg := cmd.renderData.text + text := string(cfg.stringContents.chars[:cfg.stringContents.length]) + cstr := strings.clone_to_cstring(text, context.temp_allocator) + + rl.DrawTextEx( + ui_font, + cstr, + {bounds.x, bounds.y}, + f32(cfg.fontSize), + f32(cfg.letterSpacing), + clay_color_to_rl(cfg.textColor), + ) + case .Rectangle: + cfg := cmd.renderData.rectangle + rl.DrawRectangle( + i32(math.round(bounds.x)), + i32(math.round(bounds.y)), + i32(math.round(bounds.width)), + i32(math.round(bounds.height)), + clay_color_to_rl(cfg.backgroundColor), + ) + case .ScissorStart: + rl.BeginScissorMode( + i32(math.round(bounds.x)), + i32(math.round(bounds.y)), + i32(math.round(bounds.width)), + i32(math.round(bounds.height)), + ) + case .ScissorEnd: + rl.EndScissorMode() + } + } +} +