diff --git a/DungeonShooting_Godot/resource/theme/mainTheme.tres b/DungeonShooting_Godot/resource/theme/mainTheme.tres
index 8d39025..2d0617e 100644
--- a/DungeonShooting_Godot/resource/theme/mainTheme.tres
+++ b/DungeonShooting_Godot/resource/theme/mainTheme.tres
@@ -352,7 +352,7 @@
[sub_resource type="ImageTexture" id="58"]
-[sub_resource type="Image" id="Image_6yv7w"]
+[sub_resource type="Image" id="Image_q1jht"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 1, 255, 255, 255, 39, 255, 255, 255, 67, 255, 255, 255, 67, 255, 255, 255, 39, 255, 255, 255, 1, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 39, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 39, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 66, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 66, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 66, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 66, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 39, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 75, 255, 255, 255, 39, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 1, 255, 255, 255, 39, 255, 255, 255, 67, 255, 255, 255, 67, 255, 255, 255, 39, 255, 255, 255, 1, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "RGBA8",
@@ -362,7 +362,7 @@
}
[sub_resource type="ImageTexture" id="60"]
-image = SubResource("Image_6yv7w")
+image = SubResource("Image_q1jht")
[sub_resource type="StyleBoxTexture" id="61"]
content_margin_left = 2.0
@@ -372,7 +372,7 @@
texture = SubResource("60")
region_rect = Rect2(0, 0, 12, 12)
-[sub_resource type="Image" id="Image_t1c5f"]
+[sub_resource type="Image" id="Image_7ad3g"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 191, 191, 0, 247, 247, 247, 0, 248, 248, 248, 0, 248, 248, 248, 0, 247, 247, 247, 0, 191, 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 191, 191, 0, 191, 191, 191, 4, 247, 247, 247, 98, 248, 248, 248, 167, 248, 248, 248, 167, 247, 247, 247, 98, 191, 191, 191, 4, 191, 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 247, 247, 0, 247, 247, 247, 97, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 247, 247, 247, 97, 247, 247, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 248, 248, 0, 248, 248, 248, 164, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 164, 248, 248, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 248, 248, 0, 248, 248, 248, 164, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 164, 248, 248, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 247, 247, 0, 247, 247, 247, 97, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 248, 248, 248, 186, 247, 247, 247, 97, 247, 247, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 191, 191, 0, 191, 191, 191, 4, 247, 247, 247, 98, 248, 248, 248, 167, 248, 248, 248, 167, 247, 247, 247, 98, 191, 191, 191, 4, 191, 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 191, 191, 0, 247, 247, 247, 0, 248, 248, 248, 0, 248, 248, 248, 0, 247, 247, 247, 0, 191, 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "RGBA8",
@@ -382,7 +382,7 @@
}
[sub_resource type="ImageTexture" id="63"]
-image = SubResource("Image_t1c5f")
+image = SubResource("Image_7ad3g")
[sub_resource type="StyleBoxTexture" id="64"]
content_margin_left = 2.0
@@ -392,7 +392,7 @@
texture = SubResource("63")
region_rect = Rect2(0, 0, 12, 12)
-[sub_resource type="Image" id="Image_qo22b"]
+[sub_resource type="Image" id="Image_emd8d"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 0, 173, 173, 173, 0, 173, 173, 173, 0, 173, 173, 173, 0, 173, 173, 173, 0, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 0, 127, 127, 127, 4, 173, 173, 173, 97, 173, 173, 173, 166, 173, 173, 173, 166, 173, 173, 173, 97, 127, 127, 127, 4, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 0, 172, 172, 172, 96, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 172, 172, 172, 96, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 173, 173, 0, 173, 173, 173, 163, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 163, 173, 173, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 173, 173, 0, 173, 173, 173, 163, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 163, 173, 173, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 0, 172, 172, 172, 96, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 173, 173, 173, 185, 172, 172, 172, 96, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 0, 127, 127, 127, 4, 173, 173, 173, 97, 173, 173, 173, 166, 173, 173, 173, 166, 173, 173, 173, 97, 127, 127, 127, 4, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 0, 173, 173, 173, 0, 173, 173, 173, 0, 173, 173, 173, 0, 173, 173, 173, 0, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "RGBA8",
@@ -402,7 +402,7 @@
}
[sub_resource type="ImageTexture" id="66"]
-image = SubResource("Image_qo22b")
+image = SubResource("Image_emd8d")
[sub_resource type="StyleBoxTexture" id="67"]
content_margin_left = 2.0
@@ -412,7 +412,7 @@
texture = SubResource("66")
region_rect = Rect2(0, 0, 12, 12)
-[sub_resource type="Image" id="Image_byitr"]
+[sub_resource type="Image" id="Image_dhxnp"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 4, 255, 255, 255, 16, 255, 255, 255, 16, 255, 255, 255, 4, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 16, 255, 255, 255, 21, 255, 255, 255, 21, 255, 255, 255, 16, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 16, 255, 255, 255, 21, 255, 255, 255, 21, 255, 255, 255, 16, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 4, 255, 255, 255, 16, 255, 255, 255, 16, 255, 255, 255, 4, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "RGBA8",
@@ -422,7 +422,7 @@
}
[sub_resource type="ImageTexture" id="69"]
-image = SubResource("Image_byitr")
+image = SubResource("Image_dhxnp")
[sub_resource type="StyleBoxTexture" id="70"]
content_margin_left = 0.0
@@ -446,7 +446,7 @@
content_margin_right = 4.0
content_margin_bottom = 4.0
-[sub_resource type="Image" id="Image_hghrc"]
+[sub_resource type="Image" id="Image_5ggjp"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 76, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 76, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 76, 255, 255, 255, 228, 255, 255, 255, 188, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 188, 255, 255, 255, 228, 255, 255, 255, 76, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 18, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 187, 255, 255, 255, 17, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 187, 255, 255, 255, 229, 255, 255, 255, 188, 255, 255, 255, 18, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 185, 255, 255, 255, 17, 255, 255, 255, 17, 255, 255, 255, 186, 255, 255, 255, 229, 255, 255, 255, 188, 255, 255, 255, 19, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 190, 255, 255, 255, 229, 255, 255, 255, 185, 255, 255, 255, 185, 255, 255, 255, 229, 255, 255, 255, 189, 255, 255, 255, 19, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 191, 255, 255, 255, 229, 255, 255, 255, 229, 255, 255, 255, 190, 255, 255, 255, 19, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 229, 255, 255, 255, 188, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 188, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 187, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 187, 255, 255, 255, 229, 255, 255, 255, 188, 255, 255, 255, 18, 255, 255, 255, 19, 255, 255, 255, 188, 255, 255, 255, 229, 255, 255, 255, 186, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 17, 255, 255, 255, 185, 255, 255, 255, 229, 255, 255, 255, 189, 255, 255, 255, 19, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 189, 255, 255, 255, 229, 255, 255, 255, 185, 255, 255, 255, 17, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 76, 255, 255, 255, 229, 255, 255, 255, 190, 255, 255, 255, 19, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 190, 255, 255, 255, 229, 255, 255, 255, 76, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 77, 255, 255, 255, 19, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 19, 255, 255, 255, 77, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "RGBA8",
@@ -456,7 +456,7 @@
}
[sub_resource type="ImageTexture" id="56"]
-image = SubResource("Image_hghrc")
+image = SubResource("Image_5ggjp")
[sub_resource type="StyleBoxFlat" id="57"]
content_margin_left = 6.0
diff --git a/DungeonShooting_Godot/scene/test/TestOptimizeSprite.tscn b/DungeonShooting_Godot/scene/test/TestOptimizeSprite.tscn
index 2122239..fc32b60 100644
--- a/DungeonShooting_Godot/scene/test/TestOptimizeSprite.tscn
+++ b/DungeonShooting_Godot/scene/test/TestOptimizeSprite.tscn
@@ -1,25 +1,18 @@
-[gd_scene load_steps=11 format=3 uid="uid://crwmgbequhxf3"]
+[gd_scene load_steps=3 format=3 uid="uid://crwmgbequhxf3"]
[ext_resource type="Script" path="res://src/test/TestOptimizeSprite.cs" id="1_rwuav"]
[ext_resource type="Texture2D" uid="uid://civvcowt2wklr" path="res://resource/sprite/weapon/weapon0001/Weapon0001.png" id="2_qvs0g"]
-[ext_resource type="Texture2D" uid="uid://b53kofmyan42g" path="res://resource/sprite/weapon/weapon0002/Weapon0002.png" id="3_jejmg"]
-[ext_resource type="Texture2D" uid="uid://clgf63extg800" path="res://resource/sprite/weapon/weapon0003/Weapon0003.png" id="4_twsss"]
-[ext_resource type="Texture2D" uid="uid://504f1r0mi33n" path="res://resource/sprite/weapon/weapon0005/Weapon0005.png" id="5_bdcjp"]
-[ext_resource type="Texture2D" uid="uid://dn0un05nr8xun" path="res://resource/sprite/weapon/weapon0006/Weapon0006.png" id="6_sqcu7"]
-[ext_resource type="Texture2D" uid="uid://bxhbsq0wb2yo1" path="res://resource/sprite/weapon/knife1.png" id="7_w4iwy"]
-[ext_resource type="Texture2D" uid="uid://dto03bc2qbhnj" path="res://resource/sprite/shell/Shell0001.png" id="8_csd6d"]
-[ext_resource type="Texture2D" uid="uid://yn8t7ovmt4gj" path="res://resource/sprite/weapon/gun1.png" id="9_mddgj"]
-[ext_resource type="Texture2D" uid="uid://5geiuvv6hyov" path="res://resource/sprite/weapon/gun2.png" id="10_rxwsh"]
[node name="TestOptimizeSprite" type="Node2D" node_paths=PackedStringArray("SubViewport", "ViewCamera")]
script = ExtResource("1_rwuav")
-ImageList = Array[Texture2D]([ExtResource("2_qvs0g"), ExtResource("3_jejmg"), ExtResource("4_twsss"), ExtResource("5_bdcjp"), ExtResource("6_sqcu7"), ExtResource("7_w4iwy"), ExtResource("8_csd6d"), ExtResource("9_mddgj"), ExtResource("10_rxwsh")])
+ImageList = Array[Texture2D]([ExtResource("2_qvs0g")])
SubViewport = NodePath("SubViewport")
ViewCamera = NodePath("SubViewport/Camera2D")
[node name="SubViewport" type="SubViewport" parent="."]
transparent_bg = true
canvas_item_default_texture_filter = 0
+size = Vector2i(1024, 185)
render_target_update_mode = 4
[node name="Camera2D" type="Camera2D" parent="SubViewport"]
diff --git a/DungeonShooting_Godot/src/framework/map/image/ImageCanvas.cs b/DungeonShooting_Godot/src/framework/map/image/ImageCanvas.cs
index 80eeea2..b912ff9 100644
--- a/DungeonShooting_Godot/src/framework/map/image/ImageCanvas.cs
+++ b/DungeonShooting_Godot/src/framework/map/image/ImageCanvas.cs
@@ -25,8 +25,7 @@
_canvas = Image.Create(width, height, false, Image.Format.Rgba8);
_texture = ImageTexture.CreateFromImage(_canvas);
-
- //_canvas.Fill(Colors.Gray);
+
var w = _canvas.GetWidth();
var h = _canvas.GetHeight();
for (int i = 0; i < w; i++)
@@ -67,8 +66,58 @@
item.CenterX = centerX;
item.CenterY = centerY;
item.FlipY = flipY;
+
+ var cosAngle = Mathf.Cos(item.Rotation);
+ var sinAngle = Mathf.Sin(item.Rotation);
+ if (cosAngle == 0)
+ {
+ cosAngle = 1e-6f;
+ }
- _enqueueItems.Enqueue(item);
+ if (sinAngle == 0)
+ {
+ sinAngle = 1e-6f;
+ }
+
+ var width = item.SrcImage.GetWidth();
+ var height = item.SrcImage.GetHeight();
+ if (width > 128)
+ {
+ GD.PrintErr("警告: 图像宽度大于 128, 旋转后像素点可能绘制到画布外导致像素丢失!");
+ }
+ if (height > 128)
+ {
+ GD.PrintErr("警告: 图像高度大于 128, 旋转后像素点可能绘制到画布外导致像素丢失!");
+ }
+ //旋转后的图片宽高
+ item.RenderWidth = Mathf.CeilToInt(width * Mathf.Abs(cosAngle) + height * sinAngle) + 2;
+ item.RenderHeight = Mathf.CeilToInt(width * sinAngle + height * Mathf.Abs(cosAngle)) + 2;
+
+ if (item.RenderWidth >= RenderViewportSize.X)
+ {
+ GD.PrintErr($"图像旋转后的宽度大于{RenderViewportSize.X}, 不支持绘制到 ImageCanvas 下!");
+ return;
+ }
+
+ //旋转后的图像中心点偏移
+ item.RenderOffsetX =
+ (int)((item.CenterX / sinAngle +
+ (0.5f * item.RenderWidth * sinAngle - 0.5f * item.RenderHeight * cosAngle +
+ 0.5f * height) /
+ cosAngle -
+ (-0.5f * item.RenderWidth * cosAngle - 0.5f * item.RenderHeight * sinAngle +
+ 0.5f * width) /
+ sinAngle - item.CenterY / cosAngle) /
+ (cosAngle / sinAngle + sinAngle / cosAngle)) + 1;
+ item.RenderOffsetY =
+ (int)((item.CenterX / cosAngle -
+ (-0.5f * item.RenderWidth * cosAngle - 0.5f * item.RenderHeight * sinAngle + 0.5f * width) /
+ cosAngle -
+ (0.5f * item.RenderWidth * sinAngle - 0.5f * item.RenderHeight * cosAngle + 0.5f * height) /
+ sinAngle + item.CenterY / sinAngle) /
+ (sinAngle / cosAngle + cosAngle / sinAngle)) + 1;
+
+ _queueItems.Enqueue(item);
}
public void Destroy()
@@ -88,9 +137,4 @@
{
_texture.Update(_canvas);
}
-
- private void HandlerDrawImageInCanvas(ImageRenderData item)
- {
-
- }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/image/ImageCanvas_Static.cs b/DungeonShooting_Godot/src/framework/map/image/ImageCanvas_Static.cs
index 1e63e71..c10c273 100644
--- a/DungeonShooting_Godot/src/framework/map/image/ImageCanvas_Static.cs
+++ b/DungeonShooting_Godot/src/framework/map/image/ImageCanvas_Static.cs
@@ -6,6 +6,19 @@
public partial class ImageCanvas
{
+ public class AreaPlaceholder
+ {
+ public AreaPlaceholder(int start, int end)
+ {
+ Start = start;
+ End = end;
+ }
+
+ public int Start { get; }
+ public int End { get; }
+
+ public int Width => End - Start + 1;
+ }
///
/// 同一帧下将队列里的image绘制到指定画布下最大消耗时间, 如果绘制的时间超过了这个值, 则队列中后面的image将会放到下一帧绘制
@@ -16,26 +29,89 @@
/// 渲染窗口
///
public static SubViewport RenderViewport { get; private set; }
-
+
///
- /// 渲染偏移位置
+ /// 渲染窗口大小
///
- public static Vector2 RenderOffset { get; set; }
-
+ public static Vector2 RenderViewportSize { get; private set; }
+
//预渲染队列
- private static readonly Queue _enqueueItems = new Queue();
+ private static readonly Queue _queueItems = new Queue();
//渲染中的队列
- private static readonly Queue _drawingEnqueueItems = new Queue();
-
+ private static readonly Queue _drawingQueueItems = new Queue();
+ //负责渲染的Sprite回收堆栈
private static readonly Stack _renderSpriteStack = new Stack();
- public static void Init(SubViewport renderViewport, Vector2 renderOffset)
+ private static readonly List _placeholders = new List();
+
+ ///
+ /// 初始化 viewport
+ ///
+ public static void Init(SubViewport renderViewport)
{
+ RenderViewportSize = renderViewport.Size;
RenderViewport = renderViewport;
- RenderOffset = renderOffset;
RenderingServer.FramePostDraw += OnFramePostDraw;
}
+ private static AreaPlaceholder FindNotchPlaceholder(int width)
+ {
+ if (_placeholders.Count == 0)
+ {
+ var result = new AreaPlaceholder(0, width - 1);
+ _placeholders.Add(result);
+ return result;
+ }
+
+ for (var i = 0; i < _placeholders.Count; i++)
+ {
+ if (i == 0) //第一个
+ {
+ var item = _placeholders[i];
+ var end = width - 1;
+ if (end < item.Start)
+ {
+ var result = new AreaPlaceholder(0, end);
+ _placeholders.Insert(0, result);
+ return result;
+ }
+ }
+ else if (i == _placeholders.Count - 1) //最后一个
+ {
+ var item = _placeholders[i];
+ var end = item.End + width;
+ if (end < RenderViewportSize.X)
+ {
+ var result = new AreaPlaceholder(item.End + 1, end);
+ _placeholders.Add(result);
+ return result;
+ }
+ }
+ else //中间
+ {
+ var prev = _placeholders[i - 1];
+ var next = _placeholders[i];
+ var end = prev.End + width;
+ if (end < next.Start + 1)
+ {
+ var result = new AreaPlaceholder(prev.End + 1, end);
+ _placeholders.Insert(i, result);
+ return result;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static void RemovePlaceholder(AreaPlaceholder placeholder)
+ {
+ if (!_placeholders.Remove(placeholder))
+ {
+ GD.PrintErr("移除 AreaPlaceholder 失败!");
+ }
+ }
+
private static ImageRenderSprite GetRenderSprite(Vector2 position)
{
ImageRenderSprite renderSprite;
@@ -61,39 +137,61 @@
private static void OnFramePostDraw()
{
- //上一帧绘制的image
- if (_drawingEnqueueItems.Count > 0)
+ //最大处理时间, 如果超过了, 那就下一帧再画其它的吧
+ float step1Time;
+ float step2Time;
+ if (_drawingQueueItems.Count == 0)
{
+ step1Time = 0;
+ step2Time = MaxHandlerTime;
+ }
+ else if (_queueItems.Count == 0)
+ {
+ step1Time = MaxHandlerTime;
+ step2Time = 0;
+ }
+ else
+ {
+ step1Time = step2Time = MaxHandlerTime / 2;
+ }
+
+ //上一帧绘制的image
+ if (_drawingQueueItems.Count > 0)
+ {
+ var startTime = DateTime.Now;
+
var redrawCanvas = new HashSet();
var viewportTexture = RenderViewport.GetTexture();
using (var image = viewportTexture.GetImage())
{
- var num = 0;
+ var index = 0;
do
{
- var item = _drawingEnqueueItems.Dequeue();
+ var item = _drawingQueueItems.Dequeue();
if (!item.ImageCanvas.IsDestroyed)
{
redrawCanvas.Add(item.ImageCanvas);
- //截取Viewport像素点
- item.ImageCanvas._canvas.BlendRect(image,
- new Rect2I(0, 0, item.RenderWidth, item.RenderHeight),
- new Vector2I(item.X - item.RenderOffsetX, item.Y - item.RenderOffsetY)
- );
+ //处理绘图
+ HandleDrawing(index, image, item);
+ index++;
+ }
- item.SrcImage.Dispose();
- item.SrcImage = null;
- num++;
+ //移除站位符
+ if (item.AreaPlaceholder != null)
+ {
+ RemovePlaceholder(item.AreaPlaceholder);
+ item.AreaPlaceholder = null;
}
//回收 RenderSprite
if (item.RenderSprite != null)
{
ReclaimRenderSprite(item.RenderSprite);
+ item.RenderSprite = null;
}
- } while (_drawingEnqueueItems.Count > 0);
+ } while (_drawingQueueItems.Count > 0 && (DateTime.Now - startTime).TotalMilliseconds < step1Time);
- GD.Print($"当前帧绘制完成数量: {num}, 绘制队列数量: {_drawingEnqueueItems.Count}");
+ GD.Print($"当前帧绘制完成数量: {index}, 绘制队列数量: {_drawingQueueItems.Count}");
}
//重绘画布
@@ -104,70 +202,82 @@
}
//处理下一批image
- if (_enqueueItems.Count > 0)
+ if (_queueItems.Count > 0)
{
var startTime = DateTime.Now;
-
- var num = 0;
+ List retryList = null;
+ var index = 0;
//执行绘制操作
- //绘制的总时间不能超过MaxHandlerTime, 如果超过了, 那就下一帧再画其它的吧
do
{
- var item = _enqueueItems.Dequeue();
+ var item = _queueItems.Dequeue();
if (!item.ImageCanvas.IsDestroyed)
{
-
- var cosAngle = Mathf.Cos(item.Rotation);
- var sinAngle = Mathf.Sin(item.Rotation);
- if (cosAngle == 0)
+ //排队绘制
+ if (HandleEnqueueDrawing(index, item))
{
- cosAngle = 1e-6f;
+ index++;
}
-
- if (sinAngle == 0)
+ else //添加失败
{
- sinAngle = 1e-6f;
+ if (retryList == null)
+ {
+ retryList = new List();
+ }
+ retryList.Add(item);
}
-
- var width = item.SrcImage.GetWidth();
- var height = item.SrcImage.GetHeight();
- //旋转后的图片宽高
- item.RenderWidth = Mathf.CeilToInt(width * Mathf.Abs(cosAngle) + height * sinAngle) + 2;
- item.RenderHeight = Mathf.CeilToInt(width * sinAngle + height * Mathf.Abs(cosAngle)) + 2;
-
- item.RenderOffsetX =
- (int)((item.CenterX / sinAngle +
- (0.5f * item.RenderWidth * sinAngle - 0.5f * item.RenderHeight * cosAngle +
- 0.5f * height) /
- cosAngle -
- (-0.5f * item.RenderWidth * cosAngle - 0.5f * item.RenderHeight * sinAngle +
- 0.5f * width) /
- sinAngle - item.CenterY / cosAngle) /
- (cosAngle / sinAngle + sinAngle / cosAngle)) + 1;
-
-
- item.RenderOffsetY =
- (int)((item.CenterX / cosAngle -
- (-0.5f * item.RenderWidth * cosAngle - 0.5f * item.RenderHeight * sinAngle + 0.5f * width) /
- cosAngle -
- (0.5f * item.RenderWidth * sinAngle - 0.5f * item.RenderHeight * cosAngle + 0.5f * height) /
- sinAngle + item.CenterY / sinAngle) /
- (sinAngle / cosAngle + cosAngle / sinAngle)) + 1;
-
- var renderSprite = GetRenderSprite(new Vector2(0 + item.RenderOffsetX, 0 + item.RenderOffsetY));
- item.RenderSprite = renderSprite;
- //设置绘制信息
- renderSprite.Sprite.Offset = new Vector2(item.CenterX, item.CenterY);
- renderSprite.Sprite.Rotation = item.Rotation;
-
- renderSprite.SetImage(item.SrcImage);
- _drawingEnqueueItems.Enqueue(item);
- num++;
}
- } while (_enqueueItems.Count > 0 && (DateTime.Now - startTime).TotalMilliseconds < MaxHandlerTime);
+ } while (_queueItems.Count > 0 && (DateTime.Now - startTime).TotalMilliseconds < step2Time);
- GD.Print($"当前帧进入绘制绘队列数量: {num}, 待绘制队列数量: {_enqueueItems.Count}, 绘制队列数量: {_drawingEnqueueItems.Count}");
+ if (retryList != null)
+ {
+ foreach (var renderData in retryList)
+ {
+ _queueItems.Enqueue(renderData);
+ }
+ }
+
+ GD.Print($"当前帧进入绘制绘队列数量: {index}, 待绘制队列数量: {_queueItems.Count}, 绘制队列数量: {_drawingQueueItems.Count}");
}
}
+
+ private static void HandleDrawing(int index, Image image, ImageRenderData item)
+ {
+ //截取Viewport像素点
+ item.ImageCanvas._canvas.BlendRect(image,
+ new Rect2I(item.RenderX, item.RenderY,item.RenderWidth, item.RenderHeight),
+ new Vector2I(item.X - item.RenderOffsetX, item.Y - item.RenderOffsetY)
+ );
+
+ item.SrcImage.Dispose();
+ item.SrcImage = null;
+ }
+
+ //处理排队绘制
+ private static bool HandleEnqueueDrawing(int index, ImageRenderData item)
+ {
+ var placeholder = FindNotchPlaceholder(item.RenderWidth);
+ if (placeholder == null) //没有找到合适的位置
+ {
+ return false;
+ }
+
+ item.AreaPlaceholder = placeholder;
+
+ //计算渲染在 viewport 上的位置
+ item.RenderX = placeholder.Start + item.RenderOffsetX;
+ item.RenderY = item.RenderOffsetY;
+
+ var renderSprite = GetRenderSprite(new Vector2(item.RenderX, item.RenderY));
+ item.RenderSprite = renderSprite;
+ //设置中心点
+ renderSprite.Sprite.Offset = new Vector2(item.CenterX, item.CenterY);
+ //设置旋转
+ renderSprite.Sprite.Rotation = item.Rotation;
+
+ renderSprite.SetImage(item.SrcImage);
+ _drawingQueueItems.Enqueue(item);
+ return true;
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/image/ImageRenderData.cs b/DungeonShooting_Godot/src/framework/map/image/ImageRenderData.cs
index da66b00..a171753 100644
--- a/DungeonShooting_Godot/src/framework/map/image/ImageRenderData.cs
+++ b/DungeonShooting_Godot/src/framework/map/image/ImageRenderData.cs
@@ -12,18 +12,59 @@
/// 需要绘制的原图
///
public Image SrcImage;
+ ///
+ /// x坐标
+ ///
public int X;
+ ///
+ /// y坐标
+ ///
public int Y;
+ ///
+ /// 旋转角度, 弧度制
+ ///
public float Rotation;
+ ///
+ /// 中心点x
+ ///
public int CenterX;
+ ///
+ /// 中心点y
+ ///
public int CenterY;
+ ///
+ /// 是否翻转y轴
+ ///
public bool FlipY;
- //----------------------------------------
+ //----------------------------------------------------------------------
+ ///
+ /// 将 SrcImage 渲染到 viewport 上的 sprite 对象
+ ///
public ImageRenderSprite RenderSprite;
+ ///
+ /// 在 viewport 上的宽度
+ ///
public int RenderWidth;
+ ///
+ /// 在 viewport 上的高度
+ ///
public int RenderHeight;
-
+ ///
+ /// 渲染在 viewport 上的x坐标
+ ///
+ public int RenderX;
+ ///
+ /// 渲染在 viewport 上的y坐标
+ ///
+ public int RenderY;
+ ///
+ /// 渲染在 viewport 上中心点x轴偏移量
+ ///
public int RenderOffsetX;
+ ///
+ /// 渲染在 viewport 上中心点y轴偏移量
+ ///
public int RenderOffsetY;
+ public ImageCanvas.AreaPlaceholder AreaPlaceholder;
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/test/TestOptimizeSprite.cs b/DungeonShooting_Godot/src/test/TestOptimizeSprite.cs
index f9dda88..1f62a18 100644
--- a/DungeonShooting_Godot/src/test/TestOptimizeSprite.cs
+++ b/DungeonShooting_Godot/src/test/TestOptimizeSprite.cs
@@ -10,7 +10,7 @@
public override void _Ready()
{
- ImageCanvas.Init(SubViewport, ViewCamera.Position);
+ ImageCanvas.Init(SubViewport);
ImageCanvas.MaxHandlerTime = 4;
var scale = 10;