Skip to content

Commit

Permalink
avoid tower range dijkstra map
Browse files Browse the repository at this point in the history
  • Loading branch information
sebovzeoueb committed Apr 9, 2021
1 parent a651a21 commit 1d81372
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
4 changes: 2 additions & 2 deletions entities/Enemies/ArmoredCar.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
extents = Vector2( 14.9635, 7.38137 )

[node name="Enemy" type="Area2D"]
collision_layer = 5
collision_layer = 4
collision_mask = 0
script = ExtResource( 1 )
speed = 35.0
dijkstra = "distance_to_tower"
dijkstra = "avoid_range_go_to_base"

[node name="Sprite" type="Sprite" parent="."]
texture = ExtResource( 2 )
Expand Down
3 changes: 2 additions & 1 deletion maps/Level1.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ movement_costs = {
"grass": 2.0,
"road": 1.0
}
tower_cost = 20.0

[node name="TileMap" type="TileMap" parent="."]
tile_set = ExtResource( 5 )
Expand All @@ -38,7 +39,7 @@ tag = "base"
position = Vector2( 116, 696 )
script = ExtResource( 6 )
waves = [ {
"enemies": [ ExtResource( 3 ), ExtResource( 3 ), ExtResource( 3 ), ExtResource( 3 ), ExtResource( 3 ) ],
"enemies": [ ExtResource( 2 ), ExtResource( 2 ), ExtResource( 2 ), ExtResource( 2 ), ExtResource( 2 ) ],
"wait": 10.0
}, {
"enemies": [ ExtResource( 2 ), ExtResource( 2 ), ExtResource( 2 ), ExtResource( 2 ), ExtResource( 2 ), ExtResource( 2 ), ExtResource( 2 ) ],
Expand Down
61 changes: 57 additions & 4 deletions scripts/World.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ export (int) var width = 64
export (int) var height = 64
export (int) var starting_money = 200
export var movement_costs = {}
export (float) var tower_cost = 10
var entities = []
var tile_map
var dijkstra = {}
var graphs = {}
var entity_lookups = {}
var spawners = []
var enemies = []
const quadrants = [Vector2(1, 1), Vector2(1, -1), Vector2(-1, -1), Vector2(-1, 1)]

signal on_change

Expand Down Expand Up @@ -42,13 +44,45 @@ func _ready():
for y in range(height):
graphs['cost'][x][y] = get_cost(Vector2(x, y))

# initialiser la grille des coûts modifiée par les tours
graphs['range_cost'] = []
for x in range(width):
graphs['range_cost'].append([])
graphs['range_cost'][x].resize(height)
for y in range(height):
graphs['range_cost'][x][y] = get_cost(Vector2(x, y))

# il faut ajouter la base aux entités gérées par ce script
var base = get_node("Base")
add_entity(base, base.position)

# on veut déclencher la défaite si la base est détruite
base.connect("tree_exited", self, "_on_defeat")

func add_shooter_cost(pos, attack_range):
var tile_range = ceil(attack_range / tile_map.cell_size.x)
for x in range(tile_range):
for y in range(tile_range):
if Vector2(x, y).length() > tile_range: continue
for quadrant in quadrants:
var map_x = pos.x + x * quadrant.x
var map_y = pos.y + y * quadrant.y
if map_x < 0 || map_x >= width || map_y < 0 || map_y >= height: continue
if graphs['range_cost'][map_x][map_y] == null: continue
graphs['range_cost'][map_x][map_y] = max(graphs['range_cost'][map_x][map_y], get_cost(Vector2(map_x, map_y)) + tower_cost)

func reset_shooter_cost(pos, attack_range):
var tile_range = ceil(attack_range / tile_map.cell_size.x)
for x in range(tile_range):
for y in range(tile_range):
if Vector2(x, y).length() > tile_range: continue
for quadrant in quadrants:
var map_x = pos.x + x * quadrant.x
var map_y = pos.y + y * quadrant.y
if map_x < 0 || map_x >= width || map_y < 0 || map_y >= height: continue
if graphs['range_cost'][map_x][map_y] == null: continue
graphs['range_cost'][map_x][map_y] = get_cost(Vector2(map_x, map_y))

# ajouter une entité aux systèmes "world"
func add_entity(entity, pos):
if get_node("/root/Main").state != "playing": return
Expand All @@ -75,17 +109,23 @@ func add_entity(entity, pos):
# on les créé ici s'ils n'existent pas déjà
if tilemap_entity.tag:
if !entity_lookups.has(tilemap_entity.tag): entity_lookups[tilemap_entity.tag] = []
if !dijkstra.has('distance_to_%s' % tilemap_entity.tag): dijkstra['distance_to_%s' % tilemap_entity.tag] = DijkstraMap.new(entity_lookups[tilemap_entity.tag], graphs['cost'])
if !dijkstra.has('distance_to_%s' % tilemap_entity.tag): dijkstra['distance_to_%s' % tilemap_entity.tag] = DijkstraMap.new(entity_lookups[tilemap_entity.tag], graphs['cost'])
if !dijkstra.has('avoid_range_go_to_%s' % tilemap_entity.tag): dijkstra['avoid_range_go_to_%s' % tilemap_entity.tag] = DijkstraMap.new(entity_lookups[tilemap_entity.tag], graphs['range_cost'])
else: entity_positions.append(tile_pos)

var shooter = entity.get_node_or_null("Shooter")

for pos in entity_positions:
# on remplit la grille des entités
entities[pos.x][pos.y] = entity
# et on met à jour la grille des coûts, car on ne peut pas traverser une entité (pour le moment!)
graphs['cost'][pos.x][pos.y] = null
for graph in graphs:
graphs[graph][pos.x][pos.y] = null
# on l'ajoute aussi à la liste de son tag
if tilemap_entity && tilemap_entity.tag:
entity_lookups[tilemap_entity.tag].append(pos)
entity_lookups[tilemap_entity.tag].append(pos)
if shooter:
add_shooter_cost(pos, shooter.attack_range)

# on doit recalculer tous le graphes car il y a de nouveaux obstacles à contourner
for map in dijkstra:
Expand Down Expand Up @@ -116,14 +156,27 @@ func remove_entity(entity):
entity_positions.append(Vector2(tile_pos.x + x, tile_pos.y + y))
else: entity_positions.append(tile_pos)

var shooter = entity.get_node_or_null("Shooter")
for pos in entity_positions:
# enlever de la grille des entités
entities[pos.x][pos.y] = null
# rétablir le coût maintenant qu'on peut traverser la case
graphs['cost'][pos.x][pos.y] = get_cost(pos)
for graph in graphs:
graphs[graph][pos.x][pos.y] = get_cost(pos)
# enlever de la liste par tag
if tilemap_entity && tilemap_entity.tag && entity_lookups[tilemap_entity.tag]:
entity_lookups[tilemap_entity.tag].erase(pos)
if shooter:
reset_shooter_cost(pos, shooter.attack_range)

if shooter && entity_lookups['tower']:
for tower_pos in entity_lookups['tower']:
var tower = entities[tower_pos.x][tower_pos.y]
var tower_shooter = tower.get_node_or_null("Shooter")
if !tower_shooter: continue
for x in range(tower.width):
for y in range(tower.height):
add_shooter_cost(Vector2(tower_pos.x + x, tower_pos.y + y), tower_shooter.attack_range)

# on doit recalculer tous les graphes Dijkstra car de nouveaux chemins pourraient être ouverts
for map in dijkstra:
Expand Down

0 comments on commit 1d81372

Please sign in to comment.