Skip to content

Commit 2872148

Browse files
committed
Add Navigation AStar Hexagonal demo
AStar hexagonal pathfinding Format corrections with A Thousand Ships <[email protected]> review Corrections format with external linter ```yml default_install_hook_types: [pre-commit] repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: - id: check-added-large-files - id: check-case-conflict - id: check-merge-conflict - id: end-of-file-fixer - id: trailing-whitespace - id: check-json - id: check-symlinks - repo: https://github.com/Scony/godot-gdscript-toolkit rev: 4.2.2 hooks: - id: gdlint exclude: .*screenshots/ - id: gdformat exclude: .*screenshots/ ```
1 parent 7d42ae3 commit 2872148

19 files changed

+783
-0
lines changed
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Tile-based navigation on hexagonal Tilemap (2D)
2+
3+
Example of using 2D navigation (tile based) on a hexagonal map, using :
4+
- [`TileMap`](https://docs.godotengine.org/en/stable/classes/class_tilemap.html)
5+
- [`AStar2D`](https://docs.godotengine.org/en/stable/classes/class_astar2d.html)
6+
7+
Language: GDScript
8+
9+
Renderer: Compatibility
10+
11+
Use mouse left click to interact.
12+
13+
## Screenshots
14+
15+
![Screenshot](screenshots/Hexagon_Navigation_2D.png)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class_name AStarHex2D
2+
extends AStar2D
3+
4+
var map: TileMap
5+
6+
7+
# Final cost used for pathfinding would be weight * cost.
8+
# See https://docs.godotengine.org/fr/4.x/classes/class_astar3d.html#class-astar3d
9+
func _compute_cost(_from_id: int, _to_id: int):
10+
return 1
11+
12+
13+
func _estimate_cost(_from_id: int, _to_id: int):
14+
return 1
15+
16+
# Euclidian distance heuristic would not work on hexagonal map with global position because
17+
# we are not using regular hexagon.
18+
# https://github.com/godotengine/godot/issues/92338
19+
20+
#func _compute_cost( from_id:int, to_id:int ):
21+
#var position_from = get_point_position(from_id)
22+
#var position_to = get_point_position(to_id)
23+
#return (position_to - position_from).length_squared()
24+
25+
#func _estimate_cost( from_id:int, to_id:int ):
26+
#var position_from = get_point_position(from_id)
27+
#var position_to = get_point_position(to_id)
28+
#return (position_to - position_from).length_squared()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
extends Node2D
2+
3+
const BASE_LINE_WIDTH = 3.0
4+
const DRAW_COLOR: Color = Color.WHITE
5+
const OFFSET_POSITIONS = Vector2(10, 30)
6+
const OFFSET_WEIGHT = Vector2(10, -10)
7+
8+
@export var map: Map
9+
10+
var _debug_connections = false
11+
var _debug_position = false
12+
var _debug_weights = false
13+
var _debug_costs = false
14+
var _debug_path = true
15+
16+
@onready var _font: Font = ThemeDB.fallback_font
17+
18+
19+
func _process(_delta):
20+
queue_redraw()
21+
22+
23+
func draw_arrow(src, dst, color, width, aa = true):
24+
var angle = 0.6
25+
var size_head = 20
26+
var head: Vector2 = (dst - src).normalized() * size_head
27+
draw_line(src, dst - head / 2, color, width, aa)
28+
draw_polygon(
29+
[dst, dst - head.rotated(angle), dst - head.rotated(-angle)], [color, color, color]
30+
)
31+
32+
33+
func _draw():
34+
if _debug_connections:
35+
_draw_connections()
36+
if _debug_position:
37+
_draw_positions()
38+
if _debug_weights:
39+
_draw_weights()
40+
if _debug_costs:
41+
_draw_costs()
42+
if _debug_path:
43+
_draw_path()
44+
45+
46+
func _draw_path():
47+
if not map._point_path:
48+
return
49+
var point_start: Vector2i = map._point_path[0]
50+
var point_end: Vector2i = map._point_path[len(map._point_path) - 1]
51+
52+
var last_point = point_start
53+
for index in range(1, len(map._point_path)):
54+
var current_point = map._point_path[index]
55+
draw_line(last_point, current_point, DRAW_COLOR, BASE_LINE_WIDTH, true)
56+
draw_circle(current_point, BASE_LINE_WIDTH * 2.0, DRAW_COLOR)
57+
last_point = current_point
58+
59+
60+
func _draw_weights():
61+
for id in map.astar_node.get_point_ids():
62+
var position_weight = map.astar_node.get_point_position(id)
63+
var cost = map.astar_node.get_point_weight_scale(id)
64+
draw_string(
65+
_font,
66+
position_weight + OFFSET_WEIGHT,
67+
str(cost),
68+
HORIZONTAL_ALIGNMENT_FILL,
69+
-1,
70+
16,
71+
Color.RED
72+
)
73+
74+
75+
func _draw_positions():
76+
for id in map.astar_node.get_point_ids():
77+
var position_label = map.astar_node.get_point_position(id)
78+
var position_map = map.local_to_map(map.to_local(map.astar_node.get_point_position(id)))
79+
draw_string(
80+
_font,
81+
position_label + OFFSET_POSITIONS,
82+
str(position_map),
83+
HORIZONTAL_ALIGNMENT_FILL,
84+
-1,
85+
16,
86+
Color.RED
87+
)
88+
89+
90+
func _draw_connections():
91+
for id in map.astar_node.get_point_ids():
92+
for id_con in map.astar_node.get_point_connections(id):
93+
var position_start = map.astar_node.get_point_position(id)
94+
var position_end = map.astar_node.get_point_position(id_con)
95+
var direction = position_end - position_start
96+
draw_arrow(
97+
position_start,
98+
position_end - direction / 4.0,
99+
Color(0.0, 1.0, 1.0, 1.0),
100+
BASE_LINE_WIDTH * 2,
101+
true
102+
)
103+
104+
105+
func _draw_costs():
106+
for id in map.astar_node.get_point_ids():
107+
for id_con in map.astar_node.get_point_connections(id):
108+
var position_cost_start = map.astar_node.get_point_position(id)
109+
var position_cost_end = map.astar_node.get_point_position(id_con)
110+
var cost = map.astar_node._compute_cost(id, id_con)
111+
draw_string(
112+
_font,
113+
(position_cost_start + position_cost_end) / 2.0,
114+
str("%.2f" % cost),
115+
HORIZONTAL_ALIGNMENT_CENTER,
116+
-1,
117+
16,
118+
Color.PINK
119+
)
120+
121+
122+
func _on_d_path_toggled(toggled_on):
123+
_debug_path = toggled_on
124+
125+
126+
func _on_d_costs_toggled(toggled_on):
127+
_debug_costs = toggled_on
128+
129+
130+
func _on_d_positions_toggled(toggled_on):
131+
_debug_position = toggled_on
132+
133+
134+
func _on_d_connections_toggled(toggled_on):
135+
_debug_connections = toggled_on
136+
137+
138+
func _on_d_weights_toggled(toggled_on):
139+
_debug_weights = toggled_on
+121
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
[remap]
2+
3+
importer="texture"
4+
type="CompressedTexture2D"
5+
uid="uid://brh8t0d5w2mkc"
6+
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7+
metadata={
8+
"vram_texture": false
9+
}
10+
11+
[deps]
12+
13+
source_file="res://icon.svg"
14+
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15+
16+
[params]
17+
18+
compress/mode=0
19+
compress/high_quality=false
20+
compress/lossy_quality=0.7
21+
compress/hdr_compression=1
22+
compress/normal_map=0
23+
compress/channel_pack=0
24+
mipmaps/generate=false
25+
mipmaps/limit=-1
26+
roughness/mode=0
27+
roughness/src_normal=""
28+
process/fix_alpha_border=true
29+
process/premult_alpha=false
30+
process/normal_map_invert_y=false
31+
process/hdr_as_srgb=false
32+
process/hdr_clamp_exposure=false
33+
process/size_limit=0
34+
detect_3d/compress_to=1
35+
svg/scale=1.0
36+
editor/scale_with_editor_scale=false
37+
editor/convert_colors_with_editor_theme=false
5.76 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[remap]
2+
3+
importer="texture"
4+
type="CompressedTexture2D"
5+
uid="uid://bnujvgksdtkex"
6+
path="res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex"
7+
metadata={
8+
"vram_texture": false
9+
}
10+
11+
[deps]
12+
13+
source_file="res://icon.webp"
14+
dest_files=["res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex"]
15+
16+
[params]
17+
18+
compress/mode=0
19+
compress/high_quality=false
20+
compress/lossy_quality=0.7
21+
compress/hdr_compression=1
22+
compress/normal_map=0
23+
compress/channel_pack=0
24+
mipmaps/generate=false
25+
mipmaps/limit=-1
26+
roughness/mode=0
27+
roughness/src_normal=""
28+
process/fix_alpha_border=true
29+
process/premult_alpha=false
30+
process/normal_map_invert_y=false
31+
process/hdr_as_srgb=false
32+
process/hdr_clamp_exposure=false
33+
process/size_limit=0
34+
detect_3d/compress_to=1

0 commit comments

Comments
 (0)