refactort the code, started adding unit hoover function
This commit is contained in:
parent
11acfcd892
commit
ec82ede20a
Binary file not shown.
BIN
assets/sprites/ui/ui_icons_blue_down4.png
Normal file
BIN
assets/sprites/ui/ui_icons_blue_down4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 194 B |
34
assets/sprites/ui/ui_icons_blue_down4.png.import
Normal file
34
assets/sprites/ui/ui_icons_blue_down4.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dodxrvydq6fha"
|
||||||
|
path="res://.godot/imported/ui_icons_blue_down4.png-e76857af9f0775a76b1aec4c9ba310f4.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/ui/ui_icons_blue_down4.png"
|
||||||
|
dest_files=["res://.godot/imported/ui_icons_blue_down4.png-e76857af9f0775a76b1aec4c9ba310f4.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
assets/sprites/ui/ui_icons_green_down4.png
Normal file
BIN
assets/sprites/ui/ui_icons_green_down4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 194 B |
34
assets/sprites/ui/ui_icons_green_down4.png.import
Normal file
34
assets/sprites/ui/ui_icons_green_down4.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://m5quwcs7xg70"
|
||||||
|
path="res://.godot/imported/ui_icons_green_down4.png-a9d4d3bbe5c92c27f99f5653a324edc1.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/ui/ui_icons_green_down4.png"
|
||||||
|
dest_files=["res://.godot/imported/ui_icons_green_down4.png-a9d4d3bbe5c92c27f99f5653a324edc1.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
assets/sprites/ui/ui_icons_pink_down4.png
Normal file
BIN
assets/sprites/ui/ui_icons_pink_down4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 190 B |
34
assets/sprites/ui/ui_icons_pink_down4.png.import
Normal file
34
assets/sprites/ui/ui_icons_pink_down4.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dvyayp3ndlnun"
|
||||||
|
path="res://.godot/imported/ui_icons_pink_down4.png-7ec59997376ec15e63c5d7df7180e71c.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/ui/ui_icons_pink_down4.png"
|
||||||
|
dest_files=["res://.godot/imported/ui_icons_pink_down4.png-7ec59997376ec15e63c5d7df7180e71c.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
assets/sprites/ui/ui_icons_red_down4.png
Normal file
BIN
assets/sprites/ui/ui_icons_red_down4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 185 B |
34
assets/sprites/ui/ui_icons_red_down4.png.import
Normal file
34
assets/sprites/ui/ui_icons_red_down4.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://mgbhev7rsjr7"
|
||||||
|
path="res://.godot/imported/ui_icons_red_down4.png-91b331abca07894909691d67a64bb00e.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/ui/ui_icons_red_down4.png"
|
||||||
|
dest_files=["res://.godot/imported/ui_icons_red_down4.png-91b331abca07894909691d67a64bb00e.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
assets/sprites/ui/ui_icons_rgb_down4.png
Normal file
BIN
assets/sprites/ui/ui_icons_rgb_down4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 209 B |
34
assets/sprites/ui/ui_icons_rgb_down4.png.import
Normal file
34
assets/sprites/ui/ui_icons_rgb_down4.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://vjb3lohfxdje"
|
||||||
|
path="res://.godot/imported/ui_icons_rgb_down4.png-085e05397cee56389f7a7d3fb9214d1e.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/ui/ui_icons_rgb_down4.png"
|
||||||
|
dest_files=["res://.godot/imported/ui_icons_rgb_down4.png-085e05397cee56389f7a7d3fb9214d1e.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
12
debug_size_sprites.tscn
Normal file
12
debug_size_sprites.tscn
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://cfo1w6okjjqdx"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://d1jhpluu86cbd" path="res://scenes/player.tscn" id="1_c73ov"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dodxrvydq6fha" path="res://assets/sprites/ui/ui_icons_blue_down4.png" id="2_m0f23"]
|
||||||
|
|
||||||
|
[node name="Node2D" type="Node2D"]
|
||||||
|
|
||||||
|
[node name="Player" parent="." instance=ExtResource("1_c73ov")]
|
||||||
|
|
||||||
|
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||||
|
position = Vector2(0, -17)
|
||||||
|
texture = ExtResource("2_m0f23")
|
||||||
@ -15,6 +15,10 @@ run/main_scene="uid://gl6lc08v514x"
|
|||||||
config/features=PackedStringArray("4.4", "Forward Plus")
|
config/features=PackedStringArray("4.4", "Forward Plus")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
|
[autoload]
|
||||||
|
|
||||||
|
IsometricMapSystem="*res://scripts/isometric_map_system.gd"
|
||||||
|
|
||||||
[editor]
|
[editor]
|
||||||
|
|
||||||
version_control/plugin_name="GitPlugin"
|
version_control/plugin_name="GitPlugin"
|
||||||
|
|||||||
146
scenes/isometric_map_layer_holder.tscn12214503970.tmp
Normal file
146
scenes/isometric_map_layer_holder.tscn12214503970.tmp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
[gd_scene load_steps=7 format=3 uid="uid://dg0qxdwe2rlcn"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://dxcfy8xypdde6" path="res://scripts/isometric_map_layer_holder.gd" id="1_4o54u"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://p8iyle6kr3nf" path="res://assets/sprites/tiles/iso_tileset.png" id="1_fme3d"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bsox4y2fftlh8" path="res://assets/sprites/tiles/iso_tileset_with_select.png" id="3_s16iq"]
|
||||||
|
|
||||||
|
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_4o54u"]
|
||||||
|
texture = ExtResource("1_fme3d")
|
||||||
|
texture_region_size = Vector2i(32, 32)
|
||||||
|
0:0/0 = 0
|
||||||
|
0:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
1:0/0 = 0
|
||||||
|
1:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
2:0/0 = 0
|
||||||
|
2:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
3:0/0 = 0
|
||||||
|
3:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
4:0/0 = 0
|
||||||
|
4:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
5:0/0 = 0
|
||||||
|
5:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
6:0/0 = 0
|
||||||
|
6:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
|
||||||
|
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_wvhlo"]
|
||||||
|
texture = ExtResource("3_s16iq")
|
||||||
|
texture_region_size = Vector2i(32, 32)
|
||||||
|
0:0/0 = 0
|
||||||
|
0:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
1:0/0 = 0
|
||||||
|
1:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
2:0/0 = 0
|
||||||
|
2:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
3:0/0 = 0
|
||||||
|
3:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
4:0/0 = 0
|
||||||
|
4:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
5:0/0 = 0
|
||||||
|
5:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
6:0/0 = 0
|
||||||
|
6:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
7:0/0 = 0
|
||||||
|
7:0/0/texture_origin = Vector2i(0, -8)
|
||||||
|
0:1/0 = 0
|
||||||
|
0:1/0/texture_origin = Vector2i(0, -8)
|
||||||
|
1:1/0 = 0
|
||||||
|
1:1/0/texture_origin = Vector2i(0, -8)
|
||||||
|
2:1/0 = 0
|
||||||
|
2:1/0/texture_origin = Vector2i(0, -8)
|
||||||
|
3:1/0 = 0
|
||||||
|
3:1/0/texture_origin = Vector2i(0, -8)
|
||||||
|
4:1/0 = 0
|
||||||
|
4:1/0/texture_origin = Vector2i(0, -8)
|
||||||
|
5:1/0 = 0
|
||||||
|
5:1/0/texture_origin = Vector2i(0, -8)
|
||||||
|
6:1/0 = 0
|
||||||
|
6:1/0/texture_origin = Vector2i(0, -8)
|
||||||
|
|
||||||
|
[sub_resource type="TileSet" id="TileSet_s16iq"]
|
||||||
|
tile_shape = 1
|
||||||
|
tile_layout = 5
|
||||||
|
tile_offset_axis = 1
|
||||||
|
tile_size = Vector2i(32, 16)
|
||||||
|
sources/0 = SubResource("TileSetAtlasSource_4o54u")
|
||||||
|
sources/1 = SubResource("TileSetAtlasSource_wvhlo")
|
||||||
|
|
||||||
|
[node name="IsometricMapLayerHolder" type="Node2D"]
|
||||||
|
script = ExtResource("1_4o54u")
|
||||||
|
|
||||||
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
zoom = Vector2(0.5, 0.5)
|
||||||
|
|
||||||
|
[node name="TileMapLayer" type="TileMapLayer" parent="."]
|
||||||
|
tile_set = SubResource("TileSet_s16iq")
|
||||||
|
|
||||||
|
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||||
|
|
||||||
|
[node name="ResetButton" type="Button" parent="CanvasLayer"]
|
||||||
|
anchors_preset = 7
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -25.5
|
||||||
|
offset_top = -31.0
|
||||||
|
offset_right = 25.5
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 0
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Reset"
|
||||||
|
|
||||||
|
[node name="RotationVBoxContainer" type="VBoxContainer" parent="CanvasLayer"]
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 40.0
|
||||||
|
|
||||||
|
[node name="Z_CW" type="Button" parent="CanvasLayer/RotationVBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Rotate CW Z-Axis"
|
||||||
|
|
||||||
|
[node name="Z_CCW" type="Button" parent="CanvasLayer/RotationVBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Rotate CCW Z-Axis"
|
||||||
|
|
||||||
|
[node name="X_CW" type="Button" parent="CanvasLayer/RotationVBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Rotate CW X-Axis"
|
||||||
|
|
||||||
|
[node name="X_CCW" type="Button" parent="CanvasLayer/RotationVBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Rotate CCW X-Axis"
|
||||||
|
|
||||||
|
[node name="Y_CW" type="Button" parent="CanvasLayer/RotationVBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Rotate CW Y-Axis"
|
||||||
|
|
||||||
|
[node name="Y_CCW" type="Button" parent="CanvasLayer/RotationVBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Rotate CCW Y-Axis"
|
||||||
|
|
||||||
|
[node name="DebugPlayerStuff" type="VBoxContainer" parent="CanvasLayer"]
|
||||||
|
anchors_preset = 5
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
offset_left = -37.5
|
||||||
|
offset_right = 37.5
|
||||||
|
offset_bottom = 70.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
|
||||||
|
[node name="PlayerZLayerChangeUp" type="Button" parent="CanvasLayer/DebugPlayerStuff"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Z-layer +"
|
||||||
|
|
||||||
|
[node name="PlayerZLayerChangeDown" type="Button" parent="CanvasLayer/DebugPlayerStuff"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Z-layer -"
|
||||||
|
|
||||||
|
[connection signal="pressed" from="CanvasLayer/ResetButton" to="." method="_on_reset_button_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/RotationVBoxContainer/Z_CW" to="." method="_on_cw_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/RotationVBoxContainer/Z_CCW" to="." method="_on_ccw_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/RotationVBoxContainer/X_CW" to="." method="_on_x_cw_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/RotationVBoxContainer/X_CCW" to="." method="_on_x_ccw_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/RotationVBoxContainer/Y_CW" to="." method="_on_y_cw_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/RotationVBoxContainer/Y_CCW" to="." method="_on_y_ccw_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/DebugPlayerStuff/PlayerZLayerChangeUp" to="." method="_on_player_z_layer_change_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/DebugPlayerStuff/PlayerZLayerChangeDown" to="." method="_on_player_z_layer_change_down_pressed"]
|
||||||
@ -7,7 +7,3 @@
|
|||||||
[node name="Camera2D" type="Camera2D" parent="."]
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
|
||||||
[node name="MainMenu" parent="." instance=ExtResource("1_o5qli")]
|
[node name="MainMenu" parent="." instance=ExtResource("1_o5qli")]
|
||||||
|
|
||||||
[node name="GameManager" type="Node" parent="."]
|
|
||||||
|
|
||||||
[node name="TurnManager" type="Node" parent="."]
|
|
||||||
|
|||||||
@ -111,7 +111,7 @@ animations = [{
|
|||||||
}]
|
}]
|
||||||
|
|
||||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_v6fml"]
|
[sub_resource type="RectangleShape2D" id="RectangleShape2D_v6fml"]
|
||||||
size = Vector2(36, 51)
|
size = Vector2(20, 25)
|
||||||
|
|
||||||
[node name="Player" type="CharacterBody2D"]
|
[node name="Player" type="CharacterBody2D"]
|
||||||
script = ExtResource("1_g2els")
|
script = ExtResource("1_g2els")
|
||||||
@ -123,5 +123,7 @@ animation = &"down"
|
|||||||
frame_progress = 0.830149
|
frame_progress = 0.830149
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
position = Vector2(0, 4.5)
|
position = Vector2(0, 2.5)
|
||||||
shape = SubResource("RectangleShape2D_v6fml")
|
shape = SubResource("RectangleShape2D_v6fml")
|
||||||
|
|
||||||
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
|||||||
129
scenes/player.tscn12712364768.tmp
Normal file
129
scenes/player.tscn12712364768.tmp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
[gd_scene load_steps=17 format=3 uid="uid://d1jhpluu86cbd"]
|
||||||
|
|
||||||
|
[ext_resource type="Texture2D" uid="uid://d3tfo61gemayy" path="res://assets/sprites/units/$Cat_Female (2).png" id="1_3vyb7"]
|
||||||
|
[ext_resource type="Script" uid="uid://jfojoaymauh2" path="res://scripts/player.gd" id="1_g2els"]
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_3li8b"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(0, 0, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_mdl7e"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(48, 0, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_qu4a1"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(96, 0, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_70d11"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(0, 60, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_cw2d6"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(48, 60, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_khinc"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(96, 60, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_bruh7"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(0, 120, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_6eyey"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(48, 120, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_d3wef"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(96, 120, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_o4126"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(0, 180, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_lkdrv"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(48, 180, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_p7iby"]
|
||||||
|
atlas = ExtResource("1_3vyb7")
|
||||||
|
region = Rect2(96, 180, 48, 60)
|
||||||
|
|
||||||
|
[sub_resource type="SpriteFrames" id="SpriteFrames_0rnld"]
|
||||||
|
animations = [{
|
||||||
|
"frames": [{
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_3li8b")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_mdl7e")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_qu4a1")
|
||||||
|
}],
|
||||||
|
"loop": true,
|
||||||
|
"name": &"down",
|
||||||
|
"speed": 5.0
|
||||||
|
}, {
|
||||||
|
"frames": [{
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_70d11")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_cw2d6")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_khinc")
|
||||||
|
}],
|
||||||
|
"loop": true,
|
||||||
|
"name": &"left",
|
||||||
|
"speed": 5.0
|
||||||
|
}, {
|
||||||
|
"frames": [{
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_bruh7")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_6eyey")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_d3wef")
|
||||||
|
}],
|
||||||
|
"loop": true,
|
||||||
|
"name": &"right",
|
||||||
|
"speed": 5.0
|
||||||
|
}, {
|
||||||
|
"frames": [{
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_o4126")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_lkdrv")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": SubResource("AtlasTexture_p7iby")
|
||||||
|
}],
|
||||||
|
"loop": true,
|
||||||
|
"name": &"up",
|
||||||
|
"speed": 5.0
|
||||||
|
}]
|
||||||
|
|
||||||
|
[sub_resource type="RectangleShape2D" id="RectangleShape2D_v6fml"]
|
||||||
|
size = Vector2(20, 25)
|
||||||
|
|
||||||
|
[node name="Player" type="CharacterBody2D"]
|
||||||
|
script = ExtResource("1_g2els")
|
||||||
|
|
||||||
|
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
|
||||||
|
scale = Vector2(0.5, 0.5)
|
||||||
|
sprite_frames = SubResource("SpriteFrames_0rnld")
|
||||||
|
animation = &"down"
|
||||||
|
frame_progress = 0.830149
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
|
position = Vector2(0, 2.5)
|
||||||
|
shape = SubResource("RectangleShape2D_v6fml")
|
||||||
|
|
||||||
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
@ -1,10 +1,13 @@
|
|||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
# Initialize the systems that should be available globally
|
||||||
|
if not Engine.has_singleton("IsometricMapSystem"):
|
||||||
|
Engine.register_singleton("IsometricMapSystem", load("res://scripts/isometric_map_system.gd").new())
|
||||||
|
|
||||||
var map = $IsometricMapLayerHolder
|
var map = $IsometricMapLayerHolder
|
||||||
var player = $Player
|
var player = $Player
|
||||||
|
|
||||||
|
# Setup map and player
|
||||||
map.set_player(player)
|
map.set_player(player)
|
||||||
map.init_player()
|
map.init_player()
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
|
||||||
pass
|
|
||||||
|
|||||||
46
scripts/isometric_camera_controller.gd
Normal file
46
scripts/isometric_camera_controller.gd
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
extends Node
|
||||||
|
class_name IsometricCameraController
|
||||||
|
|
||||||
|
var camera : Camera2D
|
||||||
|
var initial_position : Vector2
|
||||||
|
var initial_zoom : Vector2
|
||||||
|
|
||||||
|
var drag_start = Vector2()
|
||||||
|
var drag_active = false
|
||||||
|
var zoom_min = 0.1
|
||||||
|
var zoom_max = 4.0
|
||||||
|
var zoom_speed = 0.1
|
||||||
|
|
||||||
|
func _init(camera_node):
|
||||||
|
camera = camera_node
|
||||||
|
initial_position = camera.position
|
||||||
|
initial_zoom = camera.zoom
|
||||||
|
|
||||||
|
func handle_input(event):
|
||||||
|
# Camera drag (pan) control
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
if event.button_index == MOUSE_BUTTON_RIGHT:
|
||||||
|
if event.pressed:
|
||||||
|
drag_start = event.position
|
||||||
|
drag_active = true
|
||||||
|
else:
|
||||||
|
drag_active = false
|
||||||
|
|
||||||
|
# Zoom control with mouse wheel
|
||||||
|
if event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
|
||||||
|
zoom_camera(-zoom_speed)
|
||||||
|
elif event.button_index == MOUSE_BUTTON_WHEEL_UP:
|
||||||
|
zoom_camera(zoom_speed)
|
||||||
|
|
||||||
|
# Handle camera movement while dragging
|
||||||
|
if event is InputEventMouseMotion and drag_active:
|
||||||
|
camera.position -= event.relative / camera.zoom
|
||||||
|
|
||||||
|
func zoom_camera(zoom_amount):
|
||||||
|
var new_zoom = camera.zoom.x + zoom_amount
|
||||||
|
new_zoom = clamp(new_zoom, zoom_min, zoom_max)
|
||||||
|
camera.zoom = Vector2(new_zoom, new_zoom)
|
||||||
|
|
||||||
|
func reset_camera():
|
||||||
|
camera.position = initial_position
|
||||||
|
camera.zoom = initial_zoom
|
||||||
1
scripts/isometric_camera_controller.gd.uid
Normal file
1
scripts/isometric_camera_controller.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://tob3fou8cqr7
|
||||||
350
scripts/isometric_map_data.gd
Normal file
350
scripts/isometric_map_data.gd
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
extends Resource
|
||||||
|
class_name IsometricMapData
|
||||||
|
|
||||||
|
var GRID_SIZE_WIDTH = 50 # play area size x
|
||||||
|
var GRID_SIZE_LENGTH = 30 # play area size y
|
||||||
|
var GRID_SIZE_HEIGHT = 30 # play area size z
|
||||||
|
var OFFSET = 0
|
||||||
|
var MAX_ARRAY_SIZE = 0
|
||||||
|
|
||||||
|
# The actual map data array
|
||||||
|
var map_data = []
|
||||||
|
|
||||||
|
func _init(width = 50, length = 30, height = 30, offset = 0):
|
||||||
|
GRID_SIZE_WIDTH = width
|
||||||
|
GRID_SIZE_LENGTH = length
|
||||||
|
GRID_SIZE_HEIGHT = height
|
||||||
|
OFFSET = offset
|
||||||
|
_set_max_array_size()
|
||||||
|
initialize_map_data()
|
||||||
|
|
||||||
|
func _set_max_array_size():
|
||||||
|
MAX_ARRAY_SIZE = 0
|
||||||
|
|
||||||
|
if MAX_ARRAY_SIZE < GRID_SIZE_WIDTH:
|
||||||
|
MAX_ARRAY_SIZE = GRID_SIZE_WIDTH
|
||||||
|
if MAX_ARRAY_SIZE < GRID_SIZE_LENGTH:
|
||||||
|
MAX_ARRAY_SIZE = GRID_SIZE_LENGTH
|
||||||
|
if MAX_ARRAY_SIZE < GRID_SIZE_HEIGHT:
|
||||||
|
MAX_ARRAY_SIZE = GRID_SIZE_HEIGHT
|
||||||
|
|
||||||
|
func initialize_map_data():
|
||||||
|
# Initialize empty map structure
|
||||||
|
map_data = []
|
||||||
|
|
||||||
|
for x in MAX_ARRAY_SIZE:
|
||||||
|
var y_array = []
|
||||||
|
for y in MAX_ARRAY_SIZE:
|
||||||
|
var z_array = []
|
||||||
|
for z in MAX_ARRAY_SIZE:
|
||||||
|
z_array.append(null)
|
||||||
|
y_array.append(z_array)
|
||||||
|
map_data.append(y_array)
|
||||||
|
|
||||||
|
# Get a tile at specific coordinates, return null if out of bounds
|
||||||
|
func get_tile(x, y, z):
|
||||||
|
if x < 0 or x >= MAX_ARRAY_SIZE or y < 0 or y >= MAX_ARRAY_SIZE or z < 0 or z >= MAX_ARRAY_SIZE:
|
||||||
|
return null
|
||||||
|
return map_data[x][y][z]
|
||||||
|
|
||||||
|
# Set a tile at specific coordinates
|
||||||
|
func set_tile(x, y, z, tile_data):
|
||||||
|
if x < 0 or x >= MAX_ARRAY_SIZE or y < 0 or y >= MAX_ARRAY_SIZE or z < 0 or z >= MAX_ARRAY_SIZE:
|
||||||
|
return
|
||||||
|
map_data[x][y][z] = tile_data
|
||||||
|
|
||||||
|
# Generate the isometric coordinates for a tile
|
||||||
|
func generate_iso_coords(x, y, z):
|
||||||
|
var coord_x = x + (-1 * z) + OFFSET
|
||||||
|
var coord_y = y + (-1 * z) - OFFSET
|
||||||
|
return Vector2i(coord_x, coord_y)
|
||||||
|
|
||||||
|
# Create a map with default configuration
|
||||||
|
func create_default_map():
|
||||||
|
# First initialize all tiles with null values
|
||||||
|
for z in GRID_SIZE_HEIGHT:
|
||||||
|
for y in GRID_SIZE_LENGTH:
|
||||||
|
for x in GRID_SIZE_WIDTH:
|
||||||
|
var iso_coords = generate_iso_coords(x, y, z)
|
||||||
|
|
||||||
|
var tile_data = IsometricMapSystem.create_tile_data(
|
||||||
|
iso_coords.x,
|
||||||
|
iso_coords.y,
|
||||||
|
z,
|
||||||
|
# Give all tiles valid default atlas positions to avoid null errors
|
||||||
|
IsometricMapSystem.BLUE_ISOMETRICTILE_ATLAS_POSITION,
|
||||||
|
IsometricMapSystem.WHITE_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
)
|
||||||
|
# By default, tiles are not visible
|
||||||
|
tile_data["visibility"] = false
|
||||||
|
map_data[x][y][z] = tile_data
|
||||||
|
|
||||||
|
# Set ground floor visible with blue tiles
|
||||||
|
for y in GRID_SIZE_LENGTH:
|
||||||
|
for x in GRID_SIZE_WIDTH:
|
||||||
|
var tile = map_data[x][y][0]
|
||||||
|
tile["atlas_base_position"] = IsometricMapSystem.BLUE_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
tile["atlas_highlight_position"] = IsometricMapSystem.WHITE_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
tile["visibility"] = true
|
||||||
|
|
||||||
|
# Add a vertical column of red tiles for demonstration
|
||||||
|
# Make sure coords are within bounds
|
||||||
|
if 5 < GRID_SIZE_WIDTH and 5 < GRID_SIZE_LENGTH:
|
||||||
|
for i in range(1, min(10, GRID_SIZE_HEIGHT)):
|
||||||
|
var tile = map_data[5][5][i]
|
||||||
|
if tile != null:
|
||||||
|
tile["atlas_base_position"] = IsometricMapSystem.RED_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
tile["atlas_highlight_position"] = IsometricMapSystem.WHITE_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
tile["visibility"] = true
|
||||||
|
IsometricMapSystem.debug_print("Created red tile at 5,5," + str(i))
|
||||||
|
#var tile = map_data[10][10][1]
|
||||||
|
#if tile != null:
|
||||||
|
# tile["atlas_base_position"] = IsometricMapSystem.BLACK_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
# tile["atlas_highlight_position"] = IsometricMapSystem.GREEN_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
# tile["visibility"] = true
|
||||||
|
# IsometricMapSystem.debug_print("Created black tile at 10,10," + str(1))
|
||||||
|
|
||||||
|
# Rotate map around X axis
|
||||||
|
func rotate_around_x_axis(rotation_steps = 1):
|
||||||
|
rotation_steps = rotation_steps % 4
|
||||||
|
|
||||||
|
if rotation_steps == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
var temp_map = []
|
||||||
|
# Initialize temp_map with same structure
|
||||||
|
for x in MAX_ARRAY_SIZE:
|
||||||
|
var y_array = []
|
||||||
|
for y in MAX_ARRAY_SIZE:
|
||||||
|
var z_array = []
|
||||||
|
for z in MAX_ARRAY_SIZE:
|
||||||
|
z_array.append(null)
|
||||||
|
y_array.append(z_array)
|
||||||
|
temp_map.append(y_array)
|
||||||
|
|
||||||
|
# Create a new map with adjusted dimensions
|
||||||
|
var new_height = int(GRID_SIZE_LENGTH) if rotation_steps % 2 == 1 else int(GRID_SIZE_HEIGHT)
|
||||||
|
var new_length = int(GRID_SIZE_HEIGHT) if rotation_steps % 2 == 1 else int(GRID_SIZE_LENGTH)
|
||||||
|
|
||||||
|
# Store the original dimensions
|
||||||
|
var original_height = GRID_SIZE_HEIGHT
|
||||||
|
var original_length = GRID_SIZE_LENGTH
|
||||||
|
|
||||||
|
# Temporarily adjust grid dimensions for coordinate calculation
|
||||||
|
GRID_SIZE_HEIGHT = new_height
|
||||||
|
GRID_SIZE_LENGTH = new_length
|
||||||
|
|
||||||
|
for x in GRID_SIZE_WIDTH:
|
||||||
|
for y in original_length:
|
||||||
|
for z in original_height:
|
||||||
|
if map_data[x][y][z] == null:
|
||||||
|
continue
|
||||||
|
|
||||||
|
var new_y = 0
|
||||||
|
var new_z = 0
|
||||||
|
|
||||||
|
match rotation_steps:
|
||||||
|
1: # 90 degrees
|
||||||
|
new_y = z
|
||||||
|
new_z = original_length - 1 - y
|
||||||
|
2: # 180 degrees
|
||||||
|
new_y = original_length - 1 - y
|
||||||
|
new_z = original_height - 1 - z
|
||||||
|
3: # 270 degrees
|
||||||
|
new_y = original_height - 1 - z
|
||||||
|
new_z = y
|
||||||
|
|
||||||
|
if new_y >= 0 and new_y < new_length and new_z >= 0 and new_z < new_height:
|
||||||
|
temp_map[x][new_y][new_z] = map_data[x][y][z].duplicate()
|
||||||
|
|
||||||
|
var new_coord_x = x + (-1 * new_z) + OFFSET
|
||||||
|
var new_coord_y = new_y + (-1 * new_z) - OFFSET
|
||||||
|
|
||||||
|
temp_map[x][new_y][new_z]["x"] = new_coord_x
|
||||||
|
temp_map[x][new_y][new_z]["y"] = new_coord_y
|
||||||
|
temp_map[x][new_y][new_z]["z"] = new_z
|
||||||
|
|
||||||
|
# Update the grid dimensions
|
||||||
|
GRID_SIZE_HEIGHT = new_height
|
||||||
|
GRID_SIZE_LENGTH = new_length
|
||||||
|
|
||||||
|
map_data = temp_map
|
||||||
|
|
||||||
|
# Rotate map around Y axis
|
||||||
|
func rotate_around_y_axis(rotation_steps = 1):
|
||||||
|
rotation_steps = rotation_steps % 4
|
||||||
|
|
||||||
|
if rotation_steps == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
var temp_map = []
|
||||||
|
# Initialize temp_map with same structure
|
||||||
|
for x in MAX_ARRAY_SIZE:
|
||||||
|
var y_array = []
|
||||||
|
for y in MAX_ARRAY_SIZE:
|
||||||
|
var z_array = []
|
||||||
|
for z in MAX_ARRAY_SIZE:
|
||||||
|
z_array.append(null)
|
||||||
|
y_array.append(z_array)
|
||||||
|
temp_map.append(y_array)
|
||||||
|
|
||||||
|
# Create a new map with adjusted dimensions
|
||||||
|
var new_width = int(GRID_SIZE_HEIGHT) if rotation_steps % 2 == 1 else int(GRID_SIZE_WIDTH)
|
||||||
|
var new_height = int(GRID_SIZE_WIDTH) if rotation_steps % 2 == 1 else int(GRID_SIZE_HEIGHT)
|
||||||
|
|
||||||
|
# Store the original dimensions
|
||||||
|
var original_width = GRID_SIZE_WIDTH
|
||||||
|
var original_height = GRID_SIZE_HEIGHT
|
||||||
|
|
||||||
|
# Temporarily adjust grid dimensions for coordinate calculation
|
||||||
|
GRID_SIZE_WIDTH = new_width
|
||||||
|
GRID_SIZE_HEIGHT = new_height
|
||||||
|
|
||||||
|
for x in original_width:
|
||||||
|
for y in GRID_SIZE_LENGTH:
|
||||||
|
for z in original_height:
|
||||||
|
if map_data[x][y][z] == null:
|
||||||
|
continue
|
||||||
|
|
||||||
|
var new_x = 0
|
||||||
|
var new_z = 0
|
||||||
|
|
||||||
|
match rotation_steps:
|
||||||
|
1: # 90 degrees clockwise around Y axis
|
||||||
|
new_x = original_height - 1 - z
|
||||||
|
new_z = x
|
||||||
|
2: # 180 degrees
|
||||||
|
new_x = original_width - 1 - x
|
||||||
|
new_z = original_height - 1 - z
|
||||||
|
3: # 270 degrees
|
||||||
|
new_x = z
|
||||||
|
new_z = original_width - 1 - x
|
||||||
|
|
||||||
|
if new_x >= 0 and new_x < new_width and new_z >= 0 and new_z < new_height:
|
||||||
|
temp_map[new_x][y][new_z] = map_data[x][y][z].duplicate()
|
||||||
|
|
||||||
|
var new_coord_x = new_x + (-1 * new_z) + OFFSET
|
||||||
|
var new_coord_y = y + (-1 * new_z) - OFFSET
|
||||||
|
|
||||||
|
temp_map[new_x][y][new_z]["x"] = new_coord_x
|
||||||
|
temp_map[new_x][y][new_z]["y"] = new_coord_y
|
||||||
|
temp_map[new_x][y][new_z]["z"] = new_z
|
||||||
|
|
||||||
|
# Update the grid dimensions
|
||||||
|
GRID_SIZE_WIDTH = new_width
|
||||||
|
GRID_SIZE_HEIGHT = new_height
|
||||||
|
|
||||||
|
map_data = temp_map
|
||||||
|
|
||||||
|
# Rotate map around Z axis
|
||||||
|
func rotate_around_z_axis(rotation_steps = 1):
|
||||||
|
rotation_steps = rotation_steps % 4
|
||||||
|
|
||||||
|
if rotation_steps == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
var temp_map = []
|
||||||
|
# Initialize temp_map with same structure
|
||||||
|
for x in MAX_ARRAY_SIZE:
|
||||||
|
var y_array = []
|
||||||
|
for y in MAX_ARRAY_SIZE:
|
||||||
|
var z_array = []
|
||||||
|
for z in MAX_ARRAY_SIZE:
|
||||||
|
z_array.append(null)
|
||||||
|
y_array.append(z_array)
|
||||||
|
temp_map.append(y_array)
|
||||||
|
|
||||||
|
# Create a new map with adjusted dimensions based on rotation
|
||||||
|
var new_width = int(GRID_SIZE_LENGTH) if rotation_steps % 2 == 1 else int(GRID_SIZE_WIDTH)
|
||||||
|
var new_length = int(GRID_SIZE_WIDTH) if rotation_steps % 2 == 1 else int(GRID_SIZE_LENGTH)
|
||||||
|
|
||||||
|
# Store the original dimensions
|
||||||
|
var original_width = GRID_SIZE_WIDTH
|
||||||
|
var original_length = GRID_SIZE_LENGTH
|
||||||
|
|
||||||
|
# Temporarily adjust grid dimensions for coordinate calculation
|
||||||
|
GRID_SIZE_WIDTH = new_width
|
||||||
|
GRID_SIZE_LENGTH = new_length
|
||||||
|
|
||||||
|
for x in original_width:
|
||||||
|
for y in original_length:
|
||||||
|
for z in GRID_SIZE_HEIGHT:
|
||||||
|
if map_data[x][y][z] == null:
|
||||||
|
continue
|
||||||
|
|
||||||
|
var new_x = 0
|
||||||
|
var new_y = 0
|
||||||
|
|
||||||
|
match rotation_steps:
|
||||||
|
1: # 90 degrees
|
||||||
|
new_x = y
|
||||||
|
new_y = original_width - 1 - x
|
||||||
|
2: # 180 degrees
|
||||||
|
new_x = original_width - 1 - x
|
||||||
|
new_y = original_length - 1 - y
|
||||||
|
3: # 270 degrees
|
||||||
|
new_x = original_length - 1 - y
|
||||||
|
new_y = x
|
||||||
|
|
||||||
|
if new_x >= 0 and new_x < new_width and new_y >= 0 and new_y < new_length:
|
||||||
|
temp_map[new_x][new_y][z] = map_data[x][y][z].duplicate()
|
||||||
|
|
||||||
|
var new_coord_x = new_x + (-1 * z) + OFFSET
|
||||||
|
var new_coord_y = new_y + (-1 * z) - OFFSET
|
||||||
|
|
||||||
|
temp_map[new_x][new_y][z]["x"] = new_coord_x
|
||||||
|
temp_map[new_x][new_y][z]["y"] = new_coord_y
|
||||||
|
temp_map[new_x][new_y][z]["z"] = z
|
||||||
|
|
||||||
|
# Update the grid dimensions
|
||||||
|
GRID_SIZE_WIDTH = new_width
|
||||||
|
GRID_SIZE_LENGTH = new_length
|
||||||
|
|
||||||
|
map_data = temp_map
|
||||||
|
|
||||||
|
# Find a tile containing a specific unit
|
||||||
|
func find_unit_tile(unit_type = null):
|
||||||
|
for z in GRID_SIZE_HEIGHT:
|
||||||
|
for x in GRID_SIZE_WIDTH:
|
||||||
|
for y in GRID_SIZE_LENGTH:
|
||||||
|
var tile = map_data[x][y][z]
|
||||||
|
if tile and tile["unit"] != null:
|
||||||
|
if unit_type == null or tile["unit_type"] == unit_type:
|
||||||
|
return {"tile": tile, "x": x, "y": y, "z": z}
|
||||||
|
return null
|
||||||
|
|
||||||
|
# Move a unit from one position to another
|
||||||
|
func move_unit(from_x, from_y, from_z, to_x, to_y, to_z):
|
||||||
|
# Get the source and destination tiles safely
|
||||||
|
var from_tile = get_tile(from_x, from_y, from_z)
|
||||||
|
var to_tile = get_tile(to_x, to_y, to_z)
|
||||||
|
|
||||||
|
# Debug information
|
||||||
|
print("Moving unit from [", from_x, ",", from_y, ",", from_z, "] to [", to_x, ",", to_y, ",", to_z, "]")
|
||||||
|
|
||||||
|
# Validate that both tiles exist and source has a unit
|
||||||
|
if from_tile == null:
|
||||||
|
print("Source tile doesn't exist")
|
||||||
|
return false
|
||||||
|
|
||||||
|
if to_tile == null:
|
||||||
|
print("Destination tile doesn't exist")
|
||||||
|
return false
|
||||||
|
|
||||||
|
if from_tile["unit"] == null:
|
||||||
|
print("No unit at source tile")
|
||||||
|
return false
|
||||||
|
|
||||||
|
# Valid move - transfer the unit
|
||||||
|
to_tile["unit"] = from_tile["unit"]
|
||||||
|
to_tile["unit_type"] = from_tile["unit_type"]
|
||||||
|
to_tile["visibility"] = true
|
||||||
|
|
||||||
|
# Clear the source tile
|
||||||
|
from_tile["unit"] = null
|
||||||
|
from_tile["unit_type"] = null
|
||||||
|
# Keep source tile visible
|
||||||
|
from_tile["visibility"] = true
|
||||||
|
|
||||||
|
print("Unit moved successfully")
|
||||||
|
return true
|
||||||
1
scripts/isometric_map_data.gd.uid
Normal file
1
scripts/isometric_map_data.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://ba42vqbgh72ff
|
||||||
@ -1,695 +1,116 @@
|
|||||||
extends Node2D
|
extends Node2D
|
||||||
|
class_name ImprovedIsometricMapLayerHolder
|
||||||
|
|
||||||
#TODO add player at a tile coordinate from tile array.
|
# Components
|
||||||
#TODO player movement
|
|
||||||
#TODO player actions (movement and attack)
|
|
||||||
#TODO highlight possible tiles for actions
|
|
||||||
#TODO collisions and pathfinding
|
|
||||||
#TODO add "physiks" and "destroy" feature of tiles
|
|
||||||
#TODO add enemy with some kind of AI
|
|
||||||
#TODO refractor code to be more modular
|
|
||||||
#TODO get nice tileset and create first normal level
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# camera stuff
|
|
||||||
@onready var camera = $Camera2D
|
@onready var camera = $Camera2D
|
||||||
|
|
||||||
var drag_start = Vector2()
|
var map_data : IsometricMapData
|
||||||
var drag_active = false
|
var map_renderer : IsometricMapRenderer
|
||||||
var zoom_min = 0.1
|
var camera_controller : IsometricCameraController
|
||||||
var zoom_max = 4.0
|
var player_controller : IsometricPlayerController
|
||||||
var zoom_speed = 0.1
|
|
||||||
var initial_camera_position = Vector2(0, 0)
|
|
||||||
var initial_camera_zoom = Vector2(1, 1)
|
|
||||||
|
|
||||||
var INITIAL_GRID_SIZE_WIDTH = 50 # play area size x
|
|
||||||
var INITIAL_GRID_SIZE_LENGTH = 30 # play area size y
|
|
||||||
var INITIAL_GRID_SIZE_HEIGHT = 30 # play area size z
|
|
||||||
|
|
||||||
var GRID_SIZE_WIDTH = INITIAL_GRID_SIZE_WIDTH # play area size x
|
|
||||||
var GRID_SIZE_LENGTH = INITIAL_GRID_SIZE_LENGTH # play area size y
|
|
||||||
var GRID_SIZE_HEIGHT = INITIAL_GRID_SIZE_HEIGHT # play area size z
|
|
||||||
var TILE_SIZE = 32 # in px
|
|
||||||
var TILE_SIZE_ISOMETRIC_X = 32 # in px
|
|
||||||
var TILE_SIZE_ISOMETRIC_Y = 16 # in px
|
|
||||||
var ROTATION = 0
|
|
||||||
const MAIN_SOURCE_ID = 0
|
|
||||||
const BLUE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(0,0)
|
|
||||||
const RED_ISOMETRICTILE_ATLAS_POSITION = Vector2i(1,0)
|
|
||||||
const GREEN_ISOMETRICTILE_ATLAS_POSITION = Vector2i(2,0)
|
|
||||||
const WHITE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(3,0)
|
|
||||||
const BLACK_ISOMETRICTILE_ATLAS_POSITION = Vector2i(4,0)
|
|
||||||
const PURPLE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(5,0)
|
|
||||||
const ORANGE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(6,0)
|
|
||||||
const OFFSET = 0
|
|
||||||
|
|
||||||
var MAX_ARRAY_SIZE = 0
|
|
||||||
|
|
||||||
func _set_max_array_size():
|
|
||||||
MAX_ARRAY_SIZE = 0
|
|
||||||
|
|
||||||
if MAX_ARRAY_SIZE < GRID_SIZE_WIDTH:
|
|
||||||
MAX_ARRAY_SIZE = GRID_SIZE_WIDTH
|
|
||||||
if MAX_ARRAY_SIZE < GRID_SIZE_LENGTH:
|
|
||||||
MAX_ARRAY_SIZE = GRID_SIZE_LENGTH
|
|
||||||
if MAX_ARRAY_SIZE < GRID_SIZE_HEIGHT:
|
|
||||||
MAX_ARRAY_SIZE = GRID_SIZE_HEIGHT
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func create_debug_map_array():
|
|
||||||
var _debug_map = []
|
|
||||||
|
|
||||||
|
|
||||||
_set_max_array_size()
|
|
||||||
for x in MAX_ARRAY_SIZE:
|
|
||||||
var y_array = []
|
|
||||||
for y in MAX_ARRAY_SIZE:
|
|
||||||
var z_array = []
|
|
||||||
for z in MAX_ARRAY_SIZE:
|
|
||||||
z_array.append(null)
|
|
||||||
y_array.append(z_array)
|
|
||||||
_debug_map.append(y_array)
|
|
||||||
|
|
||||||
for z in INITIAL_GRID_SIZE_HEIGHT:
|
|
||||||
for y in INITIAL_GRID_SIZE_LENGTH:
|
|
||||||
for x in INITIAL_GRID_SIZE_WIDTH:
|
|
||||||
var coord_x = x + (-1 * z) + OFFSET
|
|
||||||
var coord_y = y + (-1 * z) - OFFSET
|
|
||||||
|
|
||||||
var tile_data = {
|
|
||||||
"x": coord_x,
|
|
||||||
"y": coord_y,
|
|
||||||
"z": z,
|
|
||||||
"atlas_base_position": null,
|
|
||||||
"atlas_highlight_position": null,
|
|
||||||
"highlighted": false,
|
|
||||||
"selected": false,
|
|
||||||
"hp": 100,
|
|
||||||
"armour": 0,
|
|
||||||
"destroyable": false,
|
|
||||||
"visibility": false,
|
|
||||||
"unit": null,
|
|
||||||
"unit_type": null, # PC (more options e.g. can move it) or NPC (can only view it)
|
|
||||||
"gravity": null,
|
|
||||||
}
|
|
||||||
_debug_map[x][y][z] = tile_data
|
|
||||||
|
|
||||||
var tile = _debug_map[0][0][0]
|
|
||||||
for y in INITIAL_GRID_SIZE_LENGTH:
|
|
||||||
for x in INITIAL_GRID_SIZE_WIDTH:
|
|
||||||
tile = _debug_map[x][y][0]
|
|
||||||
tile["atlas_base_position"] = BLUE_ISOMETRICTILE_ATLAS_POSITION
|
|
||||||
tile["atlas_highlight_position"] = WHITE_ISOMETRICTILE_ATLAS_POSITION
|
|
||||||
tile["visibility"] = true
|
|
||||||
for i in range(1,10):
|
|
||||||
tile = _debug_map[5][5][i]
|
|
||||||
tile["atlas_base_position"] = RED_ISOMETRICTILE_ATLAS_POSITION
|
|
||||||
tile["atlas_highlight_position"] = WHITE_ISOMETRICTILE_ATLAS_POSITION
|
|
||||||
tile["visibility"] = true
|
|
||||||
|
|
||||||
# for y in INITIAL_GRID_SIZE_LENGTH:
|
|
||||||
# for x in INITIAL_GRID_SIZE_WIDTH:
|
|
||||||
# tile = _debug_map[x][y][INITIAL_GRID_SIZE_HEIGHT-1]
|
|
||||||
# tile["atlas_position"] = BLUE_ISOMETRICTILE_ATLAS_POSITION
|
|
||||||
# tile["visibility"] = true
|
|
||||||
|
|
||||||
# for z in range(1,INITIAL_GRID_SIZE_HEIGHT-1):
|
|
||||||
# for x in INITIAL_GRID_SIZE_WIDTH:
|
|
||||||
# tile = _debug_map[x][0][z]
|
|
||||||
# tile["atlas_position"] = GREEN_ISOMETRICTILE_ATLAS_POSITION
|
|
||||||
# tile["visibility"] = true
|
|
||||||
# for z in range(1,INITIAL_GRID_SIZE_HEIGHT-1):
|
|
||||||
# for x in INITIAL_GRID_SIZE_WIDTH:
|
|
||||||
# tile = _debug_map[x][INITIAL_GRID_SIZE_LENGTH-1][z]
|
|
||||||
# tile["atlas_position"] = GREEN_ISOMETRICTILE_ATLAS_POSITION
|
|
||||||
# tile["visibility"] = true
|
|
||||||
|
|
||||||
# for z in range(1,INITIAL_GRID_SIZE_HEIGHT-1):
|
|
||||||
# for y in range(1,INITIAL_GRID_SIZE_LENGTH-1):
|
|
||||||
# tile = _debug_map[0][y][z]
|
|
||||||
# tile["atlas_position"] = BLACK_ISOMETRICTILE_ATLAS_POSITION
|
|
||||||
# tile["visibility"] = true
|
|
||||||
# for z in range(1,INITIAL_GRID_SIZE_HEIGHT-1):
|
|
||||||
# for y in range(1,INITIAL_GRID_SIZE_LENGTH-1):
|
|
||||||
# tile = _debug_map[INITIAL_GRID_SIZE_WIDTH-1][y][z]
|
|
||||||
# tile["atlas_position"] = RED_ISOMETRICTILE_ATLAS_POSITION
|
|
||||||
# tile["visibility"] = true
|
|
||||||
|
|
||||||
|
|
||||||
GRID_SIZE_WIDTH = INITIAL_GRID_SIZE_WIDTH # play area size x
|
|
||||||
GRID_SIZE_LENGTH = INITIAL_GRID_SIZE_LENGTH # play area size y
|
|
||||||
GRID_SIZE_HEIGHT = INITIAL_GRID_SIZE_HEIGHT # play area size z
|
|
||||||
|
|
||||||
return _debug_map
|
|
||||||
|
|
||||||
func rotate_map_around_x_axis(rotation_steps = 1):
|
|
||||||
rotation_steps = rotation_steps % 4
|
|
||||||
|
|
||||||
if rotation_steps == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
var temp_map = []
|
|
||||||
# Initialize temp_map with same structure
|
|
||||||
|
|
||||||
_set_max_array_size()
|
|
||||||
for x in MAX_ARRAY_SIZE:
|
|
||||||
var y_array = []
|
|
||||||
for y in MAX_ARRAY_SIZE:
|
|
||||||
var z_array = []
|
|
||||||
for z in MAX_ARRAY_SIZE:
|
|
||||||
z_array.append(null)
|
|
||||||
y_array.append(z_array)
|
|
||||||
temp_map.append(y_array)
|
|
||||||
|
|
||||||
# Create a new map with adjusted dimensions
|
|
||||||
var new_height = int(GRID_SIZE_LENGTH) if rotation_steps % 2 == 1 else int(GRID_SIZE_HEIGHT)
|
|
||||||
var new_length = int(GRID_SIZE_HEIGHT) if rotation_steps % 2 == 1 else int(GRID_SIZE_LENGTH)
|
|
||||||
|
|
||||||
# Store the original dimensions
|
|
||||||
var original_height = GRID_SIZE_HEIGHT
|
|
||||||
var original_length = GRID_SIZE_LENGTH
|
|
||||||
|
|
||||||
# Temporarily adjust grid dimensions for coordinate calculation
|
|
||||||
GRID_SIZE_HEIGHT = new_height
|
|
||||||
GRID_SIZE_LENGTH = new_length
|
|
||||||
|
|
||||||
for x in GRID_SIZE_WIDTH:
|
|
||||||
for y in original_length:
|
|
||||||
for z in original_height:
|
|
||||||
if debug_map[x][y][z] == null:
|
|
||||||
continue
|
|
||||||
|
|
||||||
var new_y = 0
|
|
||||||
var new_z = 0
|
|
||||||
|
|
||||||
match rotation_steps:
|
|
||||||
1: # 90 degrees
|
|
||||||
new_y = z
|
|
||||||
new_z = original_length - 1 - y
|
|
||||||
2: # 180 degrees
|
|
||||||
new_y = original_length - 1 - y
|
|
||||||
new_z = original_height - 1 - z
|
|
||||||
3: # 270 degrees
|
|
||||||
new_y = original_height - 1 - z
|
|
||||||
new_z = y
|
|
||||||
|
|
||||||
if new_y >= 0 and new_y < new_length and new_z >= 0 and new_z < new_height:
|
|
||||||
temp_map[x][new_y][new_z] = debug_map[x][y][z].duplicate()
|
|
||||||
|
|
||||||
var new_coord_x = x + (-1 * new_z) + OFFSET
|
|
||||||
var new_coord_y = new_y + (-1 * new_z) - OFFSET
|
|
||||||
|
|
||||||
temp_map[x][new_y][new_z]["x"] = new_coord_x
|
|
||||||
temp_map[x][new_y][new_z]["y"] = new_coord_y
|
|
||||||
temp_map[x][new_y][new_z]["z"] = new_z
|
|
||||||
|
|
||||||
# Update the grid dimensions
|
|
||||||
GRID_SIZE_HEIGHT = new_height
|
|
||||||
GRID_SIZE_LENGTH = new_length
|
|
||||||
|
|
||||||
debug_map = temp_map
|
|
||||||
|
|
||||||
func rotate_map_around_y_axis(rotation_steps = 1):
|
|
||||||
rotation_steps = rotation_steps % 4
|
|
||||||
|
|
||||||
if rotation_steps == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
var temp_map = []
|
|
||||||
# Initialize temp_map with same structure
|
|
||||||
_set_max_array_size()
|
|
||||||
for x in MAX_ARRAY_SIZE:
|
|
||||||
var y_array = []
|
|
||||||
for y in MAX_ARRAY_SIZE:
|
|
||||||
var z_array = []
|
|
||||||
for z in MAX_ARRAY_SIZE:
|
|
||||||
z_array.append(null)
|
|
||||||
y_array.append(z_array)
|
|
||||||
temp_map.append(y_array)
|
|
||||||
|
|
||||||
# Create a new map with adjusted dimensions
|
|
||||||
var new_width = int(GRID_SIZE_HEIGHT) if rotation_steps % 2 == 1 else int(GRID_SIZE_WIDTH)
|
|
||||||
var new_height = int(GRID_SIZE_WIDTH) if rotation_steps % 2 == 1 else int(GRID_SIZE_HEIGHT)
|
|
||||||
|
|
||||||
# Store the original dimensions
|
|
||||||
var original_width = GRID_SIZE_WIDTH
|
|
||||||
var original_height = GRID_SIZE_HEIGHT
|
|
||||||
|
|
||||||
# Temporarily adjust grid dimensions for coordinate calculation
|
|
||||||
GRID_SIZE_WIDTH = new_width
|
|
||||||
GRID_SIZE_HEIGHT = new_height
|
|
||||||
|
|
||||||
for x in original_width:
|
|
||||||
for y in GRID_SIZE_LENGTH:
|
|
||||||
for z in original_height:
|
|
||||||
if debug_map[x][y][z] == null:
|
|
||||||
continue
|
|
||||||
|
|
||||||
var new_x = 0
|
|
||||||
var new_z = 0
|
|
||||||
|
|
||||||
match rotation_steps:
|
|
||||||
1: # 90 degrees clockwise around Y axis
|
|
||||||
new_x = original_height - 1 - z
|
|
||||||
new_z = x
|
|
||||||
2: # 180 degrees
|
|
||||||
new_x = original_width - 1 - x
|
|
||||||
new_z = original_height - 1 - z
|
|
||||||
3: # 270 degrees
|
|
||||||
new_x = z
|
|
||||||
new_z = original_width - 1 - x
|
|
||||||
|
|
||||||
if new_x >= 0 and new_x < new_width and new_z >= 0 and new_z < new_height:
|
|
||||||
temp_map[new_x][y][new_z] = debug_map[x][y][z].duplicate()
|
|
||||||
|
|
||||||
var new_coord_x = new_x + (-1 * new_z) + OFFSET
|
|
||||||
var new_coord_y = y + (-1 * new_z) - OFFSET
|
|
||||||
|
|
||||||
temp_map[new_x][y][new_z]["x"] = new_coord_x
|
|
||||||
temp_map[new_x][y][new_z]["y"] = new_coord_y
|
|
||||||
temp_map[new_x][y][new_z]["z"] = new_z
|
|
||||||
|
|
||||||
# Update the grid dimensions
|
|
||||||
GRID_SIZE_WIDTH = new_width
|
|
||||||
GRID_SIZE_HEIGHT = new_height
|
|
||||||
|
|
||||||
debug_map = temp_map
|
|
||||||
|
|
||||||
func rotate_map_around_z_axis(rotation_steps = 1):
|
|
||||||
rotation_steps = rotation_steps % 4
|
|
||||||
|
|
||||||
if rotation_steps == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
var temp_map = []
|
|
||||||
# Initialize temp_map with same structure
|
|
||||||
_set_max_array_size()
|
|
||||||
for x in MAX_ARRAY_SIZE:
|
|
||||||
var y_array = []
|
|
||||||
for y in MAX_ARRAY_SIZE:
|
|
||||||
var z_array = []
|
|
||||||
for z in MAX_ARRAY_SIZE:
|
|
||||||
z_array.append(null)
|
|
||||||
y_array.append(z_array)
|
|
||||||
temp_map.append(y_array)
|
|
||||||
|
|
||||||
# Create a new map with adjusted dimensions based on rotation
|
|
||||||
var new_width = int(GRID_SIZE_LENGTH) if rotation_steps % 2 == 1 else int(GRID_SIZE_WIDTH)
|
|
||||||
var new_length = int(GRID_SIZE_WIDTH) if rotation_steps % 2 == 1 else int(GRID_SIZE_LENGTH)
|
|
||||||
|
|
||||||
# Store the original dimensions
|
|
||||||
var original_width = GRID_SIZE_WIDTH
|
|
||||||
var original_length = GRID_SIZE_LENGTH
|
|
||||||
|
|
||||||
# Temporarily adjust grid dimensions for coordinate calculation
|
|
||||||
GRID_SIZE_WIDTH = new_width
|
|
||||||
GRID_SIZE_LENGTH = new_length
|
|
||||||
|
|
||||||
for x in original_width:
|
|
||||||
for y in original_length:
|
|
||||||
for z in GRID_SIZE_HEIGHT:
|
|
||||||
if debug_map[x][y][z] == null:
|
|
||||||
continue
|
|
||||||
|
|
||||||
var new_x = 0
|
|
||||||
var new_y = 0
|
|
||||||
|
|
||||||
match rotation_steps:
|
|
||||||
1: # 90 degrees
|
|
||||||
new_x = y
|
|
||||||
new_y = original_width - 1 - x
|
|
||||||
2: # 180 degrees
|
|
||||||
new_x = original_width - 1 - x
|
|
||||||
new_y = original_length - 1 - y
|
|
||||||
3: # 270 degrees
|
|
||||||
new_x = original_length - 1 - y
|
|
||||||
new_y = x
|
|
||||||
|
|
||||||
if new_x >= 0 and new_x < new_width and new_y >= 0 and new_y < new_length:
|
|
||||||
temp_map[new_x][new_y][z] = debug_map[x][y][z].duplicate()
|
|
||||||
|
|
||||||
var new_coord_x = new_x + (-1 * z) + OFFSET
|
|
||||||
var new_coord_y = new_y + (-1 * z) - OFFSET
|
|
||||||
|
|
||||||
temp_map[new_x][new_y][z]["x"] = new_coord_x
|
|
||||||
temp_map[new_x][new_y][z]["y"] = new_coord_y
|
|
||||||
temp_map[new_x][new_y][z]["z"] = z
|
|
||||||
|
|
||||||
# Update the grid dimensions
|
|
||||||
GRID_SIZE_WIDTH = new_width
|
|
||||||
GRID_SIZE_LENGTH = new_length
|
|
||||||
|
|
||||||
debug_map = temp_map
|
|
||||||
var isometric_map_layers = []
|
|
||||||
|
|
||||||
func initialize_map_layers():
|
|
||||||
# Clear any existing layers
|
|
||||||
for layer in isometric_map_layers:
|
|
||||||
if is_instance_valid(layer):
|
|
||||||
layer.queue_free()
|
|
||||||
|
|
||||||
isometric_map_layers.clear()
|
|
||||||
|
|
||||||
# Create new layers for each height level
|
|
||||||
for z in GRID_SIZE_HEIGHT:
|
|
||||||
var new_layer = TileMapLayer.new()
|
|
||||||
new_layer.set_name("IsometricMapLayer_" + str(z))
|
|
||||||
new_layer.tile_set = $TileMapLayer.tile_set # Set your tileset
|
|
||||||
new_layer.z_index = z # Set the z-index to match the layer's height
|
|
||||||
|
|
||||||
|
|
||||||
add_child(new_layer)
|
|
||||||
isometric_map_layers.append(new_layer)
|
|
||||||
|
|
||||||
var debug_map = create_debug_map_array()
|
|
||||||
# Draw the map
|
|
||||||
func draw_visible_tiles():
|
|
||||||
# TODO change it so that tiles behind something is not drawn z+1 at same tile["x"] and tile["y"]
|
|
||||||
# clear all previously drawn tiles on each layer
|
|
||||||
for layer in isometric_map_layers:
|
|
||||||
layer.clear()
|
|
||||||
# draw the map
|
|
||||||
for z in GRID_SIZE_HEIGHT:
|
|
||||||
for y in GRID_SIZE_LENGTH:
|
|
||||||
for x in GRID_SIZE_WIDTH:
|
|
||||||
var tile = debug_map[x][y][z]
|
|
||||||
if tile != null and tile["visibility"]:
|
|
||||||
# Use the layer that corresponds to the tile's z-value
|
|
||||||
if z < isometric_map_layers.size():
|
|
||||||
isometric_map_layers[z].set_cell(
|
|
||||||
Vector2i(tile["x"], tile["y"]),
|
|
||||||
MAIN_SOURCE_ID,
|
|
||||||
tile["atlas_base_position"]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
var highlighted_tiles = {} # Dictionary to store all currently highlighted tiles
|
|
||||||
|
|
||||||
func isometric_grid_hover():
|
|
||||||
var hover_tile_position = isometric_map_layers[0].local_to_map(get_global_mouse_position())
|
|
||||||
var new_highlighted_tiles = {} # Will store tiles to highlight this frame
|
|
||||||
|
|
||||||
# First find all tiles that should be highlighted
|
|
||||||
for z in GRID_SIZE_HEIGHT:
|
|
||||||
for x in GRID_SIZE_WIDTH:
|
|
||||||
for y in GRID_SIZE_LENGTH:
|
|
||||||
var tile = debug_map[x][y][z]
|
|
||||||
|
|
||||||
if tile != null and tile["visibility"]:
|
|
||||||
if tile["x"] == hover_tile_position.x and tile["y"] == hover_tile_position.y:
|
|
||||||
# TODO: change highlighing so when the mouse is over an drawn tile and not the grid
|
|
||||||
var tile_above = isometric_map_layers[z+1].get_cell_source_id(
|
|
||||||
Vector2i(tile["x"]-1, tile["y"]-1)
|
|
||||||
)
|
|
||||||
# Store this tile for highlighting
|
|
||||||
var tile_key = str(x) + "_" + str(y) + "_" + str(z)
|
|
||||||
# print(tile_above)
|
|
||||||
# print(tile["x"], " ", tile["y"], " ", z)
|
|
||||||
# print(hover_tile_position)
|
|
||||||
if not tile_above:
|
|
||||||
new_highlighted_tiles[tile_key] = {
|
|
||||||
"x": x,
|
|
||||||
"y": y,
|
|
||||||
"z": z+1
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
new_highlighted_tiles[tile_key] = {
|
|
||||||
"x": x,
|
|
||||||
"y": y,
|
|
||||||
"z": z
|
|
||||||
}
|
|
||||||
|
|
||||||
new_highlighted_tiles[tile_key] = {
|
|
||||||
"x": x,
|
|
||||||
"y": y,
|
|
||||||
"z": z
|
|
||||||
}
|
|
||||||
|
|
||||||
# Highlight new tiles
|
|
||||||
for tile_key in new_highlighted_tiles:
|
|
||||||
var tile_data = new_highlighted_tiles[tile_key]
|
|
||||||
var tile = debug_map[tile_data.x][tile_data.y][tile_data.z]
|
|
||||||
if not tile["selected"]:
|
|
||||||
isometric_map_layers[tile_data.z].set_cell(
|
|
||||||
Vector2i(tile["x"], tile["y"]),
|
|
||||||
MAIN_SOURCE_ID,
|
|
||||||
tile["atlas_highlight_position"]
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
isometric_map_layers[tile_data.z].set_cell(
|
|
||||||
Vector2i(tile["x"], tile["y"]),
|
|
||||||
1,
|
|
||||||
Vector2i(3,1) #
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
tile["highlighted"] = true
|
|
||||||
|
|
||||||
# De-highlight tiles that are no longer under the cursor
|
|
||||||
for tile_key in highlighted_tiles:
|
|
||||||
if not (tile_key in new_highlighted_tiles):
|
|
||||||
var tile_data = highlighted_tiles[tile_key]
|
|
||||||
var tile = debug_map[tile_data.x][tile_data.y][tile_data.z]
|
|
||||||
|
|
||||||
if tile != null and tile["visibility"]:
|
|
||||||
|
|
||||||
if not tile["selected"]:
|
|
||||||
isometric_map_layers[tile_data.z].set_cell(
|
|
||||||
Vector2i(tile["x"], tile["y"]),
|
|
||||||
MAIN_SOURCE_ID,
|
|
||||||
tile["atlas_base_position"] # Original appearance
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
isometric_map_layers[tile_data.z].set_cell(
|
|
||||||
Vector2i(tile["x"], tile["y"]),
|
|
||||||
1,
|
|
||||||
Vector2i(0,1) #
|
|
||||||
)
|
|
||||||
tile["highlighted"] = false
|
|
||||||
|
|
||||||
# Update the highlighted tiles list
|
|
||||||
highlighted_tiles = new_highlighted_tiles
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
# Store initial camera position
|
|
||||||
initial_camera_position = camera.position
|
|
||||||
initial_camera_zoom = camera.zoom
|
|
||||||
initialize_map_layers()
|
|
||||||
draw_visible_tiles()
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
|
||||||
pass
|
|
||||||
# isometric_grid_hover()
|
|
||||||
|
|
||||||
func _input(event):
|
|
||||||
if event is InputEventMouseMotion:
|
|
||||||
isometric_grid_hover()
|
|
||||||
# Camera drag (pan) control
|
|
||||||
if event is InputEventMouseButton:
|
|
||||||
if event.button_index == MOUSE_BUTTON_RIGHT:
|
|
||||||
if event.pressed:
|
|
||||||
drag_start = event.position
|
|
||||||
drag_active = true
|
|
||||||
else:
|
|
||||||
drag_active = false
|
|
||||||
|
|
||||||
# Zoom control with mouse wheel
|
|
||||||
if event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
|
|
||||||
zoom_camera(-zoom_speed)
|
|
||||||
elif event.button_index == MOUSE_BUTTON_WHEEL_UP:
|
|
||||||
zoom_camera(zoom_speed)
|
|
||||||
|
|
||||||
# Handle camera movement while dragging
|
|
||||||
if event is InputEventMouseMotion and drag_active:
|
|
||||||
camera.position -= event.relative / camera.zoom
|
|
||||||
|
|
||||||
func _on_reset_button_pressed() -> void:
|
|
||||||
# Reset camera position and zoom
|
|
||||||
|
|
||||||
debug_map = create_debug_map_array()
|
|
||||||
initialize_map_layers()
|
|
||||||
draw_visible_tiles()
|
|
||||||
camera.position = initial_camera_position
|
|
||||||
camera.zoom = initial_camera_zoom
|
|
||||||
|
|
||||||
func zoom_camera(zoom_amount):
|
|
||||||
var new_zoom = camera.zoom.x + zoom_amount
|
|
||||||
new_zoom = clamp(new_zoom, zoom_min, zoom_max)
|
|
||||||
camera.zoom = Vector2(new_zoom, new_zoom)
|
|
||||||
|
|
||||||
func _on_cw_pressed() -> void:
|
|
||||||
_reset_class_values()
|
|
||||||
rotate_map_around_z_axis(3)
|
|
||||||
initialize_map_layers()
|
|
||||||
draw_visible_tiles()
|
|
||||||
|
|
||||||
func _on_ccw_pressed() -> void:
|
|
||||||
_reset_class_values()
|
|
||||||
rotate_map_around_z_axis(1)
|
|
||||||
initialize_map_layers()
|
|
||||||
draw_visible_tiles()
|
|
||||||
|
|
||||||
func _on_x_cw_pressed() -> void:
|
|
||||||
_reset_class_values()
|
|
||||||
rotate_map_around_x_axis(1)
|
|
||||||
initialize_map_layers()
|
|
||||||
draw_visible_tiles()
|
|
||||||
|
|
||||||
func _on_x_ccw_pressed() -> void:
|
|
||||||
_reset_class_values()
|
|
||||||
rotate_map_around_x_axis(3)
|
|
||||||
initialize_map_layers()
|
|
||||||
draw_visible_tiles()
|
|
||||||
|
|
||||||
func _on_y_cw_pressed() -> void:
|
|
||||||
_reset_class_values()
|
|
||||||
rotate_map_around_y_axis(3)
|
|
||||||
initialize_map_layers()
|
|
||||||
draw_visible_tiles()
|
|
||||||
|
|
||||||
func _on_y_ccw_pressed() -> void:
|
|
||||||
_reset_class_values()
|
|
||||||
rotate_map_around_y_axis(1)
|
|
||||||
initialize_map_layers()
|
|
||||||
draw_visible_tiles()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func _reset_class_values():
|
|
||||||
highlighted_tiles = {}
|
|
||||||
last_click_time = 0.0
|
|
||||||
clicked_position = Vector2i(1, 1)
|
|
||||||
is_tile_selected = false
|
|
||||||
|
|
||||||
|
# Timing for click detection
|
||||||
var click_delay: float = 0.2
|
var click_delay: float = 0.2
|
||||||
var last_click_time: float = 0.0
|
var last_click_time: float = 0.0
|
||||||
var clicked_position: Vector2i = Vector2i(1, 1)
|
var clicked_position: Vector2i = Vector2i(1, 1)
|
||||||
var is_tile_selected: bool = false
|
var is_tile_selected: bool = false
|
||||||
|
|
||||||
func tile_selction_logic():
|
func _ready() -> void:
|
||||||
for z in GRID_SIZE_HEIGHT:
|
# Initialize map data
|
||||||
for x in GRID_SIZE_WIDTH:
|
map_data = IsometricMapData.new(50, 30, 30, 0)
|
||||||
for y in GRID_SIZE_LENGTH:
|
map_data.create_default_map()
|
||||||
var tile = debug_map[x][y][z]
|
|
||||||
if tile["selected"] and tile["highlighted"]:
|
|
||||||
isometric_map_layers[z].set_cell(
|
|
||||||
Vector2i(tile["x"], tile["y"]),
|
|
||||||
1,
|
|
||||||
Vector2i(0,1) #
|
|
||||||
)
|
|
||||||
tile["selected"] = false
|
|
||||||
if tile["selected"] and not tile["highlighted"]:
|
|
||||||
isometric_map_layers[z].set_cell(
|
|
||||||
Vector2i(tile["x"], tile["y"]),
|
|
||||||
0,
|
|
||||||
Vector2i(0,0) #
|
|
||||||
)
|
|
||||||
tile["selected"] = false
|
|
||||||
if not tile["selected"] and tile["highlighted"]:
|
|
||||||
isometric_map_layers[z].set_cell(
|
|
||||||
Vector2i(tile["x"], tile["y"]),
|
|
||||||
1,
|
|
||||||
Vector2i(3,1) #
|
|
||||||
)
|
|
||||||
tile["selected"] = true
|
|
||||||
|
|
||||||
|
# Initialize the renderer
|
||||||
|
map_renderer = IsometricMapRenderer.new(map_data, $TileMapLayer)
|
||||||
|
|
||||||
|
# Initialize camera controller
|
||||||
|
camera_controller = IsometricCameraController.new(camera)
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
# Draw initial map state
|
||||||
|
map_renderer.draw_visible_tiles()
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
# This method intentionally left empty - handling done in _input
|
||||||
|
pass
|
||||||
|
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
# Handle camera movement
|
||||||
|
camera_controller.handle_input(event)
|
||||||
|
|
||||||
|
# Handle hover effects
|
||||||
|
if event is InputEventMouseMotion:
|
||||||
|
map_renderer.handle_hover(get_global_mouse_position())
|
||||||
|
|
||||||
|
# Handle tile selection
|
||||||
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
|
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
|
||||||
var current_time = Time.get_ticks_msec() / 1000.0
|
var current_time = Time.get_ticks_msec() / 1000.0
|
||||||
if current_time - last_click_time >= click_delay:
|
if current_time - last_click_time >= click_delay:
|
||||||
last_click_time = current_time
|
last_click_time = current_time
|
||||||
tile_selction_logic()
|
map_renderer.handle_tile_selection()
|
||||||
elif event is InputEventKey and event.pressed and event.keycode == KEY_ESCAPE:
|
|
||||||
pass
|
|
||||||
#deselect_tile()
|
|
||||||
|
|
||||||
var player_node
|
|
||||||
|
|
||||||
func set_player(p):
|
|
||||||
player_node = p
|
|
||||||
|
|
||||||
|
# Set a player reference
|
||||||
|
func set_player(player):
|
||||||
|
player_controller = IsometricPlayerController.new(player, map_data, map_renderer)
|
||||||
|
|
||||||
|
# Initialize player position
|
||||||
func init_player():
|
func init_player():
|
||||||
var tile = debug_map[10][10][1]
|
return player_controller.init_player()
|
||||||
tile["visibility"] = true
|
|
||||||
tile["unit"] = player_node
|
|
||||||
tile["unit_type"] ="PC"
|
|
||||||
var init_player_pos = iso_to_world(tile["x"], tile["y"], tile["z"])
|
|
||||||
tile["unit"].set_unit_position(init_player_pos.x, init_player_pos.y, tile["z"])
|
|
||||||
|
|
||||||
func _move_up_or_down(up_or_down = "up"):
|
# Reset the map to initial state
|
||||||
var z_offset = 0
|
func _on_reset_button_pressed() -> void:
|
||||||
if up_or_down == "up":
|
# Recreate map data
|
||||||
z_offset = 1
|
map_data = IsometricMapData.new(50, 30, 30, 0)
|
||||||
elif up_or_down == "down":
|
map_data.create_default_map()
|
||||||
z_offset = -1
|
|
||||||
var new_z = 0
|
|
||||||
var new_y = 0
|
|
||||||
var new_x = 0
|
|
||||||
var tile = debug_map[0][0][0]
|
|
||||||
for z in GRID_SIZE_HEIGHT:
|
|
||||||
for x in GRID_SIZE_WIDTH:
|
|
||||||
for y in GRID_SIZE_LENGTH:
|
|
||||||
tile = debug_map[x][y][z]
|
|
||||||
if tile["unit_type"] == "PC":
|
|
||||||
new_z = z + z_offset
|
|
||||||
new_y = y
|
|
||||||
new_x = x
|
|
||||||
break
|
|
||||||
if tile["unit_type"] == "PC":
|
|
||||||
break
|
|
||||||
if tile["unit_type"] == "PC":
|
|
||||||
break
|
|
||||||
print("x ", new_x, " y ", new_y, " z ", new_z)
|
|
||||||
tile["unit"] = null
|
|
||||||
tile["unit_type"] = null
|
|
||||||
tile["visibility"] = null
|
|
||||||
|
|
||||||
|
# Reinitialize map renderer
|
||||||
|
map_renderer.initialize_map_layers($TileMapLayer)
|
||||||
|
map_renderer.draw_visible_tiles()
|
||||||
|
|
||||||
var new_player_tile = debug_map[new_x][new_y][new_z]
|
# Reset camera
|
||||||
new_player_tile["unit"] = player_node
|
camera_controller.reset_camera()
|
||||||
new_player_tile["visibility"] = true
|
|
||||||
new_player_tile["unit_type"] ="PC"
|
|
||||||
var new_player_pos = iso_to_world(tile["x"], tile["y"], tile["z"])
|
|
||||||
new_player_tile["unit"].set_unit_position(new_player_pos.x, new_player_pos.y, tile["z"])
|
|
||||||
|
|
||||||
print(new_player_tile["x"], new_player_tile["y"], new_player_tile["z"])
|
# Rotation handlers
|
||||||
|
func _on_cw_pressed() -> void:
|
||||||
|
map_data.rotate_around_z_axis(3)
|
||||||
|
map_renderer.initialize_map_layers($TileMapLayer)
|
||||||
|
map_renderer.draw_visible_tiles()
|
||||||
|
|
||||||
func iso_to_world(tile_x, tile_y, player_z_layer = 0):
|
func _on_ccw_pressed() -> void:
|
||||||
# Get the tile size from your tilemap
|
map_data.rotate_around_z_axis(1)
|
||||||
var tile_width = isometric_map_layers[player_z_layer].tile_set.tile_size.x
|
map_renderer.initialize_map_layers($TileMapLayer)
|
||||||
var tile_height = isometric_map_layers[player_z_layer].tile_set.tile_size.y
|
map_renderer.draw_visible_tiles()
|
||||||
|
|
||||||
# Calculate the world position
|
func _on_x_cw_pressed() -> void:
|
||||||
var world_x = (tile_x - tile_y) * (tile_width / 2)
|
map_data.rotate_around_x_axis(1)
|
||||||
var world_y = (tile_x + tile_y) * (tile_height / 2) - (player_z_layer * tile_height / 2)
|
map_renderer.initialize_map_layers($TileMapLayer)
|
||||||
|
map_renderer.draw_visible_tiles()
|
||||||
return Vector2(world_x, world_y)
|
|
||||||
|
|
||||||
# Converts world position to isometric tile coordinates
|
|
||||||
func world_to_iso(world_pos, player_z_layer = 0):
|
|
||||||
# Get the tile size from your tilemap
|
|
||||||
var tile_width = isometric_map_layers[player_z_layer].tile_set.tile_size.x
|
|
||||||
var tile_height = isometric_map_layers[player_z_layer].tile_set.tile_size.y
|
|
||||||
|
|
||||||
# Adjust y position based on z-layer
|
|
||||||
var adjusted_y = world_pos.y + (player_z_layer * tile_height / 2)
|
|
||||||
|
|
||||||
# Calculate the tile coordinates
|
|
||||||
var tile_x = (world_pos.x / (tile_width / 2) + adjusted_y / (tile_height / 2)) / 2
|
|
||||||
var tile_y = (adjusted_y / (tile_height / 2) - world_pos.x / (tile_width / 2)) / 2
|
|
||||||
|
|
||||||
return Vector2i(round(tile_x), round(tile_y))
|
|
||||||
|
|
||||||
|
func _on_x_ccw_pressed() -> void:
|
||||||
|
map_data.rotate_around_x_axis(3)
|
||||||
|
map_renderer.initialize_map_layers($TileMapLayer)
|
||||||
|
map_renderer.draw_visible_tiles()
|
||||||
|
|
||||||
|
func _on_y_cw_pressed() -> void:
|
||||||
|
map_data.rotate_around_y_axis(3)
|
||||||
|
map_renderer.initialize_map_layers($TileMapLayer)
|
||||||
|
map_renderer.draw_visible_tiles()
|
||||||
|
|
||||||
|
func _on_y_ccw_pressed() -> void:
|
||||||
|
map_data.rotate_around_y_axis(1)
|
||||||
|
map_renderer.initialize_map_layers($TileMapLayer)
|
||||||
|
map_renderer.draw_visible_tiles()
|
||||||
|
|
||||||
|
# Player movement handlers
|
||||||
func _on_player_z_layer_change_pressed() -> void:
|
func _on_player_z_layer_change_pressed() -> void:
|
||||||
_move_up_or_down("up")
|
print("Moving player up")
|
||||||
|
var success = player_controller.move_vertical("up")
|
||||||
|
print("Move success: ", success)
|
||||||
|
# Always redraw the visible tiles to ensure consistent state
|
||||||
|
map_renderer.draw_visible_tiles()
|
||||||
|
|
||||||
func _on_player_z_layer_change_down_pressed() -> void:
|
func _on_player_z_layer_change_down_pressed() -> void:
|
||||||
_move_up_or_down("down")
|
print("Moving player down")
|
||||||
|
var success = player_controller.move_vertical("down")
|
||||||
|
print("Move success: ", success)
|
||||||
|
# Always redraw the visible tiles to ensure consistent state
|
||||||
|
map_renderer.draw_visible_tiles()
|
||||||
|
|||||||
189
scripts/isometric_map_renderer.gd
Normal file
189
scripts/isometric_map_renderer.gd
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
extends Node
|
||||||
|
class_name IsometricMapRenderer
|
||||||
|
|
||||||
|
var map_data = null
|
||||||
|
var isometric_map_layers = []
|
||||||
|
var highlighted_tiles = {} # Dictionary to store all currently highlighted tiles
|
||||||
|
|
||||||
|
var TILE_SIZE_ISOMETRIC_X = 32 # in px
|
||||||
|
var TILE_SIZE_ISOMETRIC_Y = 16 # in px
|
||||||
|
|
||||||
|
# Initialize with reference to a map data object and a tilemap to use as template
|
||||||
|
func _init(map_data_ref, tilemap_template):
|
||||||
|
map_data = map_data_ref
|
||||||
|
initialize_map_layers(tilemap_template)
|
||||||
|
|
||||||
|
# Initialize all the map layers for different heights
|
||||||
|
func initialize_map_layers(tilemap_template):
|
||||||
|
# Clear any existing layers
|
||||||
|
for layer in isometric_map_layers:
|
||||||
|
if is_instance_valid(layer):
|
||||||
|
layer.queue_free()
|
||||||
|
|
||||||
|
isometric_map_layers.clear()
|
||||||
|
|
||||||
|
# Create new layers for each height level
|
||||||
|
for z in map_data.GRID_SIZE_HEIGHT:
|
||||||
|
var new_layer = TileMapLayer.new()
|
||||||
|
new_layer.set_name("IsometricMapLayer_" + str(z))
|
||||||
|
new_layer.tile_set = tilemap_template.tile_set
|
||||||
|
new_layer.z_index = z # Set the z-index to match the layer's height
|
||||||
|
|
||||||
|
tilemap_template.get_parent().add_child(new_layer)
|
||||||
|
isometric_map_layers.append(new_layer)
|
||||||
|
|
||||||
|
# Draw all visible tiles on the map
|
||||||
|
func draw_visible_tiles():
|
||||||
|
# Clear all previously drawn tiles on each layer
|
||||||
|
for layer in isometric_map_layers:
|
||||||
|
layer.clear()
|
||||||
|
|
||||||
|
# Draw the map
|
||||||
|
for z in map_data.GRID_SIZE_HEIGHT:
|
||||||
|
for y in map_data.GRID_SIZE_LENGTH:
|
||||||
|
for x in map_data.GRID_SIZE_WIDTH:
|
||||||
|
var tile = map_data.get_tile(x, y, z)
|
||||||
|
if tile != null and tile["visibility"] and tile["atlas_base_position"] != null:
|
||||||
|
# Use the layer that corresponds to the tile's z-value
|
||||||
|
if z < isometric_map_layers.size():
|
||||||
|
isometric_map_layers[z].set_cell(
|
||||||
|
Vector2i(tile["x"], tile["y"]),
|
||||||
|
IsometricMapSystem.MAIN_SOURCE_ID,
|
||||||
|
tile["atlas_base_position"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Handle hovering over tiles
|
||||||
|
func handle_hover(mouse_position):
|
||||||
|
var hover_tile_position = isometric_map_layers[0].local_to_map(mouse_position)
|
||||||
|
var new_highlighted_tiles = {} # Will store tiles to highlight this frame
|
||||||
|
|
||||||
|
# First find all tiles that should be highlighted
|
||||||
|
for z in map_data.GRID_SIZE_HEIGHT:
|
||||||
|
for x in map_data.GRID_SIZE_WIDTH:
|
||||||
|
for y in map_data.GRID_SIZE_LENGTH:
|
||||||
|
var tile = map_data.get_tile(x, y, z)
|
||||||
|
|
||||||
|
if tile != null and tile["visibility"] and not tile["unit"]:
|
||||||
|
if tile["x"] == hover_tile_position.x and tile["y"] == hover_tile_position.y:
|
||||||
|
# Store this tile for highlighting
|
||||||
|
var tile_key = str(x) + "_" + str(y) + "_" + str(z)
|
||||||
|
|
||||||
|
new_highlighted_tiles[tile_key] = {
|
||||||
|
"x": x,
|
||||||
|
"y": y,
|
||||||
|
"z": z
|
||||||
|
}
|
||||||
|
|
||||||
|
# Highlight new tiles
|
||||||
|
for tile_key in new_highlighted_tiles:
|
||||||
|
var tile_data = new_highlighted_tiles[tile_key]
|
||||||
|
var tile = map_data.get_tile(tile_data.x, tile_data.y, tile_data.z)
|
||||||
|
if tile == null:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not tile["selected"] and not tile["unit"]:
|
||||||
|
# Only set cell if we have a valid highlight position
|
||||||
|
if tile["atlas_highlight_position"] != null:
|
||||||
|
isometric_map_layers[tile_data.z].set_cell(
|
||||||
|
Vector2i(tile["x"], tile["y"]),
|
||||||
|
IsometricMapSystem.MAIN_SOURCE_ID,
|
||||||
|
tile["atlas_highlight_position"]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
isometric_map_layers[tile_data.z].set_cell(
|
||||||
|
Vector2i(tile["x"], tile["y"]),
|
||||||
|
1,
|
||||||
|
Vector2i(3,1) #
|
||||||
|
)
|
||||||
|
|
||||||
|
tile["highlighted"] = true
|
||||||
|
|
||||||
|
# De-highlight tiles that are no longer under the cursor
|
||||||
|
for tile_key in highlighted_tiles:
|
||||||
|
if not (tile_key in new_highlighted_tiles):
|
||||||
|
var tile_data = highlighted_tiles[tile_key]
|
||||||
|
var tile = map_data.get_tile(tile_data.x, tile_data.y, tile_data.z)
|
||||||
|
|
||||||
|
if tile != null and tile["visibility"] and not tile["unit"]:
|
||||||
|
|
||||||
|
if not tile["selected"]:
|
||||||
|
# Only set cell if we have a valid base position
|
||||||
|
if tile["atlas_base_position"] != null:
|
||||||
|
isometric_map_layers[tile_data.z].set_cell(
|
||||||
|
Vector2i(tile["x"], tile["y"]),
|
||||||
|
IsometricMapSystem.MAIN_SOURCE_ID,
|
||||||
|
tile["atlas_base_position"] # Original appearance
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
isometric_map_layers[tile_data.z].set_cell(
|
||||||
|
Vector2i(tile["x"], tile["y"]),
|
||||||
|
1,
|
||||||
|
Vector2i(0,1) #
|
||||||
|
)
|
||||||
|
tile["highlighted"] = false
|
||||||
|
|
||||||
|
# Update the highlighted tiles list
|
||||||
|
highlighted_tiles = new_highlighted_tiles
|
||||||
|
|
||||||
|
# Handle tile selection logic
|
||||||
|
func handle_tile_selection():
|
||||||
|
for z in map_data.GRID_SIZE_HEIGHT:
|
||||||
|
for x in map_data.GRID_SIZE_WIDTH:
|
||||||
|
for y in map_data.GRID_SIZE_LENGTH:
|
||||||
|
var tile = map_data.get_tile(x, y, z)
|
||||||
|
if tile == null or not tile["visibility"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Get valid coordinates
|
||||||
|
var tile_x = tile["x"]
|
||||||
|
var tile_y = tile["y"]
|
||||||
|
|
||||||
|
if tile["selected"] and tile["highlighted"]:
|
||||||
|
print("direct de selected: ", Vector2i(tile_x, tile_y))
|
||||||
|
isometric_map_layers[z].set_cell(
|
||||||
|
Vector2i(tile_x, tile_y),
|
||||||
|
IsometricMapSystem.MAIN_SOURCE_ID,
|
||||||
|
IsometricMapSystem.SELECTED_BLUE_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
)
|
||||||
|
tile["selected"] = false
|
||||||
|
|
||||||
|
elif tile["selected"] and not tile["highlighted"]:
|
||||||
|
print("old de selected: ", Vector2i(tile_x, tile_y))
|
||||||
|
# If there's a base position, restore it, otherwise use a default
|
||||||
|
if tile["atlas_base_position"] != null:
|
||||||
|
isometric_map_layers[z].set_cell(
|
||||||
|
Vector2i(tile_x, tile_y),
|
||||||
|
IsometricMapSystem.MAIN_SOURCE_ID,
|
||||||
|
tile["atlas_base_position"]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
isometric_map_layers[z].set_cell(
|
||||||
|
Vector2i(tile_x, tile_y),
|
||||||
|
IsometricMapSystem.MAIN_SOURCE_ID,
|
||||||
|
IsometricMapSystem.BLUE_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
)
|
||||||
|
tile["selected"] = false
|
||||||
|
|
||||||
|
elif not tile["selected"] and tile["highlighted"]:
|
||||||
|
print("new selected: ", Vector2i(tile_x, tile_y))
|
||||||
|
isometric_map_layers[z].set_cell(
|
||||||
|
Vector2i(tile_x, tile_y),
|
||||||
|
IsometricMapSystem.MAIN_SOURCE_ID,
|
||||||
|
IsometricMapSystem.SELECTED_WHITE_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
)
|
||||||
|
tile["selected"] = true
|
||||||
|
|
||||||
|
# Position a unit on the map visually
|
||||||
|
func position_unit(unit, tile_x, tile_y, tile_z):
|
||||||
|
var world_pos = IsometricMapSystem.iso_to_world(
|
||||||
|
tile_x,
|
||||||
|
tile_y,
|
||||||
|
tile_z,
|
||||||
|
TILE_SIZE_ISOMETRIC_X,
|
||||||
|
TILE_SIZE_ISOMETRIC_Y
|
||||||
|
)
|
||||||
|
|
||||||
|
unit.z_index = tile_z
|
||||||
|
# Assuming unit has a set_unit_position method to handle actual positioning
|
||||||
|
if unit.has_method("set_unit_position"):
|
||||||
|
unit.set_unit_position(world_pos.x, world_pos.y, tile_z)
|
||||||
1
scripts/isometric_map_renderer.gd.uid
Normal file
1
scripts/isometric_map_renderer.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://bkjmtgsjwhna4
|
||||||
68
scripts/isometric_map_system.gd
Normal file
68
scripts/isometric_map_system.gd
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
# Constants for tile types/colors
|
||||||
|
const MAIN_SOURCE_ID = 1
|
||||||
|
const BLUE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(0,0)
|
||||||
|
const RED_ISOMETRICTILE_ATLAS_POSITION = Vector2i(1,0)
|
||||||
|
const GREEN_ISOMETRICTILE_ATLAS_POSITION = Vector2i(2,0)
|
||||||
|
const WHITE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(3,0)
|
||||||
|
const BLACK_ISOMETRICTILE_ATLAS_POSITION = Vector2i(4,0)
|
||||||
|
const PURPLE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(5,0)
|
||||||
|
const ORANGE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(6,0)
|
||||||
|
const LOW_ALPHA_BLOCK_ISOMETRICTILE_ATLAS_POSITION = Vector2i(7,0)
|
||||||
|
const SELECTED_BLUE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(0,1)
|
||||||
|
const SELECTED_RED_ISOMETRICTILE_ATLAS_POSITION = Vector2i(1,1)
|
||||||
|
const SELECTED_GREEN_ISOMETRICTILE_ATLAS_POSITION = Vector2i(2,1)
|
||||||
|
const SELECTED_WHITE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(3,1)
|
||||||
|
const SELECTED_BLACK_ISOMETRICTILE_ATLAS_POSITION = Vector2i(4,1)
|
||||||
|
const SELECTED_PURPLE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(5,1)
|
||||||
|
const SELECTED_ORANGE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(6,1)
|
||||||
|
# Debug flags
|
||||||
|
var debug_enabled = true
|
||||||
|
|
||||||
|
# Debug function that only prints when debug is enabled
|
||||||
|
func debug_print(message):
|
||||||
|
if debug_enabled:
|
||||||
|
print("[IsometricMapSystem] " + str(message))
|
||||||
|
|
||||||
|
# Utility functions for conversion between coordinate systems
|
||||||
|
func iso_to_world(tile_x, tile_y, player_z_layer = 0, tile_width = 32, tile_height = 16):
|
||||||
|
# Calculate the world position from isometric coordinates
|
||||||
|
var world_x = (tile_x - tile_y) * (tile_width / 2)
|
||||||
|
var world_y = (tile_x + tile_y) * (tile_height / 2) - (player_z_layer * tile_height / 2)
|
||||||
|
|
||||||
|
return Vector2(world_x, world_y)
|
||||||
|
|
||||||
|
# Converts world position to isometric tile coordinates
|
||||||
|
func world_to_iso(world_pos, player_z_layer = 0, tile_width = 32, tile_height = 16):
|
||||||
|
# Adjust y position based on z-layer
|
||||||
|
var adjusted_y = world_pos.y + (player_z_layer * tile_height / 2)
|
||||||
|
|
||||||
|
# Calculate the tile coordinates
|
||||||
|
var tile_x = (world_pos.x / (tile_width / 2) + adjusted_y / (tile_height / 2)) / 2
|
||||||
|
var tile_y = (adjusted_y / (tile_height / 2) - world_pos.x / (tile_width / 2)) / 2
|
||||||
|
|
||||||
|
return Vector2i(round(tile_x), round(tile_y))
|
||||||
|
|
||||||
|
# Create a new tile data structure with default values
|
||||||
|
func create_tile_data(coord_x, coord_y, z, atlas_base_position = null, atlas_highlight_position = null):
|
||||||
|
# Ensure we have valid default positions to avoid null reference errors
|
||||||
|
var base_pos = atlas_base_position if atlas_base_position != null else BLUE_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
var highlight_pos = atlas_highlight_position if atlas_highlight_position != null else WHITE_ISOMETRICTILE_ATLAS_POSITION
|
||||||
|
|
||||||
|
return {
|
||||||
|
"x": coord_x,
|
||||||
|
"y": coord_y,
|
||||||
|
"z": z,
|
||||||
|
"atlas_base_position": null,
|
||||||
|
"atlas_highlight_position": null,
|
||||||
|
"highlighted": false,
|
||||||
|
"selected": false,
|
||||||
|
"hp": 100,
|
||||||
|
"armour": 0,
|
||||||
|
"destroyable": false,
|
||||||
|
"visibility": false,
|
||||||
|
"unit": null,
|
||||||
|
"unit_type": null, # PC (more options e.g. can move it) or NPC (can only view it)
|
||||||
|
"gravity": null,
|
||||||
|
}
|
||||||
1
scripts/isometric_map_system.gd.uid
Normal file
1
scripts/isometric_map_system.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://buyf5d883rdj5
|
||||||
74
scripts/isometric_player_controller.gd
Normal file
74
scripts/isometric_player_controller.gd
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
extends Node
|
||||||
|
class_name IsometricPlayerController
|
||||||
|
|
||||||
|
var player_node
|
||||||
|
var map_data
|
||||||
|
var map_renderer
|
||||||
|
|
||||||
|
func _init(player, map_data_ref, renderer):
|
||||||
|
player_node = player
|
||||||
|
map_data = map_data_ref
|
||||||
|
map_renderer = renderer
|
||||||
|
|
||||||
|
# Initialize player at a specific position
|
||||||
|
func init_player(x=10, y=10, z=1):
|
||||||
|
var tile = map_data.get_tile(x, y, z)
|
||||||
|
if tile:
|
||||||
|
tile["visibility"] = true
|
||||||
|
tile["unit"] = player_node
|
||||||
|
tile["unit_type"] = "PC"
|
||||||
|
|
||||||
|
# Use renderer to position the player
|
||||||
|
map_renderer.position_unit(player_node, tile["x"], tile["y"], tile["z"])
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
# Move player up or down a layer
|
||||||
|
func move_vertical(direction = "up"):
|
||||||
|
var z_offset = 0
|
||||||
|
if direction == "up":
|
||||||
|
z_offset = 1
|
||||||
|
elif direction == "down":
|
||||||
|
z_offset = -1
|
||||||
|
|
||||||
|
# Find current player position
|
||||||
|
var player_position = map_data.find_unit_tile("PC")
|
||||||
|
if not player_position:
|
||||||
|
print("Cannot find player position")
|
||||||
|
return false
|
||||||
|
|
||||||
|
var current_x = player_position.x
|
||||||
|
var current_y = player_position.y
|
||||||
|
var current_z = player_position.z
|
||||||
|
var new_z = current_z + z_offset
|
||||||
|
|
||||||
|
# Check if new position is valid
|
||||||
|
if new_z < 0 or new_z >= map_data.GRID_SIZE_HEIGHT:
|
||||||
|
print("New Z position out of bounds: ", new_z)
|
||||||
|
return false
|
||||||
|
|
||||||
|
# Check if destination tile exists
|
||||||
|
var destination_tile = map_data.get_tile(current_x, current_y, new_z)
|
||||||
|
if destination_tile == null:
|
||||||
|
print("Destination tile doesn't exist at: ", current_x, ", ", current_y, ", ", new_z)
|
||||||
|
return false
|
||||||
|
|
||||||
|
# Debug the current tile before moving
|
||||||
|
var current_tile = map_data.get_tile(current_x, current_y, current_z)
|
||||||
|
print("Current tile before move: ", current_tile)
|
||||||
|
|
||||||
|
# Set up the destination tile to receive the player
|
||||||
|
destination_tile["unit"] = current_tile["unit"]
|
||||||
|
destination_tile["unit_type"] = "PC"
|
||||||
|
destination_tile["visibility"] = true
|
||||||
|
|
||||||
|
# Clear the current tile's unit data
|
||||||
|
current_tile["unit"] = null
|
||||||
|
current_tile["unit_type"] = null
|
||||||
|
destination_tile["visibility"] = false
|
||||||
|
|
||||||
|
# Update visual position
|
||||||
|
map_renderer.position_unit(player_node, destination_tile["x"], destination_tile["y"], destination_tile["z"])
|
||||||
|
print("Player moved to: ", current_x, ", ", current_y, ", ", new_z)
|
||||||
|
|
||||||
|
return true
|
||||||
1
scripts/isometric_player_controller.gd.uid
Normal file
1
scripts/isometric_player_controller.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://bvqgwafyxcr8r
|
||||||
@ -2,6 +2,21 @@ extends CharacterBody2D
|
|||||||
|
|
||||||
@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
|
@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
|
||||||
@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D
|
@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D
|
||||||
|
@onready var player: CharacterBody2D = $"."
|
||||||
|
|
||||||
|
var hovered_unit = null
|
||||||
|
|
||||||
|
var hover_indicator = preload("res://assets/sprites/ui/ui_icons_green_down4.png")
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
|
||||||
|
var hover_sprite = Sprite2D.new()
|
||||||
|
hover_sprite.texture = hover_indicator
|
||||||
|
hover_sprite.position.y = -15
|
||||||
|
hover_sprite.visible = false
|
||||||
|
hover_sprite.name = "HoverIndicator"
|
||||||
|
hover_sprite.z_index = 100
|
||||||
|
player.add_child(hover_sprite)
|
||||||
|
|
||||||
var player_data = {
|
var player_data = {
|
||||||
"stats": {
|
"stats": {
|
||||||
@ -13,22 +28,52 @@ var player_data = {
|
|||||||
"inventory": [],
|
"inventory": [],
|
||||||
"name": "Hero"
|
"name": "Hero"
|
||||||
}
|
}
|
||||||
|
func _input(event):
|
||||||
|
if event is InputEventMouseMotion:
|
||||||
|
check_hover()
|
||||||
|
|
||||||
|
func check_hover():
|
||||||
|
var mouse_pos = get_global_mouse_position()
|
||||||
|
print("Mouse pos: ", mouse_pos, " Player pos: ", player.position)
|
||||||
|
|
||||||
|
if hovered_unit:
|
||||||
|
hovered_unit.get_node("HoverIndicator").visible = false
|
||||||
|
hovered_unit = null
|
||||||
|
|
||||||
|
if player.has_node("CollisionShape2D"):
|
||||||
|
var collision = player.get_node("CollisionShape2D")
|
||||||
|
var shape = collision.shape
|
||||||
|
|
||||||
|
var local_pos = player.to_local(mouse_pos)
|
||||||
|
|
||||||
|
if shape is RectangleShape2D:
|
||||||
|
var extents = shape.extents
|
||||||
|
if local_pos.x >= -extents.x and local_pos.x <= extents.x and \
|
||||||
|
local_pos.y >= -extents.y and local_pos.y <= extents.y:
|
||||||
|
hovered_unit = player
|
||||||
|
player.get_node("HoverIndicator").visible = true
|
||||||
|
|
||||||
|
|
||||||
func set_unit_position(x, y, z):
|
func set_unit_position(x, y, z):
|
||||||
var z_layer = z
|
var z_layer = z
|
||||||
var x_position = x
|
#var x_position = x
|
||||||
|
var x_position = x + 16
|
||||||
var y_position = y
|
var y_position = y
|
||||||
|
#var y_position = y + get_sprite_size().size.y/2
|
||||||
# Update the visual z-index directly
|
# Update the visual z-index directly
|
||||||
animated_sprite.z_index = z_layer
|
animated_sprite.z_index = z_layer
|
||||||
animated_sprite.position = Vector2i(x_position, y_position)
|
animated_sprite.position = Vector2i(x_position, y_position)
|
||||||
|
print("Palyer Global Pos: ", animated_sprite.position)
|
||||||
print("Palyer Z-Layer: ", z_layer)
|
print("Palyer Z-Layer: ", z_layer)
|
||||||
|
|
||||||
|
func get_sprite_size():
|
||||||
|
return collision_shape_2d.shape
|
||||||
|
|
||||||
func _process(_delta: float):
|
func _process(_delta: float):
|
||||||
play_idle_animation()
|
check_hover()
|
||||||
|
play_player_animation("idle")
|
||||||
|
|
||||||
|
|
||||||
func play_idle_animation():
|
func play_player_animation(state="idle"):
|
||||||
|
if state == "idle":
|
||||||
animated_sprite.play("down")
|
animated_sprite.play("down")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user