Map Render

This commit is contained in:
2026-08-06 15:25:34 +03:00
parent c2eb4a7b24
commit dee1d4cc0f
8 changed files with 172 additions and 58 deletions
+1
View File
@@ -4,6 +4,7 @@ require("custom.runner").setup({
-- test = { cmd = "go test ./..." }, -- test = { cmd = "go test ./..." },
-- build = { cmd = "odin build ./src/" }, -- build = { cmd = "odin build ./src/" },
-- lint = { cmd = "go vet ./..." }, -- lint = { cmd = "go vet ./..." },
build = { cmd = "odin build . -debug" },
}, },
focus = false, -- фокус на нижний терминал при запуске focus = false, -- фокус на нижний терминал при запуске
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

+9 -25
View File
@@ -24,19 +24,6 @@ Enemy :: struct {
handle: ent_handle, 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) { update_player :: proc(player: ^Player, dt: f32) {
input: rl.Vector2 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) { resolve_entity_overlap :: proc(a, b: ^Entity) {
ra := calc_col_box(a.position, a.col) ra := calc_col_box(a.position, a.col)
rb := calc_col_box(b.position, b.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) { resolve_collisions :: proc(scene: ^Scene) {
// Враг против врага — чтоб толпой не слипались it := hm.iterator_make(&scene.enemies)
for i in 0 ..< scene.enemy_count { for i, _ in hm.iterate(&it) {
for j in i + 1 ..< scene.enemy_count { it2 := hm.iterator_make(&scene.enemies)
resolve_entity_overlap( for j, _ in hm.iterate(&it2) {
&scene.enemies[i].ent, if i == j do continue
&scene.enemies[j].ent, resolve_entity_overlap(i, j)
)
} }
} }
// Игрок против врагов — чтоб не захавывали друг друга it = hm.iterator_make(&scene.enemies)
for &enemy in scene.enemies[:scene.enemy_count] { for i, _ in hm.iterate(&it) {
resolve_entity_overlap(&scene.player.ent, &enemy.ent) resolve_entity_overlap(&scene.player.ent, i)
} }
} }
BIN
View File
Binary file not shown.
+77 -33
View File
@@ -9,11 +9,14 @@ SCREEN_H :: 720
MAX_ENEMIES :: 10 MAX_ENEMIES :: 10
MAX_TILES :: 4096
Scene :: struct { Scene :: struct {
player: Player, player: Player,
camera: rl.Camera2D, camera: rl.Camera2D,
enemies: hm.Static_Handle_Map(128, Enemy, ent_handle), 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}, offset = rl.Vector2{SCREEN_W / 2, SCREEN_H / 2},
}, },
} }
_ = hm.add( // _ = hm.add(
&scene.enemies, // &scene.enemies,
Enemy { // Enemy {
position = rl.Vector2{500, 500}, // position = rl.Vector2{500, 500},
hp = 100, // hp = 100,
speed = 100, // speed = 100,
col = 32, // col = 32,
}, // },
) // )
_ = hm.add( // _ = hm.add(
&scene.enemies, // &scene.enemies,
Enemy { // Enemy {
position = rl.Vector2{600, 600}, // position = rl.Vector2{600, 600},
hp = 100, // hp = 100,
speed = 100, // speed = 100,
col = 32, // col = 32,
}, // },
) // )
scene.atlas = load_atlas()
// append(
// &scene.tiles,
// Tile{atlas = &scene.atlas, pos = rl.Vector2{0, 0}, frame = 3},
// )
return scene return scene
} }
draw_scene :: proc(scene: ^Scene) { draw_scene :: proc(scene: ^Scene) {
rl.BeginMode2D(scene.camera) rl.BeginMode2D(scene.camera)
for tile in scene.tiles {
if tile.atlas == nil do continue
draw_tile(tile)
}
rl.DrawCircle( rl.DrawCircle(
cast(i32)scene.player.position.x, cast(i32)scene.player.position.x,
cast(i32)scene.player.position.y, cast(i32)scene.player.position.y,
@@ -62,15 +80,12 @@ draw_scene :: proc(scene: ^Scene) {
) )
rl.DrawRectangle(300, 300, 100, 100, rl.BLUE) rl.DrawRectangle(300, 300, 100, 100, rl.BLUE)
for enemy in scene.enemies[:scene.enemy_count] { it := hm.iterator_make(&scene.enemies)
rl.DrawCircle( for i, _ in hm.iterate(&it) {
cast(i32)enemy.position.x, rl.DrawCircle(cast(i32)i.position.x, cast(i32)i.position.y, 32, rl.RED)
cast(i32)enemy.position.y,
32,
rl.RED,
)
} }
rl.EndMode2D() rl.EndMode2D()
} }
@@ -79,25 +94,55 @@ update_scene :: proc(scene: ^Scene, dt: f32) {
update_player(&scene.player, dt) update_player(&scene.player, dt)
scene.camera.target = scene.player.position scene.camera.target = scene.player.position
// Сначала двигаем всех врагов к игроку — без страха и упрёка it := hm.iterator_make(&scene.enemies)
for &enemy in scene.enemies[:scene.enemy_count] { for i, _ in hm.iterate(&it) {
dir := rl.Vector2Normalize(scene.player.position - enemy.position) dir := rl.Vector2Normalize(scene.player.position - i.position)
enemy.position += dir * enemy.speed * dt i.position += dir * i.speed * dt
} }
// Потом разлепляем коллизии — выталкиваем кто кого переехал
resolve_collisions(scene) resolve_collisions(scene)
} }
Row :: distinct [16]i32
main :: proc() { main :: proc() {
fmt.println("Hello, world!") fmt.println("Hello, world!")
scene := create_scene()
rl.InitWindow(SCREEN_W, SCREEN_H, "HUI") rl.InitWindow(SCREEN_W, SCREEN_H, "HUI")
defer rl.CloseWindow() 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() { for !rl.WindowShouldClose() {
@@ -107,7 +152,6 @@ main :: proc() {
{ {
rl.ClearBackground(rl.BLACK) rl.ClearBackground(rl.BLACK)
draw_scene(&scene) draw_scene(&scene)
} }
rl.EndDrawing() rl.EndDrawing()
} }
+85
View File
@@ -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,
}
}