diff --git a/DungeonShooting_Godot/prefab/ui/Settlement.tscn b/DungeonShooting_Godot/prefab/ui/Settlement.tscn new file mode 100644 index 0000000..a67e040 --- /dev/null +++ b/DungeonShooting_Godot/prefab/ui/Settlement.tscn @@ -0,0 +1,63 @@ +[gd_scene load_steps=3 format=3 uid="uid://c8rugox2mbl3v"] + +[ext_resource type="Script" path="res://src/game/ui/settlement/SettlementPanel.cs" id="1_ayhkb"] +[ext_resource type="Theme" uid="uid://drb1ajgvcih7p" path="res://resource/theme/theme1.tres" id="2_63mpy"] + +[node name="Settlement" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_ayhkb") + +[node name="Bg" type="ColorRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0, 0, 0, 0.27451) + +[node name="Title" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_top = 268.0 +offset_bottom = 311.0 +grow_horizontal = 2 +theme_override_font_sizes/font_size = 160 +text = "Game Over!" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="ButtonList" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -96.0 +offset_top = -641.0 +offset_right = 96.0 +grow_horizontal = 2 +grow_vertical = 0 +alignment = 1 + +[node name="Restart" type="Button" parent="ButtonList"] +custom_minimum_size = Vector2(0, 50) +layout_mode = 2 +focus_neighbor_top = NodePath("../ToMenu") +theme = ExtResource("2_63mpy") +text = "重新开始 +" + +[node name="ToMenu" type="Button" parent="ButtonList"] +custom_minimum_size = Vector2(0, 50) +layout_mode = 2 +focus_neighbor_bottom = NodePath("../Restart") +theme = ExtResource("2_63mpy") +text = "回到主菜单" diff --git a/DungeonShooting_Godot/resource/theme/mainTheme.tres b/DungeonShooting_Godot/resource/theme/mainTheme.tres index 66396a6..7a2c8ed 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_ej516"] +[sub_resource type="Image" id="Image_blgn2"] 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_ej516") +image = SubResource("Image_blgn2") [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_irjg3"] +[sub_resource type="Image" id="Image_k4r7l"] 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_irjg3") +image = SubResource("Image_k4r7l") [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_lj2yv"] +[sub_resource type="Image" id="Image_cdubj"] 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_lj2yv") +image = SubResource("Image_cdubj") [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_1x5ku"] +[sub_resource type="Image" id="Image_g01qr"] 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_1x5ku") +image = SubResource("Image_g01qr") [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_caf60"] +[sub_resource type="Image" id="Image_ptelj"] 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_caf60") +image = SubResource("Image_ptelj") [sub_resource type="StyleBoxFlat" id="57"] content_margin_left = 6.0 diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index 7e73d3c..e64f8fd 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -173,6 +173,11 @@ /// public bool EnableCustomBehavior { get; set; } = true; + /// + /// 所在的 World 对象 + /// + public World World { get; private set; } + // -------------------------------------------------------------------------------- //组件集合 @@ -234,8 +239,9 @@ private static long _instanceIndex = 0; //初始化节点 - private void _InitNode(string itemId, string scenePath) + private void _InitNode(string itemId, string scenePath, World world) { + World = world; //加载预制体 var tempPrefab = ResourceManager.Load(scenePath); if (tempPrefab == null) diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs index 01e9f66..85f2521 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs @@ -83,10 +83,15 @@ /// public static ActivityObject Create(string itemId) { + var world = GameApplication.Instance.World; + if (world == null) + { + throw new Exception("实例化 ActivityObject 前请先调用 'GameApplication.Instance.CreateNewWorld()' 初始化 World 对象"); + } if (_activityRegisterMap.TryGetValue(itemId, out var item)) { var instance = item.CallBack(); - instance._InitNode(item.RegisterActivity.ItemId, item.RegisterActivity.PrefabPath); + instance._InitNode(item.RegisterActivity.ItemId, item.RegisterActivity.PrefabPath, world); item.RegisterActivity.CustomHandler(instance); return instance; } diff --git a/DungeonShooting_Godot/src/framework/generator/UiManagerMethodsGenerator.cs b/DungeonShooting_Godot/src/framework/generator/UiManagerMethodsGenerator.cs index 7634384..df51675 100644 --- a/DungeonShooting_Godot/src/framework/generator/UiManagerMethodsGenerator.cs +++ b/DungeonShooting_Godot/src/framework/generator/UiManagerMethodsGenerator.cs @@ -54,6 +54,30 @@ $" }}\n" + $"\n" + $" /// \n" + + $" /// 隐藏 {uiName} 的所有实例\n" + + $" /// \n" + + $" public static void Hide_{uiName}()\n" + + $" {{\n" + + $" var uiInstance = Get_{uiName}_Instance();\n" + + $" foreach (var uiPanel in uiInstance)\n" + + $" {{\n" + + $" uiPanel.HideUi();\n" + + $" }}\n" + + $" }}\n" + + $"\n" + + $" /// \n" + + $" /// 销毁 {uiName} 的所有实例\n" + + $" /// \n" + + $" public static void Dispose_{uiName}()\n" + + $" {{\n" + + $" var uiInstance = Get_{uiName}_Instance();\n" + + $" foreach (var uiPanel in uiInstance)\n" + + $" {{\n" + + $" uiPanel.DisposeUi();\n" + + $" }}\n" + + $" }}\n" + + $"\n" + + $" /// \n" + $" /// 获取所有 {uiName} 的实例, 如果没有实例, 则返回一个空数组\n" + $" /// \n" + $" public static UI.{uiName}.{uiName}Panel[] Get_{uiName}_Instance()\n" + diff --git a/DungeonShooting_Godot/src/framework/ui/UiManager.cs b/DungeonShooting_Godot/src/framework/ui/UiManager.cs index ee32c42..a9b5a61 100644 --- a/DungeonShooting_Godot/src/framework/ui/UiManager.cs +++ b/DungeonShooting_Godot/src/framework/ui/UiManager.cs @@ -139,6 +139,54 @@ } /// + /// + /// + public static void HideUi(UiBase uiBase) + { + uiBase.HideUi(); + } + + /// + /// 销毁所有Ui + /// + public static void DisposeAllUi() + { + var map = new Dictionary>(); + foreach (var item in _recordUiMap) + { + map.Add(item.Key, new List(item.Value)); + } + + foreach (var item in map) + { + foreach (var uiBase in item.Value) + { + uiBase.DisposeUi(); + } + } + } + + /// + /// 隐藏所有Ui + /// + public static void HideAllUi() + { + var map = new Dictionary>(); + foreach (var item in _recordUiMap) + { + map.Add(item.Key, new List(item.Value)); + } + + foreach (var item in map) + { + foreach (var uiBase in item.Value) + { + uiBase.HideUi(); + } + } + } + + /// /// 获取Ui实例 /// public static T[] GetUiInstance(string uiName) where T : UiBase diff --git a/DungeonShooting_Godot/src/game/Cursor.cs b/DungeonShooting_Godot/src/game/Cursor.cs index 12d0c5d..3d382cf 100644 --- a/DungeonShooting_Godot/src/game/Cursor.cs +++ b/DungeonShooting_Godot/src/game/Cursor.cs @@ -5,36 +5,6 @@ /// public partial class Cursor : Node2D { - public enum CursorStyle - { - /// - /// 手指 - /// - Finger, - /// - /// 准心模式 - /// - Sight, - } - - /// - /// 准心样式 - /// - public CursorStyle Style - { - get => _style; - set - { - if (_style != value) - { - _style = value; - SetStyle(value); - } - } - } - - private CursorStyle _style; - /// /// 是否是GUI模式 /// @@ -60,28 +30,21 @@ rt = GetNode("RT"); rb = GetNode("RB"); finger = GetNode("Finger"); - SetStyle(CursorStyle.Finger); + SetGuiMode(true); } public override void _Process(double delta) { - if (_style == CursorStyle.Sight) + if (!_isGuiMode) { - if (_isGuiMode) + var targetGun = _mountRole?.Holster.ActiveWeapon; + if (targetGun != null) { - SetScope(0, null); + SetScope(targetGun.CurrScatteringRange, targetGun); } else { - var targetGun = _mountRole?.Holster.ActiveWeapon; - if (targetGun != null) - { - SetScope(targetGun.CurrScatteringRange, targetGun); - } - else - { - SetScope(0, null); - } + SetScope(0, null); } } @@ -94,6 +57,22 @@ public void SetGuiMode(bool flag) { _isGuiMode = flag; + if (flag) //手指 + { + lt.Visible = false; + lb.Visible = false; + rt.Visible = false; + rb.Visible = false; + finger.Visible = true; + } + else //准心 + { + lt.Visible = true; + lb.Visible = true; + rt.Visible = true; + rb.Visible = true; + finger.Visible = false; + } } /// @@ -120,26 +99,6 @@ return _mountRole; } - private void SetStyle(CursorStyle style) - { - if (style == CursorStyle.Finger) //手指 - { - lt.Visible = false; - lb.Visible = false; - rt.Visible = false; - rb.Visible = false; - finger.Visible = true; - } - else if (style == CursorStyle.Sight) //准心 - { - lt.Visible = true; - lb.Visible = true; - rt.Visible = true; - rb.Visible = true; - finger.Visible = false; - } - } - /// /// 设置光标半径范围 /// diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs index 1112ec3..c340fe1 100644 --- a/DungeonShooting_Godot/src/game/GameApplication.cs +++ b/DungeonShooting_Godot/src/game/GameApplication.cs @@ -110,13 +110,10 @@ UiManager.Init(); // 初始化鼠标 InitCursor(); - //加载世界场景 - World = ResourceManager.LoadAndInstantiate(ResourcePath.scene_World_tscn); - SceneRoot.AddChild(World); //地牢管理器 DungeonManager = new DungeonManager(); DungeonManager.Name = "DungeonManager"; - World.AddChild(DungeonManager); + SceneRoot.AddChild(DungeonManager); //打开主菜单Ui UiManager.Open_Main(); } @@ -134,6 +131,33 @@ } /// + /// 创建新的 World 对象, 相当于清理房间 + /// + public World CreateNewWorld() + { + if (World != null) + { + World.QueueFree(); + } + World = ResourceManager.LoadAndInstantiate(ResourcePath.scene_World_tscn); + SceneRoot.AddChild(World); + return World; + } + + /// + /// 销毁 World 对象, 相当于清理房间 + /// + public void DestroyWorld() + { + if (World != null) + { + World.QueueFree(); + } + + World = null; + } + + /// /// 将 viewport 以外的全局坐标 转换成 viewport 内的全局坐标 /// public Vector2 GlobalToViewPosition(Vector2 globalPos) diff --git a/DungeonShooting_Godot/src/game/camera/GameCamera.cs b/DungeonShooting_Godot/src/game/camera/GameCamera.cs index 993097e..19efec9 100644 --- a/DungeonShooting_Godot/src/game/camera/GameCamera.cs +++ b/DungeonShooting_Godot/src/game/camera/GameCamera.cs @@ -70,7 +70,9 @@ // (viewportContainer.Material as ShaderMaterial)?.SetShaderParameter("offset", SubPixelPosition); // GlobalPosition = _camPos.Round(); - if (_followTarget != null) + + var world = GameApplication.Instance.World; + if (world != null && !world.Pause && _followTarget != null) { var mousePosition = InputManager.GetViewportMousePosition(); var targetPosition = _followTarget.GlobalPosition; @@ -104,7 +106,11 @@ public void SetFollowTarget(Role target) { _followTarget = target; - GlobalPosition = target.GlobalPosition; + if (target != null) + { + _camPos = target.GlobalPosition; + GlobalPosition = _camPos; + } } /// diff --git a/DungeonShooting_Godot/src/game/event/EventEnum.cs b/DungeonShooting_Godot/src/game/event/EventEnum.cs index 4d6e2ff..9432065 100644 --- a/DungeonShooting_Godot/src/game/event/EventEnum.cs +++ b/DungeonShooting_Godot/src/game/event/EventEnum.cs @@ -40,4 +40,12 @@ /// 刷新玩家手持武器纹理, 参数类型为 /// OnPlayerRefreshWeaponTexture, + /// + /// 当玩家进入地牢时调用, 没有参数 + /// + OnEnterDungeon, + /// + /// 当玩家退出地牢时调用, 没有参数 + /// + OnExitDungeon, } diff --git a/DungeonShooting_Godot/src/game/event/EventManager.cs b/DungeonShooting_Godot/src/game/event/EventManager.cs index 665fe38..394db2a 100644 --- a/DungeonShooting_Godot/src/game/event/EventManager.cs +++ b/DungeonShooting_Godot/src/game/event/EventManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; +using Godot; /// /// 事件管理器 @@ -57,7 +58,14 @@ var binder = binders[i]; if (!binder.IsDiscard) { - binder.Callback(arg); + try + { + binder.Callback(arg); + } + catch (Exception e) + { + GD.PrintErr($"EventManager 派发事件: '{eventType}' 发生异常: \n" + e.Message + "\n" + e.StackTrace); + } } } } diff --git a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs index be603f9..2d28691 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs @@ -8,11 +8,6 @@ public abstract partial class Weapon : ActivityObject { /// - /// 所有被扔在地上的武器 - /// - public static readonly HashSet UnclaimedWeapons = new HashSet(); - - /// /// 开火回调事件 /// public event Action FireEvent; @@ -288,7 +283,7 @@ //收集落在地上的武器 if (IsInGround()) { - UnclaimedWeapons.Add(this); + World.Weapon_UnclaimedWeapons.Add(this); } } @@ -296,7 +291,7 @@ { base._ExitTree(); - UnclaimedWeapons.Remove(this); + World.Weapon_UnclaimedWeapons.Remove(this); } protected override void Process(float delta) diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs index 0f65d6c..0c33cc3 100644 --- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs +++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs @@ -22,6 +22,7 @@ public const string prefab_ui_EditorTools_tscn = "res://prefab/ui/EditorTools.tscn"; public const string prefab_ui_Main_tscn = "res://prefab/ui/Main.tscn"; public const string prefab_ui_RoomUI_tscn = "res://prefab/ui/RoomUI.tscn"; + public const string prefab_ui_Settlement_tscn = "res://prefab/ui/Settlement.tscn"; public const string prefab_weapon_Knife_tscn = "res://prefab/weapon/Knife.tscn"; public const string prefab_weapon_Weapon_tscn = "res://prefab/weapon/Weapon.tscn"; public const string prefab_weapon_bullet_Bullet_tscn = "res://prefab/weapon/bullet/Bullet.tscn"; @@ -253,8 +254,8 @@ public const string resource_sprite_role_role8_png = "res://resource/sprite/role/role8.png"; public const string resource_sprite_role_role9_png = "res://resource/sprite/role/role9.png"; public const string resource_sprite_shell_shellCase_png = "res://resource/sprite/shell/shellCase.png"; - public const string resource_sprite_ui_Cursor_png = "res://resource/sprite/ui/Cursor.png"; public const string resource_sprite_ui_CursorCenter_png = "res://resource/sprite/ui/CursorCenter.png"; + public const string resource_sprite_ui_cursors_png = "res://resource/sprite/ui/cursors.png"; public const string resource_sprite_ui_font_bg_png = "res://resource/sprite/ui/font_bg.png"; public const string resource_sprite_ui_GUI_png = "res://resource/sprite/ui/GUI.png"; public const string resource_sprite_ui_healthBar_png = "res://resource/sprite/ui/healthBar.png"; diff --git a/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs b/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs index 7a6b33c..3feb3d4 100644 --- a/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs +++ b/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs @@ -9,6 +9,7 @@ public const string EditorTools = "EditorTools"; public const string Main = "Main"; public const string RoomUI = "RoomUI"; + public const string Settlement = "Settlement"; } /// @@ -20,6 +21,30 @@ } /// + /// 隐藏 EditorTools 的所有实例 + /// + public static void Hide_EditorTools() + { + var uiInstance = Get_EditorTools_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.HideUi(); + } + } + + /// + /// 销毁 EditorTools 的所有实例 + /// + public static void Dispose_EditorTools() + { + var uiInstance = Get_EditorTools_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.DisposeUi(); + } + } + + /// /// 获取所有 EditorTools 的实例, 如果没有实例, 则返回一个空数组 /// public static UI.EditorTools.EditorToolsPanel[] Get_EditorTools_Instance() @@ -36,6 +61,30 @@ } /// + /// 隐藏 Main 的所有实例 + /// + public static void Hide_Main() + { + var uiInstance = Get_Main_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.HideUi(); + } + } + + /// + /// 销毁 Main 的所有实例 + /// + public static void Dispose_Main() + { + var uiInstance = Get_Main_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.DisposeUi(); + } + } + + /// /// 获取所有 Main 的实例, 如果没有实例, 则返回一个空数组 /// public static UI.Main.MainPanel[] Get_Main_Instance() @@ -52,6 +101,30 @@ } /// + /// 隐藏 RoomUI 的所有实例 + /// + public static void Hide_RoomUI() + { + var uiInstance = Get_RoomUI_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.HideUi(); + } + } + + /// + /// 销毁 RoomUI 的所有实例 + /// + public static void Dispose_RoomUI() + { + var uiInstance = Get_RoomUI_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.DisposeUi(); + } + } + + /// /// 获取所有 RoomUI 的实例, 如果没有实例, 则返回一个空数组 /// public static UI.RoomUI.RoomUIPanel[] Get_RoomUI_Instance() @@ -59,4 +132,44 @@ return GetUiInstance(nameof(UI.RoomUI.RoomUI)); } + /// + /// 打开 Settlement, 并返回UI实例 + /// + public static UI.Settlement.SettlementPanel Open_Settlement() + { + return OpenUi(UiName.Settlement); + } + + /// + /// 隐藏 Settlement 的所有实例 + /// + public static void Hide_Settlement() + { + var uiInstance = Get_Settlement_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.HideUi(); + } + } + + /// + /// 销毁 Settlement 的所有实例 + /// + public static void Dispose_Settlement() + { + var uiInstance = Get_Settlement_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.DisposeUi(); + } + } + + /// + /// 获取所有 Settlement 的实例, 如果没有实例, 则返回一个空数组 + /// + public static UI.Settlement.SettlementPanel[] Get_Settlement_Instance() + { + return GetUiInstance(nameof(UI.Settlement.Settlement)); + } + } diff --git a/DungeonShooting_Godot/src/game/role/Player.cs b/DungeonShooting_Godot/src/game/role/Player.cs index 6687cca..8daf864 100644 --- a/DungeonShooting_Godot/src/game/role/Player.cs +++ b/DungeonShooting_Godot/src/game/role/Player.cs @@ -28,6 +28,9 @@ public static void SetCurrentPlayer(Player player) { Current = player; + //设置相机和鼠标跟随玩家 + GameCamera.Main.SetFollowTarget(player); + GameApplication.Instance.Cursor.SetMountRole(player); } public override void OnInit() @@ -62,6 +65,10 @@ protected override void Process(float delta) { + if (IsDie) + { + return; + } base.Process(delta); //脸的朝向 if (LookTarget == null) @@ -104,10 +111,20 @@ { Attack(); } + + if (Input.IsKeyPressed(Key.P)) + { + Hurt(1000, 0); + } } protected override void PhysicsProcess(float delta) { + if (IsDie) + { + return; + } + base.PhysicsProcess(delta); HandleMoveInput(delta); //播放动画 @@ -178,6 +195,13 @@ EventManager.EmitEvent(EventEnum.OnPlayerMaxShieldChange, maxShield); } + protected override void OnDie() + { + GameCamera.Main.SetFollowTarget(null); + UiManager.Open_Settlement(); + //GameApplication.Instance.World.ProcessMode = ProcessModeEnum.WhenPaused; + } + /// /// 刷新 ui 上手持的物体 /// diff --git a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs index 57e8bd8..ca1a00a 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs @@ -21,26 +21,6 @@ public partial class Enemy : Role { /// - /// 公共属性, 是否找到目标, 如果找到目标, 则与目标同房间的所有敌人都会知道目标的位置 - /// - public static bool IsFindTarget { get; private set; } - - /// - /// 公共属性, 在哪个区域找到的目标, 所有该区域下的敌人都会知道目标的位置 - /// - public static HashSet FindTargetAffiliationSet { get; } = new HashSet(); - - /// - /// 公共属性, 找到的目标的位置, 如果目标在视野内, 则一直更新 - /// - public static Vector2 FindTargetPosition { get; private set; } - - /// - /// 记录所有存活的敌人 - /// - private static readonly List _enemieList = new List(); - - /// /// 敌人身上的状态机控制器 /// public StateController StateController { get; private set; } @@ -116,16 +96,16 @@ public override void _EnterTree() { - if (!_enemieList.Contains(this)) + if (!World.Enemy_InstanceList.Contains(this)) { - _enemieList.Add(this); + World.Enemy_InstanceList.Add(this); } } public override void _ExitTree() { base._ExitTree(); - _enemieList.Remove(this); + World.Enemy_InstanceList.Remove(this); } protected override void OnDie() @@ -191,7 +171,7 @@ /// public bool CheckUsableWeaponInUnclaimed() { - foreach (var unclaimedWeapon in Weapon.UnclaimedWeapons) + foreach (var unclaimedWeapon in World.Weapon_UnclaimedWeapons) { //判断是否能拾起武器, 条件: 相同的房间 if (unclaimedWeapon.Affiliation == Affiliation) @@ -231,7 +211,7 @@ { Weapon target = null; var position = Position; - foreach (var weapon in Weapon.UnclaimedWeapons) + foreach (var weapon in World.Weapon_UnclaimedWeapons) { //判断是否能拾起武器, 条件: 相同的房间, 或者当前房间目前没有战斗, 或者不在战斗房间 if (weapon.Affiliation == Affiliation) @@ -283,7 +263,7 @@ /// public bool CanChangeLeaveFor() { - if (!IsFindTarget) + if (!World.Enemy_IsFindTarget) { return false; } @@ -292,35 +272,11 @@ if (currState == AiStateEnum.AiNormal || currState == AiStateEnum.AiProbe) { //判断是否在同一个房间内 - return FindTargetAffiliationSet.Contains(Affiliation); + return World.Enemy_FindTargetAffiliationSet.Contains(Affiliation); } return false; } - - /// - /// 更新敌人视野 - /// - public static void UpdateEnemiesView() - { - IsFindTarget = false; - FindTargetAffiliationSet.Clear(); - for (var i = 0; i < _enemieList.Count; i++) - { - var enemy = _enemieList[i]; - var state = enemy.StateController.CurrState; - if (state == AiStateEnum.AiFollowUp || state == AiStateEnum.AiSurround) //目标在视野内 - { - if (!IsFindTarget) - { - IsFindTarget = true; - FindTargetPosition = Player.Current.GetCenterPosition(); - FindTargetAffiliationSet.Add(Player.Current.Affiliation); - } - FindTargetAffiliationSet.Add(enemy.Affiliation); - } - } - } /// /// Ai触发的攻击 diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs index 6d01f73..96e90b5 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs @@ -16,9 +16,9 @@ public override void Enter(AiStateEnum prev, params object[] args) { - if (Enemy.IsFindTarget) + if (Master.World.Enemy_IsFindTarget) { - Master.NavigationAgent2D.TargetPosition = Enemy.FindTargetPosition; + Master.NavigationAgent2D.TargetPosition = Master.World.EnemyFindTargetPosition; } else { @@ -47,7 +47,7 @@ { //每隔一段时间秒更改目标位置 _navigationUpdateTimer = _navigationInterval; - Master.NavigationAgent2D.TargetPosition = Enemy.FindTargetPosition; + Master.NavigationAgent2D.TargetPosition = Master.World.EnemyFindTargetPosition; } else { @@ -58,7 +58,7 @@ { //计算移动 var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.LookTargetPosition(Enemy.FindTargetPosition); + Master.LookTargetPosition(Master.World.EnemyFindTargetPosition); Master.AnimatedSprite.Play(AnimatorNames.Run); Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * Master.MoveSpeed; diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs index 582634f..d5f45e0 100644 --- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs +++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs @@ -25,43 +25,53 @@ public AffiliationArea ActiveAffiliation => Player.Current?.Affiliation; /// - /// 地图根节点 + /// 是否在地牢里 /// - public TileMap TileRoot => GameApplication.Instance.World.TileRoot; + public bool IsInDungeon { get; private set; } private DungeonTile _dungeonTile; private AutoTileConfig _autoTileConfig; private DungeonGenerator _dungeonGenerator; + //房间内所有静态导航网格数据 + private List _roomStaticNavigationList; + private World _world; + + //用于检查房间敌人的计时器 private int _affiliationIndex = 0; private float _checkEnemyTimer = 0; - - //房间内所有静态导航网格数据 - private static List _roomStaticNavigationList = new List(); + + + public DungeonManager() + { + //绑定事件 + EventManager.AddEventListener(EventEnum.OnPlayerFirstEnterRoom, OnPlayerFirstEnterRoom); + EventManager.AddEventListener(EventEnum.OnPlayerEnterRoom, OnPlayerEnterRoom); + } /// /// 加载地牢 /// public void LoadDungeon(DungeonConfig config) { - //绑定事件 - EventManager.AddEventListener(EventEnum.OnPlayerFirstEnterRoom, OnPlayerFirstEnterRoom); - EventManager.AddEventListener(EventEnum.OnPlayerEnterRoom, OnPlayerEnterRoom); - + IsInDungeon = true; var nowTicks = DateTime.Now.Ticks; + //创建世界场景 + _world = GameApplication.Instance.CreateNewWorld(); //生成地牢房间 _dungeonGenerator = new DungeonGenerator(config); _dungeonGenerator.Generate(); //填充地牢 _autoTileConfig = new AutoTileConfig(); - _dungeonTile = new DungeonTile(TileRoot); + _dungeonTile = new DungeonTile(_world.TileRoot); _dungeonTile.AutoFillRoomTile(_autoTileConfig, _dungeonGenerator.StartRoom); //生成寻路网格, 这一步操作只生成过道的导航 _dungeonTile.GenerateNavigationPolygon(GameConfig.AisleFloorMapLayer); //挂载过道导航区域 - _dungeonTile.MountNavigationPolygon(this); + _dungeonTile.MountNavigationPolygon(_world.TileRoot); //过道导航区域数据 + _roomStaticNavigationList = new List(); _roomStaticNavigationList.AddRange(_dungeonTile.GetPolygonData()); //门导航区域数据 _roomStaticNavigationList.AddRange(_dungeonTile.GetConnectDoorPolygonData()); @@ -77,45 +87,70 @@ var playerBirthMark = StartRoom.ActivityMarks.FirstOrDefault(mark => mark.Type == ActivityIdPrefix.ActivityPrefixType.Player); //创建玩家 var player = ActivityObject.Create(ActivityIdPrefix.Role + "0001"); - Player.SetCurrentPlayer(player); if (playerBirthMark != null) { player.Position = playerBirthMark.Position; } player.Name = "Player"; + Player.SetCurrentPlayer(player); player.PutDown(RoomLayerEnum.YSortLayer); player.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0001")); - - //相机跟随玩家 - GameCamera.Main.SetFollowTarget(player); - //鼠标指针挂载到玩家身上 - var cursor = GameApplication.Instance.Cursor; - cursor.Style = Cursor.CursorStyle.Sight; - cursor.SetGuiMode(false); - cursor.SetMountRole(player); - + GameApplication.Instance.Cursor.SetGuiMode(false); //打开游戏中的ui - UiManager.Open_RoomUI(); + var roomUi = UiManager.Open_RoomUI(); + roomUi.InitData(player); + //派发进入地牢事件 + EventManager.EmitEvent(EventEnum.OnEnterDungeon); } - + + /// + /// 退出地牢 + /// + public void ExitDungeon() + { + IsInDungeon = false; + + _dungeonGenerator.EachRoom(DisposeRoomInfo); + _dungeonTile = null; + _autoTileConfig = null; + _dungeonGenerator = null; + _roomStaticNavigationList.Clear(); + _roomStaticNavigationList = null; + + UiManager.Hide_RoomUI(); + Player.SetCurrentPlayer(null); + _world = null; + GameApplication.Instance.DestroyWorld(); + //鼠标还原 + GameApplication.Instance.Cursor.SetGuiMode(false); + //派发退出地牢事件 + EventManager.EmitEvent(EventEnum.OnExitDungeon); + } + public override void _PhysicsProcess(double delta) { - _checkEnemyTimer += (float)delta; - if (_checkEnemyTimer >= 1) + if (IsInDungeon) { - _checkEnemyTimer %= 1; - //检查房间内的敌人存活状况 - OnCheckEnemy(); + _checkEnemyTimer += (float)delta; + if (_checkEnemyTimer >= 1) + { + _checkEnemyTimer %= 1; + //检查房间内的敌人存活状况 + OnCheckEnemy(); + } } } public override void _Process(double delta) { - Enemy.UpdateEnemiesView(); - if (GameApplication.Instance.Debug) + if (IsInDungeon) { - QueueRedraw(); + UpdateEnemiesView(); + if (GameApplication.Instance.Debug) + { + QueueRedraw(); + } } } @@ -160,7 +195,7 @@ var navigationPolygon = new NavigationRegion2D(); navigationPolygon.Name = "NavigationRegion" + (GetChildCount() + 1); navigationPolygon.NavigationPolygon = polygon; - AddChild(navigationPolygon); + _world.TileRoot.AddChild(navigationPolygon); } //创建门 @@ -204,7 +239,7 @@ (roomInfo.Size - new Vector2I(2, 2)) * GameConfig.TileCellSize)); roomInfo.Affiliation = affiliation; - TileRoot.AddChild(affiliation); + _world.AddChild(affiliation); } /// @@ -246,6 +281,39 @@ } } + /// + /// 更新敌人视野 + /// + private void UpdateEnemiesView() + { + _world.Enemy_IsFindTarget = false; + _world.Enemy_FindTargetAffiliationSet.Clear(); + for (var i = 0; i < _world.Enemy_InstanceList.Count; i++) + { + var enemy = _world.Enemy_InstanceList[i]; + var state = enemy.StateController.CurrState; + if (state == AiStateEnum.AiFollowUp || state == AiStateEnum.AiSurround) //目标在视野内 + { + if (!_world.Enemy_IsFindTarget) + { + _world.Enemy_IsFindTarget = true; + _world.EnemyFindTargetPosition = Player.Current.GetCenterPosition(); + _world.Enemy_FindTargetAffiliationSet.Add(Player.Current.Affiliation); + } + _world.Enemy_FindTargetAffiliationSet.Add(enemy.Affiliation); + } + } + } + + private void DisposeRoomInfo(RoomInfo roomInfo) + { + foreach (var activityMark in roomInfo.ActivityMarks) + { + activityMark.QueueFree(); + } + roomInfo.ActivityMarks.Clear(); + } + public override void _Draw() { if (GameApplication.Instance.Debug) @@ -263,7 +331,7 @@ //绘制房间区域, debug 用 private void DrawRoomInfo(RoomInfo room) { - var cellSize = TileRoot.CellQuadrantSize; + var cellSize = _world.TileRoot.CellQuadrantSize; var pos1 = (room.Position + room.Size / 2) * cellSize; //绘制下一个房间 diff --git a/DungeonShooting_Godot/src/game/room/World.cs b/DungeonShooting_Godot/src/game/room/World.cs index 72145db..74f7c4d 100644 --- a/DungeonShooting_Godot/src/game/room/World.cs +++ b/DungeonShooting_Godot/src/game/room/World.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Godot; /// @@ -19,7 +20,57 @@ /// 地图根节点 /// [Export] public TileMap TileRoot; + + /// + /// 是否暂停 + /// + public bool Pause + { + get => _pause; + set + { + if (_pause != value) + { + _pause = value; + if (value) + { + ProcessMode = ProcessModeEnum.Pausable; + } + else + { + ProcessMode = ProcessModeEnum.Inherit; + } + } + } + } + + /// + /// 所有被扔在地上的武器 + /// + public HashSet Weapon_UnclaimedWeapons { get; } = new HashSet(); + + /// + /// 记录所有存活的敌人 + /// + public List Enemy_InstanceList { get; } = new List(); + + /// + /// 公共属性, 敌人是否找到目标, 如果找到目标, 则与目标同房间的所有敌人都会知道目标的位置 + /// + public bool Enemy_IsFindTarget { get; set; } + /// + /// 公共属性, 敌人在哪个区域找到的目标, 所有该区域下的敌人都会知道目标的位置 + /// + public HashSet Enemy_FindTargetAffiliationSet { get; } = new HashSet(); + + /// + /// 公共属性, 敌人找到的目标的位置, 如果目标在视野内, 则一直更新 + /// + public Vector2 EnemyFindTargetPosition { get; set; } + + private bool _pause = false; + public override void _Ready() { TileRoot.YSortEnabled = false; @@ -40,5 +91,5 @@ return null; } - + } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs b/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs index cbf1e66..795c3e7 100644 --- a/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs @@ -38,6 +38,14 @@ _gunBar.OnHide(); } + public void InitData(Player player) + { + _healthBar.SetMaxHp(player.MaxHp); + _healthBar.SetHp(player.Hp); + _healthBar.SetMaxShield(player.MaxShield); + _healthBar.SetShield(player.Shield); + } + public override void Process(float delta) { _gunBar.Process(delta); diff --git a/DungeonShooting_Godot/src/game/ui/settlement/Settlement.cs b/DungeonShooting_Godot/src/game/ui/settlement/Settlement.cs new file mode 100644 index 0000000..e61f5ca --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/settlement/Settlement.cs @@ -0,0 +1,123 @@ +namespace UI.Settlement; + +/// +/// Ui代码, 该类是根据ui场景自动生成的, 请不要手动编辑该类, 以免造成代码丢失 +/// +public abstract partial class Settlement : UiBase +{ + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Settlement.Bg + /// + public UiNode_Bg L_Bg + { + get + { + if (_L_Bg == null) _L_Bg = new UiNode_Bg(GetNodeOrNull("Bg")); + return _L_Bg; + } + } + private UiNode_Bg _L_Bg; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Settlement.Title + /// + public UiNode_Title L_Title + { + get + { + if (_L_Title == null) _L_Title = new UiNode_Title(GetNodeOrNull("Title")); + return _L_Title; + } + } + private UiNode_Title _L_Title; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Settlement.ButtonList + /// + public UiNode_ButtonList L_ButtonList + { + get + { + if (_L_ButtonList == null) _L_ButtonList = new UiNode_ButtonList(GetNodeOrNull("ButtonList")); + return _L_ButtonList; + } + } + private UiNode_ButtonList _L_ButtonList; + + + public Settlement() : base(nameof(Settlement)) + { + } + + /// + /// 类型: , 路径: Settlement.Bg + /// + public class UiNode_Bg : IUiNode + { + public UiNode_Bg(Godot.ColorRect node) : base(node) { } + public override UiNode_Bg Clone() => new ((Godot.ColorRect)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: Settlement.Title + /// + public class UiNode_Title : IUiNode + { + public UiNode_Title(Godot.Label node) : base(node) { } + public override UiNode_Title Clone() => new ((Godot.Label)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: Settlement.ButtonList.Restart + /// + public class UiNode_Restart : IUiNode + { + public UiNode_Restart(Godot.Button node) : base(node) { } + public override UiNode_Restart Clone() => new ((Godot.Button)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: Settlement.ButtonList.ToMenu + /// + public class UiNode_ToMenu : IUiNode + { + public UiNode_ToMenu(Godot.Button node) : base(node) { } + public override UiNode_ToMenu Clone() => new ((Godot.Button)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: Settlement.ButtonList + /// + public class UiNode_ButtonList : IUiNode + { + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Settlement.Restart + /// + public UiNode_Restart L_Restart + { + get + { + if (_L_Restart == null) _L_Restart = new UiNode_Restart(Instance.GetNodeOrNull("Restart")); + return _L_Restart; + } + } + private UiNode_Restart _L_Restart; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Settlement.ToMenu + /// + public UiNode_ToMenu L_ToMenu + { + get + { + if (_L_ToMenu == null) _L_ToMenu = new UiNode_ToMenu(Instance.GetNodeOrNull("ToMenu")); + return _L_ToMenu; + } + } + private UiNode_ToMenu _L_ToMenu; + + public UiNode_ButtonList(Godot.VBoxContainer node) : base(node) { } + public override UiNode_ButtonList Clone() => new ((Godot.VBoxContainer)Instance.Duplicate()); + } + +} diff --git a/DungeonShooting_Godot/src/game/ui/settlement/SettlementPanel.cs b/DungeonShooting_Godot/src/game/ui/settlement/SettlementPanel.cs new file mode 100644 index 0000000..d5c8b89 --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/settlement/SettlementPanel.cs @@ -0,0 +1,33 @@ +using Godot; + +namespace UI.Settlement; + +public partial class SettlementPanel : Settlement +{ + + public override void OnShowUi() + { + L_ButtonList.L_Restart.Instance.Pressed += OnRestartClick; + L_ButtonList.L_ToMenu.Instance.Pressed += OnToMenuClick; + } + + public override void OnHideUi() + { + L_ButtonList.L_Restart.Instance.Pressed -= OnRestartClick; + L_ButtonList.L_ToMenu.Instance.Pressed -= OnToMenuClick; + + } + + private void OnRestartClick() + { + + } + + private void OnToMenuClick() + { + HideUi(); + GameApplication.Instance.DungeonManager.ExitDungeon(); + UiManager.Open_Main(); + } + +}