package main import hm "core:container/handle_map" import rl "vendor:raylib" ent_handle :: hm.Handle32 Entity :: struct { position: rl.Vector2, hp: i32, speed: f32, col: f32, } Player :: struct { using ent: Entity, walk_speed: f32, run_speed: f32, } Enemy :: struct { using ent: Entity, 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 if rl.IsKeyDown(.W) { input.y += -1 } if rl.IsKeyDown(.D) { input.x += 1 } if rl.IsKeyDown(.S) { input.y += 1 } if rl.IsKeyDown(.A) { input.x += -1 } input = rl.Vector2Normalize(input) if rl.IsKeyDown(.LEFT_SHIFT) { player.speed = player.run_speed } else { player.speed = player.walk_speed } player.position += input * player.speed * dt } calc_col_box :: proc(center: rl.Vector2, side: f32) -> rl.Rectangle { return rl.Rectangle { x = center.x - side / 2, y = center.y - side / 2, width = side, height = side, } } // Разлепляет два ентерия — выталкивает по оси наименьшего проникновения. // Чтоб не стояли друг в друге как родные. resolve_entity_overlap :: proc(a, b: ^Entity) { ra := calc_col_box(a.position, a.col) rb := calc_col_box(b.position, b.col) if !rl.CheckCollisionRecs(ra, rb) do return overlap_x := min(ra.x + ra.width - rb.x, rb.x + rb.width - ra.x) overlap_y := min(ra.y + ra.height - rb.y, rb.y + rb.height - ra.y) if overlap_x < overlap_y { half := overlap_x / 2 if a.position.x < b.position.x { a.position.x -= half b.position.x += half } else { a.position.x += half b.position.x -= half } } else { half := overlap_y / 2 if a.position.y < b.position.y { a.position.y -= half b.position.y += half } else { a.position.y += half b.position.y -= half } } } 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, ) } } // Игрок против врагов — чтоб не захавывали друг друга for &enemy in scene.enemies[:scene.enemy_count] { resolve_entity_overlap(&scene.player.ent, &enemy.ent) } }