diff --git a/.nvim.lua b/.nvim.lua index d1d8713..4b91e19 100644 --- a/.nvim.lua +++ b/.nvim.lua @@ -4,6 +4,7 @@ require("custom.runner").setup({ -- test = { cmd = "go test ./..." }, -- build = { cmd = "odin build ./src/" }, -- lint = { cmd = "go vet ./..." }, + build = { cmd = "odin build . -debug" }, }, focus = false, -- фокус на нижний терминал при запуске diff --git a/assets/3rdparty/tileset/Decorations/Decorations.png b/assets/3rdparty/tileset/Decorations/Decorations.png new file mode 100644 index 0000000..b0455c0 Binary files /dev/null and b/assets/3rdparty/tileset/Decorations/Decorations.png differ diff --git a/assets/3rdparty/tileset/Tiles/Tileset.png b/assets/3rdparty/tileset/Tiles/Tileset.png new file mode 100644 index 0000000..4773629 Binary files /dev/null and b/assets/3rdparty/tileset/Tiles/Tileset.png differ diff --git a/assets/3rdparty/tileset/Tiles/Tileset1xPadding.png b/assets/3rdparty/tileset/Tiles/Tileset1xPadding.png new file mode 100644 index 0000000..5618770 Binary files /dev/null and b/assets/3rdparty/tileset/Tiles/Tileset1xPadding.png differ diff --git a/entity.odin b/entity.odin index c12f035..647627a 100644 --- a/entity.odin +++ b/entity.odin @@ -24,19 +24,6 @@ Enemy :: struct { handle: ent_handle, } -create_enemy :: proc(scene: ^Scene, pos: rl.Vector2) { - if scene.enemy_count >= MAX_ENEMIES { - return - } - scene.enemies[scene.enemy_count] = Enemy { - position = pos, - hp = 100, - speed = 100, - col = 32, - } - scene.enemy_count += 1 -} - update_player :: proc(player: ^Player, dt: f32) { input: rl.Vector2 @@ -73,8 +60,6 @@ calc_col_box :: proc(center: rl.Vector2, side: f32) -> rl.Rectangle { } -// Разлепляет два ентерия — выталкивает по оси наименьшего проникновения. -// Чтоб не стояли друг в друге как родные. resolve_entity_overlap :: proc(a, b: ^Entity) { ra := calc_col_box(a.position, a.col) rb := calc_col_box(b.position, b.col) @@ -106,18 +91,17 @@ resolve_entity_overlap :: proc(a, b: ^Entity) { } resolve_collisions :: proc(scene: ^Scene) { - // Враг против врага — чтоб толпой не слипались - for i in 0 ..< scene.enemy_count { - for j in i + 1 ..< scene.enemy_count { - resolve_entity_overlap( - &scene.enemies[i].ent, - &scene.enemies[j].ent, - ) + it := hm.iterator_make(&scene.enemies) + for i, _ in hm.iterate(&it) { + it2 := hm.iterator_make(&scene.enemies) + for j, _ in hm.iterate(&it2) { + if i == j do continue + resolve_entity_overlap(i, j) } } - // Игрок против врагов — чтоб не захавывали друг друга - for &enemy in scene.enemies[:scene.enemy_count] { - resolve_entity_overlap(&scene.player.ent, &enemy.ent) + it = hm.iterator_make(&scene.enemies) + for i, _ in hm.iterate(&it) { + resolve_entity_overlap(&scene.player.ent, i) } } diff --git a/hello b/hello index 76c6bf0..22be77b 100755 Binary files a/hello and b/hello differ diff --git a/main.odin b/main.odin index f0390a6..a021739 100644 --- a/main.odin +++ b/main.odin @@ -9,11 +9,14 @@ SCREEN_H :: 720 MAX_ENEMIES :: 10 +MAX_TILES :: 4096 Scene :: struct { player: Player, camera: rl.Camera2D, enemies: hm.Static_Handle_Map(128, Enemy, ent_handle), + atlas: Atlas, + tiles: [MAX_TILES]Tile, } @@ -31,29 +34,44 @@ create_scene :: proc() -> Scene { offset = rl.Vector2{SCREEN_W / 2, SCREEN_H / 2}, }, } - _ = hm.add( - &scene.enemies, - Enemy { - position = rl.Vector2{500, 500}, - hp = 100, - speed = 100, - col = 32, - }, - ) - _ = hm.add( - &scene.enemies, - Enemy { - position = rl.Vector2{600, 600}, - hp = 100, - speed = 100, - col = 32, - }, - ) + // _ = hm.add( + // &scene.enemies, + // Enemy { + // position = rl.Vector2{500, 500}, + // hp = 100, + // speed = 100, + // col = 32, + // }, + // ) + // _ = hm.add( + // &scene.enemies, + // Enemy { + // position = rl.Vector2{600, 600}, + // hp = 100, + // speed = 100, + // col = 32, + // }, + // ) + + scene.atlas = load_atlas() + + + // append( + // &scene.tiles, + // Tile{atlas = &scene.atlas, pos = rl.Vector2{0, 0}, frame = 3}, + // ) return scene } draw_scene :: proc(scene: ^Scene) { rl.BeginMode2D(scene.camera) + + + for tile in scene.tiles { + if tile.atlas == nil do continue + draw_tile(tile) + } + rl.DrawCircle( cast(i32)scene.player.position.x, cast(i32)scene.player.position.y, @@ -62,15 +80,12 @@ draw_scene :: proc(scene: ^Scene) { ) rl.DrawRectangle(300, 300, 100, 100, rl.BLUE) - for enemy in scene.enemies[:scene.enemy_count] { - rl.DrawCircle( - cast(i32)enemy.position.x, - cast(i32)enemy.position.y, - 32, - rl.RED, - ) + it := hm.iterator_make(&scene.enemies) + for i, _ in hm.iterate(&it) { + rl.DrawCircle(cast(i32)i.position.x, cast(i32)i.position.y, 32, rl.RED) } + rl.EndMode2D() } @@ -79,25 +94,55 @@ update_scene :: proc(scene: ^Scene, dt: f32) { update_player(&scene.player, dt) scene.camera.target = scene.player.position - // Сначала двигаем всех врагов к игроку — без страха и упрёка - for &enemy in scene.enemies[:scene.enemy_count] { - dir := rl.Vector2Normalize(scene.player.position - enemy.position) - enemy.position += dir * enemy.speed * dt + it := hm.iterator_make(&scene.enemies) + for i, _ in hm.iterate(&it) { + dir := rl.Vector2Normalize(scene.player.position - i.position) + i.position += dir * i.speed * dt } - // Потом разлепляем коллизии — выталкиваем кто кого переехал resolve_collisions(scene) } +Row :: distinct [16]i32 + main :: proc() { fmt.println("Hello, world!") - scene := create_scene() rl.InitWindow(SCREEN_W, SCREEN_H, "HUI") defer rl.CloseWindow() - rl.SetTargetFPS(200) + rl.SetTargetFPS(60) + + scene := create_scene() + + map_data := [16][16]i32 { + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10}, + {16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18}, + } + for row, i in map_data { + for col, j in row { + scene.tiles[i * 16 + j] = Tile { + atlas = &scene.atlas, + pos = rl.Vector2{f32(j) * 16, f32(i) * 16}, + frame = col, + } + } + } for !rl.WindowShouldClose() { @@ -107,7 +152,6 @@ main :: proc() { { rl.ClearBackground(rl.BLACK) draw_scene(&scene) - } rl.EndDrawing() } diff --git a/map.odin b/map.odin new file mode 100644 index 0000000..bc42c0f --- /dev/null +++ b/map.odin @@ -0,0 +1,85 @@ +package main + +import "core:fmt" +import rl "vendor:raylib" + + +Atlas :: struct { + tex: rl.Texture2D, + tile_size: rl.Vector2, + cols: i32, + rows: i32, + frames: i32, +} + +TILE_MULT :: 4 + +Tile :: struct { + atlas: ^Atlas, + pos: rl.Vector2, + frame: i32, +} + +load_atlas :: proc() -> Atlas { + at: Atlas + + at.tex = rl.LoadTexture("./assets/3rdparty/tileset/Tiles/Tileset.png") + at.tile_size = rl.Vector2{16, 16} + at.rows = at.tex.height / (i32(at.tile_size.y)) + at.cols = at.tex.width / i32(at.tile_size.x) + at.frames = at.cols * at.rows + fmt.printf( + "Atlas rows: %v, Atlas cols: %v, Frames: %v\n", + at.rows, + at.cols, + at.frames, + ) + + return at +} +// +// draw_atlas :: proc(at: ^Atlas) { +// rl.DrawTexturePro( +// at^.tex, +// rl.Rectangle{0, 0, at.tile_size.x, at.tile_size.y}, +// rl.Rectangle{0, 0, 64, 64}, +// rl.Vector2{0, 0}, +// 0, +// rl.WHITE, +// ) +// } + + +draw_tile :: proc(tile: Tile) { + offset := get_offset(tile.atlas, tile.frame) + rl.DrawTexturePro( + tile.atlas^.tex, + rl.Rectangle { + offset.x, + offset.y, + tile.atlas.tile_size.x, + tile.atlas.tile_size.y, + }, + rl.Rectangle { + tile.pos.x * TILE_MULT, + tile.pos.y * TILE_MULT, + tile.atlas.tile_size.x * TILE_MULT, + tile.atlas.tile_size.y * TILE_MULT, + }, + rl.Vector2{0, 0}, + // rl.Vector2{tile.pos.x, tile.pos.y}, + 0, + rl.WHITE, + ) +} + +get_offset :: proc(atlas: ^Atlas, f: i32) -> rl.Vector2 { + + col := f % atlas.cols + row := f / atlas.cols + + return rl.Vector2 { + f32(col) * atlas.tile_size.x, + f32(row) * atlas.tile_size.y, + } +}