From f2110236e384abe5c74ae203ba56f1b06cc71bcb Mon Sep 17 00:00:00 2001 From: Jason Hilder Date: Thu, 16 Jul 2026 07:50:01 +0200 Subject: [PATCH] Initial map interface. --- src/game.odin | 19 ++++++----- src/map.odin | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 src/map.odin diff --git a/src/game.odin b/src/game.odin index c5e4c7f..70e776e 100644 --- a/src/game.odin +++ b/src/game.odin @@ -6,6 +6,7 @@ Game :: struct { assets: Asset_Manager, camera: rl.Camera2D, world: rl.RenderTexture2D, + current_map: Game_Map, player: Player, debug: Debug } @@ -20,6 +21,7 @@ game_init :: proc() -> Game { game.player = player_init(&game.assets.player) game.camera = camera_init(game.player, 1) game.world = rl.LoadRenderTexture(GAME_WIDTH, GAME_HEIGHT) + game.current_map = map_init() // DEBUG debug_init(&game) @@ -32,25 +34,26 @@ game_should_run :: proc(game: ^Game) -> bool { } game_update :: proc(game: ^Game) { - update_player(&game.player, &game.assets.player) + update_player(&game.player, &game.assets.player, game.camera) update_camera(game.player.pos, &game.camera) - // DEBUG + // DEBUG debug_camera_update(&game.debug) } game_draw :: proc(game: ^Game) { cam := game.camera if game.debug.camera_active { - cam = game.debug.camera + cam = game.debug.camera } rl.BeginTextureMode(game.world) rl.ClearBackground(rl.BLACK) rl.BeginMode2D(cam) - renderer_draw_player(&game.player) + draw_map(game.current_map) + draw_player(&game.player) - // DEBUG + // DEBUG debug_camera_draw(&game.camera, game.debug.camera_active) debug_bounds(game) rl.EndMode2D() @@ -65,7 +68,7 @@ game_draw :: proc(game: ^Game) { x = 0, y = 0, width = f32(game.world.texture.width), // raylib opengl negative to flip Y? - height = -f32(game.world.texture.height), + height = -f32(game.world.texture.height), }, rl.Rectangle{ x = 0, y = 0, @@ -77,7 +80,7 @@ game_draw :: proc(game: ^Game) { rl.WHITE, ) - // DEBUG + // DEBUG debug_fps() rl.EndDrawing() } @@ -86,4 +89,4 @@ game_close :: proc(game: ^Game) { asset_manager_destroy(&game.assets) rl.UnloadRenderTexture(game.world) rl.CloseWindow() -} \ No newline at end of file +} diff --git a/src/map.odin b/src/map.odin new file mode 100644 index 0000000..31bd803 --- /dev/null +++ b/src/map.odin @@ -0,0 +1,87 @@ +package game + +import "core:math" +import rl "vendor:raylib" + +Tile_Type :: enum { + // TEMP light gray + FLOOR, + // TEMP DARK gray + WALL, + // TREMP GREEN + PICKUP, +} + +Game_Map :: struct { + width: int, + height: int, + tile_size: int, + data: [400]int +} + +Grid_Pos :: [2]int + +map_init :: proc() -> Game_Map { + // @TODO: store maps and load them later + // NOTE: flat, row-major — data[row * width + col] + map_data := [400]int{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, + 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + } + + return Game_Map{ + width = 20, + height = 20, + tile_size = TILE_SIZE, + data = map_data, + } +} + +world_to_grid :: proc(pixel_pos: rl.Vector2, camera: rl.Camera2D) -> Grid_Pos { + grid_space := rl.GetScreenToWorld2D(pixel_pos, camera) + + // @TODO: I wonder if this floor and casting is expensive, look for a smarter way later + pos_x := int(math.floor(grid_space.x)) + pos_y := int(math.floor(grid_space.y)) + + return Grid_Pos{pos_x, pos_y} +} + +grid_to_world :: proc(col: int, row: int) -> rl.Vector2 { + world_x := f32(col * TILE_SIZE) + world_y := f32(row * TILE_SIZE) + + return rl.Vector2{world_x, world_y} +} + +draw_map :: proc(current_map: Game_Map) { + for value, index in current_map.data { + row := index / current_map.width + column := index % current_map.width + + color := rl.LIGHTGRAY + if value == 1 do color = rl.DARKGRAY + if value == 2 do color = rl.GREEN + + rect := grid_to_world(column, row) + rl.DrawRectangle(i32(rect.x), i32(rect.y), TILE_SIZE, TILE_SIZE, color) + } +}