Small tweaks and cleanup to flow field.
This commit is contained in:
+52
-3
@@ -185,7 +185,6 @@ check_map_collision :: proc(rect: rl.Rectangle, game_map: Game_Map) -> bool {
|
||||
|
||||
// true when collision found
|
||||
check_enemy_collision :: proc(rect_a: rl.Rectangle, active_enemies: int, enemies: ^[MAX_ENEMIES]Enemy) -> bool {
|
||||
|
||||
for idx in 0..<active_enemies {
|
||||
e := enemies[idx]
|
||||
enemy_rect := get_enemy_collider(e, e.position)
|
||||
@@ -222,6 +221,9 @@ draw_map :: proc(current_map: Game_Map) {
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// FLOW FIELD IMPL
|
||||
// ----------------------------------------------------------
|
||||
reset_cost_array :: proc(cost_arr: ^[400]int) {
|
||||
for val, idx in cost_arr {
|
||||
cost_arr[idx] = -1
|
||||
@@ -253,6 +255,25 @@ compute_flow_field :: proc(game_map: ^Game_Map, player_pos: rl.Vector2) {
|
||||
|
||||
nx := current.x + loop_x
|
||||
ny := current.y + loop_y
|
||||
|
||||
// diagonal — check flanking orthogonal tiles before allowing expansion
|
||||
if loop_x != 0 && loop_y != 0 {
|
||||
flank_a := Grid_Pos{current.x + loop_x, current.y}
|
||||
flank_b := Grid_Pos{current.x, current.y + loop_y}
|
||||
|
||||
// @TODO VISUALIZE + UNDERSTAND THIS CONCEPTUALLY
|
||||
if flank_a.x >= 0 && flank_a.x < game_map.width && flank_a.y >= 0 && flank_a.y < game_map.height &&
|
||||
flank_b.x >= 0 && flank_b.x < game_map.width && flank_b.y >= 0 && flank_b.y < game_map.height {
|
||||
flank_a_idx := grid_to_index(flank_a.x, flank_a.y, game_map.width)
|
||||
flank_b_idx := grid_to_index(flank_b.x, flank_b.y, game_map.width)
|
||||
flank_a_tile := Tile_Type(game_map.data[flank_a_idx])
|
||||
flank_b_tile := Tile_Type(game_map.data[flank_b_idx])
|
||||
if tile_defs[flank_a_tile].solid || tile_defs[flank_b_tile].solid {
|
||||
continue // corner-cutting diagonal, don't expand BFS through it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get_neighbor_cost({nx, ny}, &flow_field_queue, game_map, current_cost)
|
||||
}
|
||||
}
|
||||
@@ -277,10 +298,11 @@ get_neighbor_cost :: proc(grid_pos: Grid_Pos, queue: ^[dynamic]Grid_Pos, game_ma
|
||||
compute_flow_directions :: proc(game_map: ^Game_Map) {
|
||||
// walk every tile, look at neighbor costs in cost_field,
|
||||
// write a direction vector into direction_field[index]
|
||||
for value, index in game_map.data {
|
||||
for _, index in game_map.data {
|
||||
row := index / game_map.width
|
||||
column := index % game_map.width
|
||||
current_index := grid_to_index(column, row, game_map.width)
|
||||
// current_index := grid_to_index(column, row, game_map.width)
|
||||
current_index := index
|
||||
|
||||
// skip unreachable tiles
|
||||
if game_map.cost_field[current_index] == -1 do continue
|
||||
@@ -306,6 +328,33 @@ compute_flow_directions :: proc(game_map: ^Game_Map) {
|
||||
cost_index := grid_to_index(ncolumn, nrow, game_map.width)
|
||||
neighbor_cost := game_map.cost_field[cost_index]
|
||||
|
||||
// we have the lowest neighbor at this point.
|
||||
// Check if its diagonal first
|
||||
// compare the neighbor to the current tile to check the diff, it will tell if diagonal
|
||||
// Diagonal moves cut through a "corner" formed by two orthogonal tiles.
|
||||
// Before allowing one, check both flank tiles (the up/down one + the left/right one).
|
||||
// If either is solid, the diagonal is blocked — even if the target tile itself is open.
|
||||
if ncolumn - column != 0 && nrow - row != 0 {
|
||||
// no axis is 0 so we have an angle
|
||||
// diagonal — check the two flanking orthogonal neighbors
|
||||
flank_a_col := column + (ncolumn - column) // same x-offset, y unchanged
|
||||
flank_a_row := row
|
||||
flank_b_col := column
|
||||
flank_b_row := row + (nrow - row) // same y-offset, x unchanged
|
||||
|
||||
flank_a_idx := grid_to_index(flank_a_col, flank_a_row, game_map.width)
|
||||
flank_b_idx := grid_to_index(flank_b_col, flank_b_row, game_map.width)
|
||||
|
||||
flank_a_tile := Tile_Type(game_map.data[flank_a_idx])
|
||||
flank_b_tile := Tile_Type(game_map.data[flank_b_idx])
|
||||
|
||||
if tile_defs[flank_a_tile].solid || tile_defs[flank_b_tile].solid {
|
||||
// corner-cutting diagonal, disqualify — skip to next neighbor in the loop
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if neighbor_cost != -1 && neighbor_cost < lowest_cost {
|
||||
lowest_cost = neighbor_cost
|
||||
b = rl.Vector2{f32(ncolumn), f32(nrow)}
|
||||
|
||||
Reference in New Issue
Block a user