diff --git a/DungeonShooting_Godot/DungeonShooting.sln b/DungeonShooting_Godot/DungeonShooting.sln
index 759fe2f..13ae556 100644
--- a/DungeonShooting_Godot/DungeonShooting.sln
+++ b/DungeonShooting_Godot/DungeonShooting.sln
@@ -3,17 +3,17 @@
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DungeonShooting", "DungeonShooting.csproj", "{5FEA73C5-32E3-43C4-839F-A1485EAC91BC}"
EndProject
Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- ExportDebug|Any CPU = ExportDebug|Any CPU
- ExportRelease|Any CPU = ExportRelease|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
- {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
- {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
- {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
- EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ ExportDebug|Any CPU = ExportDebug|Any CPU
+ ExportRelease|Any CPU = ExportRelease|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
+ {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
+ {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
+ {5FEA73C5-32E3-43C4-839F-A1485EAC91BC}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
+ EndGlobalSection
EndGlobal
diff --git a/DungeonShooting_Godot/GameSave.json b/DungeonShooting_Godot/GameSave.json
new file mode 100644
index 0000000..d7e862e
--- /dev/null
+++ b/DungeonShooting_Godot/GameSave.json
@@ -0,0 +1,5 @@
+{
+ "FullScreen": false,
+ "BgmVolume": 0.5,
+ "SfxVolume": 0.37
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/excel/ActivityBase.xlsx b/DungeonShooting_Godot/excel/ActivityBase.xlsx
index 14e1128..312c49f 100644
--- a/DungeonShooting_Godot/excel/ActivityBase.xlsx
+++ b/DungeonShooting_Godot/excel/ActivityBase.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excel/EditorObject.xlsx b/DungeonShooting_Godot/excel/EditorObject.xlsx
new file mode 100644
index 0000000..6341a4e
--- /dev/null
+++ b/DungeonShooting_Godot/excel/EditorObject.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excel/EnemyBase.xlsx b/DungeonShooting_Godot/excel/EnemyBase.xlsx
index b70b253..3bd9165 100644
--- a/DungeonShooting_Godot/excel/EnemyBase.xlsx
+++ b/DungeonShooting_Godot/excel/EnemyBase.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excel/Sound.xlsx b/DungeonShooting_Godot/excel/Sound.xlsx
index 47c6585..f972226 100644
--- a/DungeonShooting_Godot/excel/Sound.xlsx
+++ b/DungeonShooting_Godot/excel/Sound.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/prefab/bullet/special/SpecialBullet0001.tscn b/DungeonShooting_Godot/prefab/bullet/special/SpecialBullet0001.tscn
new file mode 100644
index 0000000..91321c6
--- /dev/null
+++ b/DungeonShooting_Godot/prefab/bullet/special/SpecialBullet0001.tscn
@@ -0,0 +1,60 @@
+[gd_scene load_steps=8 format=3 uid="uid://cbs2xm3rn8ya1"]
+
+[ext_resource type="Script" path="res://src/game/activity/bullet/special/SpecialBullet0001.cs" id="1_n2flm"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_w38kf"]
+[ext_resource type="Texture2D" uid="uid://bskw374th4d8w" path="res://resource/sprite/bullet/special/SpecialBullet0001.png" id="3_ngxxk"]
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_2deln"]
+resource_local_to_scene = true
+shader = ExtResource("2_w38kf")
+shader_parameter/blend = Color(0, 0, 0, 0.470588)
+shader_parameter/schedule = 1.0
+shader_parameter/modulate = Color(1, 1, 1, 1)
+shader_parameter/show_outline = true
+shader_parameter/outline_color = Color(0, 0, 0, 1)
+shader_parameter/outline_rainbow = false
+shader_parameter/outline_use_blend = true
+shader_parameter/grey = 0.0
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_s06lj"]
+resource_local_to_scene = true
+shader = ExtResource("2_w38kf")
+shader_parameter/blend = Color(1, 1, 1, 1)
+shader_parameter/schedule = 0.0
+shader_parameter/modulate = Color(1, 1, 1, 1)
+shader_parameter/show_outline = true
+shader_parameter/outline_color = Color(0, 0, 0, 1)
+shader_parameter/outline_rainbow = false
+shader_parameter/outline_use_blend = true
+shader_parameter/grey = 0.0
+
+[sub_resource type="AtlasTexture" id="AtlasTexture_afa32"]
+atlas = ExtResource("3_ngxxk")
+region = Rect2(0, 0, 16, 16)
+
+[sub_resource type="SpriteFrames" id="SpriteFrames_e2eoq"]
+animations = [{
+"frames": [{
+"duration": 1.0,
+"texture": SubResource("AtlasTexture_afa32")
+}],
+"loop": true,
+"name": &"default",
+"speed": 5.0
+}]
+
+[node name="SpecialBullet0001" type="CharacterBody2D" node_paths=PackedStringArray("ShadowSprite", "AnimatedSprite", "Collision")]
+script = ExtResource("1_n2flm")
+ShadowSprite = NodePath("ShadowSprite")
+AnimatedSprite = NodePath("AnimatedSprite")
+Collision = NodePath("Collision")
+
+[node name="ShadowSprite" type="Sprite2D" parent="."]
+z_index = -1
+material = SubResource("ShaderMaterial_2deln")
+
+[node name="AnimatedSprite" type="AnimatedSprite2D" parent="."]
+material = SubResource("ShaderMaterial_s06lj")
+sprite_frames = SubResource("SpriteFrames_e2eoq")
+
+[node name="Collision" type="CollisionShape2D" parent="."]
diff --git a/DungeonShooting_Godot/prefab/bullet/summons/Summons0001.tscn b/DungeonShooting_Godot/prefab/bullet/summons/Summons0001.tscn
new file mode 100644
index 0000000..ab34415
--- /dev/null
+++ b/DungeonShooting_Godot/prefab/bullet/summons/Summons0001.tscn
@@ -0,0 +1,97 @@
+[gd_scene load_steps=13 format=3 uid="uid://ux8ovkebgfle"]
+
+[ext_resource type="Script" path="res://src/game/activity/bullet/summons/Summons.cs" id="1_86dyv"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_pmcyj"]
+[ext_resource type="Texture2D" uid="uid://ckd0dyueicc4r" path="res://resource/sprite/bullet/summons/Summons0001.png" id="3_osoic"]
+[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/common/Smoke.png" id="4_m8coj"]
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_bs7yr"]
+resource_local_to_scene = true
+shader = ExtResource("2_pmcyj")
+shader_parameter/blend = Color(0, 0, 0, 0.470588)
+shader_parameter/schedule = 1.0
+shader_parameter/modulate = Color(1, 1, 1, 1)
+shader_parameter/show_outline = true
+shader_parameter/outline_color = Color(0, 0, 0, 1)
+shader_parameter/outline_rainbow = false
+shader_parameter/outline_use_blend = true
+shader_parameter/grey = 0.0
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_2csl0"]
+resource_local_to_scene = true
+shader = ExtResource("2_pmcyj")
+shader_parameter/blend = Color(1, 1, 1, 1)
+shader_parameter/schedule = 0.0
+shader_parameter/modulate = Color(1.8, 1.8, 1.8, 1)
+shader_parameter/show_outline = false
+shader_parameter/outline_color = Color(0, 0, 0, 1)
+shader_parameter/outline_rainbow = false
+shader_parameter/outline_use_blend = true
+shader_parameter/grey = 0.0
+
+[sub_resource type="SpriteFrames" id="SpriteFrames_h38jn"]
+animations = [{
+"frames": [{
+"duration": 1.0,
+"texture": ExtResource("3_osoic")
+}],
+"loop": true,
+"name": &"default",
+"speed": 5.0
+}]
+
+[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_1jwtk"]
+particles_animation = true
+particles_anim_h_frames = 3
+particles_anim_v_frames = 1
+particles_anim_loop = false
+
+[sub_resource type="Curve" id="Curve_is6b3"]
+_data = [Vector2(0, 0.730415), 0.0, 0.0, 0, 0, Vector2(0.245238, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.0235023), 0.0, 0.0, 0, 0]
+point_count = 3
+
+[sub_resource type="CurveTexture" id="CurveTexture_ie2e7"]
+curve = SubResource("Curve_is6b3")
+
+[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_1ylf6"]
+lifetime_randomness = 0.7
+particle_flag_disable_z = true
+angle_max = 360.0
+spread = 180.0
+initial_velocity_min = 5.0
+initial_velocity_max = 15.0
+angular_velocity_max = 45.0
+gravity = Vector3(0, 0, 0)
+scale_min = 0.25
+scale_max = 1.2
+scale_curve = SubResource("CurveTexture_ie2e7")
+color = Color(0.87, 0.43674, 0.1479, 0.588235)
+anim_offset_max = 1.0
+
+[sub_resource type="CircleShape2D" id="CircleShape2D_woqud"]
+radius = 4.0
+
+[node name="Summons0001" type="CharacterBody2D" node_paths=PackedStringArray("ShadowSprite", "AnimatedSprite", "Collision")]
+collision_layer = 0
+script = ExtResource("1_86dyv")
+ShadowSprite = NodePath("ShadowSprite")
+AnimatedSprite = NodePath("AnimatedSprite")
+Collision = NodePath("Collision")
+
+[node name="ShadowSprite" type="Sprite2D" parent="."]
+z_index = -1
+material = SubResource("ShaderMaterial_bs7yr")
+
+[node name="AnimatedSprite" type="AnimatedSprite2D" parent="."]
+material = SubResource("ShaderMaterial_2csl0")
+sprite_frames = SubResource("SpriteFrames_h38jn")
+
+[node name="GPUParticles2D" type="GPUParticles2D" parent="AnimatedSprite"]
+material = SubResource("CanvasItemMaterial_1jwtk")
+amount = 11
+process_material = SubResource("ParticleProcessMaterial_1ylf6")
+texture = ExtResource("4_m8coj")
+lifetime = 0.65
+
+[node name="Collision" type="CollisionShape2D" parent="."]
+shape = SubResource("CircleShape2D_woqud")
diff --git a/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0001.tscn b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0001.tscn
index b6cf821..ff529d7 100644
--- a/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0001.tscn
+++ b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0001.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=5 format=3 uid="uid://m0s0k5nw7nbi"]
+[gd_scene load_steps=8 format=3 uid="uid://bi1kwcbfb0y4h"]
-[ext_resource type="Material" uid="uid://c1chld6lkpgji" path="res://resource/material/SmokeParticleMaterial.tres" id="1_leomh"]
+[ext_resource type="Texture2D" uid="uid://bs1lan5uwxyfg" path="res://resource/curve/Curve1.tres" id="1_v3mqi"]
[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/common/Smoke.png" id="2_c2t2e"]
[ext_resource type="Script" path="res://src/game/effects/AutoDestroyParticles.cs" id="3_5cpi6"]
@@ -10,11 +10,30 @@
particles_anim_v_frames = 1
particles_anim_loop = false
+[sub_resource type="Gradient" id="Gradient_ryemi"]
+colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0.537255)
+
+[sub_resource type="GradientTexture1D" id="GradientTexture1D_4mhw0"]
+gradient = SubResource("Gradient_ryemi")
+
+[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_404sd"]
+particle_flag_disable_z = true
+spread = 180.0
+initial_velocity_min = 5.0
+initial_velocity_max = 35.0
+gravity = Vector3(0, 0, 0)
+scale_min = 0.8
+scale_max = 0.8
+scale_curve = ExtResource("1_v3mqi")
+color = Color(0.992157, 0.788235, 0.788235, 0.627451)
+color_ramp = SubResource("GradientTexture1D_4mhw0")
+anim_offset_max = 1.0
+
[node name="EnemyBloodEffect" type="GPUParticles2D" node_paths=PackedStringArray("Particles2D")]
material = SubResource("CanvasItemMaterial_emuda")
emitting = false
amount = 10
-process_material = ExtResource("1_leomh")
+process_material = SubResource("ParticleProcessMaterial_404sd")
texture = ExtResource("2_c2t2e")
lifetime = 1.2
one_shot = true
diff --git a/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0002.tscn b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0002.tscn
index f402fb8..2491e9c 100644
--- a/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0002.tscn
+++ b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0002.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=6 format=3 uid="uid://dayagrbplo04b"]
-[ext_resource type="Texture2D" uid="uid://nbwtavmsjps6" path="res://resource/sprite/role/dle_liquid/enemy0001_Icon_liquid.png" id="1_ite3h"]
+[ext_resource type="Texture2D" uid="uid://d2jhv7aygfeh0" path="res://resource/sprite/role/dle_liquid/enemy0002.png" id="1_jok6p"]
[ext_resource type="Script" path="res://src/game/effects/enemy/EnemyBlood0002.cs" id="2_uof3e"]
[sub_resource type="Animation" id="Animation_p16al"]
@@ -56,8 +56,7 @@
}
[node name="EnemyBlood0002" type="Sprite2D"]
-modulate = Color(0.992157, 0.788235, 0.788235, 1)
-texture = ExtResource("1_ite3h")
+texture = ExtResource("1_jok6p")
centered = false
offset = Vector2(-16, -24)
region_enabled = true
diff --git a/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0003.tscn b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0003.tscn
new file mode 100644
index 0000000..6469f65
--- /dev/null
+++ b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0003.tscn
@@ -0,0 +1,71 @@
+[gd_scene load_steps=6 format=3 uid="uid://dcgsdlklegiia"]
+
+[ext_resource type="Texture2D" uid="uid://cjg050p1t5skx" path="res://resource/sprite/role/dle_liquid/enemy0003.png" id="1_ybkq0"]
+[ext_resource type="Script" path="res://src/game/effects/enemy/EnemyBlood0002.cs" id="2_pfwfh"]
+
+[sub_resource type="Animation" id="Animation_p16al"]
+length = 0.001
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath(".:region_rect")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Rect2(2.08165e-12, 2.08165e-12, 20, 48)]
+}
+
+[sub_resource type="Animation" id="Animation_rir6a"]
+resource_name = "default"
+length = 0.2
+step = 0.05
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath(".:region_rect")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0, 0.2),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Rect2(2.08165e-12, 2.08165e-12, 20, 48), Rect2(2.08165e-12, 2.08165e-12, 80, 48)]
+}
+tracks/1/type = "method"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath(".")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/keys = {
+"times": PackedFloat32Array(0.2),
+"transitions": PackedFloat32Array(1),
+"values": [{
+"args": [],
+"method": &"DoDestory"
+}]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_f1xdh"]
+_data = {
+"RESET": SubResource("Animation_p16al"),
+"default": SubResource("Animation_rir6a")
+}
+
+[node name="EnemyBlood0002" type="Sprite2D"]
+texture = ExtResource("1_ybkq0")
+centered = false
+offset = Vector2(-16, -24)
+region_enabled = true
+region_rect = Rect2(2.08165e-12, 2.08165e-12, 20, 48)
+region_filter_clip_enabled = true
+script = ExtResource("2_pfwfh")
+
+[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
+libraries = {
+"": SubResource("AnimationLibrary_f1xdh")
+}
+autoplay = "default"
diff --git a/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0004.tscn b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0004.tscn
new file mode 100644
index 0000000..d846b07
--- /dev/null
+++ b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0004.tscn
@@ -0,0 +1,71 @@
+[gd_scene load_steps=6 format=3 uid="uid://cur33b2isgcon"]
+
+[ext_resource type="Texture2D" uid="uid://cb4wfl7pytyle" path="res://resource/sprite/role/dle_liquid/enemy0004.png" id="1_vhrh2"]
+[ext_resource type="Script" path="res://src/game/effects/enemy/EnemyBlood0002.cs" id="2_jpad1"]
+
+[sub_resource type="Animation" id="Animation_p16al"]
+length = 0.001
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath(".:region_rect")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Rect2(2.08165e-12, 2.08165e-12, 20, 48)]
+}
+
+[sub_resource type="Animation" id="Animation_rir6a"]
+resource_name = "default"
+length = 0.2
+step = 0.05
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath(".:region_rect")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0, 0.2),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Rect2(2.08165e-12, 2.08165e-12, 20, 48), Rect2(2.08165e-12, 2.08165e-12, 80, 48)]
+}
+tracks/1/type = "method"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath(".")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/keys = {
+"times": PackedFloat32Array(0.2),
+"transitions": PackedFloat32Array(1),
+"values": [{
+"args": [],
+"method": &"DoDestory"
+}]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_f1xdh"]
+_data = {
+"RESET": SubResource("Animation_p16al"),
+"default": SubResource("Animation_rir6a")
+}
+
+[node name="EnemyBlood0002" type="Sprite2D"]
+texture = ExtResource("1_vhrh2")
+centered = false
+offset = Vector2(-16, -24)
+region_enabled = true
+region_rect = Rect2(2.08165e-12, 2.08165e-12, 20, 48)
+region_filter_clip_enabled = true
+script = ExtResource("2_jpad1")
+
+[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
+libraries = {
+"": SubResource("AnimationLibrary_f1xdh")
+}
+autoplay = "default"
diff --git a/DungeonShooting_Godot/prefab/role/enemy/Enemy0003.tscn b/DungeonShooting_Godot/prefab/role/enemy/Enemy0003.tscn
deleted file mode 100644
index 78ac185..0000000
--- a/DungeonShooting_Godot/prefab/role/enemy/Enemy0003.tscn
+++ /dev/null
@@ -1,86 +0,0 @@
-[gd_scene load_steps=13 format=3 uid="uid://87kfirk3fugd"]
-
-[ext_resource type="PackedScene" uid="uid://dbrig6dq441wo" path="res://prefab/role/template/AiTemplate.tscn" id="1_34027"]
-[ext_resource type="Script" path="res://src/game/activity/role/enemy/Enemy.cs" id="2_pakvr"]
-[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_egkdu"]
-[ext_resource type="SpriteFrames" uid="uid://cnk1wmk3uy4aa" path="res://resource/spriteFrames/role/Enemy0003.tres" id="4_sd22a"]
-[ext_resource type="Animation" uid="uid://b4mgiysicdk2b" path="res://resource/animation/enemy/Enemy_reset.res" id="5_5area"]
-[ext_resource type="Animation" uid="uid://gvkkxspcdwrp" path="res://resource/animation/enemy/Enemy_astonished.res" id="6_o4vh5"]
-[ext_resource type="Animation" uid="uid://16rxpnsgj5tl" path="res://resource/animation/enemy/Enemy_notify.res" id="7_y8dcl"]
-[ext_resource type="Animation" uid="uid://cmje7jsgrhgmx" path="res://resource/animation/enemy/Enemy_query.res" id="8_7j8ux"]
-
-[sub_resource type="ShaderMaterial" id="ShaderMaterial_3nkur"]
-resource_local_to_scene = true
-shader = ExtResource("3_egkdu")
-shader_parameter/blend = Color(0, 0, 0, 0.470588)
-shader_parameter/schedule = 1.0
-shader_parameter/modulate = Color(1, 1, 1, 1)
-shader_parameter/show_outline = true
-shader_parameter/outline_color = Color(0, 0, 0, 1)
-shader_parameter/outline_rainbow = false
-shader_parameter/outline_use_blend = true
-shader_parameter/grey = 0.0
-
-[sub_resource type="ShaderMaterial" id="ShaderMaterial_2kup1"]
-resource_local_to_scene = true
-shader = ExtResource("3_egkdu")
-shader_parameter/blend = Color(1, 1, 1, 1)
-shader_parameter/schedule = 0.0
-shader_parameter/modulate = Color(1, 1, 1, 1)
-shader_parameter/show_outline = true
-shader_parameter/outline_color = Color(0, 0, 0, 1)
-shader_parameter/outline_rainbow = false
-shader_parameter/outline_use_blend = true
-shader_parameter/grey = 0.0
-
-[sub_resource type="RectangleShape2D" id="RectangleShape2D_rkrey"]
-size = Vector2(12, 18)
-
-[sub_resource type="AnimationLibrary" id="AnimationLibrary_ur1ug"]
-_data = {
-"RESET": ExtResource("5_5area"),
-"astonished": ExtResource("6_o4vh5"),
-"notify": ExtResource("7_y8dcl"),
-"query": ExtResource("8_7j8ux")
-}
-
-[node name="Enemy0003" node_paths=PackedStringArray("ViewRay", "NavigationAgent2D", "NavigationPoint", "FirePoint", "ViewArea", "ViewAreaCollision", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "TipRoot", "TipSprite", "AnimationPlayer", "MountPoint", "BackMountPoint", "MeleeAttackArea", "MeleeAttackCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_34027")]
-script = ExtResource("2_pakvr")
-ViewRay = NodePath("ViewRay")
-NavigationAgent2D = NodePath("NavigationPoint/NavigationAgent2D")
-NavigationPoint = NodePath("NavigationPoint")
-FirePoint = NodePath("FirePoint")
-ViewArea = NodePath("MountPoint/ViewArea")
-ViewAreaCollision = NodePath("MountPoint/ViewArea/ViewAreaCollision")
-HurtArea = NodePath("HurtArea")
-HurtCollision = NodePath("HurtArea/HurtCollision")
-InteractiveArea = NodePath("InteractiveArea")
-InteractiveCollision = NodePath("InteractiveArea/InteractiveCollision")
-TipRoot = NodePath("TipRoot")
-TipSprite = NodePath("TipRoot/TipSprite")
-AnimationPlayer = NodePath("AnimationPlayer")
-MountPoint = NodePath("MountPoint")
-BackMountPoint = NodePath("BackMountPoint")
-MeleeAttackArea = NodePath("MountPoint/MeleeAttackArea")
-MeleeAttackCollision = NodePath("MountPoint/MeleeAttackArea/MeleeAttackCollision")
-ShadowSprite = NodePath("ShadowSprite")
-AnimatedSprite = NodePath("AnimatedSprite")
-Collision = NodePath("Collision")
-
-[node name="ShadowSprite" parent="." index="0"]
-material = SubResource("ShaderMaterial_3nkur")
-
-[node name="AnimatedSprite" parent="." index="2"]
-material = SubResource("ShaderMaterial_2kup1")
-sprite_frames = ExtResource("4_sd22a")
-
-[node name="HurtCollision" parent="HurtArea" index="0"]
-shape = SubResource("RectangleShape2D_rkrey")
-
-[node name="FirePoint" parent="." index="8"]
-position = Vector2(2, -9)
-
-[node name="AnimationPlayer" parent="." index="11"]
-libraries = {
-"": SubResource("AnimationLibrary_ur1ug")
-}
diff --git a/DungeonShooting_Godot/prefab/role/enemy/Enemy0004.tscn b/DungeonShooting_Godot/prefab/role/enemy/Enemy0004.tscn
deleted file mode 100644
index e1f61eb..0000000
--- a/DungeonShooting_Godot/prefab/role/enemy/Enemy0004.tscn
+++ /dev/null
@@ -1,86 +0,0 @@
-[gd_scene load_steps=13 format=3 uid="uid://dys8ke837tsqd"]
-
-[ext_resource type="PackedScene" uid="uid://dbrig6dq441wo" path="res://prefab/role/template/AiTemplate.tscn" id="1_kvs3t"]
-[ext_resource type="Script" path="res://src/game/activity/role/enemy/Enemy.cs" id="2_fehwl"]
-[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_stfjv"]
-[ext_resource type="SpriteFrames" uid="uid://cejv5k5ivm0k0" path="res://resource/spriteFrames/role/Enemy0004.tres" id="4_mfl1j"]
-[ext_resource type="Animation" uid="uid://b4mgiysicdk2b" path="res://resource/animation/enemy/Enemy_reset.res" id="5_7p0o8"]
-[ext_resource type="Animation" uid="uid://gvkkxspcdwrp" path="res://resource/animation/enemy/Enemy_astonished.res" id="6_tsq7a"]
-[ext_resource type="Animation" uid="uid://16rxpnsgj5tl" path="res://resource/animation/enemy/Enemy_notify.res" id="7_lyuvq"]
-[ext_resource type="Animation" uid="uid://cmje7jsgrhgmx" path="res://resource/animation/enemy/Enemy_query.res" id="8_nn4m4"]
-
-[sub_resource type="ShaderMaterial" id="ShaderMaterial_3nkur"]
-resource_local_to_scene = true
-shader = ExtResource("3_stfjv")
-shader_parameter/blend = Color(0, 0, 0, 0.470588)
-shader_parameter/schedule = 1.0
-shader_parameter/modulate = Color(1, 1, 1, 1)
-shader_parameter/show_outline = true
-shader_parameter/outline_color = Color(0, 0, 0, 1)
-shader_parameter/outline_rainbow = false
-shader_parameter/outline_use_blend = true
-shader_parameter/grey = 0.0
-
-[sub_resource type="ShaderMaterial" id="ShaderMaterial_2kup1"]
-resource_local_to_scene = true
-shader = ExtResource("3_stfjv")
-shader_parameter/blend = Color(1, 1, 1, 1)
-shader_parameter/schedule = 0.0
-shader_parameter/modulate = Color(1, 1, 1, 1)
-shader_parameter/show_outline = true
-shader_parameter/outline_color = Color(0, 0, 0, 1)
-shader_parameter/outline_rainbow = false
-shader_parameter/outline_use_blend = true
-shader_parameter/grey = 0.0
-
-[sub_resource type="RectangleShape2D" id="RectangleShape2D_rkrey"]
-size = Vector2(12, 18)
-
-[sub_resource type="AnimationLibrary" id="AnimationLibrary_ur1ug"]
-_data = {
-"RESET": ExtResource("5_7p0o8"),
-"astonished": ExtResource("6_tsq7a"),
-"notify": ExtResource("7_lyuvq"),
-"query": ExtResource("8_nn4m4")
-}
-
-[node name="Enemy0004" node_paths=PackedStringArray("ViewRay", "NavigationAgent2D", "NavigationPoint", "FirePoint", "ViewArea", "ViewAreaCollision", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "TipRoot", "TipSprite", "AnimationPlayer", "MountPoint", "BackMountPoint", "MeleeAttackArea", "MeleeAttackCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_kvs3t")]
-script = ExtResource("2_fehwl")
-ViewRay = NodePath("ViewRay")
-NavigationAgent2D = NodePath("NavigationPoint/NavigationAgent2D")
-NavigationPoint = NodePath("NavigationPoint")
-FirePoint = NodePath("FirePoint")
-ViewArea = NodePath("MountPoint/ViewArea")
-ViewAreaCollision = NodePath("MountPoint/ViewArea/ViewAreaCollision")
-HurtArea = NodePath("HurtArea")
-HurtCollision = NodePath("HurtArea/HurtCollision")
-InteractiveArea = NodePath("InteractiveArea")
-InteractiveCollision = NodePath("InteractiveArea/InteractiveCollision")
-TipRoot = NodePath("TipRoot")
-TipSprite = NodePath("TipRoot/TipSprite")
-AnimationPlayer = NodePath("AnimationPlayer")
-MountPoint = NodePath("MountPoint")
-BackMountPoint = NodePath("BackMountPoint")
-MeleeAttackArea = NodePath("MountPoint/MeleeAttackArea")
-MeleeAttackCollision = NodePath("MountPoint/MeleeAttackArea/MeleeAttackCollision")
-ShadowSprite = NodePath("ShadowSprite")
-AnimatedSprite = NodePath("AnimatedSprite")
-Collision = NodePath("Collision")
-
-[node name="ShadowSprite" parent="." index="0"]
-material = SubResource("ShaderMaterial_3nkur")
-
-[node name="AnimatedSprite" parent="." index="2"]
-material = SubResource("ShaderMaterial_2kup1")
-sprite_frames = ExtResource("4_mfl1j")
-
-[node name="HurtCollision" parent="HurtArea" index="0"]
-shape = SubResource("RectangleShape2D_rkrey")
-
-[node name="FirePoint" parent="." index="8"]
-position = Vector2(2, -9)
-
-[node name="AnimationPlayer" parent="." index="11"]
-libraries = {
-"": SubResource("AnimationLibrary_ur1ug")
-}
diff --git a/DungeonShooting_Godot/prefab/role/enemy/Enemy0005.tscn b/DungeonShooting_Godot/prefab/role/enemy/Enemy0005.tscn
deleted file mode 100644
index fec71a3..0000000
--- a/DungeonShooting_Godot/prefab/role/enemy/Enemy0005.tscn
+++ /dev/null
@@ -1,86 +0,0 @@
-[gd_scene load_steps=13 format=3 uid="uid://dsh23glt8ayeo"]
-
-[ext_resource type="PackedScene" uid="uid://dbrig6dq441wo" path="res://prefab/role/template/AiTemplate.tscn" id="1_sg5wx"]
-[ext_resource type="Script" path="res://src/game/activity/role/enemy/Enemy.cs" id="2_sq2kh"]
-[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_5iudd"]
-[ext_resource type="SpriteFrames" uid="uid://cke0yk8ovq6yv" path="res://resource/spriteFrames/role/Enemy0005.tres" id="4_mh8tf"]
-[ext_resource type="Animation" uid="uid://b4mgiysicdk2b" path="res://resource/animation/enemy/Enemy_reset.res" id="5_ftn01"]
-[ext_resource type="Animation" uid="uid://gvkkxspcdwrp" path="res://resource/animation/enemy/Enemy_astonished.res" id="6_8fr2g"]
-[ext_resource type="Animation" uid="uid://16rxpnsgj5tl" path="res://resource/animation/enemy/Enemy_notify.res" id="7_x4iyi"]
-[ext_resource type="Animation" uid="uid://cmje7jsgrhgmx" path="res://resource/animation/enemy/Enemy_query.res" id="8_8pl4v"]
-
-[sub_resource type="ShaderMaterial" id="ShaderMaterial_3nkur"]
-resource_local_to_scene = true
-shader = ExtResource("3_5iudd")
-shader_parameter/blend = Color(0, 0, 0, 0.470588)
-shader_parameter/schedule = 1.0
-shader_parameter/modulate = Color(1, 1, 1, 1)
-shader_parameter/show_outline = true
-shader_parameter/outline_color = Color(0, 0, 0, 1)
-shader_parameter/outline_rainbow = false
-shader_parameter/outline_use_blend = true
-shader_parameter/grey = 0.0
-
-[sub_resource type="ShaderMaterial" id="ShaderMaterial_2kup1"]
-resource_local_to_scene = true
-shader = ExtResource("3_5iudd")
-shader_parameter/blend = Color(1, 1, 1, 1)
-shader_parameter/schedule = 0.0
-shader_parameter/modulate = Color(1, 1, 1, 1)
-shader_parameter/show_outline = true
-shader_parameter/outline_color = Color(0, 0, 0, 1)
-shader_parameter/outline_rainbow = false
-shader_parameter/outline_use_blend = true
-shader_parameter/grey = 0.0
-
-[sub_resource type="RectangleShape2D" id="RectangleShape2D_rkrey"]
-size = Vector2(12, 18)
-
-[sub_resource type="AnimationLibrary" id="AnimationLibrary_ur1ug"]
-_data = {
-"RESET": ExtResource("5_ftn01"),
-"astonished": ExtResource("6_8fr2g"),
-"notify": ExtResource("7_x4iyi"),
-"query": ExtResource("8_8pl4v")
-}
-
-[node name="Enemy0005" node_paths=PackedStringArray("ViewRay", "NavigationAgent2D", "NavigationPoint", "FirePoint", "ViewArea", "ViewAreaCollision", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "TipRoot", "TipSprite", "AnimationPlayer", "MountPoint", "BackMountPoint", "MeleeAttackArea", "MeleeAttackCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_sg5wx")]
-script = ExtResource("2_sq2kh")
-ViewRay = NodePath("ViewRay")
-NavigationAgent2D = NodePath("NavigationPoint/NavigationAgent2D")
-NavigationPoint = NodePath("NavigationPoint")
-FirePoint = NodePath("FirePoint")
-ViewArea = NodePath("MountPoint/ViewArea")
-ViewAreaCollision = NodePath("MountPoint/ViewArea/ViewAreaCollision")
-HurtArea = NodePath("HurtArea")
-HurtCollision = NodePath("HurtArea/HurtCollision")
-InteractiveArea = NodePath("InteractiveArea")
-InteractiveCollision = NodePath("InteractiveArea/InteractiveCollision")
-TipRoot = NodePath("TipRoot")
-TipSprite = NodePath("TipRoot/TipSprite")
-AnimationPlayer = NodePath("AnimationPlayer")
-MountPoint = NodePath("MountPoint")
-BackMountPoint = NodePath("BackMountPoint")
-MeleeAttackArea = NodePath("MountPoint/MeleeAttackArea")
-MeleeAttackCollision = NodePath("MountPoint/MeleeAttackArea/MeleeAttackCollision")
-ShadowSprite = NodePath("ShadowSprite")
-AnimatedSprite = NodePath("AnimatedSprite")
-Collision = NodePath("Collision")
-
-[node name="ShadowSprite" parent="." index="0"]
-material = SubResource("ShaderMaterial_3nkur")
-
-[node name="AnimatedSprite" parent="." index="2"]
-material = SubResource("ShaderMaterial_2kup1")
-sprite_frames = ExtResource("4_mh8tf")
-
-[node name="HurtCollision" parent="HurtArea" index="0"]
-shape = SubResource("RectangleShape2D_rkrey")
-
-[node name="FirePoint" parent="." index="8"]
-position = Vector2(2, -9)
-
-[node name="AnimationPlayer" parent="." index="11"]
-libraries = {
-"": SubResource("AnimationLibrary_ur1ug")
-}
diff --git a/DungeonShooting_Godot/prefab/role/enemy/Enemy0006.tscn b/DungeonShooting_Godot/prefab/role/enemy/Enemy0006.tscn
deleted file mode 100644
index 973f35a..0000000
--- a/DungeonShooting_Godot/prefab/role/enemy/Enemy0006.tscn
+++ /dev/null
@@ -1,86 +0,0 @@
-[gd_scene load_steps=13 format=3 uid="uid://cfe5jf5i82x30"]
-
-[ext_resource type="PackedScene" uid="uid://dbrig6dq441wo" path="res://prefab/role/template/AiTemplate.tscn" id="1_04a2o"]
-[ext_resource type="Script" path="res://src/game/activity/role/enemy/Enemy.cs" id="2_njfo6"]
-[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_sivbl"]
-[ext_resource type="SpriteFrames" uid="uid://l3iesn33p2og" path="res://resource/spriteFrames/role/Enemy0006.tres" id="4_235p0"]
-[ext_resource type="Animation" uid="uid://b4mgiysicdk2b" path="res://resource/animation/enemy/Enemy_reset.res" id="5_8t34s"]
-[ext_resource type="Animation" uid="uid://gvkkxspcdwrp" path="res://resource/animation/enemy/Enemy_astonished.res" id="6_mhq4h"]
-[ext_resource type="Animation" uid="uid://16rxpnsgj5tl" path="res://resource/animation/enemy/Enemy_notify.res" id="7_vteg1"]
-[ext_resource type="Animation" uid="uid://cmje7jsgrhgmx" path="res://resource/animation/enemy/Enemy_query.res" id="8_isv4k"]
-
-[sub_resource type="ShaderMaterial" id="ShaderMaterial_3nkur"]
-resource_local_to_scene = true
-shader = ExtResource("3_sivbl")
-shader_parameter/blend = Color(0, 0, 0, 0.470588)
-shader_parameter/schedule = 1.0
-shader_parameter/modulate = Color(1, 1, 1, 1)
-shader_parameter/show_outline = true
-shader_parameter/outline_color = Color(0, 0, 0, 1)
-shader_parameter/outline_rainbow = false
-shader_parameter/outline_use_blend = true
-shader_parameter/grey = 0.0
-
-[sub_resource type="ShaderMaterial" id="ShaderMaterial_2kup1"]
-resource_local_to_scene = true
-shader = ExtResource("3_sivbl")
-shader_parameter/blend = Color(1, 1, 1, 1)
-shader_parameter/schedule = 0.0
-shader_parameter/modulate = Color(1, 1, 1, 1)
-shader_parameter/show_outline = true
-shader_parameter/outline_color = Color(0, 0, 0, 1)
-shader_parameter/outline_rainbow = false
-shader_parameter/outline_use_blend = true
-shader_parameter/grey = 0.0
-
-[sub_resource type="RectangleShape2D" id="RectangleShape2D_rkrey"]
-size = Vector2(12, 18)
-
-[sub_resource type="AnimationLibrary" id="AnimationLibrary_ur1ug"]
-_data = {
-"RESET": ExtResource("5_8t34s"),
-"astonished": ExtResource("6_mhq4h"),
-"notify": ExtResource("7_vteg1"),
-"query": ExtResource("8_isv4k")
-}
-
-[node name="Enemy0006" node_paths=PackedStringArray("ViewRay", "NavigationAgent2D", "NavigationPoint", "FirePoint", "ViewArea", "ViewAreaCollision", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "TipRoot", "TipSprite", "AnimationPlayer", "MountPoint", "BackMountPoint", "MeleeAttackArea", "MeleeAttackCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_04a2o")]
-script = ExtResource("2_njfo6")
-ViewRay = NodePath("ViewRay")
-NavigationAgent2D = NodePath("NavigationPoint/NavigationAgent2D")
-NavigationPoint = NodePath("NavigationPoint")
-FirePoint = NodePath("FirePoint")
-ViewArea = NodePath("MountPoint/ViewArea")
-ViewAreaCollision = NodePath("MountPoint/ViewArea/ViewAreaCollision")
-HurtArea = NodePath("HurtArea")
-HurtCollision = NodePath("HurtArea/HurtCollision")
-InteractiveArea = NodePath("InteractiveArea")
-InteractiveCollision = NodePath("InteractiveArea/InteractiveCollision")
-TipRoot = NodePath("TipRoot")
-TipSprite = NodePath("TipRoot/TipSprite")
-AnimationPlayer = NodePath("AnimationPlayer")
-MountPoint = NodePath("MountPoint")
-BackMountPoint = NodePath("BackMountPoint")
-MeleeAttackArea = NodePath("MountPoint/MeleeAttackArea")
-MeleeAttackCollision = NodePath("MountPoint/MeleeAttackArea/MeleeAttackCollision")
-ShadowSprite = NodePath("ShadowSprite")
-AnimatedSprite = NodePath("AnimatedSprite")
-Collision = NodePath("Collision")
-
-[node name="ShadowSprite" parent="." index="0"]
-material = SubResource("ShaderMaterial_3nkur")
-
-[node name="AnimatedSprite" parent="." index="2"]
-material = SubResource("ShaderMaterial_2kup1")
-sprite_frames = ExtResource("4_235p0")
-
-[node name="HurtCollision" parent="HurtArea" index="0"]
-shape = SubResource("RectangleShape2D_rkrey")
-
-[node name="FirePoint" parent="." index="8"]
-position = Vector2(2, -9)
-
-[node name="AnimationPlayer" parent="." index="11"]
-libraries = {
-"": SubResource("AnimationLibrary_ur1ug")
-}
diff --git a/DungeonShooting_Godot/prefab/room/RoomExit.tscn b/DungeonShooting_Godot/prefab/room/RoomExit.tscn
new file mode 100644
index 0000000..fa771b3
--- /dev/null
+++ b/DungeonShooting_Godot/prefab/room/RoomExit.tscn
@@ -0,0 +1,15 @@
+[gd_scene load_steps=3 format=3 uid="uid://dlgkksq6oql78"]
+
+[ext_resource type="Script" path="res://src/game/room/RoomExit.cs" id="1_jl2t4"]
+
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_jj63m"]
+size = Vector2(32, 32)
+
+[node name="RoomExit" type="Area2D"]
+collision_layer = 0
+collision_mask = 8
+monitorable = false
+script = ExtResource("1_jl2t4")
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
+shape = SubResource("RectangleShape2D_jj63m")
diff --git a/DungeonShooting_Godot/prefab/ui/Setting.tscn b/DungeonShooting_Godot/prefab/ui/Setting.tscn
index 1ecf5f0..65c975f 100644
--- a/DungeonShooting_Godot/prefab/ui/Setting.tscn
+++ b/DungeonShooting_Godot/prefab/ui/Setting.tscn
@@ -1,7 +1,8 @@
-[gd_scene load_steps=3 format=3 uid="uid://bnwweusrc44xy"]
+[gd_scene load_steps=4 format=3 uid="uid://bnwweusrc44xy"]
[ext_resource type="Script" path="res://src/game/ui/setting/SettingPanel.cs" id="1_ff0oi"]
-[ext_resource type="Texture2D" uid="uid://cajcnlimvoxk" path="res://resource/sprite/ui/commonIcon/Back.png" id="2_vgl60"]
+[ext_resource type="Texture2D" uid="uid://dawuyrurwp4ni" path="res://resource/sprite/ui/setting/option_BG.png" id="2_rgd34"]
+[ext_resource type="Theme" uid="uid://ds668te2rph30" path="res://resource/theme/mainTheme.tres" id="4_bwst8"]
[node name="Setting" type="Control"]
layout_mode = 3
@@ -11,6 +12,7 @@
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_ff0oi")
+Layer = 2
[node name="ColorRect" type="ColorRect" parent="."]
layout_mode = 1
@@ -19,35 +21,37 @@
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
-color = Color(0.109804, 0.0666667, 0.0901961, 1)
+color = Color(0, 0, 0, 0.941176)
-[node name="Back" type="Button" parent="."]
-layout_mode = 0
-offset_right = 98.0
-offset_bottom = 98.0
-icon = ExtResource("2_vgl60")
-flat = true
-icon_alignment = 1
-expand_icon = true
-
-[node name="Title" type="Label" parent="."]
+[node name="TextureRect" type="TextureRect" parent="."]
layout_mode = 1
-anchors_preset = 10
-anchor_right = 1.0
-offset_bottom = 98.0
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -538.0
+offset_top = -320.0
+offset_right = 538.0
+offset_bottom = 320.0
grow_horizontal = 2
-theme_override_font_sizes/font_size = 48
-text = "游戏设置"
-horizontal_alignment = 1
-vertical_alignment = 1
+grow_vertical = 2
+texture = ExtResource("2_rgd34")
+expand_mode = 3
+stretch_mode = 5
[node name="ScrollContainer" type="ScrollContainer" parent="."]
+custom_minimum_size = Vector2(600, 500)
layout_mode = 1
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-offset_top = 123.0
-offset_bottom = -48.0
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -4.0
+offset_top = -4.0
+offset_right = 4.0
+offset_bottom = 4.0
grow_horizontal = 2
grow_vertical = 2
@@ -56,269 +60,72 @@
size_flags_horizontal = 3
theme_override_constants/separation = 15
-[node name="VideoItem" type="Button" parent="ScrollContainer/SettingMenu"]
+[node name="Title" type="Label" parent="ScrollContainer/SettingMenu"]
layout_mode = 2
-size_flags_horizontal = 4
-text = "显示设置"
-flat = true
+theme_override_font_sizes/font_size = 48
+text = "游戏设置"
+horizontal_alignment = 1
+vertical_alignment = 1
-[node name="InputItem" type="Button" parent="ScrollContainer/SettingMenu"]
-layout_mode = 2
-size_flags_horizontal = 4
-text = "键位设置"
-flat = true
-
-[node name="VideoSetting" type="VBoxContainer" parent="ScrollContainer"]
-visible = false
-layout_mode = 2
-size_flags_horizontal = 3
-theme_override_constants/separation = 15
-
-[node name="FullScreen" type="HBoxContainer" parent="ScrollContainer/VideoSetting"]
+[node name="FullScreen" type="HBoxContainer" parent="ScrollContainer/SettingMenu"]
custom_minimum_size = Vector2(600, 0)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 0
-[node name="Name" type="Label" parent="ScrollContainer/VideoSetting/FullScreen"]
+[node name="Name" type="Label" parent="ScrollContainer/SettingMenu/FullScreen"]
layout_mode = 2
size_flags_horizontal = 3
text = "全屏"
-[node name="CheckBox" type="CheckBox" parent="ScrollContainer/VideoSetting/FullScreen"]
+[node name="CheckBox" type="CheckBox" parent="ScrollContainer/SettingMenu/FullScreen"]
layout_mode = 2
size_flags_horizontal = 10
-[node name="Back" type="Button" parent="ScrollContainer/VideoSetting"]
+[node name="FullScreen2" type="HBoxContainer" parent="ScrollContainer/SettingMenu"]
+custom_minimum_size = Vector2(600, 0)
layout_mode = 2
size_flags_horizontal = 4
-text = "返回"
-flat = true
+size_flags_vertical = 0
-[node name="KeySetting" type="VBoxContainer" parent="ScrollContainer"]
-visible = false
+[node name="Label" type="Label" parent="ScrollContainer/SettingMenu/FullScreen2"]
layout_mode = 2
size_flags_horizontal = 3
-theme_override_constants/separation = 15
-
-[node name="Tip" type="Label" parent="ScrollContainer/KeySetting"]
-layout_mode = 2
-text = "暂不支持修改键位"
-horizontal_alignment = 1
+text = "背景音量"
vertical_alignment = 1
-[node name="Key" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
+[node name="BGM" type="HSlider" parent="ScrollContainer/SettingMenu/FullScreen2"]
+custom_minimum_size = Vector2(300, 0)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 4
+max_value = 1.0
+step = 0.01
+value = 0.5
+
+[node name="FullScreen3" type="HBoxContainer" parent="ScrollContainer/SettingMenu"]
custom_minimum_size = Vector2(600, 0)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 0
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key"]
+[node name="Label" type="Label" parent="ScrollContainer/SettingMenu/FullScreen3"]
layout_mode = 2
size_flags_horizontal = 3
-text = "上"
+text = "音效音量"
+vertical_alignment = 1
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key"]
-layout_mode = 2
-text = "W"
-
-[node name="Key2" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key2"]
+[node name="SFX" type="HSlider" parent="ScrollContainer/SettingMenu/FullScreen3"]
+custom_minimum_size = Vector2(300, 0)
layout_mode = 2
size_flags_horizontal = 3
-text = "下"
+size_flags_vertical = 4
+max_value = 1.0
+step = 0.01
+value = 0.5
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key2"]
-layout_mode = 2
-text = "S"
-
-[node name="Key3" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
+[node name="Back" type="Button" parent="ScrollContainer/SettingMenu"]
layout_mode = 2
size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key3"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "左"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key3"]
-layout_mode = 2
-text = "A"
-
-[node name="Key4" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key4"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "右"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key4"]
-layout_mode = 2
-text = "D"
-
-[node name="Key5" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key5"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "互动/拾取"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key5"]
-layout_mode = 2
-text = "E"
-
-[node name="Key6" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key6"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "切换武器"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key6"]
-layout_mode = 2
-text = "Q"
-
-[node name="Key7" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key7"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "使用道具"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key7"]
-layout_mode = 2
-text = "F"
-
-[node name="Key8" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key8"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "扔掉武器"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key8"]
-layout_mode = 2
-text = "G"
-
-[node name="Key11" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key11"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "扔掉道具"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key11"]
-layout_mode = 2
-text = "X"
-
-[node name="Key9" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key9"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "开火"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key9"]
-layout_mode = 2
-text = "鼠标左键"
-
-[node name="Key10" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key10"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "换弹"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key10"]
-layout_mode = 2
-text = "R"
-
-[node name="Key12" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key12"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "翻滚"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key12"]
-layout_mode = 2
-text = "鼠标右键"
-
-[node name="Key13" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key13"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "武器近战"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key13"]
-layout_mode = 2
-text = "空格"
-
-[node name="Key14" type="HBoxContainer" parent="ScrollContainer/KeySetting"]
-custom_minimum_size = Vector2(600, 0)
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 0
-
-[node name="Name" type="Label" parent="ScrollContainer/KeySetting/Key14"]
-layout_mode = 2
-size_flags_horizontal = 3
-text = "展开小地图"
-
-[node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key14"]
-layout_mode = 2
-text = "Shift"
-
-[node name="Back" type="Button" parent="ScrollContainer/KeySetting"]
-layout_mode = 2
-size_flags_horizontal = 4
+theme = ExtResource("4_bwst8")
text = "返回"
-flat = true
diff --git a/DungeonShooting_Godot/prefab/ui/Victory.tscn b/DungeonShooting_Godot/prefab/ui/Victory.tscn
new file mode 100644
index 0000000..7f8e351
--- /dev/null
+++ b/DungeonShooting_Godot/prefab/ui/Victory.tscn
@@ -0,0 +1,39 @@
+[gd_scene load_steps=2 format=3 uid="uid://di268t2hu2c83"]
+
+[ext_resource type="Script" path="res://src/game/ui/victory/VictoryPanel.cs" id="1_suuiw"]
+
+[node name="Victory" 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_suuiw")
+
+[node name="Label" type="Label" parent="."]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+text = "胜利"
+horizontal_alignment = 1
+vertical_alignment = 1
+
+[node name="Button" type="Button" parent="."]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -38.0
+offset_top = 93.0
+offset_right = 38.0
+offset_bottom = 133.0
+grow_horizontal = 2
+grow_vertical = 2
+text = "返回"
+flat = true
diff --git a/DungeonShooting_Godot/project.godot b/DungeonShooting_Godot/project.godot
index 1822292..73b8211 100644
--- a/DungeonShooting_Godot/project.godot
+++ b/DungeonShooting_Godot/project.godot
@@ -23,7 +23,7 @@
window/size/viewport_width=1920
window/size/viewport_height=1080
-window/stretch/aspect="keep_width"
+window/stretch/mode="canvas_items"
[dotnet]
diff --git a/DungeonShooting_Godot/resource/config/ActivityBase.json b/DungeonShooting_Godot/resource/config/ActivityBase.json
index b557529..fd324d1 100644
--- a/DungeonShooting_Godot/resource/config/ActivityBase.json
+++ b/DungeonShooting_Godot/resource/config/ActivityBase.json
@@ -42,45 +42,17 @@
"ShowInMapEditor": true
},
{
- "Id": "enemy0003",
- "Name": "\u654C\u4EBA3",
- "Type": 4,
+ "Id": "boss0001",
+ "Name": "Boss",
+ "Type": 12,
"Quality": 0,
"Price": 0,
- "Intro": "\u654C\u4EBA3",
- "Details": "",
+ "Intro": "Boss",
+ "Details": "Boss",
"IsStatic": false,
"__Material": "",
- "Prefab": "res://prefab/role/enemy/Enemy0003.tscn",
- "Icon": "res://resource/sprite/role/enemy0003/enemy0003_Icon.png",
- "ShowInMapEditor": true
- },
- {
- "Id": "enemy0004",
- "Name": "\u654C\u4EBA4",
- "Type": 4,
- "Quality": 0,
- "Price": 0,
- "Intro": "\u654C\u4EBA3",
- "Details": "",
- "IsStatic": false,
- "__Material": "",
- "Prefab": "res://prefab/role/enemy/Enemy0004.tscn",
- "Icon": "res://resource/sprite/role/enemy0004/enemy0004_Icon.png",
- "ShowInMapEditor": true
- },
- {
- "Id": "enemy0005",
- "Name": "\u654C\u4EBA5",
- "Type": 4,
- "Quality": 0,
- "Price": 0,
- "Intro": "\u654C\u4EBA3",
- "Details": "",
- "IsStatic": false,
- "__Material": "",
- "Prefab": "res://prefab/role/enemy/Enemy0005.tscn",
- "Icon": "res://resource/sprite/role/enemy0005/enemy0005_Icon.png",
+ "Prefab": "res://prefab/role/boss/Boss0001.tscn",
+ "Icon": "",
"ShowInMapEditor": true
},
{
@@ -420,6 +392,34 @@
"ShowInMapEditor": false
},
{
+ "Id": "summons0001",
+ "Name": "boss\u53EC\u5524\u7269\u5B50\u5F39",
+ "Type": 99,
+ "Quality": 0,
+ "Price": 0,
+ "Intro": "",
+ "Details": "",
+ "IsStatic": false,
+ "__Material": "",
+ "Prefab": "res://prefab/bullet/summons/Summons0001.tscn",
+ "Icon": "",
+ "ShowInMapEditor": false
+ },
+ {
+ "Id": "special0001",
+ "Name": "boss\u7279\u6B8A\u5B50\u5F39",
+ "Type": 99,
+ "Quality": 0,
+ "Price": 0,
+ "Intro": "",
+ "Details": "",
+ "IsStatic": false,
+ "__Material": "",
+ "Prefab": "res://prefab/bullet/special/SpecialBullet0001.tscn",
+ "Icon": "",
+ "ShowInMapEditor": false
+ },
+ {
"Id": "shell0001",
"Name": "",
"Type": 7,
diff --git a/DungeonShooting_Godot/resource/config/EditorObject.json b/DungeonShooting_Godot/resource/config/EditorObject.json
new file mode 100644
index 0000000..aaf4454
--- /dev/null
+++ b/DungeonShooting_Godot/resource/config/EditorObject.json
@@ -0,0 +1,212 @@
+[
+ {
+ "Id": "0001",
+ "Name": "",
+ "Remark": "",
+ "Prefab": "item_0003",
+ "Icon": ""
+ },
+ {
+ "Id": "0002",
+ "Name": "",
+ "Remark": "",
+ "Prefab": "item_0005",
+ "Icon": ""
+ },
+ {
+ "Id": "0003",
+ "Name": "",
+ "Remark": "",
+ "Prefab": "item_0020",
+ "Icon": ""
+ },
+ {
+ "Id": "0004",
+ "Name": "",
+ "Remark": "",
+ "Prefab": "item_0023",
+ "Icon": ""
+ },
+ {
+ "Id": "0005",
+ "Name": "\u751F\u65E5\u86CB\u7CD5",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0001.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0001_ICON.png"
+ },
+ {
+ "Id": "0006",
+ "Name": "\u76F8\u673A",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0002.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0002_ICON.png"
+ },
+ {
+ "Id": "0007",
+ "Name": "\u5893\u7891",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0003.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0003_ICON.png"
+ },
+ {
+ "Id": "0008",
+ "Name": "\u74F6\u5B5001",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0004.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0004_ICON.png"
+ },
+ {
+ "Id": "0009",
+ "Name": "\u9EC4\u7CD6\u68CD-\u5DE6",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0005.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0005_ICON.png"
+ },
+ {
+ "Id": "0010",
+ "Name": "\u7EA2\u7CD6\u68CD-\u5DE6",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0006.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0006_ICON.png"
+ },
+ {
+ "Id": "0011",
+ "Name": "\u9EC4\u7CD6\u68CD-\u53F3",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0007.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0007_ICON.png"
+ },
+ {
+ "Id": "0012",
+ "Name": "\u7EA2\u7CD6\u68CD-\u53F3",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0008.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0008_ICON.png"
+ },
+ {
+ "Id": "0013",
+ "Name": "\u7EA2\u68D2\u68D2\u7CD6",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0009.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0009_ICON.png"
+ },
+ {
+ "Id": "0014",
+ "Name": "\u9EC4\u68D2\u68D2\u7CD6",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0010.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0010_ICON.png"
+ },
+ {
+ "Id": "0015",
+ "Name": "\u751C\u751C\u5708",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0011.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0011_ICON.png"
+ },
+ {
+ "Id": "0016",
+ "Name": "\u9999\u8549",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0012.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0012_ICON.png"
+ },
+ {
+ "Id": "0017",
+ "Name": "\u68A8\u5B50",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0013.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0013_ICON.png"
+ },
+ {
+ "Id": "0018",
+ "Name": "\u897F\u74DC",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0014.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0014_ICON.png"
+ },
+ {
+ "Id": "0019",
+ "Name": "\u5C71\u7AF9",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0015.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0015_ICON.png"
+ },
+ {
+ "Id": "0020",
+ "Name": "\u6A59\u5B50",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0016.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0016_ICON.png"
+ },
+ {
+ "Id": "0021",
+ "Name": "\u7B3C\u5B50",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0017.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0017_ICON.png"
+ },
+ {
+ "Id": "0022",
+ "Name": "\u6C99\u53D1",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0018.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0018_ICON.png"
+ },
+ {
+ "Id": "0023",
+ "Name": "\u6905\u5B5001",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0019.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0019_ICON.png"
+ },
+ {
+ "Id": "0024",
+ "Name": "\u996E\u6C34\u673A",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0020.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0020_ICON.png"
+ },
+ {
+ "Id": "0025",
+ "Name": "\u6728\u7BB1",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0021.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0021_ICON.png"
+ },
+ {
+ "Id": "0026",
+ "Name": "\u74F6\u5B5002",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0022.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0022_ICON.png"
+ },
+ {
+ "Id": "0027",
+ "Name": "\u9152\u6876-\u5173",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0023.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0023_ICON.png"
+ },
+ {
+ "Id": "0028",
+ "Name": "\u9152\u6876-\u5F00",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0024.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0024_ICON.png"
+ },
+ {
+ "Id": "0029",
+ "Name": "\u5DE7\u514B\u529B\u5757",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0025.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0025_ICON.png"
+ },
+ {
+ "Id": "0030",
+ "Name": "\u6728\u677F",
+ "Remark": "",
+ "Prefab": "res://prefab/dungeonitem/Dungenitem0026.tscn",
+ "Icon": "res://resource/DungeonitemICON/Dungeonitem0026_ICON.png"
+ }
+]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/config/EnemyBase.json b/DungeonShooting_Godot/resource/config/EnemyBase.json
index cb68e7e..3ca2e9d 100644
--- a/DungeonShooting_Godot/resource/config/EnemyBase.json
+++ b/DungeonShooting_Godot/resource/config/EnemyBase.json
@@ -4,7 +4,7 @@
"__Activity": "enemy0001",
"Remark": "\u654C\u4EBA1",
"Hp": 20,
- "MoveSpeed": 80,
+ "MoveSpeed": 20,
"Acceleration": 1500,
"Friction": 900,
"AttackInterval": 0,
@@ -15,14 +15,16 @@
"Gold": [
-2,
3
- ]
+ ],
+ "BloodColor": "fdc9c9",
+ "__BodyFragment": "enemy_dead0001"
},
{
"Id": "0002",
"__Activity": "enemy0002",
"Remark": "\u654C\u4EBA2",
"Hp": 25,
- "MoveSpeed": 120,
+ "MoveSpeed": 15,
"Acceleration": 1500,
"Friction": 900,
"AttackInterval": 2.2,
@@ -33,60 +35,8 @@
"Gold": [
-2,
4
- ]
- },
- {
- "Id": "0003",
- "__Activity": "enemy0003",
- "Remark": "\u654C\u4EBA3",
- "Hp": 20,
- "MoveSpeed": 80,
- "Acceleration": 1500,
- "Friction": 900,
- "AttackInterval": 0,
- "CanPickUpWeapon": true,
- "ViewRange": 250,
- "TailAfterViewRange": 300,
- "ViewAngleRange": 150,
- "Gold": [
- -2,
- 3
- ]
- },
- {
- "Id": "0004",
- "__Activity": "enemy0004",
- "Remark": "\u654C\u4EBA4",
- "Hp": 20,
- "MoveSpeed": 80,
- "Acceleration": 1500,
- "Friction": 900,
- "AttackInterval": 0,
- "CanPickUpWeapon": true,
- "ViewRange": 250,
- "TailAfterViewRange": 300,
- "ViewAngleRange": 150,
- "Gold": [
- -2,
- 3
- ]
- },
- {
- "Id": "0005",
- "__Activity": "enemy0005",
- "Remark": "\u654C\u4EBA5",
- "Hp": 20,
- "MoveSpeed": 80,
- "Acceleration": 1500,
- "Friction": 900,
- "AttackInterval": 0,
- "CanPickUpWeapon": true,
- "ViewRange": 250,
- "TailAfterViewRange": 300,
- "ViewAngleRange": 150,
- "Gold": [
- -2,
- 3
- ]
+ ],
+ "BloodColor": "",
+ "__BodyFragment": ""
}
]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/config/Sound.json b/DungeonShooting_Godot/resource/config/Sound.json
index 76bbf8c..1350fe6 100644
--- a/DungeonShooting_Godot/resource/config/Sound.json
+++ b/DungeonShooting_Godot/resource/config/Sound.json
@@ -316,5 +316,41 @@
"Path": "res://resource/sound/sfx/common/gold.ogg",
"Volume": 1.5,
"Remark": "\u91D1\u5E01"
+ },
+ {
+ "Id": "enemy_hurt",
+ "Path": "res://resource/sound/sfx/role/enemy/EnemyHurt.ogg",
+ "Volume": 1,
+ "Remark": "\u602A\u7269\u53D7\u4F24\u97F3\u6548"
+ },
+ {
+ "Id": "enemy_die",
+ "Path": "res://resource/sound/sfx/role/enemy/Enemydie.mp3",
+ "Volume": 1,
+ "Remark": "\u602A\u7269\u6B7B\u4EA1\u7206\u679C\u6C41\u97F3\u6548"
+ },
+ {
+ "Id": "role_hurt",
+ "Path": "res://resource/sound/sfx/role/player/RoleHurt.mp3",
+ "Volume": 1,
+ "Remark": "\u89D2\u8272\u53D7\u4F24\u97F3\u6548"
+ },
+ {
+ "Id": "role_die",
+ "Path": "res://resource/sound/sfx/role/player/RoleDie.mp3",
+ "Volume": 1,
+ "Remark": "\u89D2\u8272\u6B7B\u4EA1\u97F3\u6548"
+ },
+ {
+ "Id": "role_rolling",
+ "Path": "res://resource/sound/sfx/role/player/Rolling.mp3",
+ "Volume": 1,
+ "Remark": "\u89D2\u8272\u7FFB\u6EDA"
+ },
+ {
+ "Id": "role_pickup",
+ "Path": "res://resource/sound/sfx/role/player/PickupWeapon.mp3",
+ "Volume": 1,
+ "Remark": "\u89D2\u8272\u6309E\u4EA4\u4E92\u6361\u8D77"
}
]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json b/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json
index fa56e95..d175f22 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json
@@ -2,6 +2,17 @@
"Test1": {
"GroupName": "Test1",
"TileSet": "TileSet1",
+ "BgColor": {
+ "R8": 0,
+ "G8": 0,
+ "B8": 0,
+ "A8": 0,
+ "H": 0,
+ "S": 0,
+ "V": 0,
+ "Luminance": 0
+ },
+ "SoundId": null,
"BattleList": [
{
"ErrorType": 0,
@@ -64,22 +75,5 @@
],
"EventList": [],
"Remark": ""
- },
- "test2": {
- "GroupName": "test2",
- "TileSet": "TileSet1",
- "BattleList": [
- {
- "ErrorType": 1,
- "Path": "resource/map/tileMaps/test2/battle/1"
- }
- ],
- "InletList": [],
- "OutletList": [],
- "BossList": [],
- "RewardList": [],
- "ShopList": [],
- "EventList": [],
- "Remark": "\u611F\u8C22\u5927\u5BB6\u7684\u652F\u6301"
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/Preview.png
index 434657d..d7771d5 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/TileInfo.json
index d51b806..ed50bf4 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/TileInfo.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/TileInfo.json
@@ -1 +1 @@
-{"NavigationVertices":[{"X":278,"Y":-218},{"X":278,"Y":-294},{"X":330,"Y":-362},{"X":330,"Y":90},{"X":-170,"Y":-362},{"X":186,"Y":-294},{"X":278,"Y":6},{"X":-170,"Y":90},{"X":186,"Y":6},{"X":-10,"Y":6},{"X":186,"Y":-70},{"X":-102,"Y":6},{"X":-102,"Y":-70},{"X":-10,"Y":-70},{"X":186,"Y":-218},{"X":-10,"Y":-218},{"X":-10,"Y":-294},{"X":-102,"Y":-294},{"X":-102,"Y":-218},{"X":278,"Y":-70}],"NavigationPolygon":[[0,1,2,3],[4,2,1,5],[6,3,7,8],[8,7,9,10],[11,9,7],[11,7,4,12],[10,9,13],[5,14,15,16],[4,5,16],[4,16,17],[4,17,18],[12,4,18],[13,12,18,15],[10,13,15,14],[19,10,14,0],[19,0,3],[19,3,6]],"Floor":[-11,-23,0,3,-11,-22,0,3,-11,-21,0,3,-11,-20,0,3,-11,-19,0,3,-11,-18,0,3,-11,-17,0,3,-11,-16,0,3,-11,-15,0,3,-11,-14,0,3,-11,-13,0,3,-11,-12,0,3,-11,-11,0,3,-11,-10,0,3,-11,-9,0,3,-11,-8,0,3,-11,-7,0,3,-11,-6,0,3,-11,-5,0,3,-11,-4,0,3,-11,-3,0,3,-11,-2,0,3,-11,-1,0,3,-11,0,0,3,-11,1,0,3,-11,2,0,3,-11,3,0,3,-11,4,0,3,-10,-23,0,3,-10,-22,0,3,-10,-21,0,3,-10,-20,0,3,-10,-19,0,3,-10,-18,0,3,-10,-17,0,3,-10,-16,0,3,-10,-15,0,3,-10,-14,0,3,-10,-13,0,3,-10,-12,0,3,-10,-11,0,3,-10,-10,0,3,-10,-9,0,3,-10,-8,0,3,-10,-7,0,3,-10,-6,0,3,-10,-5,0,3,-10,-4,0,3,-10,-3,0,3,-10,-2,0,3,-10,-1,0,3,-10,0,0,3,-10,1,0,3,-10,2,0,3,-10,3,0,3,-10,4,0,3,-9,-23,0,3,-9,-22,0,3,-9,-21,0,3,-9,-20,0,3,-9,-19,0,3,-9,-18,0,3,-9,-17,0,3,-9,-16,0,3,-9,-15,0,3,-9,-14,0,3,-9,-13,0,3,-9,-12,0,3,-9,-11,0,3,-9,-10,0,3,-9,-9,0,3,-9,-8,0,3,-9,-7,0,3,-9,-6,0,3,-9,-5,0,3,-9,-4,0,3,-9,-3,0,3,-9,-2,0,3,-9,-1,0,3,-9,0,0,3,-9,1,0,3,-9,2,0,3,-9,3,0,3,-9,4,0,3,-8,-23,0,3,-8,-22,0,3,-8,-21,0,3,-8,-20,0,3,-8,-19,0,3,-8,-18,0,3,-8,-17,0,3,-8,-16,0,3,-8,-15,0,3,-8,-14,0,3,-8,-13,0,3,-8,-12,0,3,-8,-11,0,3,-8,-10,0,3,-8,-9,0,3,-8,-8,0,3,-8,-7,0,3,-8,-6,0,3,-8,-5,0,3,-8,-4,0,3,-8,-3,0,3,-8,-2,0,3,-8,-1,0,3,-8,0,0,3,-8,1,0,3,-8,2,0,3,-8,3,0,3,-8,4,0,3,-7,-23,0,3,-7,-22,0,3,-7,-21,0,3,-7,-20,0,3,-7,-19,0,3,-7,-18,0,3,-7,-17,0,3,-7,-16,0,3,-7,-15,0,3,-7,-14,0,3,-7,-13,0,3,-7,-12,0,3,-7,-11,0,3,-7,-10,0,3,-7,-9,0,3,-7,-8,0,3,-7,-7,0,3,-7,-6,0,3,-7,-5,0,3,-7,-4,0,3,-7,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-7,4,0,3,-6,-23,0,3,-6,-22,0,3,-6,-21,0,3,-6,-20,0,3,-6,-14,0,3,-6,-13,0,3,-6,-12,0,3,-6,-11,0,3,-6,-10,0,3,-6,-9,0,3,-6,-8,0,3,-6,-7,0,3,-6,-6,0,3,-6,0,0,3,-6,1,0,3,-6,2,0,3,-6,3,0,3,-6,4,0,3,-5,-23,0,3,-5,-22,0,3,-5,-21,0,3,-5,-20,0,3,-5,-14,0,3,-5,-13,0,3,-5,-12,0,3,-5,-11,0,3,-5,-10,0,3,-5,-9,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,0,0,3,-5,1,0,3,-5,2,0,3,-5,3,0,3,-5,4,0,3,-4,-23,0,3,-4,-22,0,3,-4,-21,0,3,-4,-20,0,3,-4,-14,0,3,-4,-13,0,3,-4,-12,0,3,-4,-11,0,3,-4,-10,0,3,-4,-9,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-4,0,0,3,-4,1,0,3,-4,2,0,3,-4,3,0,3,-4,4,0,3,-3,-23,0,3,-3,-22,0,3,-3,-21,0,3,-3,-20,0,3,-3,-14,0,3,-3,-13,0,3,-3,-12,0,3,-3,-11,0,3,-3,-10,0,3,-3,-9,0,3,-3,-8,0,3,-3,-7,0,3,-3,-6,0,3,-3,0,0,3,-3,1,0,3,-3,2,0,3,-3,3,0,3,-3,4,0,3,-2,-23,0,3,-2,-22,0,3,-2,-21,0,3,-2,-20,0,3,-2,-14,0,3,-2,-13,0,3,-2,-12,0,3,-2,-11,0,3,-2,-10,0,3,-2,-9,0,3,-2,-8,0,3,-2,-7,0,3,-2,-6,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-2,4,0,3,-1,-23,0,3,-1,-22,0,3,-1,-21,0,3,-1,-20,0,3,-1,-19,0,3,-1,-18,0,3,-1,-17,0,3,-1,-16,0,3,-1,-15,0,3,-1,-14,0,3,-1,-13,0,3,-1,-12,0,3,-1,-11,0,3,-1,-10,0,3,-1,-9,0,3,-1,-8,0,3,-1,-7,0,3,-1,-6,0,3,-1,-5,0,3,-1,-4,0,3,-1,-3,0,3,-1,-2,0,3,-1,-1,0,3,-1,0,0,3,-1,1,0,3,-1,2,0,3,-1,3,0,3,-1,4,0,3,0,-23,0,3,0,-22,0,3,0,-21,0,3,0,-20,0,3,0,-19,0,3,0,-18,0,3,0,-17,0,3,0,-16,0,3,0,-15,0,3,0,-14,0,3,0,-13,0,3,0,-12,0,3,0,-11,0,3,0,-10,0,3,0,-9,0,3,0,-8,0,3,0,-7,0,3,0,-6,0,3,0,-5,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,0,1,0,3,0,2,0,3,0,3,0,3,0,4,0,3,1,-23,0,3,1,-22,0,3,1,-21,0,3,1,-20,0,3,1,-19,0,3,1,-18,0,3,1,-17,0,3,1,-16,0,3,1,-15,0,3,1,-14,0,3,1,-13,0,3,1,-12,0,3,1,-11,0,3,1,-10,0,3,1,-9,0,3,1,-8,0,3,1,-7,0,3,1,-6,0,3,1,-5,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,1,1,0,3,1,2,0,3,1,3,0,3,1,4,0,3,2,-23,0,3,2,-22,0,3,2,-21,0,3,2,-20,0,3,2,-19,0,3,2,-18,0,3,2,-17,0,3,2,-16,0,3,2,-15,0,3,2,-14,0,3,2,-13,0,3,2,-12,0,3,2,-11,0,3,2,-10,0,3,2,-9,0,3,2,-8,0,3,2,-7,0,3,2,-6,0,3,2,-5,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,2,1,0,3,2,2,0,3,2,3,0,3,2,4,0,3,3,-23,0,3,3,-22,0,3,3,-21,0,3,3,-20,0,3,3,-19,0,3,3,-18,0,3,3,-17,0,3,3,-16,0,3,3,-15,0,3,3,-14,0,3,3,-13,0,3,3,-12,0,3,3,-11,0,3,3,-10,0,3,3,-9,0,3,3,-8,0,3,3,-7,0,3,3,-6,0,3,3,-5,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,3,1,0,3,3,2,0,3,3,3,0,3,3,4,0,3,4,-23,0,3,4,-22,0,3,4,-21,0,3,4,-20,0,3,4,-19,0,3,4,-18,0,3,4,-17,0,3,4,-16,0,3,4,-15,0,3,4,-14,0,3,4,-13,0,3,4,-12,0,3,4,-11,0,3,4,-10,0,3,4,-9,0,3,4,-8,0,3,4,-7,0,3,4,-6,0,3,4,-5,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,4,1,0,3,4,2,0,3,4,3,0,3,4,4,0,3,5,-23,0,3,5,-22,0,3,5,-21,0,3,5,-20,0,3,5,-19,0,3,5,-18,0,3,5,-17,0,3,5,-16,0,3,5,-15,0,3,5,-14,0,3,5,-13,0,3,5,-12,0,3,5,-11,0,3,5,-10,0,3,5,-9,0,3,5,-8,0,3,5,-7,0,3,5,-6,0,3,5,-5,0,3,5,-4,0,3,5,-3,0,3,5,-2,0,3,5,-1,0,3,5,0,0,3,5,1,0,3,5,2,0,3,5,3,0,3,5,4,0,3,6,-23,0,3,6,-22,0,3,6,-21,0,3,6,-20,0,3,6,-19,0,3,6,-18,0,3,6,-17,0,3,6,-16,0,3,6,-15,0,3,6,-14,0,3,6,-13,0,3,6,-12,0,3,6,-11,0,3,6,-10,0,3,6,-9,0,3,6,-8,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,6,-3,0,3,6,-2,0,3,6,-1,0,3,6,0,0,3,6,1,0,3,6,2,0,3,6,3,0,3,6,4,0,3,7,-23,0,3,7,-22,0,3,7,-21,0,3,7,-20,0,3,7,-19,0,3,7,-18,0,3,7,-17,0,3,7,-16,0,3,7,-15,0,3,7,-14,0,3,7,-13,0,3,7,-12,0,3,7,-11,0,3,7,-10,0,3,7,-9,0,3,7,-8,0,3,7,-7,0,3,7,-6,0,3,7,-5,0,3,7,-4,0,3,7,-3,0,3,7,-2,0,3,7,-1,0,3,7,0,0,3,7,1,0,3,7,2,0,3,7,3,0,3,7,4,0,3,8,-23,0,3,8,-22,0,3,8,-21,0,3,8,-20,0,3,8,-19,0,3,8,-18,0,3,8,-17,0,3,8,-16,0,3,8,-15,0,3,8,-14,0,3,8,-13,0,3,8,-12,0,3,8,-11,0,3,8,-10,0,3,8,-9,0,3,8,-8,0,3,8,-7,0,3,8,-6,0,3,8,-5,0,3,8,-4,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,0,0,3,8,1,0,3,8,2,0,3,8,3,0,3,8,4,0,3,9,-23,0,3,9,-22,0,3,9,-21,0,3,9,-20,0,3,9,-19,0,3,9,-18,0,3,9,-17,0,3,9,-16,0,3,9,-15,0,3,9,-14,0,3,9,-13,0,3,9,-12,0,3,9,-11,0,3,9,-10,0,3,9,-9,0,3,9,-8,0,3,9,-7,0,3,9,-6,0,3,9,-5,0,3,9,-4,0,3,9,-3,0,3,9,-2,0,3,9,-1,0,3,9,0,0,3,9,1,0,3,9,2,0,3,9,3,0,3,9,4,0,3,10,-23,0,3,10,-22,0,3,10,-21,0,3,10,-20,0,3,10,-19,0,3,10,-18,0,3,10,-17,0,3,10,-16,0,3,10,-15,0,3,10,-14,0,3,10,-13,0,3,10,-12,0,3,10,-11,0,3,10,-10,0,3,10,-9,0,3,10,-8,0,3,10,-7,0,3,10,-6,0,3,10,-5,0,3,10,-4,0,3,10,-3,0,3,10,-2,0,3,10,-1,0,3,10,0,0,3,10,1,0,3,10,2,0,3,10,3,0,3,10,4,0,3,11,-23,0,3,11,-22,0,3,11,-21,0,3,11,-20,0,3,11,-19,0,3,11,-18,0,3,11,-17,0,3,11,-16,0,3,11,-15,0,3,11,-14,0,3,11,-13,0,3,11,-12,0,3,11,-11,0,3,11,-10,0,3,11,-9,0,3,11,-8,0,3,11,-7,0,3,11,-6,0,3,11,-5,0,3,11,-4,0,3,11,-3,0,3,11,-2,0,3,11,-1,0,3,11,0,0,3,11,1,0,3,11,2,0,3,11,3,0,3,11,4,0,3,12,-23,0,3,12,-22,0,3,12,-21,0,3,12,-20,0,3,12,-14,0,3,12,-13,0,3,12,-12,0,3,12,-11,0,3,12,-10,0,3,12,-9,0,3,12,-8,0,3,12,-7,0,3,12,-6,0,3,12,0,0,3,12,1,0,3,12,2,0,3,12,3,0,3,12,4,0,3,13,-23,0,3,13,-22,0,3,13,-21,0,3,13,-20,0,3,13,-14,0,3,13,-13,0,3,13,-12,0,3,13,-11,0,3,13,-10,0,3,13,-9,0,3,13,-8,0,3,13,-7,0,3,13,-6,0,3,13,0,0,3,13,1,0,3,13,2,0,3,13,3,0,3,13,4,0,3,14,-23,0,3,14,-22,0,3,14,-21,0,3,14,-20,0,3,14,-14,0,3,14,-13,0,3,14,-12,0,3,14,-11,0,3,14,-10,0,3,14,-9,0,3,14,-8,0,3,14,-7,0,3,14,-6,0,3,14,0,0,3,14,1,0,3,14,2,0,3,14,3,0,3,14,4,0,3,15,-23,0,3,15,-22,0,3,15,-21,0,3,15,-20,0,3,15,-14,0,3,15,-13,0,3,15,-12,0,3,15,-11,0,3,15,-10,0,3,15,-9,0,3,15,-8,0,3,15,-7,0,3,15,-6,0,3,15,0,0,3,15,1,0,3,15,2,0,3,15,3,0,3,15,4,0,3,16,-23,0,3,16,-22,0,3,16,-21,0,3,16,-20,0,3,16,-14,0,3,16,-13,0,3,16,-12,0,3,16,-11,0,3,16,-10,0,3,16,-9,0,3,16,-8,0,3,16,-7,0,3,16,-6,0,3,16,0,0,3,16,1,0,3,16,2,0,3,16,3,0,3,16,4,0,3,17,-23,0,3,17,-22,0,3,17,-21,0,3,17,-20,0,3,17,-19,0,3,17,-18,0,3,17,-17,0,3,17,-16,0,3,17,-15,0,3,17,-14,0,3,17,-13,0,3,17,-12,0,3,17,-11,0,3,17,-10,0,3,17,-9,0,3,17,-8,0,3,17,-7,0,3,17,-6,0,3,17,-5,0,3,17,-4,0,3,17,-3,0,3,17,-2,0,3,17,-1,0,3,17,0,0,3,17,1,0,3,17,2,0,3,17,3,0,3,17,4,0,3,18,-23,0,3,18,-22,0,3,18,-21,0,3,18,-20,0,3,18,-19,0,3,18,-18,0,3,18,-17,0,3,18,-16,0,3,18,-15,0,3,18,-14,0,3,18,-13,0,3,18,-12,0,3,18,-11,0,3,18,-10,0,3,18,-9,0,3,18,-8,0,3,18,-7,0,3,18,-6,0,3,18,-5,0,3,18,-4,0,3,18,-3,0,3,18,-2,0,3,18,-1,0,3,18,0,0,3,18,1,0,3,18,2,0,3,18,3,0,3,18,4,0,3,19,-23,0,3,19,-22,0,3,19,-21,0,3,19,-20,0,3,19,-19,0,3,19,-18,0,3,19,-17,0,3,19,-16,0,3,19,-15,0,3,19,-14,0,3,19,-13,0,3,19,-12,0,3,19,-11,0,3,19,-10,0,3,19,-9,0,3,19,-8,0,3,19,-7,0,3,19,-6,0,3,19,-5,0,3,19,-4,0,3,19,-3,0,3,19,-2,0,3,19,-1,0,3,19,0,0,3,19,1,0,3,19,2,0,3,19,3,0,3,19,4,0,3,20,-23,0,3,20,-22,0,3,20,-21,0,3,20,-20,0,3,20,-19,0,3,20,-18,0,3,20,-17,0,3,20,-16,0,3,20,-15,0,3,20,-14,0,3,20,-13,0,3,20,-12,0,3,20,-11,0,3,20,-10,0,3,20,-9,0,3,20,-8,0,3,20,-7,0,3,20,-6,0,3,20,-5,0,3,20,-4,0,3,20,-3,0,3,20,-2,0,3,20,-1,0,3,20,0,0,3,20,1,0,3,20,2,0,3,20,3,0,3,20,4,0,3],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[]}
\ No newline at end of file
+{"NavigationVertices":[{"X":278,"Y":-218},{"X":278,"Y":-294},{"X":330,"Y":-362},{"X":330,"Y":90},{"X":-170,"Y":-362},{"X":186,"Y":-294},{"X":278,"Y":6},{"X":-170,"Y":90},{"X":186,"Y":6},{"X":-10,"Y":6},{"X":186,"Y":-70},{"X":-102,"Y":6},{"X":-102,"Y":-70},{"X":-10,"Y":-70},{"X":186,"Y":-218},{"X":-10,"Y":-218},{"X":-10,"Y":-294},{"X":-102,"Y":-294},{"X":-102,"Y":-218},{"X":278,"Y":-70}],"NavigationPolygon":[[0,1,2,3],[4,2,1,5],[6,3,7,8],[8,7,9,10],[11,9,7],[11,7,4,12],[10,9,13],[5,14,15,16],[4,5,16],[4,16,17],[4,17,18],[12,4,18],[13,12,18,15],[10,13,15,14],[19,10,14,0],[19,0,3],[19,3,6]],"Floor":[-11,-23,0,3,-11,-22,0,3,-11,-21,0,3,-11,-20,0,3,-11,-19,0,3,-11,-18,0,3,-11,-17,0,3,-11,-16,0,3,-11,-15,0,3,-11,-14,0,3,-11,-13,0,3,-11,-12,0,3,-11,-11,0,3,-11,-10,0,3,-11,-9,0,3,-11,-8,0,3,-11,-7,0,3,-11,-6,0,3,-11,-5,0,3,-11,-4,0,3,-11,-3,0,3,-11,-2,0,3,-11,-1,0,3,-11,0,0,3,-11,1,0,3,-11,2,0,3,-11,3,0,3,-11,4,0,3,-10,-23,0,3,-10,-22,0,3,-10,-21,0,3,-10,-20,0,3,-10,-19,0,3,-10,-18,0,3,-10,-17,0,3,-10,-16,0,3,-10,-15,0,3,-10,-14,0,3,-10,-13,0,3,-10,-12,0,3,-10,-11,0,3,-10,-10,0,3,-10,-9,0,3,-10,-8,0,3,-10,-7,0,3,-10,-6,0,3,-10,-5,0,3,-10,-4,0,3,-10,-3,0,3,-10,-2,0,3,-10,-1,0,3,-10,0,0,3,-10,1,0,3,-10,2,0,3,-10,3,0,3,-10,4,0,3,-9,-23,0,3,-9,-22,0,3,-9,-21,0,3,-9,-20,0,3,-9,-19,0,3,-9,-18,0,3,-9,-17,0,3,-9,-16,0,3,-9,-15,0,3,-9,-14,0,3,-9,-13,0,3,-9,-12,0,3,-9,-11,0,3,-9,-10,0,3,-9,-9,0,3,-9,-8,0,3,-9,-7,0,3,-9,-6,0,3,-9,-5,0,3,-9,-4,0,3,-9,-3,0,3,-9,-2,0,3,-9,-1,0,3,-9,0,0,3,-9,1,0,3,-9,2,0,3,-9,3,0,3,-9,4,0,3,-8,-23,0,3,-8,-22,0,3,-8,-21,0,3,-8,-20,0,3,-8,-19,0,3,-8,-18,0,3,-8,-17,0,3,-8,-16,0,3,-8,-15,0,3,-8,-14,0,3,-8,-13,0,3,-8,-12,0,3,-8,-11,0,3,-8,-10,0,3,-8,-9,0,3,-8,-8,0,3,-8,-7,0,3,-8,-6,0,3,-8,-5,0,3,-8,-4,0,3,-8,-3,0,3,-8,-2,0,3,-8,-1,0,3,-8,0,0,3,-8,1,0,3,-8,2,0,3,-8,3,0,3,-8,4,0,3,-7,-23,0,3,-7,-22,0,3,-7,-21,0,3,-7,-20,0,3,-7,-19,0,3,-7,-18,0,3,-7,-17,0,3,-7,-16,0,3,-7,-15,0,3,-7,-14,0,3,-7,-13,0,3,-7,-12,0,3,-7,-11,0,3,-7,-10,0,3,-7,-9,0,3,-7,-8,0,3,-7,-7,0,3,-7,-6,0,3,-7,-5,0,3,-7,-4,0,3,-7,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-7,4,0,3,-6,-23,0,3,-6,-22,0,3,-6,-21,0,3,-6,-20,0,3,-6,-14,0,3,-6,-13,0,3,-6,-12,0,3,-6,-11,0,3,-6,-10,0,3,-6,-9,0,3,-6,-8,0,3,-6,-7,0,3,-6,-6,0,3,-6,0,0,3,-6,1,0,3,-6,2,0,3,-6,3,0,3,-6,4,0,3,-5,-23,0,3,-5,-22,0,3,-5,-21,0,3,-5,-20,0,3,-5,-14,0,3,-5,-13,0,3,-5,-12,0,3,-5,-11,0,3,-5,-10,0,3,-5,-9,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,0,0,3,-5,1,0,3,-5,2,0,3,-5,3,0,3,-5,4,0,3,-4,-23,0,3,-4,-22,0,3,-4,-21,0,3,-4,-20,0,3,-4,-14,0,3,-4,-13,0,3,-4,-12,0,3,-4,-11,0,3,-4,-10,0,3,-4,-9,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-4,0,0,3,-4,1,0,3,-4,2,0,3,-4,3,0,3,-4,4,0,3,-3,-23,0,3,-3,-22,0,3,-3,-21,0,3,-3,-20,0,3,-3,-14,0,3,-3,-13,0,3,-3,-12,0,3,-3,-11,0,3,-3,-10,0,3,-3,-9,0,3,-3,-8,0,3,-3,-7,0,3,-3,-6,0,3,-3,0,0,3,-3,1,0,3,-3,2,0,3,-3,3,0,3,-3,4,0,3,-2,-23,0,3,-2,-22,0,3,-2,-21,0,3,-2,-20,0,3,-2,-14,0,3,-2,-13,0,3,-2,-12,0,3,-2,-11,0,3,-2,-10,0,3,-2,-9,0,3,-2,-8,0,3,-2,-7,0,3,-2,-6,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-2,4,0,3,-1,-23,0,3,-1,-22,0,3,-1,-21,0,3,-1,-20,0,3,-1,-19,0,3,-1,-18,0,3,-1,-17,0,3,-1,-16,0,3,-1,-15,0,3,-1,-14,0,3,-1,-13,0,3,-1,-12,0,3,-1,-11,0,3,-1,-10,0,3,-1,-9,0,3,-1,-8,0,3,-1,-7,0,3,-1,-6,0,3,-1,-5,0,3,-1,-4,0,3,-1,-3,0,3,-1,-2,0,3,-1,-1,0,3,-1,0,0,3,-1,1,0,3,-1,2,0,3,-1,3,0,3,-1,4,0,3,0,-23,0,3,0,-22,0,3,0,-21,0,3,0,-20,0,3,0,-19,0,3,0,-18,0,3,0,-17,0,3,0,-16,0,3,0,-15,0,3,0,-14,0,3,0,-13,0,3,0,-12,0,3,0,-11,0,3,0,-10,0,3,0,-9,0,3,0,-8,0,3,0,-7,0,3,0,-6,0,3,0,-5,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,0,1,0,3,0,2,0,3,0,3,0,3,0,4,0,3,1,-23,0,3,1,-22,0,3,1,-21,0,3,1,-20,0,3,1,-19,0,3,1,-18,0,3,1,-17,0,3,1,-16,0,3,1,-15,0,3,1,-14,0,3,1,-13,0,3,1,-12,0,3,1,-11,0,3,1,-10,0,3,1,-9,0,3,1,-8,0,3,1,-7,0,3,1,-6,0,3,1,-5,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,1,1,0,3,1,2,0,3,1,3,0,3,1,4,0,3,2,-23,0,3,2,-22,0,3,2,-21,0,3,2,-20,0,3,2,-19,0,3,2,-18,0,3,2,-17,0,3,2,-16,0,3,2,-15,0,3,2,-14,0,3,2,-13,0,3,2,-12,0,3,2,-11,0,3,2,-10,0,3,2,-9,0,3,2,-8,0,3,2,-7,0,3,2,-6,0,3,2,-5,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,2,1,0,3,2,2,0,3,2,3,0,3,2,4,0,3,3,-23,0,3,3,-22,0,3,3,-21,0,3,3,-20,0,3,3,-19,0,3,3,-18,0,3,3,-17,0,3,3,-16,0,3,3,-15,0,3,3,-14,0,3,3,-13,0,3,3,-12,0,3,3,-11,0,3,3,-10,0,3,3,-9,0,3,3,-8,0,3,3,-7,0,3,3,-6,0,3,3,-5,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,3,1,0,3,3,2,0,3,3,3,0,3,3,4,0,3,4,-23,0,3,4,-22,0,3,4,-21,0,3,4,-20,0,3,4,-19,0,3,4,-18,0,3,4,-17,0,3,4,-16,0,3,4,-15,0,3,4,-14,0,3,4,-13,0,3,4,-12,0,3,4,-11,0,3,4,-10,0,3,4,-9,0,3,4,-8,0,3,4,-7,0,3,4,-6,0,3,4,-5,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,4,1,0,3,4,2,0,3,4,3,0,3,4,4,0,3,5,-23,0,3,5,-22,0,3,5,-21,0,3,5,-20,0,3,5,-19,0,3,5,-18,0,3,5,-17,0,3,5,-16,0,3,5,-15,0,3,5,-14,0,3,5,-13,0,3,5,-12,0,3,5,-11,0,3,5,-10,0,3,5,-9,0,3,5,-8,0,3,5,-7,0,3,5,-6,0,3,5,-5,0,3,5,-4,0,3,5,-3,0,3,5,-2,0,3,5,-1,0,3,5,0,0,3,5,1,0,3,5,2,0,3,5,3,0,3,5,4,0,3,6,-23,0,3,6,-22,0,3,6,-21,0,3,6,-20,0,3,6,-19,0,3,6,-18,0,3,6,-17,0,3,6,-16,0,3,6,-15,0,3,6,-14,0,3,6,-13,0,3,6,-12,0,3,6,-11,0,3,6,-10,0,3,6,-9,0,3,6,-8,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,6,-3,0,3,6,-2,0,3,6,-1,0,3,6,0,0,3,6,1,0,3,6,2,0,3,6,3,0,3,6,4,0,3,7,-23,0,3,7,-22,0,3,7,-21,0,3,7,-20,0,3,7,-19,0,3,7,-18,0,3,7,-17,0,3,7,-16,0,3,7,-15,0,3,7,-14,0,3,7,-13,0,3,7,-12,0,3,7,-11,0,3,7,-10,0,3,7,-9,0,3,7,-8,0,3,7,-7,0,3,7,-6,0,3,7,-5,0,3,7,-4,0,3,7,-3,0,3,7,-2,0,3,7,-1,0,3,7,0,0,3,7,1,0,3,7,2,0,3,7,3,0,3,7,4,0,3,8,-23,0,3,8,-22,0,3,8,-21,0,3,8,-20,0,3,8,-19,0,3,8,-18,0,3,8,-17,0,3,8,-16,0,3,8,-15,0,3,8,-14,0,3,8,-13,0,3,8,-12,0,3,8,-11,0,3,8,-10,0,3,8,-9,0,3,8,-8,0,3,8,-7,0,3,8,-6,0,3,8,-5,0,3,8,-4,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,0,0,3,8,1,0,3,8,2,0,3,8,3,0,3,8,4,0,3,9,-23,0,3,9,-22,0,3,9,-21,0,3,9,-20,0,3,9,-19,0,3,9,-18,0,3,9,-17,0,3,9,-16,0,3,9,-15,0,3,9,-14,0,3,9,-13,0,3,9,-12,0,3,9,-11,0,3,9,-10,0,3,9,-9,0,3,9,-8,0,3,9,-7,0,3,9,-6,0,3,9,-5,0,3,9,-4,0,3,9,-3,0,3,9,-2,0,3,9,-1,0,3,9,0,0,3,9,1,0,3,9,2,0,3,9,3,0,3,9,4,0,3,10,-23,0,3,10,-22,0,3,10,-21,0,3,10,-20,0,3,10,-19,0,3,10,-18,0,3,10,-17,0,3,10,-16,0,3,10,-15,0,3,10,-14,0,3,10,-13,0,3,10,-12,0,3,10,-11,0,3,10,-10,0,3,10,-9,0,3,10,-8,0,3,10,-7,0,3,10,-6,0,3,10,-5,0,3,10,-4,0,3,10,-3,0,3,10,-2,0,3,10,-1,0,3,10,0,0,3,10,1,0,3,10,2,0,3,10,3,0,3,10,4,0,3,11,-23,0,3,11,-22,0,3,11,-21,0,3,11,-20,0,3,11,-19,0,3,11,-18,0,3,11,-17,0,3,11,-16,0,3,11,-15,0,3,11,-14,0,3,11,-13,0,3,11,-12,0,3,11,-11,0,3,11,-10,0,3,11,-9,0,3,11,-8,0,3,11,-7,0,3,11,-6,0,3,11,-5,0,3,11,-4,0,3,11,-3,0,3,11,-2,0,3,11,-1,0,3,11,0,0,3,11,1,0,3,11,2,0,3,11,3,0,3,11,4,0,3,12,-23,0,3,12,-22,0,3,12,-21,0,3,12,-20,0,3,12,-14,0,3,12,-13,0,3,12,-12,0,3,12,-11,0,3,12,-10,0,3,12,-9,0,3,12,-8,0,3,12,-7,0,3,12,-6,0,3,12,0,0,3,12,1,0,3,12,2,0,3,12,3,0,3,12,4,0,3,13,-23,0,3,13,-22,0,3,13,-21,0,3,13,-20,0,3,13,-14,0,3,13,-13,0,3,13,-12,0,3,13,-11,0,3,13,-10,0,3,13,-9,0,3,13,-8,0,3,13,-7,0,3,13,-6,0,3,13,0,0,3,13,1,0,3,13,2,0,3,13,3,0,3,13,4,0,3,14,-23,0,3,14,-22,0,3,14,-21,0,3,14,-20,0,3,14,-14,0,3,14,-13,0,3,14,-12,0,3,14,-11,0,3,14,-10,0,3,14,-9,0,3,14,-8,0,3,14,-7,0,3,14,-6,0,3,14,0,0,3,14,1,0,3,14,2,0,3,14,3,0,3,14,4,0,3,15,-23,0,3,15,-22,0,3,15,-21,0,3,15,-20,0,3,15,-14,0,3,15,-13,0,3,15,-12,0,3,15,-11,0,3,15,-10,0,3,15,-9,0,3,15,-8,0,3,15,-7,0,3,15,-6,0,3,15,0,0,3,15,1,0,3,15,2,0,3,15,3,0,3,15,4,0,3,16,-23,0,3,16,-22,0,3,16,-21,0,3,16,-20,0,3,16,-14,0,3,16,-13,0,3,16,-12,0,3,16,-11,0,3,16,-10,0,3,16,-9,0,3,16,-8,0,3,16,-7,0,3,16,-6,0,3,16,0,0,3,16,1,0,3,16,2,0,3,16,3,0,3,16,4,0,3,17,-23,0,3,17,-22,0,3,17,-21,0,3,17,-20,0,3,17,-19,0,3,17,-18,0,3,17,-17,0,3,17,-16,0,3,17,-15,0,3,17,-14,0,3,17,-13,0,3,17,-12,0,3,17,-11,0,3,17,-10,0,3,17,-9,0,3,17,-8,0,3,17,-7,0,3,17,-6,0,3,17,-5,0,3,17,-4,0,3,17,-3,0,3,17,-2,0,3,17,-1,0,3,17,0,0,3,17,1,0,3,17,2,0,3,17,3,0,3,17,4,0,3,18,-23,0,3,18,-22,0,3,18,-21,0,3,18,-20,0,3,18,-19,0,3,18,-18,0,3,18,-17,0,3,18,-16,0,3,18,-15,0,3,18,-14,0,3,18,-13,0,3,18,-12,0,3,18,-11,0,3,18,-10,0,3,18,-9,0,3,18,-8,0,3,18,-7,0,3,18,-6,0,3,18,-5,0,3,18,-4,0,3,18,-3,0,3,18,-2,0,3,18,-1,0,3,18,0,0,3,18,1,0,3,18,2,0,3,18,3,0,3,18,4,0,3,19,-23,0,3,19,-22,0,3,19,-21,0,3,19,-20,0,3,19,-19,0,3,19,-18,0,3,19,-17,0,3,19,-16,0,3,19,-15,0,3,19,-14,0,3,19,-13,0,3,19,-12,0,3,19,-11,0,3,19,-10,0,3,19,-9,0,3,19,-8,0,3,19,-7,0,3,19,-6,0,3,19,-5,0,3,19,-4,0,3,19,-3,0,3,19,-2,0,3,19,-1,0,3,19,0,0,3,19,1,0,3,19,2,0,3,19,3,0,3,19,4,0,3,20,-23,0,3,20,-22,0,3,20,-21,0,3,20,-20,0,3,20,-19,0,3,20,-18,0,3,20,-17,0,3,20,-16,0,3,20,-15,0,3,20,-14,0,3,20,-13,0,3,20,-12,0,3,20,-11,0,3,20,-10,0,3,20,-9,0,3,20,-8,0,3,20,-7,0,3,20,-6,0,3,20,-5,0,3,20,-4,0,3,20,-3,0,3,20,-2,0,3,20,-1,0,3,20,0,0,3,20,1,0,3,20,2,0,3,20,3,0,3,20,4,0,3],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[],"NormalLayerObjects":null,"YSortLayerObjects":null}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/TileInfo.json
index 24f0fb4..c50b032 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/TileInfo.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/TileInfo.json
@@ -1 +1 @@
-{"NavigationVertices":[{"X":134,"Y":38},{"X":138,"Y":-122},{"X":138,"Y":138},{"X":134,"Y":90},{"X":134,"Y":-6},{"X":90,"Y":-6},{"X":86,"Y":-58},{"X":86,"Y":-102},{"X":-106,"Y":-122},{"X":-22,"Y":-102},{"X":74,"Y":10},{"X":74,"Y":54},{"X":58,"Y":90},{"X":-26,"Y":38},{"X":-26,"Y":-6},{"X":90,"Y":10},{"X":-22,"Y":-58},{"X":118,"Y":54},{"X":118,"Y":38},{"X":134,"Y":138},{"X":58,"Y":138},{"X":-58,"Y":138},{"X":-58,"Y":106},{"X":-86,"Y":38},{"X":-106,"Y":106},{"X":-86,"Y":-6}],"NavigationPolygon":[[0,1,2,3],[1,0,4],[1,4,5,6,7],[8,1,7,9],[10,11,12,13,14],[6,5,15,10,14,16],[17,18,0,3],[2,19,3],[17,3,12,11],[13,12,20,21,22],[23,13,22,24],[23,24,8,25],[25,8,9,16,14]],"Floor":[-3,-4,0,3,-2,-4,0,3,-2,-3,0,3,-3,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-7,4,0,3,-7,5,0,3,-6,-3,0,3,-6,-2,0,3,-6,-1,0,3,-6,0,0,3,-6,1,0,3,-6,2,0,3,-6,3,0,3,-6,4,0,3,-6,5,0,3,-5,-3,0,3,-5,-2,0,3,-5,2,0,3,-5,3,0,3,-5,4,0,3,-5,5,0,3,-4,-3,0,3,-4,-2,0,3,-4,2,0,3,-4,3,0,3,-4,4,0,3,-4,5,0,3,-3,-2,0,3,-3,2,0,3,-3,3,0,3,-3,4,0,3,-3,5,0,3,-2,-2,0,3,-2,-1,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-2,4,0,3,-2,5,0,3,-4,6,0,3,-4,7,0,3,-3,6,0,3,-3,7,0,3,-2,6,0,3,-2,7,0,3,-1,3,0,3,-1,4,0,3,-1,7,0,3,0,3,0,3,0,4,0,3,0,7,0,3,1,3,0,3,1,4,0,3,1,5,0,3,1,6,0,3,1,7,0,3,2,3,0,3,2,4,0,3,2,5,0,3,2,6,0,3,2,7,0,3,3,3,0,3,3,4,0,3,3,5,0,3,3,6,0,3,-1,-4,0,3,-1,-3,0,3,-1,-2,0,3,-1,-1,0,3,-1,0,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,5,-4,0,3,5,-3,0,3,5,-1,0,3,3,1,0,3,3,2,0,3,4,1,0,3,4,2,0,3,4,3,0,3,4,4,0,3,5,3,0,3,5,4,0,3,6,3,0,3,6,4,0,3,6,-3,0,3,7,-3,0,3,7,-2,0,3,7,2,0,3,7,3,0,3,7,4,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,0,0,3,8,1,0,3,8,2,0,3,8,3,0,3,8,4,0,3,-1,2,0,3,0,2,0,3,1,2,0,3,2,2,0,3,2,1,0,3,1,1,0,3,0,1,0,3,-1,1,0,3,-1,5,0,3,0,5,0,3,0,6,0,3,-1,6,0,3,-7,-3,0,3,6,-2,0,3,5,-2,0,3,8,5,0,3,8,6,0,3,8,7,0,3,-3,-5,0,3,-3,-6,0,3,5,-6,0,3,5,-5,0,3,5,-7,0,3,-3,-7,0,3,5,-8,0,3,4,-8,0,3,3,-8,0,3,2,-8,0,3,1,-8,0,3,0,-8,0,3,-1,-8,0,3,-2,-8,0,3,-3,-8,0,3,3,7,0,3,-7,-8,0,3,-7,-7,0,3,-7,-6,0,3,-7,-5,0,3,-7,-4,0,3,-6,-8,0,3,-6,-7,0,3,-6,-6,0,3,-6,-5,0,3,-6,-4,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,-5,0,3,-5,-4,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-4,-5,0,3,-4,-4,0,3,6,-8,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,7,-8,0,3,7,-7,0,3,7,-6,0,3,7,-5,0,3,7,-4,0,3,8,-8,0,3,8,-7,0,3,8,-6,0,3,8,-5,0,3,8,-4,0,3,-2,-6,0,3,-2,-7,0,3,-2,-5,0,3],"CustomFloor1":[-4,2,1,7,14,-3,3,1,8,15,-4,3,1,7,15,-5,3,1,6,15,6,4,1,8,15,5,4,1,7,15,-5,2,1,6,14,4,3,1,6,14,4,4,1,6,15,6,3,1,8,14,5,3,1,7,14,-3,2,1,8,14],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[-3,4,1,10,5,-3,5,1,10,6,2,4,1,10,5,2,5,1,10,6],"CustomMiddle2":[5,-4,1,6,0,5,-3,1,6,1,-2,-1,1,5,0,-2,0,1,5,1],"CustomTop":[]}
\ No newline at end of file
+{"NavigationVertices":[{"X":134,"Y":38},{"X":138,"Y":-122},{"X":138,"Y":138},{"X":134,"Y":90},{"X":134,"Y":-6},{"X":90,"Y":-6},{"X":86,"Y":-58},{"X":86,"Y":-102},{"X":-106,"Y":-122},{"X":-22,"Y":-102},{"X":74,"Y":10},{"X":74,"Y":54},{"X":58,"Y":90},{"X":-26,"Y":38},{"X":-26,"Y":-6},{"X":90,"Y":10},{"X":-22,"Y":-58},{"X":118,"Y":54},{"X":118,"Y":38},{"X":134,"Y":138},{"X":58,"Y":138},{"X":-58,"Y":138},{"X":-58,"Y":106},{"X":-86,"Y":38},{"X":-106,"Y":106},{"X":-86,"Y":-6}],"NavigationPolygon":[[0,1,2,3],[1,0,4],[1,4,5,6,7],[8,1,7,9],[10,11,12,13,14],[6,5,15,10,14,16],[17,18,0,3],[2,19,3],[17,3,12,11],[13,12,20,21,22],[23,13,22,24],[23,24,8,25],[25,8,9,16,14]],"Floor":[-3,-4,0,3,-2,-4,0,3,-2,-3,0,3,-3,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-7,4,0,3,-7,5,0,3,-6,-3,0,3,-6,-2,0,3,-6,-1,0,3,-6,0,0,3,-6,1,0,3,-6,2,0,3,-6,3,0,3,-6,4,0,3,-6,5,0,3,-5,-3,0,3,-5,-2,0,3,-5,2,0,3,-5,3,0,3,-5,4,0,3,-5,5,0,3,-4,-3,0,3,-4,-2,0,3,-4,2,0,3,-4,3,0,3,-4,4,0,3,-4,5,0,3,-3,-2,0,3,-3,2,0,3,-3,3,0,3,-3,4,0,3,-3,5,0,3,-2,-2,0,3,-2,-1,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-2,4,0,3,-2,5,0,3,-4,6,0,3,-4,7,0,3,-3,6,0,3,-3,7,0,3,-2,6,0,3,-2,7,0,3,-1,3,0,3,-1,4,0,3,-1,7,0,3,0,3,0,3,0,4,0,3,0,7,0,3,1,3,0,3,1,4,0,3,1,5,0,3,1,6,0,3,1,7,0,3,2,3,0,3,2,4,0,3,2,5,0,3,2,6,0,3,2,7,0,3,3,3,0,3,3,4,0,3,3,5,0,3,3,6,0,3,-1,-4,0,3,-1,-3,0,3,-1,-2,0,3,-1,-1,0,3,-1,0,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,5,-4,0,3,5,-3,0,3,5,-1,0,3,3,1,0,3,3,2,0,3,4,1,0,3,4,2,0,3,4,3,0,3,4,4,0,3,5,3,0,3,5,4,0,3,6,3,0,3,6,4,0,3,6,-3,0,3,7,-3,0,3,7,-2,0,3,7,2,0,3,7,3,0,3,7,4,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,0,0,3,8,1,0,3,8,2,0,3,8,3,0,3,8,4,0,3,-1,2,0,3,0,2,0,3,1,2,0,3,2,2,0,3,2,1,0,3,1,1,0,3,0,1,0,3,-1,1,0,3,-1,5,0,3,0,5,0,3,0,6,0,3,-1,6,0,3,-7,-3,0,3,6,-2,0,3,5,-2,0,3,8,5,0,3,8,6,0,3,8,7,0,3,-3,-5,0,3,-3,-6,0,3,5,-6,0,3,5,-5,0,3,5,-7,0,3,-3,-7,0,3,5,-8,0,3,4,-8,0,3,3,-8,0,3,2,-8,0,3,1,-8,0,3,0,-8,0,3,-1,-8,0,3,-2,-8,0,3,-3,-8,0,3,3,7,0,3,-7,-8,0,3,-7,-7,0,3,-7,-6,0,3,-7,-5,0,3,-7,-4,0,3,-6,-8,0,3,-6,-7,0,3,-6,-6,0,3,-6,-5,0,3,-6,-4,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,-5,0,3,-5,-4,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-4,-5,0,3,-4,-4,0,3,6,-8,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,7,-8,0,3,7,-7,0,3,7,-6,0,3,7,-5,0,3,7,-4,0,3,8,-8,0,3,8,-7,0,3,8,-6,0,3,8,-5,0,3,8,-4,0,3,-2,-6,0,3,-2,-7,0,3,-2,-5,0,3],"CustomFloor1":[-4,2,1,7,14,-3,3,1,8,15,-4,3,1,7,15,-5,3,1,6,15,6,4,1,8,15,5,4,1,7,15,-5,2,1,6,14,4,3,1,6,14,4,4,1,6,15,6,3,1,8,14,5,3,1,7,14,-3,2,1,8,14],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[-3,4,1,10,5,-3,5,1,10,6,2,4,1,10,5,2,5,1,10,6],"CustomMiddle2":[5,-4,1,6,0,5,-3,1,6,1,-2,-1,1,5,0,-2,0,1,5,1],"CustomTop":[],"NormalLayerObjects":null,"YSortLayerObjects":null}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/Preinstall.json
index e8a0962..662507d 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/Preinstall.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/Preinstall.json
@@ -1 +1 @@
-[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":true,"WaveList":[[{"Position":{"X":-81,"Y":25},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":31,"Y":32},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0004","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0003","CurrAmmon":"12","ResidueAmmo":"12"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-54,"Y":20},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":81,"Y":-1},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0002","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":5.551115E-14}]}]]}]
\ No newline at end of file
+[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":true,"WaveList":[[{"Position":{"X":-81,"Y":25},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":-54,"Y":20},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":81,"Y":-1},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0002","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":5.551115E-14}]}]]}]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/TileInfo.json
index d48b637..f5b2cc8 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/TileInfo.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/TileInfo.json
@@ -1 +1 @@
-{"NavigationVertices":[{"X":6,"Y":86},{"X":122,"Y":122},{"X":-106,"Y":122},{"X":-22,"Y":86},{"X":-106,"Y":-58},{"X":-22,"Y":-22},{"X":122,"Y":-58},{"X":6,"Y":-22}],"NavigationPolygon":[[0,1,2,3],[3,2,4,5],[5,4,6,7],[6,1,0,7]],"Floor":[-3,-4,0,3,-3,-3,0,3,-3,-2,0,3,-3,-1,0,3,-3,0,0,3,-3,1,0,3,-3,2,0,3,-3,3,0,3,-3,4,0,3,-3,5,0,3,-3,6,0,3,-2,-4,0,3,-2,-3,0,3,-2,-2,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-2,4,0,3,-2,5,0,3,-2,6,0,3,-1,-4,0,3,-1,-3,0,3,-1,5,0,3,-1,6,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,0,1,0,3,0,2,0,3,0,3,0,3,0,4,0,3,0,5,0,3,0,6,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,1,1,0,3,1,2,0,3,1,3,0,3,1,4,0,3,1,5,0,3,1,6,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,2,1,0,3,2,2,0,3,2,3,0,3,2,4,0,3,2,5,0,3,2,6,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,3,1,0,3,3,2,0,3,3,3,0,3,3,4,0,3,3,5,0,3,3,6,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,4,1,0,3,4,2,0,3,4,3,0,3,4,4,0,3,4,5,0,3,4,6,0,3,5,-4,0,3,5,-3,0,3,5,-2,0,3,5,-1,0,3,5,0,0,3,5,1,0,3,5,2,0,3,5,3,0,3,5,4,0,3,5,5,0,3,5,6,0,3,6,-4,0,3,6,-3,0,3,6,-2,0,3,6,-1,0,3,6,0,0,3,6,1,0,3,6,2,0,3,6,3,0,3,6,4,0,3,6,5,0,3,6,6,0,3,7,-4,0,3,7,-3,0,3,7,-2,0,3,7,-1,0,3,7,0,0,3,7,1,0,3,7,2,0,3,7,3,0,3,7,4,0,3,7,5,0,3,7,6,0,3,-4,6,0,3,-4,5,0,3,-4,4,0,3,-4,3,0,3,-4,2,0,3,-4,1,0,3,-4,0,0,3,-4,-1,0,3,-4,-2,0,3,-4,-3,0,3,-4,-4,0,3,-5,-4,0,3,-5,-3,0,3,-5,-2,0,3,-5,-1,0,3,-5,0,0,3,-5,1,0,3,-5,2,0,3,-5,3,0,3,-5,4,0,3,-5,5,0,3,-5,6,0,3,-6,6,0,3,-6,5,0,3,-6,4,0,3,-6,3,0,3,-6,2,0,3,-6,1,0,3,-6,0,0,3,-6,-1,0,3,-6,-2,0,3,-6,-3,0,3,-6,-4,0,3,-7,-4,0,3,-7,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-7,4,0,3,-7,5,0,3,-7,6,0,3,-2,-1,0,3],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[]}
\ No newline at end of file
+{"NavigationVertices":[{"X":6,"Y":86},{"X":122,"Y":122},{"X":-106,"Y":122},{"X":-22,"Y":86},{"X":-106,"Y":-58},{"X":-22,"Y":-22},{"X":122,"Y":-58},{"X":6,"Y":-22}],"NavigationPolygon":[[0,1,2,3],[3,2,4,5],[5,4,6,7],[6,1,0,7]],"Floor":[-3,-4,0,3,-3,-3,0,3,-3,-2,0,3,-3,-1,0,3,-3,0,0,3,-3,1,0,3,-3,2,0,3,-3,3,0,3,-3,4,0,3,-3,5,0,3,-3,6,0,3,-2,-4,0,3,-2,-3,0,3,-2,-2,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-2,4,0,3,-2,5,0,3,-2,6,0,3,-1,-4,0,3,-1,-3,0,3,-1,5,0,3,-1,6,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,0,1,0,3,0,2,0,3,0,3,0,3,0,4,0,3,0,5,0,3,0,6,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,1,1,0,3,1,2,0,3,1,3,0,3,1,4,0,3,1,5,0,3,1,6,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,2,1,0,3,2,2,0,3,2,3,0,3,2,4,0,3,2,5,0,3,2,6,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,3,1,0,3,3,2,0,3,3,3,0,3,3,4,0,3,3,5,0,3,3,6,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,4,1,0,3,4,2,0,3,4,3,0,3,4,4,0,3,4,5,0,3,4,6,0,3,5,-4,0,3,5,-3,0,3,5,-2,0,3,5,-1,0,3,5,0,0,3,5,1,0,3,5,2,0,3,5,3,0,3,5,4,0,3,5,5,0,3,5,6,0,3,6,-4,0,3,6,-3,0,3,6,-2,0,3,6,-1,0,3,6,0,0,3,6,1,0,3,6,2,0,3,6,3,0,3,6,4,0,3,6,5,0,3,6,6,0,3,7,-4,0,3,7,-3,0,3,7,-2,0,3,7,-1,0,3,7,0,0,3,7,1,0,3,7,2,0,3,7,3,0,3,7,4,0,3,7,5,0,3,7,6,0,3,-4,6,0,3,-4,5,0,3,-4,4,0,3,-4,3,0,3,-4,2,0,3,-4,1,0,3,-4,0,0,3,-4,-1,0,3,-4,-2,0,3,-4,-3,0,3,-4,-4,0,3,-5,-4,0,3,-5,-3,0,3,-5,-2,0,3,-5,-1,0,3,-5,0,0,3,-5,1,0,3,-5,2,0,3,-5,3,0,3,-5,4,0,3,-5,5,0,3,-5,6,0,3,-6,6,0,3,-6,5,0,3,-6,4,0,3,-6,3,0,3,-6,2,0,3,-6,1,0,3,-6,0,0,3,-6,-1,0,3,-6,-2,0,3,-6,-3,0,3,-6,-4,0,3,-7,-4,0,3,-7,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-7,4,0,3,-7,5,0,3,-7,6,0,3,-2,-1,0,3],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[],"NormalLayerObjects":null,"YSortLayerObjects":null}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/test2/battle/1/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/test2/battle/1/Preinstall.json
deleted file mode 100644
index a9f951a..0000000
--- a/DungeonShooting_Godot/resource/map/tileMaps/test2/battle/1/Preinstall.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":true,"WaveList":[[]]}]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/test2/battle/1/RoomInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/test2/battle/1/RoomInfo.json
deleted file mode 100644
index 257e929..0000000
--- a/DungeonShooting_Godot/resource/map/tileMaps/test2/battle/1/RoomInfo.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Position":{"X":0,"Y":0},"Size":{"X":0,"Y":0},"DoorAreaInfos":[],"GroupName":"test2","RoomType":1,"RoomName":"1","Weight":100,"Remark":""}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/test2/battle/1/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/test2/battle/1/TileInfo.json
deleted file mode 100644
index 5b98aa4..0000000
--- a/DungeonShooting_Godot/resource/map/tileMaps/test2/battle/1/TileInfo.json
+++ /dev/null
@@ -1 +0,0 @@
-{"NavigationVertices":[],"NavigationPolygon":[],"Floor":[],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[]}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/enemy/EnemyHurt.ogg b/DungeonShooting_Godot/resource/sound/sfx/role/enemy/EnemyHurt.ogg
new file mode 100644
index 0000000..74c7aea
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/enemy/EnemyHurt.ogg
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/enemy/EnemyHurt.ogg.import b/DungeonShooting_Godot/resource/sound/sfx/role/enemy/EnemyHurt.ogg.import
new file mode 100644
index 0000000..24272a7
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/enemy/EnemyHurt.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://dhgp1xx0636e5"
+path="res://.godot/imported/EnemyHurt.ogg-9ab5108382bce091da229e6eeba6b3ec.oggvorbisstr"
+
+[deps]
+
+source_file="res://resource/sound/sfx/role/enemy/EnemyHurt.ogg"
+dest_files=["res://.godot/imported/EnemyHurt.ogg-9ab5108382bce091da229e6eeba6b3ec.oggvorbisstr"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/enemy/Enemydie.mp3 b/DungeonShooting_Godot/resource/sound/sfx/role/enemy/Enemydie.mp3
new file mode 100644
index 0000000..2825563
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/enemy/Enemydie.mp3
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/enemy/Enemydie.mp3.import b/DungeonShooting_Godot/resource/sound/sfx/role/enemy/Enemydie.mp3.import
new file mode 100644
index 0000000..74e3250
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/enemy/Enemydie.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://4r84jtberebl"
+path="res://.godot/imported/Enemydie.mp3-da0b5b91213017a1ab2f062b59b2ddd8.mp3str"
+
+[deps]
+
+source_file="res://resource/sound/sfx/role/enemy/Enemydie.mp3"
+dest_files=["res://.godot/imported/Enemydie.mp3-da0b5b91213017a1ab2f062b59b2ddd8.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/player/PickupWeapon.mp3 b/DungeonShooting_Godot/resource/sound/sfx/role/player/PickupWeapon.mp3
new file mode 100644
index 0000000..04279c4
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/player/PickupWeapon.mp3
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/player/PickupWeapon.mp3.import b/DungeonShooting_Godot/resource/sound/sfx/role/player/PickupWeapon.mp3.import
new file mode 100644
index 0000000..5c255f1
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/player/PickupWeapon.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://dduu7jeb55wk1"
+path="res://.godot/imported/PickupWeapon.mp3-c05a192b8e854c7f008a30e5a82f1200.mp3str"
+
+[deps]
+
+source_file="res://resource/sound/sfx/role/player/PickupWeapon.mp3"
+dest_files=["res://.godot/imported/PickupWeapon.mp3-c05a192b8e854c7f008a30e5a82f1200.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleDie.mp3 b/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleDie.mp3
new file mode 100644
index 0000000..cb88266
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleDie.mp3
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleDie.mp3.import b/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleDie.mp3.import
new file mode 100644
index 0000000..3e01b8b
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleDie.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://dl4q88vcjffu0"
+path="res://.godot/imported/RoleDie.mp3-d98249b8cac77913e70c87b605730d00.mp3str"
+
+[deps]
+
+source_file="res://resource/sound/sfx/role/player/RoleDie.mp3"
+dest_files=["res://.godot/imported/RoleDie.mp3-d98249b8cac77913e70c87b605730d00.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleHurt.mp3 b/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleHurt.mp3
new file mode 100644
index 0000000..3884188
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleHurt.mp3
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleHurt.mp3.import b/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleHurt.mp3.import
new file mode 100644
index 0000000..4d2cb74
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/player/RoleHurt.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://c6fcvvxo6myxp"
+path="res://.godot/imported/RoleHurt.mp3-f9154f177d19d1b88ed3b22a1caecbcc.mp3str"
+
+[deps]
+
+source_file="res://resource/sound/sfx/role/player/RoleHurt.mp3"
+dest_files=["res://.godot/imported/RoleHurt.mp3-f9154f177d19d1b88ed3b22a1caecbcc.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/player/Rolling.mp3 b/DungeonShooting_Godot/resource/sound/sfx/role/player/Rolling.mp3
new file mode 100644
index 0000000..903ea6e
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/player/Rolling.mp3
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sound/sfx/role/player/Rolling.mp3.import b/DungeonShooting_Godot/resource/sound/sfx/role/player/Rolling.mp3.import
new file mode 100644
index 0000000..438c6c2
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sound/sfx/role/player/Rolling.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://mjl6ilt7unlm"
+path="res://.godot/imported/Rolling.mp3-6e7c54f312ec2fe453691c3f664cf1d5.mp3str"
+
+[deps]
+
+source_file="res://resource/sound/sfx/role/player/Rolling.mp3"
+dest_files=["res://.godot/imported/Rolling.mp3-6e7c54f312ec2fe453691c3f664cf1d5.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/DungeonShooting_Godot/resource/sprite/bullet/special/SpecialBullet0001.png b/DungeonShooting_Godot/resource/sprite/bullet/special/SpecialBullet0001.png
new file mode 100644
index 0000000..68dee73
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/bullet/special/SpecialBullet0001.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/bullet/special/SpecialBullet0001.png.import b/DungeonShooting_Godot/resource/sprite/bullet/special/SpecialBullet0001.png.import
new file mode 100644
index 0000000..f9466ed
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/bullet/special/SpecialBullet0001.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bskw374th4d8w"
+path="res://.godot/imported/SpecialBullet0001.png-cbee613bc30c197cdb261108ae54dc86.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/bullet/special/SpecialBullet0001.png"
+dest_files=["res://.godot/imported/SpecialBullet0001.png-cbee613bc30c197cdb261108ae54dc86.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
diff --git a/DungeonShooting_Godot/resource/sprite/bullet/summons/Summons0001.png b/DungeonShooting_Godot/resource/sprite/bullet/summons/Summons0001.png
new file mode 100644
index 0000000..600ed71
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/bullet/summons/Summons0001.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/bullet/summons/Summons0001.png.import b/DungeonShooting_Godot/resource/sprite/bullet/summons/Summons0001.png.import
new file mode 100644
index 0000000..e628e46
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/bullet/summons/Summons0001.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ckd0dyueicc4r"
+path="res://.godot/imported/Summons0001.png-e07b1004ce147f79086eecc4c1d5c0d6.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/bullet/summons/Summons0001.png"
+dest_files=["res://.godot/imported/Summons0001.png-e07b1004ce147f79086eecc4c1d5c0d6.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0002.png b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0002.png
new file mode 100644
index 0000000..ccfbaa4
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0002.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0002.png.import b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0002.png.import
new file mode 100644
index 0000000..781a04d
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0002.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://d2jhv7aygfeh0"
+path="res://.godot/imported/enemy0002.png-2acff162303a357157359257f6cf05cf.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/role/dle_liquid/enemy0002.png"
+dest_files=["res://.godot/imported/enemy0002.png-2acff162303a357157359257f6cf05cf.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0003.png b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0003.png
new file mode 100644
index 0000000..1f2f0e8
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0003.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0003.png.import b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0003.png.import
new file mode 100644
index 0000000..23db0f1
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0003.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cjg050p1t5skx"
+path="res://.godot/imported/enemy0003.png-e4735d609b3654151ba4171ac7355fa7.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/role/dle_liquid/enemy0003.png"
+dest_files=["res://.godot/imported/enemy0003.png-e4735d609b3654151ba4171ac7355fa7.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0004.png b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0004.png
new file mode 100644
index 0000000..75c153c
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0004.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0004.png.import b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0004.png.import
new file mode 100644
index 0000000..d739657
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/role/dle_liquid/enemy0004.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cb4wfl7pytyle"
+path="res://.godot/imported/enemy0004.png-66d8d815f8dee0604635c9e169c3b994.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/role/dle_liquid/enemy0004.png"
+dest_files=["res://.godot/imported/enemy0004.png-66d8d815f8dee0604635c9e169c3b994.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003.png b/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003.png
deleted file mode 100644
index 05033ec..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003.png.import
deleted file mode 100644
index 23761ad..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://cdf1al6kpv3ta"
-path="res://.godot/imported/enemy0003.png-2aff5a98bb5dd4db23d6f75b0e990221.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0003/enemy0003.png"
-dest_files=["res://.godot/imported/enemy0003.png-2aff5a98bb5dd4db23d6f75b0e990221.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Debris.png b/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Debris.png
deleted file mode 100644
index 0c428a8..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Debris.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Debris.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Debris.png.import
deleted file mode 100644
index 82f98bd..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Debris.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://dj68fnvd2qrm4"
-path="res://.godot/imported/enemy0003_Debris.png-0d49499ec67ee7fedfebc509ec159ea0.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0003/enemy0003_Debris.png"
-dest_files=["res://.godot/imported/enemy0003_Debris.png-0d49499ec67ee7fedfebc509ec159ea0.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Icon.png b/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Icon.png
deleted file mode 100644
index ef31ab5..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Icon.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Icon.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Icon.png.import
deleted file mode 100644
index 6ae8808..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0003/enemy0003_Icon.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://d0n3ncp68nnk6"
-path="res://.godot/imported/enemy0003_Icon.png-b9629b2c5194b2a54d5cd4d819d3b505.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0003/enemy0003_Icon.png"
-dest_files=["res://.godot/imported/enemy0003_Icon.png-b9629b2c5194b2a54d5cd4d819d3b505.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004.png b/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004.png
deleted file mode 100644
index 77139b8..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004.png.import
deleted file mode 100644
index 50561a7..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://digotsm6pux62"
-path="res://.godot/imported/enemy0004.png-48437bd7fc483bcc9164f9278838c427.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0004/enemy0004.png"
-dest_files=["res://.godot/imported/enemy0004.png-48437bd7fc483bcc9164f9278838c427.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Debris.png b/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Debris.png
deleted file mode 100644
index b531577..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Debris.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Debris.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Debris.png.import
deleted file mode 100644
index 2fc93e2..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Debris.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://v63ex2nsmve8"
-path="res://.godot/imported/enemy0004_Debris.png-8490ea147f0c0301c8ff1081373d661a.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0004/enemy0004_Debris.png"
-dest_files=["res://.godot/imported/enemy0004_Debris.png-8490ea147f0c0301c8ff1081373d661a.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Icon.png b/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Icon.png
deleted file mode 100644
index 73333fe..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Icon.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Icon.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Icon.png.import
deleted file mode 100644
index e91bc90..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0004/enemy0004_Icon.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://dbw81vt8cv47a"
-path="res://.godot/imported/enemy0004_Icon.png-afab614bd8c989b6254232cbe479a533.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0004/enemy0004_Icon.png"
-dest_files=["res://.godot/imported/enemy0004_Icon.png-afab614bd8c989b6254232cbe479a533.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005.png b/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005.png
deleted file mode 100644
index 6162fc8..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005.png.import
deleted file mode 100644
index cf72c61..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://5tge3befo7le"
-path="res://.godot/imported/enemy0005.png-e2e97973c857a4e2da0bd848aff0b022.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0005/enemy0005.png"
-dest_files=["res://.godot/imported/enemy0005.png-e2e97973c857a4e2da0bd848aff0b022.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Debris.png b/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Debris.png
deleted file mode 100644
index 8675634..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Debris.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Debris.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Debris.png.import
deleted file mode 100644
index bcdda13..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Debris.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://dw4jvgt7iwi2d"
-path="res://.godot/imported/enemy0005_Debris.png-8cdee7278caf6047bdf1b37bc055bc6e.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0005/enemy0005_Debris.png"
-dest_files=["res://.godot/imported/enemy0005_Debris.png-8cdee7278caf6047bdf1b37bc055bc6e.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Icon.png b/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Icon.png
deleted file mode 100644
index c1dd6d1..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Icon.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Icon.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Icon.png.import
deleted file mode 100644
index be68958..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0005/enemy0005_Icon.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://mvpyaurvr278"
-path="res://.godot/imported/enemy0005_Icon.png-6c35e6f3e277f42cce227ff83451f989.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0005/enemy0005_Icon.png"
-dest_files=["res://.godot/imported/enemy0005_Icon.png-6c35e6f3e277f42cce227ff83451f989.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005.png b/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005.png
deleted file mode 100644
index 43f6a74..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005.png.import
deleted file mode 100644
index 0735258..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://cdin8mr0sj5v0"
-path="res://.godot/imported/enemy0005.png-d7d5d324302d03139b72cada5c03b905.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0006/enemy0005.png"
-dest_files=["res://.godot/imported/enemy0005.png-d7d5d324302d03139b72cada5c03b905.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005_Icon.png b/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005_Icon.png
deleted file mode 100644
index c1dd6d1..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005_Icon.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005_Icon.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005_Icon.png.import
deleted file mode 100644
index b43d044..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0005_Icon.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://bwtmntgepkiee"
-path="res://.godot/imported/enemy0005_Icon.png-2897ecc50529bab5d0643e849e41cf6f.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0006/enemy0005_Icon.png"
-dest_files=["res://.godot/imported/enemy0005_Icon.png-2897ecc50529bab5d0643e849e41cf6f.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0006_Debris.png b/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0006_Debris.png
deleted file mode 100644
index b0116cd..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0006_Debris.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0006_Debris.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0006_Debris.png.import
deleted file mode 100644
index 43b68c0..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy0006_Debris.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://dj03mufxwgfek"
-path="res://.godot/imported/enemy0006_Debris.png-d1fbf79bad5aefa7d37040e3a6e8db7d.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0006/enemy0006_Debris.png"
-dest_files=["res://.godot/imported/enemy0006_Debris.png-d1fbf79bad5aefa7d37040e3a6e8db7d.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy005.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy005.png.import
deleted file mode 100644
index 542466b..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0006/enemy005.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://bpujly44rboun"
-path="res://.godot/imported/enemy005.png-6312988475feeb1cbcc99baeb7ad3e72.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy005/enemy005.png"
-dest_files=["res://.godot/imported/enemy005.png-6312988475feeb1cbcc99baeb7ad3e72.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0007/dle.png b/DungeonShooting_Godot/resource/sprite/role/enemy0007/dle.png
deleted file mode 100644
index bc8c816..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0007/dle.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0007/dle.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0007/dle.png.import
deleted file mode 100644
index 2626a0b..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0007/dle.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://duyr3ic6hh3ek"
-path="res://.godot/imported/dle.png-79145da0f375bf73578bd141d00d2ce8.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0007/dle.png"
-dest_files=["res://.godot/imported/dle.png-79145da0f375bf73578bd141d00d2ce8.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0005_Icon.png b/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0005_Icon.png
deleted file mode 100644
index 70e70ef..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0005_Icon.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0005_Icon.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0005_Icon.png.import
deleted file mode 100644
index 60c2729..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0005_Icon.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://cpd6jhjfg7cyk"
-path="res://.godot/imported/enemy0005_Icon.png-0a336b66135db16c8e2f50cd4c955d4e.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0007/enemy0005_Icon.png"
-dest_files=["res://.godot/imported/enemy0005_Icon.png-0a336b66135db16c8e2f50cd4c955d4e.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0006_Debris.png b/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0006_Debris.png
deleted file mode 100644
index b615687..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0006_Debris.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0006_Debris.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0006_Debris.png.import
deleted file mode 100644
index d701ca4..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy0006_Debris.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://d0nfvywb17dup"
-path="res://.godot/imported/enemy0006_Debris.png-8d79cda8586b6b07126be2733324473d.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0007/enemy0006_Debris.png"
-dest_files=["res://.godot/imported/enemy0006_Debris.png-8d79cda8586b6b07126be2733324473d.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
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy005.png b/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy005.png
deleted file mode 100644
index 15cd671..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy005.png
+++ /dev/null
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy005.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy005.png.import
deleted file mode 100644
index 7c10fb0..0000000
--- a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy005.png.import
+++ /dev/null
@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://bft65nd80tlju"
-path="res://.godot/imported/enemy005.png-36beaed69baad591e8b54a29a147644f.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://resource/sprite/role/enemy0007/enemy005.png"
-dest_files=["res://.godot/imported/enemy005.png-36beaed69baad591e8b54a29a147644f.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
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_BACK.png b/DungeonShooting_Godot/resource/sprite/ui/setting/option_BACK.png
new file mode 100644
index 0000000..b069137
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_BACK.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_BACK.png.import b/DungeonShooting_Godot/resource/sprite/ui/setting/option_BACK.png.import
new file mode 100644
index 0000000..f1dff64
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_BACK.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bdi0artf53sag"
+path="res://.godot/imported/option_BACK.png-34427990b594935e009faf1d5d036b3e.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/ui/setting/option_BACK.png"
+dest_files=["res://.godot/imported/option_BACK.png-34427990b594935e009faf1d5d036b3e.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
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_BG.png b/DungeonShooting_Godot/resource/sprite/ui/setting/option_BG.png
new file mode 100644
index 0000000..85e6c5c
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_BG.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_BG.png.import b/DungeonShooting_Godot/resource/sprite/ui/setting/option_BG.png.import
new file mode 100644
index 0000000..78f4f49
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_BG.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dawuyrurwp4ni"
+path="res://.godot/imported/option_BG.png-3c4a41354b98c9bcfe6167fe86861333.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/ui/setting/option_BG.png"
+dest_files=["res://.godot/imported/option_BG.png-3c4a41354b98c9bcfe6167fe86861333.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
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_KEYS.png b/DungeonShooting_Godot/resource/sprite/ui/setting/option_KEYS.png
new file mode 100644
index 0000000..46cd476
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_KEYS.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_KEYS.png.import b/DungeonShooting_Godot/resource/sprite/ui/setting/option_KEYS.png.import
new file mode 100644
index 0000000..7a03215
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_KEYS.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cfuex7id07qky"
+path="res://.godot/imported/option_KEYS.png-184789ee683a326e2d14d86259406daa.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/ui/setting/option_KEYS.png"
+dest_files=["res://.godot/imported/option_KEYS.png-184789ee683a326e2d14d86259406daa.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
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_VIEW.png b/DungeonShooting_Godot/resource/sprite/ui/setting/option_VIEW.png
new file mode 100644
index 0000000..115276c
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_VIEW.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_VIEW.png.import b/DungeonShooting_Godot/resource/sprite/ui/setting/option_VIEW.png.import
new file mode 100644
index 0000000..0fe82f5
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_VIEW.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dkapu3yit1me0"
+path="res://.godot/imported/option_VIEW.png-d3ba75564d9f07e84a75b7daad243119.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/ui/setting/option_VIEW.png"
+dest_files=["res://.godot/imported/option_VIEW.png-d3ba75564d9f07e84a75b7daad243119.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
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_VOICE.png b/DungeonShooting_Godot/resource/sprite/ui/setting/option_VOICE.png
new file mode 100644
index 0000000..d1fd4d3
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_VOICE.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_VOICE.png.import b/DungeonShooting_Godot/resource/sprite/ui/setting/option_VOICE.png.import
new file mode 100644
index 0000000..61f3694
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_VOICE.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b1vphb1f4wefo"
+path="res://.godot/imported/option_VOICE.png-59d44c7cb9c198de356d3b7f7b9a06b1.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/ui/setting/option_VOICE.png"
+dest_files=["res://.godot/imported/option_VOICE.png-59d44c7cb9c198de356d3b7f7b9a06b1.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
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_cursor.png b/DungeonShooting_Godot/resource/sprite/ui/setting/option_cursor.png
new file mode 100644
index 0000000..dc760ec
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_cursor.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/ui/setting/option_cursor.png.import b/DungeonShooting_Godot/resource/sprite/ui/setting/option_cursor.png.import
new file mode 100644
index 0000000..75aa605
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/ui/setting/option_cursor.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b5x73pjycunyd"
+path="res://.godot/imported/option_cursor.png-437a0a4cc775557f8c28459ec7c16547.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/ui/setting/option_cursor.png"
+dest_files=["res://.godot/imported/option_cursor.png-437a0a4cc775557f8c28459ec7c16547.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
diff --git a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0003.tres b/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0003.tres
deleted file mode 100644
index 935369a..0000000
--- a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0003.tres
+++ /dev/null
@@ -1,114 +0,0 @@
-[gd_resource type="SpriteFrames" load_steps=15 format=3 uid="uid://cnk1wmk3uy4aa"]
-
-[ext_resource type="Texture2D" uid="uid://d0n3ncp68nnk6" path="res://resource/sprite/role/enemy0003/enemy0003_Icon.png" id="1_4n7kk"]
-[ext_resource type="Texture2D" uid="uid://cdf1al6kpv3ta" path="res://resource/sprite/role/enemy0003/enemy0003.png" id="2_gvc60"]
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_fiqik"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(0, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_algye"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(16, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_rovd5"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(32, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_k7bjp"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(48, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_yyuaf"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(48, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_ijjls"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(32, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_e2uc8"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(16, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_id4xp"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(0, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_hof3c"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(0, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_3n1od"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(16, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_3jmh0"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(32, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_ddpq5"]
-atlas = ExtResource("2_gvc60")
-region = Rect2(48, 48, 16, 24)
-
-[resource]
-animations = [{
-"frames": [{
-"duration": 1.0,
-"texture": ExtResource("1_4n7kk")
-}],
-"loop": true,
-"name": &"default",
-"speed": 5.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_fiqik")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_algye")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_rovd5")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_k7bjp")
-}],
-"loop": true,
-"name": &"idle",
-"speed": 7.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_yyuaf")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_ijjls")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_e2uc8")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_id4xp")
-}],
-"loop": true,
-"name": &"reverseRun",
-"speed": 10.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_hof3c")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_3n1od")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_3jmh0")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_ddpq5")
-}],
-"loop": true,
-"name": &"run",
-"speed": 10.0
-}]
diff --git a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0004.tres b/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0004.tres
deleted file mode 100644
index d229cf7..0000000
--- a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0004.tres
+++ /dev/null
@@ -1,114 +0,0 @@
-[gd_resource type="SpriteFrames" load_steps=15 format=3 uid="uid://cejv5k5ivm0k0"]
-
-[ext_resource type="Texture2D" uid="uid://dbw81vt8cv47a" path="res://resource/sprite/role/enemy0004/enemy0004_Icon.png" id="1_81co3"]
-[ext_resource type="Texture2D" uid="uid://digotsm6pux62" path="res://resource/sprite/role/enemy0004/enemy0004.png" id="2_abhfm"]
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_2ru4b"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(0, 24, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_uxd8i"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(18, 24, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_h133c"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(36, 24, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_ap8tv"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(54, 24, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_7ego7"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(54, 48, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_jix76"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(36, 48, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_bkoo2"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(18, 48, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_q7ixj"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(0, 48, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_05rwa"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(0, 48, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_7yta5"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(18, 48, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_nfyei"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(36, 48, 18, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_0elaw"]
-atlas = ExtResource("2_abhfm")
-region = Rect2(54, 48, 18, 24)
-
-[resource]
-animations = [{
-"frames": [{
-"duration": 1.0,
-"texture": ExtResource("1_81co3")
-}],
-"loop": true,
-"name": &"default",
-"speed": 5.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_2ru4b")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_uxd8i")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_h133c")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_ap8tv")
-}],
-"loop": true,
-"name": &"idle",
-"speed": 7.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_7ego7")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_jix76")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_bkoo2")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_q7ixj")
-}],
-"loop": true,
-"name": &"reverseRun",
-"speed": 10.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_05rwa")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_7yta5")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_nfyei")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_0elaw")
-}],
-"loop": true,
-"name": &"run",
-"speed": 10.0
-}]
diff --git a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0005.tres b/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0005.tres
deleted file mode 100644
index a4feb08..0000000
--- a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0005.tres
+++ /dev/null
@@ -1,114 +0,0 @@
-[gd_resource type="SpriteFrames" load_steps=15 format=3 uid="uid://cke0yk8ovq6yv"]
-
-[ext_resource type="Texture2D" uid="uid://mvpyaurvr278" path="res://resource/sprite/role/enemy0005/enemy0005_Icon.png" id="1_qhawc"]
-[ext_resource type="Texture2D" uid="uid://5tge3befo7le" path="res://resource/sprite/role/enemy0005/enemy0005.png" id="2_6qavs"]
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_58dkt"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(0, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_4kxem"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(16, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_llugx"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(32, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_bffuk"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(48, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_x46sj"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(48, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_2lcqb"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(32, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_745io"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(16, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_1fwab"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(0, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_4dga3"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(0, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_wrisn"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(16, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_hxbal"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(32, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_hnjkd"]
-atlas = ExtResource("2_6qavs")
-region = Rect2(48, 48, 16, 24)
-
-[resource]
-animations = [{
-"frames": [{
-"duration": 1.0,
-"texture": ExtResource("1_qhawc")
-}],
-"loop": true,
-"name": &"default",
-"speed": 5.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_58dkt")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_4kxem")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_llugx")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_bffuk")
-}],
-"loop": true,
-"name": &"idle",
-"speed": 7.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_x46sj")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_2lcqb")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_745io")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_1fwab")
-}],
-"loop": true,
-"name": &"reverseRun",
-"speed": 10.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_4dga3")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_wrisn")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_hxbal")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_hnjkd")
-}],
-"loop": true,
-"name": &"run",
-"speed": 10.0
-}]
diff --git a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0006.tres b/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0006.tres
deleted file mode 100644
index cb453da..0000000
--- a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0006.tres
+++ /dev/null
@@ -1,110 +0,0 @@
-[gd_resource type="SpriteFrames" load_steps=14 format=3 uid="uid://l3iesn33p2og"]
-
-[ext_resource type="Texture2D" uid="uid://5tge3befo7le" path="res://resource/sprite/role/enemy0005/enemy0005.png" id="2_4bmn3"]
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_58dkt"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(0, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_4kxem"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(16, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_llugx"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(32, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_bffuk"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(48, 24, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_x46sj"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(48, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_2lcqb"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(32, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_745io"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(16, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_1fwab"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(0, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_4dga3"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(0, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_wrisn"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(16, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_hxbal"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(32, 48, 16, 24)
-
-[sub_resource type="AtlasTexture" id="AtlasTexture_hnjkd"]
-atlas = ExtResource("2_4bmn3")
-region = Rect2(48, 48, 16, 24)
-
-[resource]
-animations = [{
-"frames": [],
-"loop": true,
-"name": &"default",
-"speed": 5.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_58dkt")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_4kxem")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_llugx")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_bffuk")
-}],
-"loop": true,
-"name": &"idle",
-"speed": 7.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_x46sj")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_2lcqb")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_745io")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_1fwab")
-}],
-"loop": true,
-"name": &"reverseRun",
-"speed": 10.0
-}, {
-"frames": [{
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_4dga3")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_wrisn")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_hxbal")
-}, {
-"duration": 1.0,
-"texture": SubResource("AtlasTexture_hnjkd")
-}],
-"loop": true,
-"name": &"run",
-"speed": 10.0
-}]
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig.cs b/DungeonShooting_Godot/src/config/ExcelConfig.cs
index df8bd8d..8b1bbd9 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig.cs
@@ -8,42 +8,6 @@
public static partial class ExcelConfig
{
///
- /// ActivePropBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
- ///
- public static List ActivePropBase_List { get; private set; }
- ///
- /// ActivePropBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
- ///
- public static Dictionary ActivePropBase_Map { get; private set; }
-
- ///
- /// ActivityBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
- ///
- public static List ActivityBase_List { get; private set; }
- ///
- /// ActivityBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
- ///
- public static Dictionary ActivityBase_Map { get; private set; }
-
- ///
- /// ActivityMaterial.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
- ///
- public static List ActivityMaterial_List { get; private set; }
- ///
- /// ActivityMaterial.xlsx表数据集合, 里 Map 形式存储, key 为 Id
- ///
- public static Dictionary ActivityMaterial_Map { get; private set; }
-
- ///
- /// AiAttackAttr.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
- ///
- public static List AiAttackAttr_List { get; private set; }
- ///
- /// AiAttackAttr.xlsx表数据集合, 里 Map 形式存储, key 为 Id
- ///
- public static Dictionary AiAttackAttr_Map { get; private set; }
-
- ///
/// BuffPropBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
///
public static List BuffPropBase_List { get; private set; }
@@ -53,33 +17,6 @@
public static Dictionary BuffPropBase_Map { get; private set; }
///
- /// BulletBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
- ///
- public static List BulletBase_List { get; private set; }
- ///
- /// BulletBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
- ///
- public static Dictionary BulletBase_Map { get; private set; }
-
- ///
- /// EnemyBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
- ///
- public static List EnemyBase_List { get; private set; }
- ///
- /// EnemyBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
- ///
- public static Dictionary EnemyBase_Map { get; private set; }
-
- ///
- /// LiquidMaterial.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
- ///
- public static List LiquidMaterial_List { get; private set; }
- ///
- /// LiquidMaterial.xlsx表数据集合, 里 Map 形式存储, key 为 Id
- ///
- public static Dictionary LiquidMaterial_Map { get; private set; }
-
- ///
/// Sound.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
///
public static List Sound_List { get; private set; }
@@ -97,6 +34,78 @@
///
public static Dictionary WeaponBase_Map { get; private set; }
+ ///
+ /// ActivityMaterial.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List ActivityMaterial_List { get; private set; }
+ ///
+ /// ActivityMaterial.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary ActivityMaterial_Map { get; private set; }
+
+ ///
+ /// EditorObject.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List EditorObject_List { get; private set; }
+ ///
+ /// EditorObject.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary EditorObject_Map { get; private set; }
+
+ ///
+ /// AiAttackAttr.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List AiAttackAttr_List { get; private set; }
+ ///
+ /// AiAttackAttr.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary AiAttackAttr_Map { get; private set; }
+
+ ///
+ /// BulletBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List BulletBase_List { get; private set; }
+ ///
+ /// BulletBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary BulletBase_Map { get; private set; }
+
+ ///
+ /// ActivePropBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List ActivePropBase_List { get; private set; }
+ ///
+ /// ActivePropBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary ActivePropBase_Map { get; private set; }
+
+ ///
+ /// EnemyBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List EnemyBase_List { get; private set; }
+ ///
+ /// EnemyBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary EnemyBase_Map { get; private set; }
+
+ ///
+ /// ActivityBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List ActivityBase_List { get; private set; }
+ ///
+ /// ActivityBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary ActivityBase_Map { get; private set; }
+
+ ///
+ /// LiquidMaterial.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List LiquidMaterial_List { get; private set; }
+ ///
+ /// LiquidMaterial.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary LiquidMaterial_Map { get; private set; }
+
private static bool _init = false;
///
@@ -107,94 +116,23 @@
if (_init) return;
_init = true;
- _InitActivePropBaseConfig();
- _InitActivityBaseConfig();
- _InitActivityMaterialConfig();
- _InitAiAttackAttrConfig();
_InitBuffPropBaseConfig();
- _InitBulletBaseConfig();
- _InitEnemyBaseConfig();
- _InitLiquidMaterialConfig();
_InitSoundConfig();
_InitWeaponBaseConfig();
+ _InitActivityMaterialConfig();
+ _InitEditorObjectConfig();
+ _InitAiAttackAttrConfig();
+ _InitBulletBaseConfig();
+ _InitActivePropBaseConfig();
+ _InitEnemyBaseConfig();
+ _InitActivityBaseConfig();
+ _InitLiquidMaterialConfig();
- _InitActivePropBaseRef();
- _InitActivityBaseRef();
_InitBuffPropBaseRef();
- _InitEnemyBaseRef();
_InitWeaponBaseRef();
- }
- private static void _InitActivePropBaseConfig()
- {
- try
- {
- var text = _ReadConfigAsText("res://resource/config/ActivePropBase.json");
- ActivePropBase_List = new List(JsonSerializer.Deserialize>(text));
- ActivePropBase_Map = new Dictionary();
- foreach (var item in ActivePropBase_List)
- {
- ActivePropBase_Map.Add(item.Id, item);
- }
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化表'ActivePropBase'失败!");
- }
- }
- private static void _InitActivityBaseConfig()
- {
- try
- {
- var text = _ReadConfigAsText("res://resource/config/ActivityBase.json");
- ActivityBase_List = new List(JsonSerializer.Deserialize>(text));
- ActivityBase_Map = new Dictionary();
- foreach (var item in ActivityBase_List)
- {
- ActivityBase_Map.Add(item.Id, item);
- }
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化表'ActivityBase'失败!");
- }
- }
- private static void _InitActivityMaterialConfig()
- {
- try
- {
- var text = _ReadConfigAsText("res://resource/config/ActivityMaterial.json");
- ActivityMaterial_List = JsonSerializer.Deserialize>(text);
- ActivityMaterial_Map = new Dictionary();
- foreach (var item in ActivityMaterial_List)
- {
- ActivityMaterial_Map.Add(item.Id, item);
- }
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化表'ActivityMaterial'失败!");
- }
- }
- private static void _InitAiAttackAttrConfig()
- {
- try
- {
- var text = _ReadConfigAsText("res://resource/config/AiAttackAttr.json");
- AiAttackAttr_List = JsonSerializer.Deserialize>(text);
- AiAttackAttr_Map = new Dictionary();
- foreach (var item in AiAttackAttr_List)
- {
- AiAttackAttr_Map.Add(item.Id, item);
- }
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化表'AiAttackAttr'失败!");
- }
+ _InitActivePropBaseRef();
+ _InitEnemyBaseRef();
+ _InitActivityBaseRef();
}
private static void _InitBuffPropBaseConfig()
{
@@ -214,60 +152,6 @@
throw new Exception("初始化表'BuffPropBase'失败!");
}
}
- private static void _InitBulletBaseConfig()
- {
- try
- {
- var text = _ReadConfigAsText("res://resource/config/BulletBase.json");
- BulletBase_List = JsonSerializer.Deserialize>(text);
- BulletBase_Map = new Dictionary();
- foreach (var item in BulletBase_List)
- {
- BulletBase_Map.Add(item.Id, item);
- }
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化表'BulletBase'失败!");
- }
- }
- private static void _InitEnemyBaseConfig()
- {
- try
- {
- var text = _ReadConfigAsText("res://resource/config/EnemyBase.json");
- EnemyBase_List = new List(JsonSerializer.Deserialize>(text));
- EnemyBase_Map = new Dictionary();
- foreach (var item in EnemyBase_List)
- {
- EnemyBase_Map.Add(item.Id, item);
- }
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化表'EnemyBase'失败!");
- }
- }
- private static void _InitLiquidMaterialConfig()
- {
- try
- {
- var text = _ReadConfigAsText("res://resource/config/LiquidMaterial.json");
- LiquidMaterial_List = JsonSerializer.Deserialize>(text);
- LiquidMaterial_Map = new Dictionary();
- foreach (var item in LiquidMaterial_List)
- {
- LiquidMaterial_Map.Add(item.Id, item);
- }
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化表'LiquidMaterial'失败!");
- }
- }
private static void _InitSoundConfig()
{
try
@@ -304,45 +188,151 @@
throw new Exception("初始化表'WeaponBase'失败!");
}
}
-
- private static void _InitActivePropBaseRef()
+ private static void _InitActivityMaterialConfig()
{
- foreach (Ref_ActivePropBase item in ActivePropBase_List)
+ try
{
- try
+ var text = _ReadConfigAsText("res://resource/config/ActivityMaterial.json");
+ ActivityMaterial_List = JsonSerializer.Deserialize>(text);
+ ActivityMaterial_Map = new Dictionary();
+ foreach (var item in ActivityMaterial_List)
{
- if (!string.IsNullOrEmpty(item.__Activity))
- {
- item.Activity = ActivityBase_Map[item.__Activity];
- }
-
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化'ActivePropBase'引用其他表数据失败, 当前行id: " + item.Id);
+ ActivityMaterial_Map.Add(item.Id, item);
}
}
- }
- private static void _InitActivityBaseRef()
- {
- foreach (Ref_ActivityBase item in ActivityBase_List)
+ catch (Exception e)
{
- try
- {
- if (!string.IsNullOrEmpty(item.__Material))
- {
- item.Material = ActivityMaterial_Map[item.__Material];
- }
-
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化'ActivityBase'引用其他表数据失败, 当前行id: " + item.Id);
- }
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'ActivityMaterial'失败!");
}
}
+ private static void _InitEditorObjectConfig()
+ {
+ try
+ {
+ var text = _ReadConfigAsText("res://resource/config/EditorObject.json");
+ EditorObject_List = JsonSerializer.Deserialize>(text);
+ EditorObject_Map = new Dictionary();
+ foreach (var item in EditorObject_List)
+ {
+ EditorObject_Map.Add(item.Id, item);
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'EditorObject'失败!");
+ }
+ }
+ private static void _InitAiAttackAttrConfig()
+ {
+ try
+ {
+ var text = _ReadConfigAsText("res://resource/config/AiAttackAttr.json");
+ AiAttackAttr_List = JsonSerializer.Deserialize>(text);
+ AiAttackAttr_Map = new Dictionary();
+ foreach (var item in AiAttackAttr_List)
+ {
+ AiAttackAttr_Map.Add(item.Id, item);
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'AiAttackAttr'失败!");
+ }
+ }
+ private static void _InitBulletBaseConfig()
+ {
+ try
+ {
+ var text = _ReadConfigAsText("res://resource/config/BulletBase.json");
+ BulletBase_List = JsonSerializer.Deserialize>(text);
+ BulletBase_Map = new Dictionary();
+ foreach (var item in BulletBase_List)
+ {
+ BulletBase_Map.Add(item.Id, item);
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'BulletBase'失败!");
+ }
+ }
+ private static void _InitActivePropBaseConfig()
+ {
+ try
+ {
+ var text = _ReadConfigAsText("res://resource/config/ActivePropBase.json");
+ ActivePropBase_List = new List(JsonSerializer.Deserialize>(text));
+ ActivePropBase_Map = new Dictionary();
+ foreach (var item in ActivePropBase_List)
+ {
+ ActivePropBase_Map.Add(item.Id, item);
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'ActivePropBase'失败!");
+ }
+ }
+ private static void _InitEnemyBaseConfig()
+ {
+ try
+ {
+ var text = _ReadConfigAsText("res://resource/config/EnemyBase.json");
+ EnemyBase_List = new List(JsonSerializer.Deserialize>(text));
+ EnemyBase_Map = new Dictionary();
+ foreach (var item in EnemyBase_List)
+ {
+ EnemyBase_Map.Add(item.Id, item);
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'EnemyBase'失败!");
+ }
+ }
+ private static void _InitActivityBaseConfig()
+ {
+ try
+ {
+ var text = _ReadConfigAsText("res://resource/config/ActivityBase.json");
+ ActivityBase_List = new List(JsonSerializer.Deserialize>(text));
+ ActivityBase_Map = new Dictionary();
+ foreach (var item in ActivityBase_List)
+ {
+ ActivityBase_Map.Add(item.Id, item);
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'ActivityBase'失败!");
+ }
+ }
+ private static void _InitLiquidMaterialConfig()
+ {
+ try
+ {
+ var text = _ReadConfigAsText("res://resource/config/LiquidMaterial.json");
+ LiquidMaterial_List = JsonSerializer.Deserialize>(text);
+ LiquidMaterial_Map = new Dictionary();
+ foreach (var item in LiquidMaterial_List)
+ {
+ LiquidMaterial_Map.Add(item.Id, item);
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'LiquidMaterial'失败!");
+ }
+ }
+
private static void _InitBuffPropBaseRef()
{
foreach (Ref_BuffPropBase item in BuffPropBase_List)
@@ -362,25 +352,6 @@
}
}
}
- private static void _InitEnemyBaseRef()
- {
- foreach (Ref_EnemyBase item in EnemyBase_List)
- {
- try
- {
- if (!string.IsNullOrEmpty(item.__Activity))
- {
- item.Activity = ActivityBase_Map[item.__Activity];
- }
-
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化'EnemyBase'引用其他表数据失败, 当前行id: " + item.Id);
- }
- }
- }
private static void _InitWeaponBaseRef()
{
foreach (Ref_WeaponBase item in WeaponBase_List)
@@ -449,6 +420,68 @@
}
}
}
+ private static void _InitActivePropBaseRef()
+ {
+ foreach (Ref_ActivePropBase item in ActivePropBase_List)
+ {
+ try
+ {
+ if (!string.IsNullOrEmpty(item.__Activity))
+ {
+ item.Activity = ActivityBase_Map[item.__Activity];
+ }
+
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化'ActivePropBase'引用其他表数据失败, 当前行id: " + item.Id);
+ }
+ }
+ }
+ private static void _InitEnemyBaseRef()
+ {
+ foreach (Ref_EnemyBase item in EnemyBase_List)
+ {
+ try
+ {
+ if (!string.IsNullOrEmpty(item.__Activity))
+ {
+ item.Activity = ActivityBase_Map[item.__Activity];
+ }
+
+ if (!string.IsNullOrEmpty(item.__BodyFragment))
+ {
+ item.BodyFragment = ActivityBase_Map[item.__BodyFragment];
+ }
+
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化'EnemyBase'引用其他表数据失败, 当前行id: " + item.Id);
+ }
+ }
+ }
+ private static void _InitActivityBaseRef()
+ {
+ foreach (Ref_ActivityBase item in ActivityBase_List)
+ {
+ try
+ {
+ if (!string.IsNullOrEmpty(item.__Material))
+ {
+ item.Material = ActivityMaterial_Map[item.__Material];
+ }
+
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化'ActivityBase'引用其他表数据失败, 当前行id: " + item.Id);
+ }
+ }
+ }
private static string _ReadConfigAsText(string path)
{
var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_ActivePropBase.cs b/DungeonShooting_Godot/src/config/ExcelConfig_ActivePropBase.cs
index f2a7f17..02da62e 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_ActivePropBase.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_ActivePropBase.cs
@@ -5,7 +5,7 @@
public static partial class ExcelConfig
{
- public class ActivePropBase
+ public partial class ActivePropBase
{
///
/// Buff Id
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_ActivityBase.cs b/DungeonShooting_Godot/src/config/ExcelConfig_ActivityBase.cs
index f9af8d4..a4e0660 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_ActivityBase.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_ActivityBase.cs
@@ -5,7 +5,7 @@
public static partial class ExcelConfig
{
- public class ActivityBase
+ public partial class ActivityBase
{
///
/// 物体唯一id
@@ -31,6 +31,7 @@
/// Prop(道具): 9
/// Treasure(宝箱): 10
/// Npc: 11
+ /// Boss: 12
/// Other(其它类型): 99
///
[JsonInclude]
@@ -95,7 +96,8 @@
public string Icon;
///
- /// 是否在地图编辑器中显示该物体
+ /// 是否在地图编辑器中显示该物体
+ /// 仅对角色, 武器, 道具, 敌人和Boss类型对物体有效
///
[JsonInclude]
public bool ShowInMapEditor;
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_ActivityMaterial.cs b/DungeonShooting_Godot/src/config/ExcelConfig_ActivityMaterial.cs
index fe76940..d4c0f62 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_ActivityMaterial.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_ActivityMaterial.cs
@@ -5,7 +5,7 @@
public static partial class ExcelConfig
{
- public class ActivityMaterial
+ public partial class ActivityMaterial
{
///
/// 表Id
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs b/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs
index c3c734c..7bc3bc4 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs
@@ -5,7 +5,7 @@
public static partial class ExcelConfig
{
- public class AiAttackAttr
+ public partial class AiAttackAttr
{
///
/// Id
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_BuffPropBase.cs b/DungeonShooting_Godot/src/config/ExcelConfig_BuffPropBase.cs
index 45c042d..b8614ac 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_BuffPropBase.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_BuffPropBase.cs
@@ -5,7 +5,7 @@
public static partial class ExcelConfig
{
- public class BuffPropBase
+ public partial class BuffPropBase
{
///
/// Buff Id
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_BulletBase.cs b/DungeonShooting_Godot/src/config/ExcelConfig_BulletBase.cs
index 549ed11..326d630 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_BulletBase.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_BulletBase.cs
@@ -5,7 +5,7 @@
public static partial class ExcelConfig
{
- public class BulletBase
+ public partial class BulletBase
{
///
/// 子弹id
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_EditorObject.cs b/DungeonShooting_Godot/src/config/ExcelConfig_EditorObject.cs
new file mode 100644
index 0000000..8a94926
--- /dev/null
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_EditorObject.cs
@@ -0,0 +1,57 @@
+using System.Text.Json.Serialization;
+using System.Collections.Generic;
+
+namespace Config;
+
+public static partial class ExcelConfig
+{
+ public partial class EditorObject
+ {
+ ///
+ /// Id
+ ///
+ [JsonInclude]
+ public string Id;
+
+ ///
+ /// 物体名称
+ /// 如果Prefab填的是ActivityBase数据, 则可以不填, 因为会从ActivityBase表中获取名称
+ ///
+ [JsonInclude]
+ public string Name;
+
+ ///
+ /// 备注
+ ///
+ [JsonInclude]
+ public string Remark;
+
+ ///
+ /// 物体预制体路径或者ActivityBase表Id
+ /// 这里区分是否是ActivityBase对象是直接判断字符串开头是否有"res://"
+ ///
+ [JsonInclude]
+ public string Prefab;
+
+ ///
+ /// 图标
+ /// 如果Prefab填的是ActivityBase数据, 则可以不填, 因为会从ActivityBase表中获取图标
+ ///
+ [JsonInclude]
+ public string Icon;
+
+ ///
+ /// 返回浅拷贝出的新对象
+ ///
+ public EditorObject Clone()
+ {
+ var inst = new EditorObject();
+ inst.Id = Id;
+ inst.Name = Name;
+ inst.Remark = Remark;
+ inst.Prefab = Prefab;
+ inst.Icon = Icon;
+ return inst;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_EnemyBase.cs b/DungeonShooting_Godot/src/config/ExcelConfig_EnemyBase.cs
index 7e9aaa9..9be083c 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_EnemyBase.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_EnemyBase.cs
@@ -5,7 +5,7 @@
public static partial class ExcelConfig
{
- public class EnemyBase
+ public partial class EnemyBase
{
///
/// 表Id
@@ -87,6 +87,19 @@
public int[] Gold;
///
+ /// 敌人死亡爆浆血液颜色, 填十六进制字符串(小写),
+ /// 例如: ff0000
+ /// 不填默认白色
+ ///
+ [JsonInclude]
+ public string BloodColor;
+
+ ///
+ /// 死亡时的尸体碎片
+ ///
+ public ActivityBase BodyFragment;
+
+ ///
/// 返回浅拷贝出的新对象
///
public EnemyBase Clone()
@@ -105,6 +118,8 @@
inst.TailAfterViewRange = TailAfterViewRange;
inst.ViewAngleRange = ViewAngleRange;
inst.Gold = Gold;
+ inst.BloodColor = BloodColor;
+ inst.BodyFragment = BodyFragment;
return inst;
}
}
@@ -113,5 +128,8 @@
[JsonInclude]
public string __Activity;
+ [JsonInclude]
+ public string __BodyFragment;
+
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_LiquidMaterial.cs b/DungeonShooting_Godot/src/config/ExcelConfig_LiquidMaterial.cs
index 9fd52d3..4dd8e49 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_LiquidMaterial.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_LiquidMaterial.cs
@@ -5,7 +5,7 @@
public static partial class ExcelConfig
{
- public class LiquidMaterial
+ public partial class LiquidMaterial
{
///
/// 表Id
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_Sound.cs b/DungeonShooting_Godot/src/config/ExcelConfig_Sound.cs
index 5131c2a..1b65091 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_Sound.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_Sound.cs
@@ -5,7 +5,7 @@
public static partial class ExcelConfig
{
- public class Sound
+ public partial class Sound
{
///
/// 音效id
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_WeaponBase.cs b/DungeonShooting_Godot/src/config/ExcelConfig_WeaponBase.cs
index 57323b4..8012d27 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_WeaponBase.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_WeaponBase.cs
@@ -5,7 +5,7 @@
public static partial class ExcelConfig
{
- public class WeaponBase
+ public partial class WeaponBase
{
///
/// 武器属性id
diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityInstance.cs b/DungeonShooting_Godot/src/framework/activity/ActivityInstance.cs
index 87e857f..fe1528e 100644
--- a/DungeonShooting_Godot/src/framework/activity/ActivityInstance.cs
+++ b/DungeonShooting_Godot/src/framework/activity/ActivityInstance.cs
@@ -9,456 +9,456 @@
[Tool]
public partial class ActivityInstance : Node2D
{
- private const string GroupName = "Editor";
-
- ///
- /// 物体Id
- ///
- [Export]
- public string Id
- {
- get => _id;
- set
- {
- _id = value;
- _dirty = true;
- }
- }
+ private const string GroupName = "Editor";
+
+ ///
+ /// 物体Id
+ ///
+ [Export]
+ public string Id
+ {
+ get => _id;
+ set
+ {
+ _id = value;
+ _dirty = true;
+ }
+ }
- ///
- /// 默认所在层级
- ///
- [Export]
- public RoomLayerEnum DefaultLayer { get; set; } = RoomLayerEnum.NormalLayer;
+ ///
+ /// 默认所在层级
+ ///
+ [Export]
+ public RoomLayerEnum DefaultLayer { get; set; } = RoomLayerEnum.NormalLayer;
- ///
- /// 是否显示阴影
- ///
- [Export]
- public bool ShowShadow
- {
- get => _showShadow;
- set
- {
- _showShadow = value;
- if (_activityObject != null)
- {
- if (value)
- {
- _activityObject.ShowShadowSprite();
- }
- else
- {
- _activityObject.HideShadowSprite();
- }
- }
- }
- }
+ ///
+ /// 是否显示阴影
+ ///
+ [Export]
+ public bool ShowShadow
+ {
+ get => _showShadow;
+ set
+ {
+ _showShadow = value;
+ if (_activityObject != null)
+ {
+ if (value)
+ {
+ _activityObject.ShowShadowSprite();
+ }
+ else
+ {
+ _activityObject.HideShadowSprite();
+ }
+ }
+ }
+ }
- ///
- /// 阴影偏移
- ///
- [Export]
- public Vector2 ShowOffset
- {
- get => _showOffset;
- set
- {
- _showOffset = value;
- if (_activityObject != null)
- {
- _activityObject.ShadowOffset = value;
- }
- }
- }
+ ///
+ /// 阴影偏移
+ ///
+ [Export]
+ public Vector2 ShowOffset
+ {
+ get => _showOffset;
+ set
+ {
+ _showOffset = value;
+ if (_activityObject != null)
+ {
+ _activityObject.ShadowOffset = value;
+ }
+ }
+ }
- ///
- /// 初始海拔高度
- ///
- [Export]
- public float Altitude
- {
- get => _altitude;
- set
- {
- _altitude = value;
- if (_activityObject != null)
- {
- _activityObject.Altitude = value;
- _activityObject.Collision.Position = _collPos;
- _activityObject.UpdateShadowSprite((float)GetProcessDeltaTime());
- _activityObject.CalcThrowAnimatedPosition();
- }
- }
- }
+ ///
+ /// 初始海拔高度
+ ///
+ [Export]
+ public float Altitude
+ {
+ get => _altitude;
+ set
+ {
+ _altitude = value;
+ if (_activityObject != null)
+ {
+ _activityObject.Altitude = value;
+ _activityObject.Collision.Position = _collPos;
+ _activityObject.UpdateShadowSprite((float)GetProcessDeltaTime());
+ _activityObject.CalcThrowAnimatedPosition();
+ }
+ }
+ }
- ///
- /// 动画精灵的z轴索引
- ///
- [Export]
- public int SpriteZIndex
- {
- get => _spriteZIndex;
- set
- {
- _spriteZIndex = value;
- if (_activityObject != null)
- {
- _activityObject.AnimatedSprite.ZIndex = value;
- }
- }
- }
-
- ///
- /// 阴影z轴索引
- ///
- [Export]
- public int ShadowZIndex
- {
- get => _shadowZIndex;
- set
- {
- _shadowZIndex = value;
- if (_activityObject != null)
- {
- _activityObject.ShadowSprite.ZIndex = value;
- }
- }
- }
-
- ///
- /// 是否启用垂直运动模拟
- ///
- [Export]
- public bool VerticalMotion { get; private set; } = true;
+ ///
+ /// 动画精灵的z轴索引
+ ///
+ [Export]
+ public int SpriteZIndex
+ {
+ get => _spriteZIndex;
+ set
+ {
+ _spriteZIndex = value;
+ if (_activityObject != null)
+ {
+ _activityObject.AnimatedSprite.ZIndex = value;
+ }
+ }
+ }
+
+ ///
+ /// 阴影z轴索引
+ ///
+ [Export]
+ public int ShadowZIndex
+ {
+ get => _shadowZIndex;
+ set
+ {
+ _shadowZIndex = value;
+ if (_activityObject != null)
+ {
+ _activityObject.ShadowSprite.ZIndex = value;
+ }
+ }
+ }
+
+ ///
+ /// 是否启用垂直运动模拟
+ ///
+ [Export]
+ public bool VerticalMotion { get; private set; } = true;
- ///
- /// 是否启用碰撞器
- ///
- [Export]
- public bool CollisionEnabled
- {
- get => _collisionEnabled;
- set
- {
- _collisionEnabled = value;
- if (_activityObject != null)
- {
- _activityObject.Collision.Disabled = !value;
- }
- }
- }
-
- ///
- /// 编辑器属性, 物体子碰撞器在编辑器中是否可见
- ///
- [Export]
- public bool CollisionVisible
- {
- get => _collisionVisible;
- set
- {
- _collisionVisible = value;
- OnChangeCollisionVisible();
- }
- }
+ ///
+ /// 是否启用碰撞器
+ ///
+ [Export]
+ public bool CollisionEnabled
+ {
+ get => _collisionEnabled;
+ set
+ {
+ _collisionEnabled = value;
+ if (_activityObject != null)
+ {
+ _activityObject.Collision.Disabled = !value;
+ }
+ }
+ }
+
+ ///
+ /// 编辑器属性, 物体子碰撞器在编辑器中是否可见
+ ///
+ [Export]
+ public bool CollisionVisible
+ {
+ get => _collisionVisible;
+ set
+ {
+ _collisionVisible = value;
+ OnChangeCollisionVisible();
+ }
+ }
- private bool _dirty = false;
- private bool _collisionVisible = true;
- private string _prevId;
- private string _id;
- private ActivityObject _activityObject;
- private Sprite2D _errorSprite;
- private bool _showShadow = true;
- private Vector2 _showOffset = new Vector2(0, 2);
- private float _altitude;
- private int _spriteZIndex = 0;
- private int _shadowZIndex = -1;
- private bool _collisionEnabled = true;
+ private bool _dirty = false;
+ private bool _collisionVisible = true;
+ private string _prevId;
+ private string _id;
+ private ActivityObject _activityObject;
+ private Sprite2D _errorSprite;
+ private bool _showShadow = true;
+ private Vector2 _showOffset = new Vector2(0, 2);
+ private float _altitude;
+ private int _spriteZIndex = 0;
+ private int _shadowZIndex = -1;
+ private bool _collisionEnabled = true;
- private Vector2 _collPos;
- private bool _createFlag = false;
-
- //嵌套Instance相关
- private bool _isNested = false;
- private ActivityObject _activityInstance;
-
- private static string _jsonText;
+ private Vector2 _collPos;
+ private bool _createFlag = false;
+
+ //嵌套Instance相关
+ private bool _isNested = false;
+ private ActivityObject _activityInstance;
+
+ private static string _jsonText;
- ///
- /// 清空缓存的json
- ///
- public static void ClearCacheJson()
- {
- _jsonText = null;
- }
-
- public override void _Ready()
- {
+ ///
+ /// 清空缓存的json
+ ///
+ public static void ClearCacheJson()
+ {
+ _jsonText = null;
+ }
+
+ public override void _Ready()
+ {
#if TOOLS
- if (!Engine.IsEditorHint())
- {
+ if (!Engine.IsEditorHint())
+ {
#endif
- var world = World.Current;
- if (world != null && world.YSortLayer != null && world.NormalLayer != null)
- {
- DoCreateObject();
- }
+ var world = World.Current;
+ if (world != null && world.YSortLayer != null && world.NormalLayer != null)
+ {
+ DoCreateObject();
+ }
#if TOOLS
- }
+ }
#endif
- }
+ }
- public override void _Process(double delta)
- {
+ public override void _Process(double delta)
+ {
#if TOOLS
- if (Engine.IsEditorHint())
- {
- if (_dirty || (_activityObject != null && _activityObject.GetParent() != this))
- {
- _dirty = false;
-
- if (_prevId != _id)
- {
- OnChangeActivityId(_id);
- }
- else if (string.IsNullOrEmpty(_id))
- {
- ShowErrorSprite();
- }
+ if (Engine.IsEditorHint())
+ {
+ if (_dirty || (_activityObject != null && _activityObject.GetParent() != this))
+ {
+ _dirty = false;
+
+ if (_prevId != _id)
+ {
+ OnChangeActivityId(_id);
+ }
+ else if (string.IsNullOrEmpty(_id))
+ {
+ ShowErrorSprite();
+ }
- OnChangeCollisionVisible();
- }
+ OnChangeCollisionVisible();
+ }
- if (_activityObject != null)
- {
- _activityObject.Collision.Position = _collPos;
- _activityObject.UpdateShadowSprite((float)delta);
- _activityObject.CalcThrowAnimatedPosition();
- }
- }
- else
- {
+ if (_activityObject != null)
+ {
+ _activityObject.Collision.Position = _collPos;
+ _activityObject.UpdateShadowSprite((float)delta);
+ _activityObject.CalcThrowAnimatedPosition();
+ }
+ }
+ else
+ {
#endif
- var world = World.Current;
- if (world != null && world.YSortLayer != null && world.NormalLayer != null)
- {
- DoCreateObject();
- }
+ var world = World.Current;
+ if (world != null && world.YSortLayer != null && world.NormalLayer != null)
+ {
+ DoCreateObject();
+ }
#if TOOLS
- }
+ }
#endif
- }
+ }
- public override void _EnterTree()
- {
+ public override void _EnterTree()
+ {
#if TOOLS
- if (Engine.IsEditorHint())
- {
- _dirty = true;
-
- var children = GetChildren();
- foreach (var child in children)
- {
- if (child is ActivityObject)
- {
- child.QueueFree();
- }
- }
- if (_activityObject != null)
- {
- _activityObject.QueueFree();
- }
- _activityObject = null;
- _prevId = null;
- }
+ if (Engine.IsEditorHint())
+ {
+ _dirty = true;
+
+ var children = GetChildren();
+ foreach (var child in children)
+ {
+ if (child is ActivityObject)
+ {
+ child.QueueFree();
+ }
+ }
+ if (_activityObject != null)
+ {
+ _activityObject.QueueFree();
+ }
+ _activityObject = null;
+ _prevId = null;
+ }
#endif
- }
+ }
- public override void _ExitTree()
- {
+ public override void _ExitTree()
+ {
#if TOOLS
- if (Engine.IsEditorHint() && _activityObject != null)
- {
- _activityObject.QueueFree();
- _activityObject = null;
- }
+ if (Engine.IsEditorHint() && _activityObject != null)
+ {
+ _activityObject.QueueFree();
+ _activityObject = null;
+ }
#endif
- }
+ }
- private ActivityObject DoCreateObject()
- {
- if (_createFlag)
- {
- return _activityInstance;
- }
+ private ActivityObject DoCreateObject()
+ {
+ if (_createFlag)
+ {
+ return _activityInstance;
+ }
- _createFlag = true;
- var activityObject = ActivityObject.Create(Id);
- if (_isNested)
- {
- activityObject.Position = Position - new Vector2(0, 1);
- activityObject.Scale = Scale;
- activityObject.Rotation = Rotation;
- }
- else
- {
- activityObject.Position = GlobalPosition + new Vector2(0, 1);
- activityObject.Scale = GlobalScale;
- activityObject.Rotation = GlobalRotation;
- }
-
- activityObject.Visible = Visible;
- activityObject.ShadowOffset = _showOffset;
- activityObject.Altitude = _altitude;
- activityObject.AnimatedSprite.ZIndex = _spriteZIndex;
- activityObject.ShadowSprite.ZIndex = _shadowZIndex;
- activityObject.EnableVerticalMotion = VerticalMotion;
- activityObject.Collision.Disabled = !_collisionEnabled;
- if (!_isNested)
- {
- activityObject.PutDown(DefaultLayer, _showShadow);
- }
- else
- {
- activityObject.DefaultLayer = DefaultLayer;
- activityObject.ShowShadowSprite();
- }
+ _createFlag = true;
+ var activityObject = ActivityObject.Create(Id);
+ if (_isNested)
+ {
+ activityObject.Position = Position - new Vector2(0, 1);
+ activityObject.Scale = Scale;
+ activityObject.Rotation = Rotation;
+ }
+ else
+ {
+ activityObject.Position = GlobalPosition + new Vector2(0, 1);
+ activityObject.Scale = GlobalScale;
+ activityObject.Rotation = GlobalRotation;
+ }
+
+ activityObject.Visible = Visible;
+ activityObject.ShadowOffset = _showOffset;
+ activityObject.Altitude = _altitude;
+ activityObject.AnimatedSprite.ZIndex = _spriteZIndex;
+ activityObject.ShadowSprite.ZIndex = _shadowZIndex;
+ activityObject.EnableVerticalMotion = VerticalMotion;
+ activityObject.Collision.Disabled = !_collisionEnabled;
+ if (!_isNested)
+ {
+ activityObject.PutDown(DefaultLayer, _showShadow);
+ }
+ else
+ {
+ activityObject.DefaultLayer = DefaultLayer;
+ activityObject.ShowShadowSprite();
+ }
- var children = GetChildren();
- foreach (var child in children)
- {
- if (!child.IsInGroup(GroupName))
- {
- if (child is ActivityInstance o)
- {
- o._isNested = true;
- var instance = o.DoCreateObject();
- activityObject.AddChild(instance);
- if (instance is IMountItem mountItem)
- {
- activityObject.AddMountObject(mountItem);
- }
- else if (instance is IDestroy destroy)
- {
- activityObject.AddDestroyObject(destroy);
- }
- }
- else
- {
- child.Reparent(activityObject);
- if (child is Node2D node2D && activityObject.GetCurrentTexture().GetHeight() % 2 == 0)
- {
- node2D.Position += new Vector2(0, 1);
- }
- }
- }
- }
+ var children = GetChildren();
+ foreach (var child in children)
+ {
+ if (!child.IsInGroup(GroupName))
+ {
+ if (child is ActivityInstance o)
+ {
+ o._isNested = true;
+ var instance = o.DoCreateObject();
+ activityObject.AddChild(instance);
+ if (instance is IMountItem mountItem)
+ {
+ activityObject.AddMountObject(mountItem);
+ }
+ else if (instance is IDestroy destroy)
+ {
+ activityObject.AddDestroyObject(destroy);
+ }
+ }
+ else
+ {
+ child.Reparent(activityObject);
+ if (child is Node2D node2D && activityObject.GetCurrentTexture().GetHeight() % 2 == 0)
+ {
+ node2D.Position += new Vector2(0, 1);
+ }
+ }
+ }
+ }
- QueueFree();
- _activityInstance = activityObject;
- return activityObject;
- }
+ QueueFree();
+ _activityInstance = activityObject;
+ return activityObject;
+ }
- private void OnChangeActivityId(string id)
- {
- _prevId = id;
+ private void OnChangeActivityId(string id)
+ {
+ _prevId = id;
- if (_activityObject != null)
- {
- _activityObject.QueueFree();
- _activityObject = null;
- }
+ if (_activityObject != null)
+ {
+ _activityObject.QueueFree();
+ _activityObject = null;
+ }
- if (string.IsNullOrEmpty(id))
- {
- ShowErrorSprite();
- return;
- }
+ if (string.IsNullOrEmpty(id))
+ {
+ ShowErrorSprite();
+ return;
+ }
- if (_jsonText == null)
- {
- _jsonText = File.ReadAllText("resource/config/ActivityBase.json");
- }
- var str = $"\"Id\": \"{id}\",";
- var index = _jsonText.IndexOf(str, StringComparison.Ordinal);
- if (index > -1)
- {
- const string s = "\"Prefab\": \"";
- var startIndex = _jsonText.IndexOf(s, index, StringComparison.Ordinal);
- if (startIndex > -1)
- {
- var endIndex = _jsonText.IndexOf('"', startIndex + s.Length + 1);
- if (endIndex > -1)
- {
- var prefab = _jsonText.Substring(startIndex + s.Length, endIndex - (startIndex + s.Length));
- var instance = ResourceManager.LoadAndInstantiate(prefab);
- _activityObject = instance;
- _collPos = instance.Collision.Position - instance.AnimatedSprite.Position - instance.AnimatedSprite.Offset;
- instance.IsCustomShadowSprite = instance.ShadowSprite.Texture != null;
- instance.Altitude = _altitude;
- instance.ShadowOffset = _showOffset;
- _activityObject.Position = _activityObject.AnimatedSprite.Position;
- if (_showShadow)
- {
- instance.ShowShadowSprite();
- var shadowSpriteMaterial = instance.ShadowSprite.Material as ShaderMaterial;
- if (shadowSpriteMaterial != null)
- {
- shadowSpriteMaterial.SetShaderParameter(
- ShaderParamNames.ShowOutline,
- ((ShaderMaterial)instance.AnimatedSprite.Material).GetShaderParameter(ShaderParamNames
- .ShowOutline)
- );
- }
- }
- AddChild(instance);
- MoveChild(instance, 0);
- HideErrorSprite();
- return;
- }
- }
- }
- GD.PrintErr($"未找到Id为'{id}'的物体!");
- ShowErrorSprite();
- }
+ if (_jsonText == null)
+ {
+ _jsonText = File.ReadAllText("resource/config/ActivityBase.json");
+ }
+ var str = $"\"Id\": \"{id}\",";
+ var index = _jsonText.IndexOf(str, StringComparison.Ordinal);
+ if (index > -1)
+ {
+ const string s = "\"Prefab\": \"";
+ var startIndex = _jsonText.IndexOf(s, index, StringComparison.Ordinal);
+ if (startIndex > -1)
+ {
+ var endIndex = _jsonText.IndexOf('"', startIndex + s.Length + 1);
+ if (endIndex > -1)
+ {
+ var prefab = _jsonText.Substring(startIndex + s.Length, endIndex - (startIndex + s.Length));
+ var instance = ResourceManager.LoadAndInstantiate(prefab);
+ _activityObject = instance;
+ _collPos = instance.Collision.Position - instance.AnimatedSprite.Position - instance.AnimatedSprite.Offset;
+ instance.IsCustomShadowSprite = instance.ShadowSprite.Texture != null;
+ instance.Altitude = _altitude;
+ instance.ShadowOffset = _showOffset;
+ _activityObject.Position = _activityObject.AnimatedSprite.Position;
+ if (_showShadow)
+ {
+ instance.ShowShadowSprite();
+ var shadowSpriteMaterial = instance.ShadowSprite.Material as ShaderMaterial;
+ if (shadowSpriteMaterial != null)
+ {
+ shadowSpriteMaterial.SetShaderParameter(
+ ShaderParamNames.ShowOutline,
+ ((ShaderMaterial)instance.AnimatedSprite.Material).GetShaderParameter(ShaderParamNames
+ .ShowOutline)
+ );
+ }
+ }
+ AddChild(instance);
+ MoveChild(instance, 0);
+ HideErrorSprite();
+ return;
+ }
+ }
+ }
+ GD.PrintErr($"未找到Id为'{id}'的物体!");
+ ShowErrorSprite();
+ }
- private void OnChangeCollisionVisible()
- {
- if (_activityObject != null)
- {
- Utils.EachNode(_activityObject, node =>
- {
- if (node is CollisionShape2D collisionShape2D)
- {
- collisionShape2D.Visible = _collisionVisible;
- }
- else if (node is CollisionPolygon2D collisionPolygon2D)
- {
- collisionPolygon2D.Visible = _collisionVisible;
- }
- });
- }
- }
+ private void OnChangeCollisionVisible()
+ {
+ if (_activityObject != null)
+ {
+ Utils.EachNode(_activityObject, node =>
+ {
+ if (node is CollisionShape2D collisionShape2D)
+ {
+ collisionShape2D.Visible = _collisionVisible;
+ }
+ else if (node is CollisionPolygon2D collisionPolygon2D)
+ {
+ collisionPolygon2D.Visible = _collisionVisible;
+ }
+ });
+ }
+ }
- private void ShowErrorSprite()
- {
- if (_errorSprite == null)
- {
- _errorSprite = new Sprite2D();
- _errorSprite.AddToGroup(GroupName);
- _errorSprite.Texture = ResourceManager.LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_Error_mini_png);
- AddChild(_errorSprite);
- MoveChild(_errorSprite, GetChildCount() - 1);
- }
- }
+ private void ShowErrorSprite()
+ {
+ if (_errorSprite == null)
+ {
+ _errorSprite = new Sprite2D();
+ _errorSprite.AddToGroup(GroupName);
+ _errorSprite.Texture = ResourceManager.LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_Error_mini_png);
+ AddChild(_errorSprite);
+ MoveChild(_errorSprite, GetChildCount() - 1);
+ }
+ }
- private void HideErrorSprite()
- {
- if (_errorSprite != null)
- {
- _errorSprite.QueueFree();
- _errorSprite = null;
- }
- }
+ private void HideErrorSprite()
+ {
+ if (_errorSprite != null)
+ {
+ _errorSprite.QueueFree();
+ _errorSprite = null;
+ }
+ }
}
diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
index ec21309..3043dbd 100644
--- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
+++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
@@ -11,7 +11,7 @@
/// ActivityObject 子类实例化请不要直接使用 new, 而用该在类上标上 [Tool], 并在 ActivityObject.xlsx 配置文件中注册物体, 导出配置表后使用 ActivityObject.Create(id) 来创建实例.
///
[Tool]
-public partial class ActivityObject : CharacterBody2D, IDestroy, ICoroutine
+public partial class ActivityObject : CharacterBody2D, ICoroutine, IInteractive, IOutline
{
///
/// 是否是调试模式
@@ -61,6 +61,11 @@
public AnimatedSprite2D AnimatedSprite { get; set; }
///
+ /// 阴影自定义缩放值
+ ///
+ public float ShadowScale { get; set; } = 1;
+
+ ///
/// 当前物体碰撞器节点, 节点名称必须叫 "Collision", 类型为 CollisionShape2D
///
[Export, ExportFillNode]
@@ -211,9 +216,7 @@
///
public World World { get; set; }
- ///
- /// 是否开启描边
- ///
+
public bool ShowOutline
{
get => _blendShaderMaterial == null ? false : _blendShaderMaterial.GetShaderParameter(ShaderParamNames.ShowOutline).AsBool();
@@ -223,10 +226,7 @@
_shadowBlendShaderMaterial?.SetShaderParameter(ShaderParamNames.ShowOutline, value);
}
}
-
- ///
- /// 描边颜色
- ///
+
public Color OutlineColor
{
get => _blendShaderMaterial == null ? Colors.Black : _blendShaderMaterial.GetShaderParameter(ShaderParamNames.OutlineColor).AsColor();
@@ -362,7 +362,7 @@
World = world;
ActivityBase = config;
#if TOOLS
- Name = GetType().Name + (_instanceIndex++);
+ Name = GetType().Name + '#' + (_instanceIndex++);
#endif
Id = _instanceIndex;
@@ -386,6 +386,17 @@
OnInit();
}
+
+ public override string ToString()
+ {
+ if (ActivityBase != null)
+ {
+ return "<" + Name + ":" + ActivityBase.Id + ">";
+ }
+
+ return "<" + Name + ">";
+ }
+
///
/// 子类重写的 _Ready() 可能会比 _InitNode() 函数调用晚, 所以禁止子类重写, 如需要 _Ready() 类似的功能需重写 OnInit()
///
@@ -532,23 +543,31 @@
{
}
- ///
- /// 返回是否能与其他ActivityObject互动
- ///
- /// 触发者
public virtual CheckInteractiveResult CheckInteractive(ActivityObject master)
{
return new CheckInteractiveResult(this);
}
-
- ///
- /// 与其它ActivityObject互动时调用, 如果要检测是否能互动请 CheckInteractive() 函数, 如果直接调用该函数那么属于强制互动行为, 例如子弹碰到物体
- ///
- /// 触发者
+
public virtual void Interactive(ActivityObject master)
{
}
+ public virtual void OnTargetEnterd(ActivityObject target)
+ {
+ if (target is Player)
+ {
+ OutlineColor = Colors.White;
+ }
+ }
+
+ public virtual void OnTargetExitd(ActivityObject target)
+ {
+ if (target is Player)
+ {
+ OutlineColor = Colors.Black;
+ }
+ }
+
///
/// 开始投抛该物体时调用
///
@@ -766,6 +785,24 @@
Throw(altitude, verticalSpeed, velocity, rotateSpeed);
}
+ ///
+ /// 往一个指定位置投抛物体, 使其能正好落到目标位置
+ ///
+ /// 起始位置
+ /// 起始高度
+ /// 旋转速度
+ /// 目标位置
+ /// 投抛到目标点的速度
+ public void ThrowToPosition(Vector2 position, float altitude, float rotateSpeed, Vector2 targetPosition, float speed)
+ {
+ var distance = position.DistanceTo(targetPosition);
+ var time = distance / speed;
+ var verticalSpeed = -(altitude - 0.5f * GameConfig.G * time * time) / time;
+ var velocity = (targetPosition - position).Normalized() * speed;
+
+ Throw(position, altitude, verticalSpeed, velocity, rotateSpeed);
+ }
+
///
/// 强制停止投抛运动
@@ -884,7 +921,7 @@
///
/// 根据类型获取一个组件
///
- public T GetComponent() where T : Component
+ public T GetComponent()
{
for (int i = 0; i < _components.Count; i++)
{
@@ -907,7 +944,7 @@
}
}
- return null;
+ return default;
}
///
@@ -943,7 +980,7 @@
///
/// 根据类型获取所有相同类型的组件
///
- public T[] GetComponents() where T : Component
+ public T[] GetComponents()
{
var list = new List();
for (int i = 0; i < _components.Count; i++)
@@ -1420,7 +1457,7 @@
}
//缩放
- ShadowSprite.Scale = AnimatedSprite.Scale;
+ ShadowSprite.Scale = AnimatedSprite.Scale * ShadowScale;
//阴影角度
ShadowSprite.Rotation = 0;
//阴影位置计算
@@ -1766,13 +1803,16 @@
/// 播放 AnimatedSprite 上的动画, 如果没有这个动画, 则什么也不会发生
///
/// 动画名称
- public void PlaySpriteAnimation(string name)
+ public bool PlaySpriteAnimation(string name)
{
var spriteFrames = AnimatedSprite.SpriteFrames;
if (spriteFrames != null && spriteFrames.HasAnimation(name))
{
AnimatedSprite.Play(name);
+ return true;
}
+
+ return false;
}
///
diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs
index 3da7566..8b75ae7 100644
--- a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs
+++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs
@@ -24,20 +24,10 @@
///
public const string Id_enemy0002 = "enemy0002";
///
- /// 名称: 敌人3
- /// 简介: 敌人3
+ /// 名称: Boss
+ /// 简介: Boss
///
- public const string Id_enemy0003 = "enemy0003";
- ///
- /// 名称: 敌人4
- /// 简介: 敌人3
- ///
- public const string Id_enemy0004 = "enemy0004";
- ///
- /// 名称: 敌人5
- /// 简介: 敌人3
- ///
- public const string Id_enemy0005 = "enemy0005";
+ public const string Id_boss0001 = "boss0001";
///
/// 名称: 商店老板
/// 简介: 商店老板
@@ -159,6 +149,16 @@
///
public const string Id_bullet0009 = "bullet0009";
///
+ /// 名称: boss召唤物子弹
+ /// 简介:
+ ///
+ public const string Id_summons0001 = "summons0001";
+ ///
+ /// 名称: boss特殊子弹
+ /// 简介:
+ ///
+ public const string Id_special0001 = "special0001";
+ ///
/// 名称:
/// 简介:
///
diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityType.cs b/DungeonShooting_Godot/src/framework/activity/ActivityType.cs
index acf51f0..e51990d 100644
--- a/DungeonShooting_Godot/src/framework/activity/ActivityType.cs
+++ b/DungeonShooting_Godot/src/framework/activity/ActivityType.cs
@@ -1,5 +1,4 @@
-
-///
+///
/// 物体类型
///
public enum ActivityType
@@ -53,6 +52,10 @@
///
Npc,
///
+ /// Boss
+ ///
+ Boss,
+ ///
/// 其它类型
///
Other = 99,
diff --git a/DungeonShooting_Godot/src/framework/activity/CheckInteractiveResult.cs b/DungeonShooting_Godot/src/framework/activity/CheckInteractiveResult.cs
index fb38e21..ca81a0f 100644
--- a/DungeonShooting_Godot/src/framework/activity/CheckInteractiveResult.cs
+++ b/DungeonShooting_Godot/src/framework/activity/CheckInteractiveResult.cs
@@ -33,7 +33,7 @@
///
/// 互动物体
///
- public ActivityObject Target;
+ public IInteractive Target;
///
/// 是否可以互动
///
@@ -43,18 +43,18 @@
///
public InteractiveType Type = InteractiveType.PickUp;
- public CheckInteractiveResult(ActivityObject target)
+ public CheckInteractiveResult(IInteractive target)
{
Target = target;
}
- public CheckInteractiveResult(ActivityObject target, bool canInteractive)
+ public CheckInteractiveResult(IInteractive target, bool canInteractive)
{
Target = target;
CanInteractive = canInteractive;
}
- public CheckInteractiveResult(ActivityObject target, bool canInteractive, InteractiveType type)
+ public CheckInteractiveResult(IInteractive target, bool canInteractive, InteractiveType type)
{
Target = target;
CanInteractive = canInteractive;
diff --git a/DungeonShooting_Godot/src/framework/activity/components/IStateController.cs b/DungeonShooting_Godot/src/framework/activity/components/IStateController.cs
index 5fb7c0f..6f3e6d0 100644
--- a/DungeonShooting_Godot/src/framework/activity/components/IStateController.cs
+++ b/DungeonShooting_Godot/src/framework/activity/components/IStateController.cs
@@ -4,5 +4,5 @@
///
public interface IStateController
{
-
+ public bool Enable { get; set; }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/activity/interactive/IInteractive.cs b/DungeonShooting_Godot/src/framework/activity/interactive/IInteractive.cs
new file mode 100644
index 0000000..337be15
--- /dev/null
+++ b/DungeonShooting_Godot/src/framework/activity/interactive/IInteractive.cs
@@ -0,0 +1,30 @@
+
+///
+/// 可互动物体接口
+///
+public interface IInteractive : IDestroy
+{
+ ///
+ /// 返回是否能与其他ActivityObject互动
+ ///
+ /// 触发互动的物体
+ CheckInteractiveResult CheckInteractive(ActivityObject master);
+
+ ///
+ /// 与其它ActivityObject互动时调用, 如果要检测是否能互动请 CheckInteractive() 函数, 如果直接调用该函数那么属于强制互动行为
+ ///
+ /// 触发互动的物体
+ void Interactive(ActivityObject master);
+
+ ///
+ /// 当目标进入互动区域时调用
+ ///
+ /// 触发互动的物体
+ void OnTargetEnterd(ActivityObject target);
+
+ ///
+ /// 当目标离开互动区域时调用
+ ///
+ /// 触发互动的物体
+ void OnTargetExitd(ActivityObject target);
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/activity/outline/IOutline.cs b/DungeonShooting_Godot/src/framework/activity/outline/IOutline.cs
new file mode 100644
index 0000000..f2a3f19
--- /dev/null
+++ b/DungeonShooting_Godot/src/framework/activity/outline/IOutline.cs
@@ -0,0 +1,18 @@
+
+using Godot;
+
+///
+/// 描边属性接口
+///
+public interface IOutline
+{
+ ///
+ /// 是否开启描边
+ ///
+ bool ShowOutline { get; set; }
+
+ ///
+ /// 描边颜色
+ ///
+ Color OutlineColor { get; set; }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/common/SpiralUtil.cs b/DungeonShooting_Godot/src/framework/common/SpiralUtil.cs
index 67d8a79..f1f94ee 100644
--- a/DungeonShooting_Godot/src/framework/common/SpiralUtil.cs
+++ b/DungeonShooting_Godot/src/framework/common/SpiralUtil.cs
@@ -3,54 +3,54 @@
public static class SpiralUtil
{
- ///
- /// 螺旋算法 顺时针
- /// 7 8 9 10
- /// 6 1 2
- /// 5 4 3
- ///
- private static float[][] SCREW_CLOCKWISE = new float[][] { new float[] { 1, 2, 3, 4 }, new float[] { 4, 1, 2, 3 } };
+ ///
+ /// 螺旋算法 顺时针
+ /// 7 8 9 10
+ /// 6 1 2
+ /// 5 4 3
+ ///
+ private static float[][] SCREW_CLOCKWISE = new float[][] { new float[] { 1, 2, 3, 4 }, new float[] { 4, 1, 2, 3 } };
- ///
- /// 螺旋算法
- ///
- /// 当前序列
- /// 返回当前序列应该所在的位置
- public static Vector2I Screw(int index)
- {
- //总体思路是先找到第几圈 然后再找到第几个拐角 然后用switch
- //因为一般序列都是从0开始的,所以此处加一以适应规则
- index++;
- //如果求的是中心点 直接返回就行了
- if (index <= 1) return new Vector2I(0, 0);
+ ///
+ /// 螺旋算法
+ ///
+ /// 当前序列
+ /// 返回当前序列应该所在的位置
+ public static Vector2I Screw(int index)
+ {
+ //总体思路是先找到第几圈 然后再找到第几个拐角 然后用switch
+ //因为一般序列都是从0开始的,所以此处加一以适应规则
+ index++;
+ //如果求的是中心点 直接返回就行了
+ if (index <= 1) return new Vector2I(0, 0);
- //开平方得到当前序列在哪个阶段中(阶段=第几圈*2)
- var n = Mathf.Ceil(Mathf.Sqrt(index));
- var step = Mathf.FloorToInt(n / 2) * 2;
- //求出当前序列是当前阶段中的第几个数
- var stepIndex = index - (step - 1) * (step - 1);
- //求出当前序列在当前阶段中的第几条边上
- var stepStep = Mathf.CeilToInt((float)stepIndex / step);
- //当前序列是当前边上第几个数
- var ssi = stepIndex % step;
- if (ssi == 0) ssi = step;
+ //开平方得到当前序列在哪个阶段中(阶段=第几圈*2)
+ var n = Mathf.Ceil(Mathf.Sqrt(index));
+ var step = Mathf.FloorToInt(n / 2) * 2;
+ //求出当前序列是当前阶段中的第几个数
+ var stepIndex = index - (step - 1) * (step - 1);
+ //求出当前序列在当前阶段中的第几条边上
+ var stepStep = Mathf.CeilToInt((float)stepIndex / step);
+ //当前序列是当前边上第几个数
+ var ssi = stepIndex % step;
+ if (ssi == 0) ssi = step;
- return new Vector2I(
- GetValue(step, ssi, SCREW_CLOCKWISE[0][stepStep - 1]),
- GetValue(step, ssi, SCREW_CLOCKWISE[1][stepStep - 1])
- );
- }
+ return new Vector2I(
+ GetValue(step, ssi, SCREW_CLOCKWISE[0][stepStep - 1]),
+ GetValue(step, ssi, SCREW_CLOCKWISE[1][stepStep - 1])
+ );
+ }
- private static int GetValue(int step, int ssi, float switchIndex)
- {
- switch (switchIndex)
- {
- case 1: return step / 2;
- case 2: return step / 2 - ssi;
- case 3: return -step / 2;
- case 4: return -step / 2 + ssi;
- }
+ private static int GetValue(int step, int ssi, float switchIndex)
+ {
+ switch (switchIndex)
+ {
+ case 1: return step / 2;
+ case 2: return step / 2 - ssi;
+ case 3: return -step / 2;
+ case 4: return -step / 2 + ssi;
+ }
- return 0;
- }
+ return 0;
+ }
}
diff --git a/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs b/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs
index 3c9123d..b114ba7 100644
--- a/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs
+++ b/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs
@@ -287,7 +287,11 @@
{
if (IsFirstEnterFlag)
{
- RoomInfo.World.Player.OnFirstEnterRoom(RoomInfo);
+ if (RoomInfo.World.Player is Player player)
+ {
+ player.OnFirstEnterRoom(RoomInfo);
+ }
+
EventManager.EmitEvent(EventEnum.OnPlayerFirstEnterRoom, RoomInfo);
}
EventManager.EmitEvent(EventEnum.OnPlayerEnterRoom, RoomInfo);
diff --git a/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs b/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs
index 8781e28..966d3d0 100644
--- a/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs
+++ b/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs
@@ -10,6 +10,11 @@
/// 地牢使用的随机种子
///
public int? RandomSeed = null;
+
+ ///
+ /// 当前地牢层级
+ ///
+ public int DungeonLayer;
///
/// 地牢组名称
@@ -95,12 +100,18 @@
/// 纵轴范围
///
public int RangeY = 120;
+
+ ///
+ /// 是否允许包含拐角的过道
+ ///
+ public bool AllowedCornerAisles = false;
//----------------------- 地牢编辑使用 -------------------------
///
/// 是否指定了房间
///
public bool HasDesignatedRoom => DesignatedRoom != null && DesignatedRoom.Count > 0;
+
///
/// 指定预设的房间类型
///
diff --git a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
index 4111d82..be03c8b 100644
--- a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
+++ b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Linq;
using Godot;
///
@@ -76,7 +77,7 @@
private int _failCount = 0;
//最大尝试次数
- private int _maxTryCount = 10;
+ private int _maxTryCount = 10;
private int _currMaxLayer = 0;
//地牢房间规则处理类
@@ -86,6 +87,8 @@
private RoomInfo prevRoomInfo = null;
private readonly List _tempList = new List();
+ private List _battleRoomList;
+
public DungeonGenerator(DungeonConfig config, SeedRandom seedRandom)
{
Config = config;
@@ -103,6 +106,8 @@
Debug.Log("创建地牢生成器, 随机种子: " + Random.Seed);
RoomGroup.InitWeight(Random);
+
+ _battleRoomList = RoomGroup.BattleList.ToList();
}
///
@@ -221,6 +226,7 @@
currTryCount++;
if (currTryCount >= maxTryCount)
{
+ Debug.Log("生成失败, 房间总数: " + RoomInfos.Count);
return false;
}
@@ -281,7 +287,7 @@
{
_rule.GenerateRoomFail(tempPrevRoomInfo, nextRoomType);
- //Debug.Log("生成第" + (_count + 1) + "个房间失败! 失败原因: " + errorCode);
+ //Debug.Log("生成第" + (RoomInfos.Count + 1) + "个房间失败! 失败原因: " + errorCode);
if (errorCode == GenerateRoomErrorCode.OutArea)
{
_failCount++;
@@ -299,6 +305,7 @@
currTryCount++;
if (currTryCount >= maxTryCount)
{
+ Debug.Log("生成失败, 房间总数: " + RoomInfos.Count);
return false;
}
}
@@ -335,7 +342,18 @@
}
else
{
- roomSplit = RoomGroup.GetRandomRoom(roomType);
+ //原代码
+ //roomSplit = RoomGroup.GetRandomRoom(roomType);
+
+ //临时处理, 不生成相同的战斗房间
+ if (roomType == DungeonRoomType.Battle && _battleRoomList.Count > 0)
+ {
+ roomSplit = Random.RandomChooseAndRemove(_battleRoomList);
+ }
+ else
+ {
+ roomSplit = RoomGroup.GetRandomRoom(roomType);
+ }
}
}
@@ -375,11 +393,11 @@
if (direction == RoomDirection.Up) //上
{
room.Position = new Vector2I(prevRoom.Position.X + offset,
- prevRoom.Position.Y - room.Size.Y - space);
+ prevRoom.Position.Y - room.Size.Y - space - 1);
}
else if (direction == RoomDirection.Right) //右
{
- room.Position = new Vector2I(prevRoom.Position.X + prevRoom.Size.Y + space,
+ room.Position = new Vector2I(prevRoom.Position.X + prevRoom.Size.X + space,
prevRoom.Position.Y + offset);
}
else if (direction == RoomDirection.Down) //下
@@ -669,9 +687,14 @@
}
}
- //包含1个拐角的通道
- return TryConnectCrossDoor(roomInfo, roomDoor, nextRoomInfo, nextRoomDoor);
- //包含2个拐角的通道 (后面再开发)
+ if (Config.AllowedCornerAisles)
+ {
+ //包含1个拐角的通道
+ return TryConnectCrossDoor(roomInfo, roomDoor, nextRoomInfo, nextRoomDoor);
+ //包含2个拐角的通道 (后面再开发)
+ }
+
+ return false;
}
///
diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs b/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs
index de5efc9..5a8ce88 100644
--- a/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs
@@ -1,4 +1,4 @@
-
+using System;
using System.Collections.Generic;
using Godot;
@@ -34,20 +34,25 @@
///
public float DelayTime { get; set; }
- ///
- /// 物体初始海拔高度
- ///
- public int Altitude { get; set; } = 8;
+ ///
+ /// 物体初始海拔高度
+ ///
+ public int Altitude { get; set; } = 8;
- ///
- /// 物体初始纵轴速度
- ///
- public float VerticalSpeed { get; set; } = 0;
+ ///
+ /// 物体初始纵轴速度
+ ///
+ public float VerticalSpeed { get; set; } = 0;
///
/// 物体类型
///
public ActivityType ActivityType { get; set; }
+
+ ///
+ /// 地牢房间加载完成事件
+ ///
+ public Action OnReadyEvent;
///
/// 快速创建标记
diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/MissActivityBase.cs b/DungeonShooting_Godot/src/framework/map/preinstall/MissActivityBase.cs
new file mode 100644
index 0000000..ae73c93
--- /dev/null
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/MissActivityBase.cs
@@ -0,0 +1,9 @@
+
+using Config;
+
+///
+/// 缺失物体配置
+///
+public class MissActivityBase : ExcelConfig.ActivityBase
+{
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/PreinstallMarkManager.cs b/DungeonShooting_Godot/src/framework/map/preinstall/PreinstallMarkManager.cs
index e888f8d..26a8cfa 100644
--- a/DungeonShooting_Godot/src/framework/map/preinstall/PreinstallMarkManager.cs
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/PreinstallMarkManager.cs
@@ -41,6 +41,18 @@
ShowInMapEditor = true
};
+ ///
+ /// 丢失物体
+ ///
+ public static readonly MissActivityBase Miss = new MissActivityBase()
+ {
+ Id = "$Miss",
+ Name = "丢失引用",
+ Type = ActivityType.Other,
+ Icon = ResourcePath.resource_sprite_ui_commonIcon_UnknownActivity_png,
+ ShowInMapEditor = true
+ };
+
private static Dictionary> _cache = new Dictionary>();
private static bool _init = false;
@@ -80,6 +92,10 @@
}
ExcelConfig.ActivityBase_Map.TryGetValue(id, out var activityBase);
+ if (activityBase == null)
+ {
+ return Miss;
+ }
return activityBase;
}
diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs
index 4e398ae..bdb3b33 100644
--- a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs
@@ -42,6 +42,11 @@
///
public bool IsLastWave => _currWaveIndex >= WaveList.Count;
+ ///
+ /// 包含的 Boss 列表
+ ///
+ public List BossList { get; } = new List();
+
//是否运行过预处理
private bool _runPretreatment = false;
//当前房间是否会刷新敌人
@@ -107,7 +112,7 @@
}
else if (markInfo.SpecialMarkType == SpecialMarkType.OutPoint) //出口标记
{
-
+ HandlerOutPointMark(world, markInfo, mark);
}
else if (markInfo.SpecialMarkType == SpecialMarkType.ShopBoss) //商店老板标记
{
@@ -117,6 +122,10 @@
{
HandlerTreasureMark(world, markInfo, mark);
}
+ else if (markInfo.SpecialMarkType == SpecialMarkType.Boss) //Boss标记
+ {
+ HandlerBossMark(world, markInfo, mark);
+ }
else
{
Debug.LogError("暂未支持的类型: " + markInfo.SpecialMarkType);
@@ -198,6 +207,11 @@
return true;
}
}
+ else if (activityBase is MissActivityBase) //丢失物体
+ {
+ Debug.LogError("丢失物体:" + markInfoItem.Id);
+ return true;
+ }
else
{
mark.Id = markInfoItem.Id;
@@ -224,6 +238,16 @@
return false;
}
+ private void HandlerOutPointMark(World world, MarkInfo markInfo, ActivityMark mark)
+ {
+ mark.OnReadyEvent += () =>
+ {
+ var roomExit = ResourceManager.LoadAndInstantiate(ResourcePath.prefab_room_RoomExit_tscn);
+ roomExit.Position = mark.Position;
+ roomExit.AddToActivityRoot(RoomLayerEnum.NormalLayer);
+ };
+ }
+
private void HandlerShopBossMark(World world, MarkInfo markInfo, ActivityMark mark)
{
mark.Id = ActivityObject.Ids.Id_shopBoss0001;
@@ -238,13 +262,20 @@
mark.Altitude = 0;
}
+ private void HandlerBossMark(World world, MarkInfo markInfo, ActivityMark mark)
+ {
+ mark.Id = ActivityObject.Ids.Id_boss0001;
+ mark.ActivityType = ActivityType.Boss;
+ mark.Altitude = 0;
+ }
+
private void CheckHasEnemy()
{
foreach (var marks in WaveList)
{
foreach (var activityMark in marks)
{
- if (activityMark.ActivityType == ActivityType.Enemy)
+ if (activityMark.ActivityType == ActivityType.Enemy || activityMark.ActivityType == ActivityType.Boss)
{
_hsaEnemy = true;
return;
@@ -273,23 +304,28 @@
var activityMarks = WaveList[0];
foreach (var activityMark in activityMarks)
{
- if (activityMark.MarkType == SpecialMarkType.Normal ||
- activityMark.MarkType == SpecialMarkType.Treasure ||
- activityMark.MarkType == SpecialMarkType.ShopBoss)
+ var activityObject = CreateItem(activityMark);
+ if (activityObject != null)
{
- var activityObject = CreateItem(activityMark);
- if (activityObject == null)
- {
- continue;
- }
//初始化属性
InitAttr(activityObject, activityMark);
+
if (_readyList == null)
{
_readyList = new List();
}
_readyList.Add(new PreloadData(activityObject, GetDefaultLayer(activityMark)));
activityObject.OnCreateWithMark(this, activityMark);
+
+ if (activityObject is Boss boss)
+ {
+ BossList.Add(boss);
+ }
+ }
+
+ if (activityMark.OnReadyEvent != null)
+ {
+ activityMark.OnReadyEvent();
}
}
}
@@ -317,12 +353,29 @@
foreach (var preloadData in _readyList)
{
//有敌人
- if (!hasEnemy && preloadData.ActivityObject is Role role && role.IsEnemyWithPlayer())
+ var activityObject = preloadData.ActivityObject;
+ if (!hasEnemy && activityObject is Role role && role.IsEnemyWithPlayer())
{
hasEnemy = true;
}
- preloadData.ActivityObject.PutDown(preloadData.Layer);
+ //临时处理
+ //播放出生动画
+ activityObject.PutDown(preloadData.Layer);
+ if (activityObject is not Boss)
+ {
+ activityObject.StartCoroutine(OnActivityObjectBirth(activityObject));
+ activityObject.UpdateFall((float)GameApplication.Instance.GetProcessDeltaTime());
+ //出生特效
+ var effect = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_common_Effect1_tscn);
+ var node = (Node2D)effect;
+ node.Position = activityObject.Position + new Vector2(0, -activityObject.Altitude);
+ node.AddToActivityRoot(RoomLayerEnum.YSortLayer);
+ effect.PlayEffect();
+ }
+
+ //原本代码
+ //preloadData.ActivityObject.PutDown(preloadData.Layer);
}
_readyList.Clear();
@@ -395,6 +448,7 @@
enemy.OnBornFromMark();
}
+ //出生特效
var effect = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_common_Effect1_tscn);
var node = (Node2D)effect;
node.Position = activityObject.Position + new Vector2(0, -activityMark.Altitude);
@@ -452,11 +506,16 @@
//创建物体
private ActivityObject CreateItem(ActivityMark activityMark)
{
+ if (string.IsNullOrEmpty(activityMark.Id))
+ {
+ return null;
+ }
var activityObject = ActivityObject.Create(activityMark.Id);
if (activityObject == null)
{
return null;
}
+
activityObject.Position = activityMark.Position;
activityObject.VerticalSpeed = activityMark.VerticalSpeed;
activityObject.Altitude = activityMark.Altitude;
@@ -471,6 +530,7 @@
case ActivityType.Player:
case ActivityType.Enemy:
case ActivityType.Npc:
+ case ActivityType.Boss:
case ActivityType.Treasure:
return RoomLayerEnum.YSortLayer;
default:
diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs b/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs
index 8a96abb..3874394 100644
--- a/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs
@@ -1,5 +1,4 @@
-
-///
+///
/// 特殊标记类型
///
public enum SpecialMarkType
@@ -24,4 +23,8 @@
/// 商店房商店老板刷新点
///
ShopBoss,
+ ///
+ /// boss刷新点
+ ///
+ Boss
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonRoomGroup.cs b/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonRoomGroup.cs
index 5c47f06..e7ba659 100644
--- a/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonRoomGroup.cs
+++ b/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonRoomGroup.cs
@@ -20,6 +20,18 @@
///
[JsonInclude]
public string TileSet;
+
+ ///
+ /// 背景颜色
+ ///
+ [JsonInclude]
+ public Color BgColor;
+
+ ///
+ /// 音乐ID
+ ///
+ [JsonInclude]
+ public string SoundId;
///
/// 普通战斗房间, 进入该房间时会关上门, 并刷出若干波敌人, 消灭所有敌人后开门
@@ -207,6 +219,8 @@
var inst = new DungeonRoomGroup();
inst.GroupName = GroupName;
inst.TileSet = TileSet;
+ inst.SoundId = SoundId;
+ inst.BgColor = BgColor;
inst.BattleList.AddRange(BattleList);
inst.InletList.AddRange(InletList);
inst.OutletList.AddRange(OutletList);
diff --git a/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonTileInfo.cs b/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonTileInfo.cs
index 9e97d81..f3e11d7 100644
--- a/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonTileInfo.cs
+++ b/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonTileInfo.cs
@@ -57,6 +57,18 @@
///
[JsonInclude]
public List CustomTop;
+
+ ///
+ /// 普通层级自定义对象
+ ///
+ [JsonInclude]
+ public List NormalLayerObjects;
+
+ ///
+ /// Y排序层级自定义对象
+ ///
+ [JsonInclude]
+ public List YSortLayerObjects;
public void InitData()
{
@@ -69,5 +81,7 @@
CustomMiddle1 = new List();
CustomMiddle2 = new List();
CustomTop = new List();
+ NormalLayerObjects = new List();
+ YSortLayerObjects = new List();
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/serialize/room/RoomObjectInfo.cs b/DungeonShooting_Godot/src/framework/map/serialize/room/RoomObjectInfo.cs
new file mode 100644
index 0000000..edc3fd2
--- /dev/null
+++ b/DungeonShooting_Godot/src/framework/map/serialize/room/RoomObjectInfo.cs
@@ -0,0 +1,50 @@
+
+using System.Text.Json.Serialization;
+using Config;
+
+///
+/// 房间中的自定义物体
+///
+public class RoomObjectInfo : IClone
+{
+ ///
+ /// 对应 表中的 id
+ ///
+ [JsonInclude]
+ public string Id;
+
+ ///
+ /// X 坐标, 单位: 像素
+ ///
+ [JsonInclude]
+ public int X;
+
+ ///
+ /// Y 坐标: 单位: 像素
+ ///
+ [JsonInclude]
+ public int Y;
+
+ public RoomObjectInfo Clone()
+ {
+ return new RoomObjectInfo
+ {
+ Id = Id,
+ X = X,
+ Y = Y,
+ };
+ }
+
+ ///
+ /// 获取 EditorObject 配置表数据
+ ///
+ public ExcelConfig.EditorObject GetConfig()
+ {
+ if (ExcelConfig.EditorObject_Map.TryGetValue(Id, out var config))
+ {
+ return config;
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs
index 0c2112e..dd4469a 100644
--- a/DungeonShooting_Godot/src/game/GameApplication.cs
+++ b/DungeonShooting_Godot/src/game/GameApplication.cs
@@ -1,8 +1,6 @@
-using System;
using System.Collections;
using System.Collections.Generic;
-using System.Linq;
using System.Text.Json;
using Config;
using Godot;
@@ -10,291 +8,353 @@
public partial class GameApplication : Node2D, ICoroutine
{
- public static GameApplication Instance { get; private set; }
-
- ///
- /// 游戏渲染视口
- ///
- public SubViewport SubViewport;
+ public static GameApplication Instance { get; private set; }
+
+ ///
+ /// 游戏渲染视口
+ ///
+ public SubViewport SubViewport;
- ///
- /// SubViewportContainer 组件
- ///
- public SubViewportContainer SubViewportContainer;
+ ///
+ /// SubViewportContainer 组件
+ ///
+ public SubViewportContainer SubViewportContainer;
- ///
- /// 场景根节点
- ///
- public Node2D SceneRoot;
-
- ///
- /// 全局根节点
- ///
- public Node2D GlobalNodeRoot;
-
- ///
- /// 游戏目标帧率
- ///
- public int TargetFps { get; private set; }
-
- ///
- /// 鼠标指针
- ///
- public Cursor Cursor { get; private set; }
+ ///
+ /// 场景根节点
+ ///
+ public Node2D SceneRoot;
+
+ ///
+ /// 全局根节点
+ ///
+ public Node2D GlobalNodeRoot;
+
+ ///
+ /// 游戏目标帧率
+ ///
+ public int TargetFps { get; private set; }
+
+ ///
+ /// 鼠标指针
+ ///
+ public Cursor Cursor { get; private set; }
- ///
- /// 地牢管理器
- ///
- public DungeonManager DungeonManager { get; private set; }
-
- ///
- /// 房间配置
- ///
- public Dictionary RoomConfig { get; private set; }
-
- ///
- /// TileSet配置
- ///
- public Dictionary TileSetConfig { get; private set; }
-
- // ///
- // /// 房间配置数据, key: 模板房间资源路径
- // ///
- // public Dictionary RoomConfigMap { get; private set; }
+ ///
+ /// 地牢管理器
+ ///
+ public DungeonManager DungeonManager { get; private set; }
+
+ ///
+ /// 房间配置
+ ///
+ public Dictionary RoomConfig { get; private set; }
+
+ ///
+ /// TileSet配置
+ ///
+ public Dictionary TileSetConfig { get; private set; }
+
+ // ///
+ // /// 房间配置数据, key: 模板房间资源路径
+ // ///
+ // public Dictionary RoomConfigMap { get; private set; }
- ///
- /// 游戏视图大小
- ///
- public Vector2 ViewportSize { get; private set; } = new Vector2(480, 270);
-
- ///
- /// 像素缩放
- ///
- public int PixelScale { get; private set; } = 4;
-
- ///
- /// 地牢配置信息
- ///
- public DungeonConfig DungeonConfig { get; private set; }
+ ///
+ /// 游戏视图大小
+ ///
+ public Vector2 ViewportSize { get; private set; } = new Vector2(480, 270);
+
+ ///
+ /// 像素缩放
+ ///
+ public int PixelScale { get; private set; } = 4;
+
+ ///
+ /// 第一层地牢配置信息
+ ///
+ public DungeonConfig FirstDungeonConfig { get; private set; }
- //开启的协程
- private List _coroutineList;
-
- public GameApplication()
- {
- Instance = this;
- //TargetFps = 20;
- TargetFps = Mathf.RoundToInt(DisplayServer.ScreenGetRefreshRate());
-
- Utils.InitRandom();
+ ///
+ /// 地牢组加载顺序
+ ///
+ public List DungeonGroupList { get; } = new List();
- //初始化配置表
- ExcelConfig.Init();
- PreinstallMarkManager.Init();
- PropFragmentRegister.Init();
- //初始化房间配置数据
- InitRoomConfig();
- //初始化TileSet配置数据
- InitTileSetConfig();
- //初始化武器数据
- Weapon.InitWeaponAttribute();
- //初始化敌人数据
- Enemy.InitEnemyAttribute();
- //初始化buff数据
- BuffProp.InitBuffAttribute();
- //初始化主动道具数据
- ActiveProp.InitActiveAttribute();
-
- DungeonConfig = new DungeonConfig();
- DungeonConfig.GroupName = "Test1";
- DungeonConfig.RandomSeed = null;
- DungeonConfig.BattleRoomCount = 15;
- // DungeonConfig.BossRoomCount = 0;
- // DungeonConfig.RewardRoomCount = 0;
- // DungeonConfig.ShopRoomCount = 0;
- // DungeonConfig.OutRoomCount = 0;
- // DungeonConfig.RoomHorizontalMinDispersion = -1;
- // DungeonConfig.RoomHorizontalMaxDispersion = 1;
- // DungeonConfig.RoomVerticalMinDispersion = -1;
- // DungeonConfig.RoomVerticalMaxDispersion = 1;
- // DungeonConfig.EnableLimitRange = false;
- }
+ ///
+ /// 游戏存档
+ ///
+ public GameSave GameSave { get; private set; }
+
+ //开启的协程
+ private List _coroutineList;
+
+ public GameApplication()
+ {
+ Instance = this;
+ //TargetFps = 20;
+ TargetFps = Mathf.RoundToInt(DisplayServer.ScreenGetRefreshRate());
+
+ Utils.InitRandom();
- public override void _EnterTree()
- {
- SubViewport = GetNode("ViewCanvas/SubViewportContainer/SubViewport");
- SubViewportContainer = GetNode("ViewCanvas/SubViewportContainer");
- SceneRoot = GetNode("ViewCanvas/SubViewportContainer/SubViewport/SceneRoot");
- GlobalNodeRoot = GetNode("GlobalNodeRoot");
-
- //背景颜色
- RenderingServer.SetDefaultClearColor(new Color(0, 0, 0, 1));
- //随机化种子
- //GD.Randomize();
- //固定帧率
- //Engine.MaxFps = TargetFps;
- //调试绘制开关
- ActivityObject.IsDebug = false;
- //Engine.TimeScale = 0.2f;
- //调整窗口分辨率
- OnWindowSizeChanged();
- //窗体大小改变
- GetWindow().SizeChanged += OnWindowSizeChanged;
+ //初始化配置表
+ ExcelConfig.Init();
+ PreinstallMarkManager.Init();
+ PropFragmentRegister.Init();
+ //初始化房间配置数据
+ InitRoomConfig();
+ //初始化TileSet配置数据
+ InitTileSetConfig();
+ //初始化武器数据
+ Weapon.InitWeaponAttribute();
+ //初始化敌人数据
+ Enemy.InitEnemyAttribute();
+ //初始化buff数据
+ BuffProp.InitBuffAttribute();
+ //初始化主动道具数据
+ ActiveProp.InitActiveAttribute();
+
+ foreach (var dungeonRoomGroup in RoomConfig)
+ {
+ DungeonGroupList.Add(dungeonRoomGroup.Key);
+ }
- ImageCanvas.Init(GetTree().CurrentScene);
-
- //初始化ui
- UiManager.Init();
- //调试Ui
- UiManager.Open_Debugger();
-
- // 初始化鼠标
- InitCursor();
- //地牢管理器
- DungeonManager = new DungeonManager();
- DungeonManager.Name = "DungeonManager";
- SceneRoot.AddChild(DungeonManager);
+ FirstDungeonConfig = GetDungeonConfig(DungeonGroupList[0], 1);
+
+ //临时处理
+ RoomConfig[DungeonGroupList[0]].BgColor = new Color("0a0a19");
+ RoomConfig[DungeonGroupList[0]].SoundId = null; //"level1_bgm";
+ }
- MapProjectManager.Init();
- EditorTileSetManager.Init();
- BottomTipsPanel.Init();
- //打开主菜单Ui
- UiManager.Open_Main();
- //UiManager.Open_MapEditorProject();
- }
+ ///
+ /// 获取地牢配置数据
+ ///
+ public DungeonConfig GetDungeonConfig(string groupName, int layer)
+ {
+ var config = new DungeonConfig();
+ config.DungeonLayer = layer;
+ config.GroupName = groupName;
+ config.RandomSeed = null;
- public override void _Process(double delta)
- {
- var newDelta = (float)delta;
- InputManager.Update(newDelta);
- SoundManager.Update(newDelta);
-
- //协程更新
- ProxyCoroutineHandler.ProxyUpdateCoroutine(ref _coroutineList, newDelta);
- }
-
- ///
- /// 将 viewport 以外的全局坐标 转换成 viewport 内的全局坐标
- ///
- public Vector2 GlobalToViewPosition(Vector2 globalPos)
- {
- return globalPos / PixelScale - (ViewportSize / 2) + GameCamera.Main.GlobalPosition - GameCamera.Main.PixelOffset;
- }
+ config.BattleRoomCount = 12;
+ config.RewardRoomCount = 2;
+ config.BossRoomCount = 0;
- ///
- /// 将 viewport 以内的全局坐标 转换成 viewport 外的全局坐标
- ///
- public Vector2 ViewToGlobalPosition(Vector2 viewPos)
- {
- return (viewPos + GameCamera.Main.PixelOffset - (GameCamera.Main.GlobalPosition + GameCamera.Main.Offset) + (ViewportSize / 2)) * PixelScale;
- }
-
- public long StartCoroutine(IEnumerator able)
- {
- return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
- }
-
- public void StopCoroutine(long coroutineId)
- {
- ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
- }
+ config.ShopRoomCount = 1;
+ config.EnableLimitRange = false;
+ config.AllowedCornerAisles = false;
+ return config;
+ }
- public bool IsCoroutineOver(long coroutineId)
- {
- return ProxyCoroutineHandler.ProxyIsCoroutineOver(ref _coroutineList, coroutineId);
- }
+ ///
+ /// 获取下一个地牢组名称
+ ///
+ /// 当前地牢组名称
+ public string GetNextDungeonGroup(string currGroupName)
+ {
+ var index = DungeonGroupList.IndexOf(currGroupName);
+ if (index == -1 || index == DungeonGroupList.Count - 1)
+ {
+ return null;
+ }
+ return DungeonGroupList[index + 1];
+ }
- public void StopAllCoroutine()
- {
- ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
- }
+ public override void _EnterTree()
+ {
+ SubViewport = GetNode("ViewCanvas/SubViewportContainer/SubViewport");
+ SubViewportContainer = GetNode("ViewCanvas/SubViewportContainer");
+ SceneRoot = GetNode("ViewCanvas/SubViewportContainer/SubViewport/SceneRoot");
+ GlobalNodeRoot = GetNode("GlobalNodeRoot");
+
+ //背景颜色
+ RenderingServer.SetDefaultClearColor(new Color(0, 0, 0, 1));
+ //随机化种子
+ //GD.Randomize();
+ //固定帧率
+ //Engine.MaxFps = TargetFps;
+ //调试绘制开关
+ ActivityObject.IsDebug = false;
+ //Engine.TimeScale = 0.2f;
+ //调整窗口分辨率
+ OnWindowSizeChanged();
+ //窗体大小改变
+ //GetWindow().SizeChanged += OnWindowSizeChanged;
- public void SetRoomConfig(Dictionary roomConfig)
- {
- RoomConfig = roomConfig;
- InitReadyRoom();
- }
+ ImageCanvas.Init(GetTree().CurrentScene);
+
+ //加载存档
+ LoadGameSave();
+
+ //初始化ui
+ UiManager.Init();
+ //调试Ui
+ //UiManager.Open_Debugger();
+
+ // 初始化鼠标
+ InitCursor();
+ //地牢管理器
+ DungeonManager = new DungeonManager(ActivityObject.Ids.Id_role0001);
+ DungeonManager.Name = "DungeonManager";
+ SceneRoot.AddChild(DungeonManager);
- //初始化房间配置
- private void InitRoomConfig()
- {
- //加载房间配置信息
- var asText = ResourceManager.LoadText("res://" + GameConfig.RoomTileDir + GameConfig.RoomGroupConfigFile);
- RoomConfig = JsonSerializer.Deserialize>(asText);
+ MapProjectManager.Init();
+ EditorTileSetManager.Init();
+ BottomTipsPanel.Init();
- InitReadyRoom();
- }
-
- //初始化房间数据
- private void InitReadyRoom()
- {
- foreach (var dungeonRoomGroup in RoomConfig)
- {
- RemoveUnreadyRooms(dungeonRoomGroup.Value.BattleList);
- RemoveUnreadyRooms(dungeonRoomGroup.Value.InletList);
- RemoveUnreadyRooms(dungeonRoomGroup.Value.OutletList);
- RemoveUnreadyRooms(dungeonRoomGroup.Value.BossList);
- RemoveUnreadyRooms(dungeonRoomGroup.Value.ShopList);
- RemoveUnreadyRooms(dungeonRoomGroup.Value.RewardList);
- RemoveUnreadyRooms(dungeonRoomGroup.Value.EventList);
- }
- }
-
- //移除未准备好的房间
- private void RemoveUnreadyRooms(List roomInfos)
- {
- for (var i = 0; i < roomInfos.Count; i++)
- {
- if (roomInfos[i].ErrorType != RoomErrorType.None) //存在错误
- {
- roomInfos.RemoveAt(i);
- i--;
- }
- }
- }
+ this.CallDelay(0, () =>
+ {
+ //打开主菜单Ui
+ UiManager.Open_Main();
+ });
+ //UiManager.Open_MapEditorProject();
+ }
- //初始化TileSet配置
- private void InitTileSetConfig()
- {
- //加载房间配置信息
- var asText = ResourceManager.LoadText("res://" + GameConfig.RoomTileSetDir + GameConfig.TileSetConfigFile);
- TileSetConfig = JsonSerializer.Deserialize>(asText);
-
- //加载所有数据
- foreach (var tileSetSplit in TileSetConfig)
- {
- tileSetSplit.Value.ReloadTileSetInfo();
- }
- }
+ public override void _Process(double delta)
+ {
+ var newDelta = (float)delta;
+ InputManager.Update(newDelta);
+ SoundManager.Update(newDelta);
+
+ //协程更新
+ ProxyCoroutineHandler.ProxyUpdateCoroutine(ref _coroutineList, newDelta);
+ }
+
+ ///
+ /// 将 viewport 以外的全局坐标 转换成 viewport 内的全局坐标
+ ///
+ public Vector2 GlobalToViewPosition(Vector2 globalPos)
+ {
+ return globalPos / PixelScale - (ViewportSize / 2) + GameCamera.Main.GlobalPosition - GameCamera.Main.PixelOffset;
+ }
- //窗体大小改变
- private void OnWindowSizeChanged()
- {
- var size = GetWindow().Size;
- ViewportSize = size / PixelScale;
- RefreshSubViewportSize();
- }
-
- //刷新视窗大小
- private void RefreshSubViewportSize()
- {
- var s = new Vector2I((int)ViewportSize.X, (int)ViewportSize.Y);
- s.X = s.X / 2 * 2 + 2;
- s.Y = s.Y / 2 * 2 + 2;
- SubViewport.Size = s;
- SubViewportContainer.Scale = new Vector2(PixelScale, PixelScale);
- SubViewportContainer.Size = s;
- SubViewportContainer.Position = new Vector2(-PixelScale, -PixelScale);
- }
+ ///
+ /// 将 viewport 以内的全局坐标 转换成 viewport 外的全局坐标
+ ///
+ public Vector2 ViewToGlobalPosition(Vector2 viewPos)
+ {
+ return (viewPos + GameCamera.Main.PixelOffset - (GameCamera.Main.GlobalPosition + GameCamera.Main.Offset) + (ViewportSize / 2)) * PixelScale;
+ }
+
+ public long StartCoroutine(IEnumerator able)
+ {
+ return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
+ }
+
+ public void StopCoroutine(long coroutineId)
+ {
+ ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
+ }
- //初始化鼠标
- private void InitCursor()
- {
- Cursor = ResourceManager.LoadAndInstantiate(ResourcePath.prefab_Cursor_tscn);
- var cursorLayer = new CanvasLayer();
- cursorLayer.Name = "CursorLayer";
- cursorLayer.Layer = UiManager.GetUiLayer(UiLayer.Pop).Layer + 10;
- AddChild(cursorLayer);
- cursorLayer.AddChild(Cursor);
- }
+ public bool IsCoroutineOver(long coroutineId)
+ {
+ return ProxyCoroutineHandler.ProxyIsCoroutineOver(ref _coroutineList, coroutineId);
+ }
+
+ public void StopAllCoroutine()
+ {
+ ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
+ }
+
+ public void SetRoomConfig(Dictionary roomConfig)
+ {
+ foreach (var dungeonRoomGroup in roomConfig)
+ {
+ if (RoomConfig.TryGetValue(dungeonRoomGroup.Key, out var temp))
+ {
+ dungeonRoomGroup.Value.BgColor = temp.BgColor;
+ dungeonRoomGroup.Value.SoundId = temp.SoundId;
+ }
+ }
+ RoomConfig = roomConfig;
+ InitReadyRoom();
+ }
+
+ //初始化房间配置
+ private void InitRoomConfig()
+ {
+ //加载房间配置信息
+ var asText = ResourceManager.LoadText("res://" + GameConfig.RoomTileDir + GameConfig.RoomGroupConfigFile);
+ RoomConfig = JsonSerializer.Deserialize>(asText);
+
+ InitReadyRoom();
+ }
+
+ //初始化房间数据
+ private void InitReadyRoom()
+ {
+ foreach (var dungeonRoomGroup in RoomConfig)
+ {
+ RemoveUnreadyRooms(dungeonRoomGroup.Value.BattleList);
+ RemoveUnreadyRooms(dungeonRoomGroup.Value.InletList);
+ RemoveUnreadyRooms(dungeonRoomGroup.Value.OutletList);
+ RemoveUnreadyRooms(dungeonRoomGroup.Value.BossList);
+ RemoveUnreadyRooms(dungeonRoomGroup.Value.ShopList);
+ RemoveUnreadyRooms(dungeonRoomGroup.Value.RewardList);
+ RemoveUnreadyRooms(dungeonRoomGroup.Value.EventList);
+ }
+ }
+
+ //移除未准备好的房间
+ private void RemoveUnreadyRooms(List roomInfos)
+ {
+ for (var i = 0; i < roomInfos.Count; i++)
+ {
+ if (roomInfos[i].ErrorType != RoomErrorType.None) //存在错误
+ {
+ roomInfos.RemoveAt(i);
+ i--;
+ }
+ }
+ }
+
+ //初始化TileSet配置
+ private void InitTileSetConfig()
+ {
+ //加载房间配置信息
+ var asText = ResourceManager.LoadText("res://" + GameConfig.RoomTileSetDir + GameConfig.TileSetConfigFile);
+ TileSetConfig = JsonSerializer.Deserialize>(asText);
+
+ //加载所有数据
+ foreach (var tileSetSplit in TileSetConfig)
+ {
+ tileSetSplit.Value.ReloadTileSetInfo();
+ }
+ }
+
+ //窗体大小改变
+ private void OnWindowSizeChanged()
+ {
+ var size = GetWindow().Size;
+ ViewportSize = size / PixelScale;
+ RefreshSubViewportSize();
+ }
+
+ //刷新视窗大小
+ private void RefreshSubViewportSize()
+ {
+ var s = new Vector2I((int)ViewportSize.X, (int)ViewportSize.Y);
+ s.X = s.X / 2 * 2 + 2;
+ s.Y = s.Y / 2 * 2 + 2;
+ SubViewport.Size = s;
+ SubViewportContainer.Scale = new Vector2(PixelScale, PixelScale);
+ SubViewportContainer.Size = s;
+ SubViewportContainer.Position = new Vector2(-PixelScale, -PixelScale);
+ }
+
+ //初始化鼠标
+ private void InitCursor()
+ {
+ Cursor = ResourceManager.LoadAndInstantiate(ResourcePath.prefab_Cursor_tscn);
+ var cursorLayer = new CanvasLayer();
+ cursorLayer.Name = "CursorLayer";
+ cursorLayer.Layer = UiManager.GetUiLayer(UiLayer.Pop).Layer + 10;
+ AddChild(cursorLayer);
+ cursorLayer.AddChild(Cursor);
+ }
+
+ private void LoadGameSave()
+ {
+ GameSave = GameSave.Load();
+ GameSave.Init();
+ }
}
diff --git a/DungeonShooting_Godot/src/game/GameConfig.cs b/DungeonShooting_Godot/src/game/GameConfig.cs
index 8a36f3c..a375d40 100644
--- a/DungeonShooting_Godot/src/game/GameConfig.cs
+++ b/DungeonShooting_Godot/src/game/GameConfig.cs
@@ -95,6 +95,11 @@
public const float NavigationCellSize = 4;
///
+ /// 游戏存档文件名称
+ ///
+ public const string GameSaveFile = "GameSave.json";
+
+ ///
/// 地形掩码纹理大小, 顶部墙壁/47格地形
///
public static readonly Vector2I TerrainBit3x3 = new Vector2I(12, 4);
diff --git a/DungeonShooting_Godot/src/game/activity/box/TreasureBox.cs b/DungeonShooting_Godot/src/game/activity/box/TreasureBox.cs
index ae746e6..ef92626 100644
--- a/DungeonShooting_Godot/src/game/activity/box/TreasureBox.cs
+++ b/DungeonShooting_Godot/src/game/activity/box/TreasureBox.cs
@@ -6,37 +6,37 @@
[Tool]
public partial class TreasureBox : ObstacleObject
{
- public bool IsOpen { get; private set; }
+ public bool IsOpen { get; private set; }
- public override void OnInit()
- {
- AnimatedSprite.AnimationFinished += OnAnimationFinished;
- }
+ public override void OnInit()
+ {
+ AnimatedSprite.AnimationFinished += OnAnimationFinished;
+ }
- public override CheckInteractiveResult CheckInteractive(ActivityObject master)
- {
- return new CheckInteractiveResult(this, !IsOpen, CheckInteractiveResult.InteractiveType.OpenTreasureBox);
- }
+ public override CheckInteractiveResult CheckInteractive(ActivityObject master)
+ {
+ return new CheckInteractiveResult(this, !IsOpen, CheckInteractiveResult.InteractiveType.OpenTreasureBox);
+ }
- public override void Interactive(ActivityObject master)
- {
- if (IsOpen)
- {
- return;
- }
+ public override void Interactive(ActivityObject master)
+ {
+ if (IsOpen)
+ {
+ return;
+ }
- IsOpen = true;
- AnimatedSprite.Play(AnimatorNames.Open);
- }
+ IsOpen = true;
+ AnimatedSprite.Play(AnimatorNames.Open);
+ }
- private void OnAnimationFinished()
- {
- var weapon = Create(World.RandomPool.GetRandomProp());
- weapon.Throw(Position, 2, 95, new Vector2(0, 11), 0);
- }
+ private void OnAnimationFinished()
+ {
+ var weapon = Create(World.RandomPool.GetRandomProp());
+ weapon.Throw(Position, 2, 95, new Vector2(0, 11), 0);
+ }
- public override void Hurt(ActivityObject target, int damage, float angle)
- {
- PlayHitAnimation();
- }
+ public override void Hurt(ActivityObject target, int damage, float angle)
+ {
+ PlayHitAnimation();
+ }
}
diff --git a/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs b/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs
index 52af65a..afa7756 100644
--- a/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs
+++ b/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs
@@ -185,4 +185,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs
index ec86e93..c977c57 100644
--- a/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs
+++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs
@@ -74,4 +74,4 @@
);
}
}
-}
\ No newline at end of file
+}
diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/BrushBullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/BrushBullet.cs
index c685601..6e9cf76 100644
--- a/DungeonShooting_Godot/src/game/activity/bullet/normal/BrushBullet.cs
+++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/BrushBullet.cs
@@ -1,5 +1,4 @@
-
-using Godot;
+using Godot;
///
/// 带笔刷的子弹
diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs
index d96b193..2188cb4 100644
--- a/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs
+++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs
@@ -59,7 +59,7 @@
///
/// 子弹状态
///
- public BulletStateEnum State { get; protected set; } = BulletStateEnum.Normal;
+ public BulletStateEnum State { get; set; } = BulletStateEnum.Normal;
//当前子弹已经飞行的距离
private float CurrFlyDistance = 0;
@@ -69,8 +69,8 @@
public override void OnInit()
{
base.OnInit();
- OutlineColor = new Color(2.5f, 0, 0);
- SetBlendColor(new Color(2.5f, 2.5f, 2.5f));
+ OutlineColor = new Color(2.2f, 0, 0);
+ SetBlendColor(new Color(2.2f, 2.2f, 2.2f));
CollisionArea.CollisionMask = Role.AttackLayer;
}
@@ -397,4 +397,4 @@
CollisionArea.Monitorable = v;
Collision.Disabled = !v;
}
-}
\ No newline at end of file
+}
diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/SplitBullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/SplitBullet.cs
new file mode 100644
index 0000000..3e0da61
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/SplitBullet.cs
@@ -0,0 +1,60 @@
+
+using System;
+using Config;
+using Godot;
+
+///
+/// 分裂子弹
+///
+[Tool]
+public partial class SplitBullet : Bullet
+{
+ ///
+ /// 创建子分裂子弹时的回调
+ ///
+ public event Action OnCreateSplitBulletEvent;
+
+ private BulletData _bulletData;
+ private int _count = 0;
+
+ ///
+ /// 设置分裂的子弹
+ ///
+ /// 子弹数据
+ /// 子弹数量
+ public void SetSplitBullet(BulletData data, int count)
+ {
+ _bulletData = data;
+ _count = count;
+ }
+
+ public override void LogicalFinish()
+ {
+ base.LogicalFinish();
+
+ //创建分裂子弹
+ if (_count > 0 && _bulletData != null)
+ {
+ var a = Mathf.Pi * 2 / _count;
+ for (var i = 0; i < _count; i++)
+ {
+ var clone = _bulletData.Clone();
+ clone.Rotation = a * i;
+ clone.Position = Position + new Vector2(5, 0).Rotated(clone.Rotation);
+ var shootBullet = FireManager.ShootBullet(clone, clone.TriggerRole.Camp);
+ if (OnCreateSplitBulletEvent != null)
+ {
+ OnCreateSplitBulletEvent(shootBullet);
+ }
+ }
+ }
+ }
+
+ public override void OnLeavePool()
+ {
+ base.OnLeavePool();
+ OnCreateSplitBulletEvent = null;
+ _bulletData = null;
+ _count = 0;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/bullet/special/SpecialBullet0001.cs b/DungeonShooting_Godot/src/game/activity/bullet/special/SpecialBullet0001.cs
new file mode 100644
index 0000000..1ff1d5c
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/bullet/special/SpecialBullet0001.cs
@@ -0,0 +1,84 @@
+
+using System;
+using Config;
+using Godot;
+
+///
+/// 垂直往填上飞, 落在地上爆炸产生一个子弹圈
+///
+[Tool]
+public partial class SpecialBullet0001 : ActivityObject, IPoolItem
+{
+ ///
+ /// 创建子分裂子弹时的回调
+ ///
+ public event Action OnCreateSplitBulletEvent;
+
+ public bool IsRecycled { get; set; }
+ public string Logotype { get; set; }
+
+ private string _bulletId;
+ private int _bulletCount;
+ private Role _role;
+ private Vector2 _targetPosition;
+
+ public void InitBullet(string bulletId, int bulletCount, Role role, Vector2 targetPosition)
+ {
+ _bulletId = bulletId;
+ _bulletCount = bulletCount;
+ _role = role;
+ _targetPosition = targetPosition;
+ }
+
+ protected override void OnThrowMaxHeight(float height)
+ {
+ Position = _targetPosition;
+ VerticalSpeed = -50;
+ ShowShadowSprite();
+ }
+
+ protected override void OnFallToGround()
+ {
+ if (!string.IsNullOrEmpty(_bulletId) && (_role != null && !_role.IsDestroyed))
+ {
+ var bulletBase = ExcelConfig.BulletBase_Map[_bulletId];
+ var bulletData = FireManager.GetBulletData(_role, 0, bulletBase);
+
+ //创建分裂子弹
+ var a = Mathf.Pi * 2 / _bulletCount;
+ for (var i = 0; i < _bulletCount; i++)
+ {
+ var clone = bulletData.Clone();
+ clone.Rotation = a * i;
+ clone.Position = Position + new Vector2(5, 0).Rotated(clone.Rotation);
+ var shootBullet = FireManager.ShootBullet(clone, clone.TriggerRole.Camp);
+ if (OnCreateSplitBulletEvent != null)
+ {
+ OnCreateSplitBulletEvent(shootBullet);
+ }
+ }
+ }
+
+ //执行回收
+ ObjectPool.Reclaim(this);
+ }
+
+ public void OnReclaim()
+ {
+ Visible = false;
+ GetParent().CallDeferred(Node.MethodName.RemoveChild, this);
+ }
+
+ public void OnLeavePool()
+ {
+ OnCreateSplitBulletEvent = null;
+ Visible = true;
+ _role = null;
+ Altitude = 0;
+ VerticalSpeed = 0;
+ MoveController.ClearForce();
+ MoveController.BasisVelocity = Vector2.Zero;
+ Velocity = Vector2.Zero;
+ _bulletId = null;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/bullet/summons/Summons.cs b/DungeonShooting_Godot/src/game/activity/bullet/summons/Summons.cs
new file mode 100644
index 0000000..8408336
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/bullet/summons/Summons.cs
@@ -0,0 +1,43 @@
+
+using AiState;
+using Godot;
+
+///
+/// boss用于召唤小怪的投射物
+///
+[Tool]
+public partial class Summons : ActivityObject
+{
+ private ActivityObject _target;
+
+ public void InitTarget(ActivityObject target)
+ {
+ _target = target;
+ }
+
+ protected override void OnFirstFallToGround()
+ {
+ var id = Utils.Random.RandomChoose(Ids.Id_enemy0001);
+ var enemy = Create(id);
+ var randomWeapon = World.RandomPool.GetRandomWeapon();
+ enemy.PickUpWeapon(Create(randomWeapon));
+
+ if (_target != null)
+ {
+ var stateBase = (AiAstonishedState)enemy.StateController.GetState(AIStateEnum.AiAstonished);
+ stateBase.IsEntred = true;
+ enemy.LookTarget = _target;
+ }
+ enemy.PutDown(Position, RoomLayerEnum.YSortLayer);
+
+ //出生特效
+ var effect = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_common_Effect1_tscn);
+ var node = (Node2D)effect;
+ node.Position = Position + new Vector2(0, -5);
+ node.AddToActivityRoot(RoomLayerEnum.YSortLayer);
+ effect.PlayEffect();
+
+
+ Destroy();
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/common/AutoFreezeObject.cs b/DungeonShooting_Godot/src/game/activity/common/AutoFreezeObject.cs
index 7a3c94a..fadd763 100644
--- a/DungeonShooting_Godot/src/game/activity/common/AutoFreezeObject.cs
+++ b/DungeonShooting_Godot/src/game/activity/common/AutoFreezeObject.cs
@@ -1,4 +1,3 @@
-
using Godot;
///
diff --git a/DungeonShooting_Godot/src/game/activity/currency/Gold.cs b/DungeonShooting_Godot/src/game/activity/currency/Gold.cs
index edc0514..2297c99 100644
--- a/DungeonShooting_Godot/src/game/activity/currency/Gold.cs
+++ b/DungeonShooting_Godot/src/game/activity/currency/Gold.cs
@@ -8,92 +8,92 @@
[Tool]
public partial class Gold : ActivityObject, IPoolItem
{
- ///
- /// 金币数量
- ///
- [Export]
- public int GoldCount { get; set; } = 1;
-
- public bool IsRecycled { get; set; }
- public string Logotype { get; set; }
-
- private float _maxSpeed = 250;
- private float _speed = 0;
- private Role _moveTarget;
-
- public override void OnInit()
- {
- DefaultLayer = RoomLayerEnum.YSortLayer;
- }
+ ///
+ /// 金币数量
+ ///
+ [Export]
+ public int GoldCount { get; set; } = 1;
+
+ public bool IsRecycled { get; set; }
+ public string Logotype { get; set; }
+
+ private float _maxSpeed = 250;
+ private float _speed = 0;
+ private Role _moveTarget;
+
+ public override void OnInit()
+ {
+ DefaultLayer = RoomLayerEnum.YSortLayer;
+ }
- protected override void OnThrowOver()
- {
- var current = World.Player;
- if (current != null)
- {
- this.CallDelay(0.3f, () =>
- {
- _moveTarget = current;
- MoveController.Enable = false;
- });
- }
- }
+ protected override void OnThrowOver()
+ {
+ var current = World.Player;
+ if (current != null)
+ {
+ this.CallDelay(0.3f, () =>
+ {
+ _moveTarget = current;
+ MoveController.Enable = false;
+ });
+ }
+ }
- protected override void Process(float delta)
- {
- if (_moveTarget != null && !_moveTarget.IsDestroyed)
- {
- var position = Position;
- var targetPosition = _moveTarget.Position;
- if (position.DistanceSquaredTo(targetPosition) < 3 * 3)
- {
- _moveTarget.AddGold(GoldCount);
- ObjectPool.Reclaim(this);
- }
- else
- {
- _speed = Mathf.MoveToward(_speed, _maxSpeed, _maxSpeed * delta);
- Position = position.MoveToward(targetPosition, _speed * delta);
- }
- }
- }
-
- public void OnReclaim()
- {
- GetParent().RemoveChild(this);
- _moveTarget = null;
- }
+ protected override void Process(float delta)
+ {
+ if (_moveTarget != null && !_moveTarget.IsDestroyed)
+ {
+ var position = Position;
+ var targetPosition = _moveTarget.Position;
+ if (position.DistanceSquaredTo(targetPosition) < 3 * 3)
+ {
+ _moveTarget.AddGold(GoldCount);
+ ObjectPool.Reclaim(this);
+ }
+ else
+ {
+ _speed = Mathf.MoveToward(_speed, _maxSpeed, _maxSpeed * delta);
+ Position = position.MoveToward(targetPosition, _speed * delta);
+ }
+ }
+ }
+
+ public void OnReclaim()
+ {
+ GetParent().RemoveChild(this);
+ _moveTarget = null;
+ }
- public void OnLeavePool()
- {
- _speed = 0;
- MoveController.Enable = true;
- MoveController.ClearForce();
- MoveController.SetAllVelocity(Vector2.Zero);
- }
-
- ///
- /// 创建散落的金币
- ///
- /// 位置
- /// 金币数量
- /// 投抛力度
- public static List CreateGold(Vector2 position, int count, int force = 10)
- {
- var list = new List();
- var goldList = Utils.GetGoldList(count);
- foreach (var id in goldList)
- {
- var o = ObjectManager.GetActivityObject(id);
- o.Position = position;
- o.Throw(0,
- Utils.Random.RandomRangeInt(5 * force, 11 * force),
- new Vector2(Utils.Random.RandomRangeInt(-2 * force, 2 * force), Utils.Random.RandomRangeInt(-2 * force, 2 * force)),
- 0
- );
- list.Add(o);
- }
+ public void OnLeavePool()
+ {
+ _speed = 0;
+ MoveController.Enable = true;
+ MoveController.ClearForce();
+ MoveController.SetAllVelocity(Vector2.Zero);
+ }
+
+ ///
+ /// 创建散落的金币
+ ///
+ /// 位置
+ /// 金币数量
+ /// 投抛力度
+ public static List CreateGold(Vector2 position, int count, int force = 10)
+ {
+ var list = new List();
+ var goldList = Utils.GetGoldList(count);
+ foreach (var id in goldList)
+ {
+ var o = ObjectManager.GetActivityObject(id);
+ o.Position = position;
+ o.Throw(0,
+ Utils.Random.RandomRangeInt(5 * force, 11 * force),
+ new Vector2(Utils.Random.RandomRangeInt(-2 * force, 2 * force), Utils.Random.RandomRangeInt(-2 * force, 2 * force)),
+ 0
+ );
+ list.Add(o);
+ }
- return list;
- }
+ return list;
+ }
}
diff --git a/DungeonShooting_Godot/src/game/activity/item/ObstacleObject.cs b/DungeonShooting_Godot/src/game/activity/item/ObstacleObject.cs
index f49703d..d9efc27 100644
--- a/DungeonShooting_Godot/src/game/activity/item/ObstacleObject.cs
+++ b/DungeonShooting_Godot/src/game/activity/item/ObstacleObject.cs
@@ -7,12 +7,12 @@
[Tool]
public partial class ObstacleObject : ActivityObject, IHurt
{
- public virtual bool CanHurt(CampEnum targetCamp)
- {
- return true;
- }
+ public virtual bool CanHurt(CampEnum targetCamp)
+ {
+ return true;
+ }
- public virtual void Hurt(ActivityObject target, int damage, float angle)
- {
- }
+ public virtual void Hurt(ActivityObject target, int damage, float angle)
+ {
+ }
}
diff --git a/DungeonShooting_Godot/src/game/activity/prop/ActiveProp.cs b/DungeonShooting_Godot/src/game/activity/prop/ActiveProp.cs
index 830eb27..595839f 100644
--- a/DungeonShooting_Godot/src/game/activity/prop/ActiveProp.cs
+++ b/DungeonShooting_Godot/src/game/activity/prop/ActiveProp.cs
@@ -384,7 +384,7 @@
public override void Interactive(ActivityObject master)
{
- if (master is Player player)
+ if (master is Role player)
{
if (player.ActivePropsPack.Capacity == 0)
{
@@ -427,7 +427,7 @@
public override CheckInteractiveResult CheckInteractive(ActivityObject master)
{
- if (master is Player player)
+ if (master is Role player)
{
if (player.ActivePropsPack.Capacity == 0)
{
diff --git a/DungeonShooting_Godot/src/game/activity/prop/BuffProp.cs b/DungeonShooting_Godot/src/game/activity/prop/BuffProp.cs
index b1d3b55..08a1db5 100644
--- a/DungeonShooting_Godot/src/game/activity/prop/BuffProp.cs
+++ b/DungeonShooting_Godot/src/game/activity/prop/BuffProp.cs
@@ -90,7 +90,7 @@
public override void Interactive(ActivityObject master)
{
- if (master is Player role)
+ if (master is Role role)
{
Pickup();
role.PickUpBuffProp(this);
@@ -99,7 +99,7 @@
public override CheckInteractiveResult CheckInteractive(ActivityObject master)
{
- if (master is Player)
+ if (master is Role)
{
return new CheckInteractiveResult(this, true, CheckInteractiveResult.InteractiveType.PickUp);
}
diff --git a/DungeonShooting_Godot/src/game/activity/prop/PropActivity.cs b/DungeonShooting_Godot/src/game/activity/prop/PropActivity.cs
index dc05bae..75fac42 100644
--- a/DungeonShooting_Godot/src/game/activity/prop/PropActivity.cs
+++ b/DungeonShooting_Godot/src/game/activity/prop/PropActivity.cs
@@ -1,5 +1,4 @@
-
-using Godot;
+using Godot;
///
/// 道具基类
diff --git a/DungeonShooting_Godot/src/game/activity/role/MountRotation.cs b/DungeonShooting_Godot/src/game/activity/role/MountRotation.cs
index e265b10..8970b96 100644
--- a/DungeonShooting_Godot/src/game/activity/role/MountRotation.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/MountRotation.cs
@@ -1,4 +1,3 @@
-
using Godot;
///
diff --git a/DungeonShooting_Godot/src/game/activity/role/Role.cs b/DungeonShooting_Godot/src/game/activity/role/Role.cs
index 9cf5391..0ffe87c 100644
--- a/DungeonShooting_Godot/src/game/activity/role/Role.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/Role.cs
@@ -10,6 +10,13 @@
///
public abstract partial class Role : ActivityObject
{
+ public delegate void ShootBulletCallback(Role role, Weapon weapon, float fireRotation, ExcelConfig.BulletBase attributeBullet);
+
+ ///
+ /// 发射子弹回调
+ ///
+ public event ShootBulletCallback OnShootBulletEvent;
+
///
/// 攻击目标的碰撞器所属层级, 数据源自于:
///
@@ -21,6 +28,14 @@
/// 参数2为造成对伤害值
///
public event Action OnDamageEvent;
+
+ ///
+ /// 当角色受到伤害时回调
+ /// 参数1为造成伤害的角色
+ /// 参数2为造成伤害值
+ /// 参数3为是否受到真实伤害, 如果为false, 则表示该伤害被护盾格挡掉了
+ ///
+ public event Action OnHitEvent;
///
/// 是否是 Ai
@@ -290,7 +305,7 @@
///
/// 当前可以互动的物体
///
- public ActivityObject InteractiveItem { get; private set; }
+ public IInteractive InteractiveItem { get; private set; }
///
/// 瞄准辅助线, 需要手动调用 InitSubLine() 初始化
@@ -300,7 +315,7 @@
///
/// 所有角色碰撞的物体
///
- public List InteractiveItemList { get; } = new List();
+ public List InteractiveItemList { get; } = new List();
///
/// 角色看向的坐标
@@ -485,6 +500,8 @@
//连接互动物体信号
InteractiveArea.BodyEntered += _OnPropsEnter;
InteractiveArea.BodyExited += _OnPropsExit;
+ InteractiveArea.AreaEntered += _OnAreaEnter;
+ InteractiveArea.AreaExited += _OnAreaExit;
//------------------------
@@ -527,10 +544,15 @@
{
InteractiveItemList.RemoveAt(i--);
}
- else if (!item.IsThrowing)
+ else
{
+ var flag = true;
+ if (item is ActivityObject ao && ao.IsThrowing)
+ {
+ flag = false;
+ }
//找到可互动的物体了
- if (!findFlag)
+ if (flag && !findFlag)
{
var result = item.CheckInteractive(this);
var prev = _currentResultData;
@@ -541,9 +563,11 @@
if (InteractiveItem != item) //更改互动物体
{
InteractiveItem = item;
+ prev?.Target.OnTargetExitd(this);
+ result?.Target.OnTargetEnterd(this);
ChangeInteractiveItem(prev, result);
}
- else if (result.Type != _currentResultData.Type) //切换状态
+ else if (result.Type != prev.Type) //切换状态
{
ChangeInteractiveItem(prev, result);
}
@@ -558,6 +582,7 @@
var prev = _currentResultData;
_currentResultData = null;
InteractiveItem = null;
+ prev?.Target.OnTargetExitd(this);
ChangeInteractiveItem(prev, null);
}
@@ -817,7 +842,7 @@
///
/// 触发与碰撞的物体互动, 并返回与其互动的物体
///
- public ActivityObject TriggerInteractive()
+ public IInteractive TriggerInteractive()
{
if (HasInteractive())
{
@@ -879,6 +904,10 @@
PrevHitAngle = angle;
OnHit(target, damage, angle, !flag);
+ if (OnHitEvent != null)
+ {
+ OnHitEvent(target, damage, !flag);
+ }
if (target is Role targetRole && !targetRole.IsDestroyed)
{
@@ -901,7 +930,7 @@
IsDie = true;
//禁用状态机控制器
- var stateController = GetComponent(typeof(IStateController));
+ var stateController = GetComponent();
if (stateController != null)
{
stateController.Enable = false;
@@ -934,7 +963,10 @@
private IEnumerator DoDieWithAnimatedSprite()
{
AnimatedSprite.Play(AnimatorNames.Die);
- yield return ToSignal(AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
+ if (AnimatedSprite.SpriteFrames.GetFrameCount(AnimatorNames.Die) > 1)
+ {
+ yield return ToSignal(AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
+ }
DoDieHandler();
}
@@ -1008,12 +1040,9 @@
///
private void _OnPropsEnter(Node2D other)
{
- if (other is ActivityObject propObject && !propObject.CollisionWithMask(PhysicsLayer.OnHand))
+ if (other is IInteractive propObject)
{
- if (!InteractiveItemList.Contains(propObject))
- {
- InteractiveItemList.Add(propObject);
- }
+ OnInteractiveEnter(propObject);
}
}
@@ -1023,23 +1052,57 @@
///
private void _OnPropsExit(Node2D other)
{
- if (other is ActivityObject propObject)
+ if (other is IInteractive propObject)
{
- if (InteractiveItemList.Contains(propObject))
- {
- InteractiveItemList.Remove(propObject);
- }
- if (InteractiveItem == propObject)
- {
- var prev = _currentResultData;
- _currentResultData = null;
- InteractiveItem = null;
- ChangeInteractiveItem(prev, null);
- }
+ OnInteractiveExit(propObject);
}
}
+ private void _OnAreaEnter(Area2D other)
+ {
+ if (other is IInteractive propObject)
+ {
+ OnInteractiveEnter(propObject);
+ }
+ }
+
+ private void _OnAreaExit(Area2D other)
+ {
+ if (other is IInteractive propObject)
+ {
+ OnInteractiveExit(propObject);
+ }
+ }
+
+ private void OnInteractiveEnter(IInteractive propObject)
+ {
+ if (propObject is ActivityObject ao && ao.CollisionWithMask(PhysicsLayer.OnHand))
+ {
+ return;
+ }
+ if (!InteractiveItemList.Contains(propObject))
+ {
+ InteractiveItemList.Add(propObject);
+ }
+ }
+
+ private void OnInteractiveExit(IInteractive propObject)
+ {
+ if (InteractiveItemList.Contains(propObject))
+ {
+ InteractiveItemList.Remove(propObject);
+ }
+ if (InteractiveItem == propObject)
+ {
+ var prev = _currentResultData;
+ _currentResultData = null;
+ InteractiveItem = null;
+ prev?.Target.OnTargetExitd(this);
+ ChangeInteractiveItem(prev, null);
+ }
+ }
+
///
/// 返回当前角色是否是玩家
///
@@ -1077,6 +1140,11 @@
///
public bool IsEnemy(CampEnum otherCamp)
{
+ if (Camp == CampEnum.None || otherCamp == CampEnum.None)
+ {
+ return true;
+ }
+
if (otherCamp == Camp || otherCamp == CampEnum.Peace || Camp == CampEnum.Peace)
{
return false;
@@ -1098,7 +1166,7 @@
}
///
- /// 将 Role 子节点的旋转角度转换为正常的旋转角度
+ /// 将 Role 子节点的旋转角度转换为正常的旋转角度, 单位: 弧度制
/// 因为 Role 受到 Face 影响, 会出现转向动作, 所以需要该函数来转换旋转角度
///
/// 角度, 弧度制
@@ -1524,4 +1592,19 @@
WeaponPack.Destroy();
}
+
+ ///
+ /// 武器发射子弹回调
+ ///
+ /// 武器对象
+ /// 开火角度
+ /// 子弹数据
+ public void ShootBulletHandler(Weapon weapon, float fireRotation, ExcelConfig.BulletBase attributeBullet)
+ {
+ if (OnShootBulletEvent != null)
+ {
+ OnShootBulletEvent(this, weapon, fireRotation, attributeBullet);
+ }
+ //throw new NotImplementedException();
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/RoleState.cs b/DungeonShooting_Godot/src/game/activity/role/RoleState.cs
index 3a328e4..23ffd22 100644
--- a/DungeonShooting_Godot/src/game/activity/role/RoleState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/RoleState.cs
@@ -1,5 +1,6 @@
using System;
+using Config;
///
/// 角色属性类
@@ -242,4 +243,20 @@
return gold;
}
+
+ ///
+ /// 计算射出的子弹
+ ///
+ public event Action> CalcBulletEvent;
+ public ExcelConfig.BulletBase CalcBullet(ExcelConfig.BulletBase attributeBullet)
+ {
+ if (CalcBulletEvent != null)
+ {
+ var result = new RefValue(attributeBullet);
+ CalcBulletEvent(attributeBullet, result);
+ return result.Value;
+ }
+
+ return attributeBullet;
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs b/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs
index 238abe8..542a95f 100644
--- a/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs
@@ -81,6 +81,11 @@
public float LockTargetTime { get; set; } = 0;
///
+ /// 开火时是否站立不动
+ ///
+ public bool FiringStand { get; set; } = false;
+
+ ///
/// 视野半径, 单位像素, 发现玩家后改视野范围可以穿墙
///
public float ViewRange
@@ -471,7 +476,7 @@
///
public void UpdateMarkTargetPosition()
{
- if (LookTarget != null)
+ if (LookTarget != null && AffiliationArea != null)
{
AffiliationArea.RoomInfo.MarkTargetPosition[LookTarget.Id] = LookTarget.Position;
}
@@ -507,6 +512,32 @@
HasMoveDesire = v;
}
+ ///
+ /// 更新玩家脸的朝向
+ ///
+ public void UpdateFace()
+ {
+ //看向目标
+ if (LookTarget != null && MountLookTarget)
+ {
+ var pos = LookTarget.Position;
+ LookPosition = pos;
+ //脸的朝向
+ var gPos = Position;
+ if (pos.X > gPos.X && Face == FaceDirection.Left)
+ {
+ Face = FaceDirection.Right;
+ }
+ else if (pos.X < gPos.X && Face == FaceDirection.Right)
+ {
+ Face = FaceDirection.Left;
+ }
+
+ //枪口跟随目标
+ MountPoint.SetLookAt(pos);
+ }
+ }
+
protected override void OnHit(ActivityObject target, int damage, float angle, bool realHarm)
{
//受到伤害
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAstonishedState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAstonishedState.cs
index d3f446f..adfd6d3 100644
--- a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAstonishedState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAstonishedState.cs
@@ -7,10 +7,13 @@
///
public class AiAstonishedState : StateBase
{
+ ///
+ /// 用于判断是否进入过惊讶状态
+ ///
+ public bool IsEntred = false;
+
private float _timer;
private object[] _args;
- //用于判断是否进入过惊讶状态
- private bool _flag = false;
public AiAstonishedState() : base(AIStateEnum.AiAstonished)
{
@@ -25,22 +28,19 @@
return;
}
- if (_flag)
+ if (IsEntred || !Master.AnimationPlayer.HasAnimation(AnimatorNames.Astonished))
{
ChangeNextState(args);
return;
}
- _flag = true;
+ IsEntred = true;
_args = args;
-
+
_timer = 0.6f;
-
+
//播放惊讶表情
- if (Master.AnimationPlayer.HasAnimation(AnimatorNames.Astonished))
- {
- Master.AnimationPlayer.Play(AnimatorNames.Astonished);
- }
+ Master.AnimationPlayer.Play(AnimatorNames.Astonished);
}
public override void Process(float delta)
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAttackState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAttackState.cs
index 417a039..5c29d6e 100644
--- a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAttackState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAttackState.cs
@@ -206,9 +206,10 @@
Master.MountLookTarget = true;
}
- if (AttackState == AiAttackEnum.Attack && weapon.Attribute.AiAttackAttr.FiringStand) //开火时站立不动
+ if (AttackState == AiAttackEnum.Attack &&
+ (Master.FiringStand || weapon.Attribute.AiAttackAttr.FiringStand)) //开火时站立不动
{
- Master.DoIdle();
+ Master.BasisVelocity = Vector2.Zero;
}
else //正常移动
{
@@ -239,6 +240,15 @@
else //攻击状态
{
Master.Attack();
+
+ if (Master.FiringStand) //开火时站立不动
+ {
+ Master.BasisVelocity = Vector2.Zero;
+ }
+ else //正常移动
+ {
+ MoveHandler(delta);
+ }
}
}
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiFollowUpState.cs
index 6ea8880..613087c 100644
--- a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiFollowUpState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiFollowUpState.cs
@@ -32,7 +32,7 @@
public override void Process(float delta)
{
//先检查弹药是否打光
- if (Master.IsAllWeaponTotalAmmoEmpty())
+ if ((Master.WeaponPack.Capacity > 0 && !Master.NoWeaponAttack) && Master.IsAllWeaponTotalAmmoEmpty())
{
//再寻找是否有可用的武器
var targetWeapon = Master.FindTargetWeapon();
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiLeaveForState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiLeaveForState.cs
index 5bec8fc..d2dd137 100644
--- a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiLeaveForState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiLeaveForState.cs
@@ -35,7 +35,7 @@
_target = (ActivityObject)args[0];
//先检查弹药是否打光
- if (Master.IsAllWeaponTotalAmmoEmpty())
+ if ((Master.WeaponPack.Capacity > 0 && !Master.NoWeaponAttack) && Master.IsAllWeaponTotalAmmoEmpty())
{
//再寻找是否有可用的武器
var targetWeapon = Master.FindTargetWeapon();
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiNotifyState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiNotifyState.cs
index fac6cc8..b27c81a 100644
--- a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiNotifyState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiNotifyState.cs
@@ -22,12 +22,17 @@
//throw new Exception("进入 AIAdvancedStateEnum.AiNotify 没有攻击目标!");
}
_timer = 1.2f;
- //通知其它角色
- Master.World.NotifyEnemyTarget(Master, Master.LookTarget);
+
if (Master.AnimationPlayer.HasAnimation(AnimatorNames.Notify))
{
+ //通知其它角色
+ Master.World.NotifyEnemyTarget(Master, Master.LookTarget);
Master.AnimationPlayer.Play(AnimatorNames.Notify);
}
+ else
+ {
+ ChangeState(AIStateEnum.AiTailAfter);
+ }
}
public override void Process(float delta)
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiSurroundState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiSurroundState.cs
index 559a034..36236bc 100644
--- a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiSurroundState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiSurroundState.cs
@@ -51,7 +51,7 @@
}
//先检查弹药是否打光
- if (Master.IsAllWeaponTotalAmmoEmpty())
+ if ((Master.WeaponPack.Capacity > 0 && !Master.NoWeaponAttack) && Master.IsAllWeaponTotalAmmoEmpty())
{
//再寻找是否有可用的武器
var targetWeapon = Master.FindTargetWeapon();
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs
index 3cd816f..c64ec6c 100644
--- a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs
@@ -39,7 +39,7 @@
_viewTimer = 0;
//先检查弹药是否打光
- if (Master.IsAllWeaponTotalAmmoEmpty())
+ if ((Master.WeaponPack.Capacity > 0 && !Master.NoWeaponAttack) && Master.IsAllWeaponTotalAmmoEmpty())
{
//再寻找是否有可用的武器
var targetWeapon = Master.FindTargetWeapon();
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/Boss.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/Boss.cs
new file mode 100644
index 0000000..6d30d17
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Boss.cs
@@ -0,0 +1,488 @@
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using Config;
+using Godot;
+
+///
+/// Boss逻辑类
+///
+[Tool]
+public partial class Boss : AiRole
+{
+ private long _attaclCoroutine = -1;
+ private List _vertices;
+ private float _targetRotation;
+
+ private int state = 0;
+
+ public override void OnInit()
+ {
+ base.OnInit();
+ WeaponPack.SetCapacity(0);
+ Camp = CampEnum.Camp2;
+ NoWeaponAttack = true;
+ MountLookTarget = true;
+
+ FiringStand = true;
+
+ MaxHp = 2000;
+ Hp = MaxHp;
+
+ AnimatedSprite.Visible = false;
+ StateController.Enable = false;
+ }
+
+ protected override RoleState OnCreateRoleState()
+ {
+ var roleState = base.OnCreateRoleState();
+ roleState.MoveSpeed = 45;
+ return roleState;
+ }
+
+ protected override void Process(float delta)
+ {
+ if (Hp <= 0)
+ {
+ return;
+ }
+ base.Process(delta);
+ LookTarget = World.Player;
+ ViewArea.LookAt(LookTarget.Position);
+ //UpdateFace();
+
+ var velocity = BasisVelocity;
+ if ((Face == FaceDirection.Right && velocity.X > 0) || (Face == FaceDirection.Left && velocity.X < 0))
+ {
+ _targetRotation = 10;
+ }
+ else if ((Face == FaceDirection.Right && velocity.X < 0) || (Face == FaceDirection.Left && velocity.X > 0))
+ {
+ _targetRotation = -10;
+ }
+ else
+ {
+ _targetRotation = 0;
+ }
+
+ AnimatedSprite.RotationDegrees = Mathf.MoveToward(AnimatedSprite.RotationDegrees, _targetRotation, 25 * delta);
+ }
+
+ public override void HurtHandler(ActivityObject target, int damage, float angle)
+ {
+ base.HurtHandler(target, damage, angle);
+
+ if (Hp <= 0) //死亡
+ {
+ StateController.Enable = false;
+ MoveController.Enable = false;
+ MoveController.ClearForce();
+ Velocity = Vector2.Zero;
+ AnimatedSprite.RotationDegrees = 0;
+ StopCoroutine(_attaclCoroutine);
+ }
+ }
+
+ public override void Attack()
+ {
+ if (_attaclCoroutine < 0)
+ {
+ if (World.Current.Player != null) //玩家快没有子弹了, 就生成小兵
+ {
+ var total = 0;
+ var itemSlot = World.Current.Player.WeaponPack.ItemSlot;
+ for (var i = 0; i < itemSlot.Length; i++)
+ {
+ var item = itemSlot[i];
+ if (item != null)
+ {
+ total += item.TotalAmmon;
+ break;
+ }
+ }
+
+ if (total < 30)
+ {
+ var count = AffiliationArea.FindEnterItemsCount(o => o != this && o is AiRole aiRole && aiRole.IsEnemyWithPlayer());
+ if (count == 0)
+ {
+ _attaclCoroutine = StartCoroutine(RunAttack4());
+ return;
+ }
+ }
+ }
+ if (Hp / (float)MaxHp > 0.5f) //第一阶段
+ {
+ switch (Utils.Random.RandomRangeInt(0, 4))
+ {
+ case 0:
+ _attaclCoroutine = StartCoroutine(RunAttack1());
+ break;
+ case 1:
+ _attaclCoroutine = StartCoroutine(RunAttack3());
+ break;
+ case 2:
+ _attaclCoroutine = StartCoroutine(RunAttack4());
+ break;
+ case 3:
+ _attaclCoroutine = StartCoroutine(RunAttack5());
+ break;
+ case 4:
+ _attaclCoroutine = StartCoroutine(RunAttack6());
+ break;
+ }
+ }
+ else //第二阶段
+ {
+ if (state == 0) //
+ {
+ state++;
+ _attaclCoroutine = StartCoroutine(RunAttack2());
+ }
+ else if (state == 1)
+ {
+ state++;
+ _attaclCoroutine = StartCoroutine(RunAttack7());
+ }
+ else
+ {
+ switch (Utils.Random.RandomRangeInt(0, 6))
+ {
+ case 0:
+ _attaclCoroutine = StartCoroutine(RunAttack1());
+ break;
+ case 1:
+ _attaclCoroutine = StartCoroutine(RunAttack2());
+ break;
+ case 2:
+ _attaclCoroutine = StartCoroutine(RunAttack3());
+ break;
+ case 3:
+ _attaclCoroutine = StartCoroutine(RunAttack4());
+ break;
+ case 4:
+ _attaclCoroutine = StartCoroutine(RunAttack5());
+ break;
+ case 5:
+ _attaclCoroutine = StartCoroutine(RunAttack6());
+ break;
+ case 6:
+ _attaclCoroutine = StartCoroutine(RunAttack7());
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ //发射两个子弹圈
+ private IEnumerator RunAttack1()
+ {
+ var bulletData = FireManager.GetBulletData(this, 0, ExcelConfig.BulletBase_Map["0030"]);
+ bulletData.Altitude = 1;
+
+ AnimatedSprite.Play("readyAttack1");
+ yield return ToSignal(AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
+ AnimatedSprite.Play("attack2");
+ yield return new WaitForSeconds(0.4f);
+
+ CreateBulletCircle(15, 0, bulletData, (shootBullet) =>
+ {
+ if (shootBullet is Bullet bullet)
+ {
+ var twistMovement = bullet.MoveController.AddForce(new TwistForce());
+ twistMovement.MoveRotation = shootBullet.BulletData.Rotation;
+ twistMovement.TimeOffset = Utils.Random.RandomRangeFloat(0, Mathf.Pi);
+ }
+ });
+ yield return new WaitForSeconds(0.2f);
+ CreateBulletCircle(60, 0, bulletData);
+ yield return new WaitForSeconds(0.1f);
+ CreateBulletCircle(60, 0, bulletData);
+ yield return new WaitForSeconds(0.2f);
+ CreateBulletCircle(15, Mathf.DegToRad(360 / 15f * 0.5f) , bulletData, (shootBullet) =>
+ {
+ if (shootBullet is Bullet bullet)
+ {
+ var twistMovement = bullet.MoveController.AddForce(new TwistForce());
+ twistMovement.MoveRotation = shootBullet.BulletData.Rotation;
+ twistMovement.TimeOffset = Utils.Random.RandomRangeFloat(0, Mathf.Pi);
+ }
+ });
+
+ yield return new WaitForSeconds(0.5f);
+
+
+ AttackTimer = 1.5f;
+ _attaclCoroutine = -1;
+ }
+
+ //全屏发射子弹
+ private IEnumerator RunAttack2()
+ {
+ var bulletData = FireManager.GetBulletData(this, 0, ExcelConfig.BulletBase_Map["0030"]);
+ bulletData.Altitude = 1;
+ AnimatedSprite.Play("readyAttack6");
+ yield return ToSignal(AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
+ AnimatedSprite.Play("attack6");
+
+ var count = 18;
+ var angle = Mathf.DegToRad(360f / count * 0.5f);
+ for (int i = 0; i < 15; i++)
+ {
+ if (i == 13)
+ {
+ CreateBulletCircle(60, 0, bulletData);
+ }
+ CreateBulletCircle(count, angle * i, bulletData);
+ yield return new WaitForSeconds(0.4f);
+ }
+
+ AnimatedSprite.Play("endAttack6");
+ yield return ToSignal(AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
+
+ AnimatedSprite.Play(AnimatorNames.Idle);
+
+ AttackTimer = 2.5f;
+ _attaclCoroutine = -1;
+ }
+
+ //玩家方向发射扇形子弹
+ private IEnumerator RunAttack3()
+ {
+ var count = 100;
+ var r = Mathf.Pi;
+ var d = r / count;
+ AnimatedSprite.Play("readyAttack5");
+ yield return ToSignal(AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
+ AnimatedSprite.Play("attack5");
+
+ for (var j = 0; j < 3; j++)
+ {
+ var angle = Position.AngleToPoint(LookTarget.Position);
+ var bulletData = FireManager.GetBulletData(this, angle - r * 0.5f, ExcelConfig.BulletBase_Map["0030"]);
+ bulletData.Altitude = 1;
+
+ for (var i = 0; i < 100; i++)
+ {
+ var clone = bulletData.Clone();
+ clone.Position = FirePoint.GlobalPosition;
+ clone.Rotation += i * d;
+ clone.FlySpeed *= Utils.Random.RandomRangeFloat(1, 1.5f);
+ var shootBullet = FireManager.ShootBullet(clone, Camp);
+ if (shootBullet is Bullet bullet)
+ {
+ bullet.HideShadowSprite();
+ var twistMovement = bullet.MoveController.AddForce(new TwistForce());
+ twistMovement.MoveRotation = clone.Rotation;
+ twistMovement.TimeOffset = Utils.Random.RandomRangeFloat(0, Mathf.Pi);
+ }
+
+ if (i % 2 == 0)
+ {
+ yield return null;
+ }
+ }
+
+ yield return new WaitForSeconds(1.5f);
+ }
+ AnimatedSprite.Play(AnimatorNames.Idle);
+
+ AttackTimer = 2.5f;
+ _attaclCoroutine = -1;
+ }
+
+ //随机生成敌人
+ private IEnumerator RunAttack4()
+ {
+ AnimatedSprite.Play("readyGenerate");
+ yield return ToSignal(AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
+ AnimatedSprite.Play("generate");
+ yield return new WaitForSeconds(0.3f);
+
+ var count = (Hp / (float)MaxHp) < 0.5f ? Utils.Random.RandomRangeInt(2, 3) : 1;
+ var positionArray = GetRandomPoint(count);
+ for (var i = 0; i < count; i++)
+ {
+ var summons = Create(Ids.Id_summons0001);
+ summons.InitTarget(World.Player);
+ summons.ThrowToPosition(Position, 40, 0, AffiliationArea.RoomInfo.ToGlobalPosition(positionArray[i]), 150);
+ summons.PutDown(RoomLayerEnum.YSortLayer);
+ yield return new WaitForSeconds(0.5f);
+ }
+
+ yield return new WaitForSeconds(1f);
+
+ AnimatedSprite.Play(AnimatorNames.Idle);
+
+ AttackTimer = 2f;
+ _attaclCoroutine = -1;
+ }
+
+ //发射分裂子弹
+ private IEnumerator RunAttack5()
+ {
+ AnimatedSprite.Play("readyAttack1");
+ yield return ToSignal(AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
+ AnimatedSprite.Play("attack1");
+ yield return new WaitForSeconds(0.2f);
+
+ for (int i = 0; i < 5; i++)
+ {
+ var bulletData = FireManager.GetBulletData(this, Utils.Random.RandomRangeFloat(0, Mathf.Pi * 2), ExcelConfig.BulletBase_Map["0034"]);
+ bulletData.Altitude = 1;
+
+ var shootBullet = FireManager.ShootBullet(bulletData, Camp);
+ if (shootBullet is Bullet bullet)
+ {
+ bullet.HideShadowSprite();
+ if (bullet is SplitBullet splitBullet)
+ {
+ var childBullet = FireManager.GetBulletData(this, 0, ExcelConfig.BulletBase_Map["0030"]);
+ childBullet.Altitude = 1;
+ splitBullet.SetSplitBullet(childBullet, 20);
+ splitBullet.OnCreateSplitBulletEvent += iBullet =>
+ {
+ if (iBullet is Bullet bullet1)
+ {
+ bullet1.HideShadowSprite();
+ }
+ };
+ }
+ }
+
+ yield return new WaitForSeconds(0.5f);
+ }
+
+ yield return new WaitForSeconds(1f);
+
+ AnimatedSprite.Play(AnimatorNames.Idle);
+
+ AttackTimer = 1.5f;
+ _attaclCoroutine = -1;
+ }
+
+ //发射一堆低速子弹
+ private IEnumerator RunAttack6()
+ {
+ AnimatedSprite.Play("readyAttack1");
+ yield return ToSignal(AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
+ AnimatedSprite.Play("attack1");
+ yield return new WaitForSeconds(0.2f);
+
+ var bulletData = FireManager.GetBulletData(this, 0, ExcelConfig.BulletBase_Map["0030"]);
+ bulletData.Altitude = 1;
+ var count = 50;
+ for (var i = 0; i < count; i++)
+ {
+ var clone = bulletData.Clone();
+ clone.Position = Position;
+ clone.Rotation = Utils.Random.RandomRangeFloat(0, Mathf.Pi * 2);
+ clone.FlySpeed *= Utils.Random.RandomRangeFloat(0.2f, 0.9f);
+ var shootBullet = FireManager.ShootBullet(clone, Camp);
+ if (shootBullet is Bullet bullet)
+ {
+ bullet.HideShadowSprite();
+ }
+
+ if (count % 5 == 0)
+ {
+ yield return null;
+ }
+ }
+
+ yield return new WaitForSeconds(1f);
+ AnimatedSprite.Play(AnimatorNames.Idle);
+
+ AttackTimer = 1f;
+ _attaclCoroutine = -1;
+ }
+
+ //向上发射火箭炮(非常难躲避)
+ private IEnumerator RunAttack7()
+ {
+ AnimatedSprite.Play("readyAttack4");
+ yield return ToSignal(AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
+
+ var count = 3;
+ _randomPosList = GetRandomPoint(count * 4).ToList();
+ for (int i = 0; i < count; i++)
+ {
+ AnimationPlayer.Play("attack4");
+ yield return ToSignal(AnimationPlayer, AnimationMixer.SignalName.AnimationFinished);
+ }
+
+ AnimatedSprite.Play(AnimatorNames.Idle);
+
+ AttackTimer = 6f;
+ _attaclCoroutine = -1;
+ }
+
+ private List _randomPosList;
+ private void CreateMissileBullet(NodePath node)
+ {
+ if (_randomPosList == null || _randomPosList.Count == 0)
+ {
+ return;
+ }
+ var node2D = GetNode(node);
+ var bullet = ObjectManager.GetActivityObject(Ids.Id_special0001);
+ bullet.InitBullet("0030", 10, this, AffiliationArea.RoomInfo.ToGlobalPosition(_randomPosList[_randomPosList.Count - 1]));
+ _randomPosList.RemoveAt(_randomPosList.Count - 1);
+ var localPos = node2D.Position;
+ bullet.Position = Position + new Vector2(localPos.X, 0);
+ bullet.Altitude = -localPos.Y;
+ bullet.VerticalSpeed = 800;
+ bullet.OnCreateSplitBulletEvent += b =>
+ {
+ if (b is Bullet blt)
+ {
+ blt.Altitude = 1;
+ blt.HideShadowSprite();
+ }
+ };
+ bullet.PutDown(RoomLayerEnum.YSortLayer, false);
+ bullet.UpdateFall((float)GetProcessDeltaTime());
+ bullet.HideShadowSprite();
+ }
+
+ private Vector2[] GetRandomPoint(int count)
+ {
+ var tileInfo = AffiliationArea.RoomInfo.RoomSplit.TileInfo;
+ if (_vertices == null)
+ {
+ var serializeVector2s = tileInfo.NavigationVertices;
+ _vertices = new List();
+ foreach (var sv2 in serializeVector2s)
+ {
+ _vertices.Add(sv2.AsVector2());
+ }
+ }
+
+ var positionArray = World.Random.GetRandomPositionInPolygon(_vertices, tileInfo.NavigationPolygon, count);
+ return positionArray;
+ }
+
+ private void CreateBulletCircle(int count, float offsetAngle, BulletData bulletData, Action callback = null)
+ {
+ var pos = FirePoint.GlobalPosition;
+ for (var i = 0; i < count; i++)
+ {
+ var clone = bulletData.Clone();
+ clone.Position = pos;
+ clone.Rotation = Mathf.Pi * 2 / count * i + offsetAngle;
+ var shootBullet = FireManager.ShootBullet(clone, Camp);
+ if (shootBullet is Bullet bullet)
+ {
+ bullet.HideShadowSprite();
+ }
+
+ if (callback != null)
+ {
+ callback(shootBullet);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
index b7d2e4c..946d900 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
@@ -64,11 +64,6 @@
{
base.OnInit();
Camp = CampEnum.Camp2;
-
- RoleState.MoveSpeed = 20;
-
- MaxHp = 20;
- Hp = 20;
}
protected override RoleState OnCreateRoleState()
@@ -92,9 +87,33 @@
roleState.Gold = Mathf.Max(0, Utils.Random.RandomConfigRange(enemyBase.Gold));
return roleState;
}
-
+
+ protected override void OnHit(ActivityObject target, int damage, float angle, bool realHarm)
+ {
+ base.OnHit(target, damage, angle, realHarm);
+
+ if (Hp > 0) //受伤
+ {
+ SoundManager.PlaySoundByConfig("enemy_hurt", Position);
+ }
+ else if (Hp <= 0) //死亡
+ {
+ SoundManager.PlaySoundByConfig("enemy_die", Position);
+ }
+ }
+
protected override void OnDie()
{
+ Color color;
+ if (!string.IsNullOrEmpty(_enemyAttribute.BloodColor))
+ {
+ color = Color.FromHtml(_enemyAttribute.BloodColor);
+ }
+ else
+ {
+ color = new Color(1, 1, 1, 0.5f);
+ }
+
var effPos = Position + new Vector2(0, -Altitude);
//血液特效
var blood = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_enemy_EnemyBlood0001_tscn);
@@ -105,24 +124,54 @@
var realVelocity = GetRealVelocity();
var velocity = (realVelocity * 1.5f).LimitLength(80);
//创建敌人碎片
- var count = Utils.Random.RandomRangeInt(3, 6);
- for (var i = 0; i < count; i++)
+ if (_enemyAttribute.BodyFragment != null)
{
- var debris = Create(Ids.Id_enemy_dead0001);
- debris.PutDown(effPos, RoomLayerEnum.NormalLayer);
- debris.MoveController.AddForce(velocity);
+ var count = Utils.Random.RandomRangeInt(3, 6);
+ for (var i = 0; i < count; i++)
+ {
+ var debris = Create(_enemyAttribute.BodyFragment);
+ debris.PutDown(effPos, RoomLayerEnum.NormalLayer);
+ debris.MoveController.AddForce(velocity);
+ if (debris is EnemyDead0001 dead0001)
+ {
+ var gpuParticles2D = dead0001.GetNodeOrNull("GPUParticles2D");
+ if (gpuParticles2D != null)
+ {
+ var particleProcessMaterial = (ParticleProcessMaterial)gpuParticles2D.ProcessMaterial;
+ particleProcessMaterial.Color = color;
+ }
+ }
+ }
}
//派发敌人死亡信号
EventManager.EmitEvent(EventEnum.OnEnemyDie, this);
- var obj = ResourceManager.LoadAndInstantiate(ResourcePath.prefab_effect_enemy_EnemyBlood0002_tscn);
+ var obj = ResourceManager.LoadAndInstantiate(
+ Utils.Random.RandomChoose(
+ ResourcePath.prefab_effect_enemy_EnemyBlood0002_tscn,
+ ResourcePath.prefab_effect_enemy_EnemyBlood0003_tscn,
+ ResourcePath.prefab_effect_enemy_EnemyBlood0004_tscn
+ )
+ );
obj.AddToActivityRoot(RoomLayerEnum.NormalLayer);
obj.InitRoom(AffiliationArea.RoomInfo);
obj.Position = Position;
obj.Rotation = PrevHitAngle;
obj.ZIndex = AffiliationArea.RoomInfo.StaticImageCanvas.ZIndex;
+ obj.Modulate = color;
+ if (Utils.Random.RandomBoolean(0.04f)) //掉落心之容器
+ {
+ var activityObject = Create(Ids.Id_prop0002);
+ activityObject.Throw(Position, 8, 35, Vector2.Zero, 0);
+ }
+ else if (Utils.Random.RandomBoolean(0.015f)) //掉落护盾
+ {
+ var activityObject = Create(Ids.Id_prop0003);
+ activityObject.Throw(Position, 8, 35, Vector2.Zero, 0);
+ }
+
base.OnDie();
}
@@ -134,25 +183,7 @@
return;
}
- //看向目标
- if (LookTarget != null && MountLookTarget)
- {
- var pos = LookTarget.Position;
- LookPosition = pos;
- //脸的朝向
- var gPos = Position;
- if (pos.X > gPos.X && Face == FaceDirection.Left)
- {
- Face = FaceDirection.Right;
- }
- else if (pos.X < gPos.X && Face == FaceDirection.Right)
- {
- Face = FaceDirection.Left;
- }
-
- //枪口跟随目标
- MountPoint.SetLookAt(pos);
- }
+ UpdateFace();
if (RoleState.CanPickUpWeapon)
{
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs
index 6359971..5063e1a 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs
@@ -14,6 +14,7 @@
{
base.OnInit();
NoWeaponAttack = true;
+ FiringStand = true;
WeaponPack.SetCapacity(0);
AnimationPlayer.AnimationFinished += OnAnimationFinished;
@@ -89,4 +90,4 @@
AttackTimer = AttackInterval;
}
}
-}
\ No newline at end of file
+}
diff --git a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs
index c42b9fb..3413f52 100644
--- a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs
@@ -302,11 +302,21 @@
}
//血量为0, 扔掉所有武器
- if (Hp <= 0)
+ if (Hp <= 0) //死亡
{
BasisVelocity = Vector2.Zero;
Velocity = Vector2.Zero;
ThrowAllWeapon();
+
+ GameCamera.Main.CreateShake(new Vector2(3, 3), 1f, true);
+ GameCamera.Main.FollowsMouseAmount = 0;
+ GameCamera.Main.PlayZoomAnimation(new Vector2(2, 2), 5);
+
+ SoundManager.PlaySoundByConfig("role_die", Position);
+ }
+ else //受伤
+ {
+ SoundManager.PlaySoundByConfig("role_hurt", Position);
}
}
@@ -324,14 +334,6 @@
protected override void ChangeInteractiveItem(CheckInteractiveResult prev, CheckInteractiveResult result)
{
- if (prev != null && prev.Target.ShowOutline)
- {
- prev.Target.OutlineColor = Colors.Black;
- }
- if (result != null && result.Target.ShowOutline)
- {
- result.Target.OutlineColor = Colors.White;
- }
//派发互动对象改变事件
EventManager.EmitEvent(EventEnum.OnPlayerChangeInteractiveItem, result);
}
diff --git a/DungeonShooting_Godot/src/game/activity/role/player/state/PlayerRollState.cs b/DungeonShooting_Godot/src/game/activity/role/player/state/PlayerRollState.cs
index 8af732a..299732b 100644
--- a/DungeonShooting_Godot/src/game/activity/role/player/state/PlayerRollState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/player/state/PlayerRollState.cs
@@ -65,6 +65,8 @@
{
Master.Face = FaceDirection.Left;
}
+
+ SoundManager.PlaySoundByConfigDelay("role_rolling", Master.Position, 0.25f);
yield return Master.AnimatedSprite.ToSignal(Master.AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);
_coroutineId = -1;
diff --git a/DungeonShooting_Godot/src/game/activity/role/shop/ShopBoss.cs b/DungeonShooting_Godot/src/game/activity/role/shop/ShopBoss.cs
index 02360d5..28d3691 100644
--- a/DungeonShooting_Godot/src/game/activity/role/shop/ShopBoss.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/shop/ShopBoss.cs
@@ -1,5 +1,6 @@
-
+using System.Collections.Generic;
using Godot;
+using Godot.Collections;
///
/// 商店老板
@@ -7,9 +8,18 @@
[Tool]
public partial class ShopBoss : AiRole
{
+ [Export]
+ public PackedScene ShopItemSlot;
+
+ [Export]
+ public Array SlotMarkerList;
+
+ private List _slot = new List();
+
public override void OnInit()
{
base.OnInit();
+ Camp = CampEnum.Peace;
SetAttackDesire(false); //默认不攻击
SetMoveDesire(false); //默认不攻击
}
@@ -23,6 +33,36 @@
public override void OnCreateWithMark(RoomPreinstall roomPreinstall, ActivityMark activityMark)
{
-
+ if (SlotMarkerList != null)
+ {
+ var layer = World.GetRoomLayer(RoomLayerEnum.NormalLayer);
+ foreach (var marker2D in SlotMarkerList)
+ {
+ var position = marker2D.GlobalPosition;
+ marker2D.Reparent(layer, false);
+ marker2D.Position = position;
+
+ var activityBase = World.RandomPool.GetRandomProp();
+ var itemSlot = ShopItemSlot.Instantiate();
+ _slot.Add(itemSlot);
+ marker2D.AddChild(itemSlot);
+ itemSlot.InitItem(activityBase);
+ }
+ }
+ }
+
+ protected override void OnDestroy()
+ {
+ base.OnDestroy();
+
+ if (_slot != null)
+ {
+ foreach (var shopItemSlot in _slot)
+ {
+ shopItemSlot.Destroy();
+ }
+
+ _slot = null;
+ }
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/shop/ShopItemSlot.cs b/DungeonShooting_Godot/src/game/activity/role/shop/ShopItemSlot.cs
new file mode 100644
index 0000000..e89777b
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/shop/ShopItemSlot.cs
@@ -0,0 +1,127 @@
+
+using System;
+using Config;
+using Godot;
+
+public partial class ShopItemSlot : Area2D, IInteractive, IOutline
+{
+ private Label _name;
+ private Label _price;
+ private Sprite2D _icon;
+ private ExcelConfig.ActivityBase _config;
+
+ private uint _finalPrice;
+ //是否买得起
+ private bool _flag = true;
+
+ public bool ShowOutline { get; set; } = true;
+ public Color OutlineColor
+ {
+ get => _blendShaderMaterial == null ? Colors.Black : _blendShaderMaterial.GetShaderParameter(ShaderParamNames.OutlineColor).AsColor();
+ set => _blendShaderMaterial?.SetShaderParameter(ShaderParamNames.OutlineColor, value);
+ }
+
+
+ public bool IsDestroyed { get; private set; }
+
+ private ShaderMaterial _blendShaderMaterial;
+
+ public void InitItem(ExcelConfig.ActivityBase config)
+ {
+ _price = GetNode
public partial class GameCamera : Camera2D
{
- private class ShakeData
- {
- public Vector2 Value;
- public bool Decline;
- public float DataDelta;
+ private class ShakeData
+ {
+ public Vector2 Value;
+ public bool Decline;
+ public float DataDelta;
- public ShakeData(Vector2 value, bool decline, float dataDelta)
- {
- Value = value;
- Decline = decline;
- DataDelta = dataDelta;
- }
- }
+ public ShakeData(Vector2 value, bool decline, float dataDelta)
+ {
+ Value = value;
+ Decline = decline;
+ DataDelta = dataDelta;
+ }
+ }
- ///
- /// 当前场景的相机对象
- ///
- public static GameCamera Main { get; private set; }
+ ///
+ /// 当前场景的相机对象
+ ///
+ public static GameCamera Main { get; private set; }
- ///
- /// 相机坐标更新完成事件, 参数为 delta
- ///
- public event Action OnPositionUpdateEvent;
+ ///
+ /// 相机坐标更新完成事件, 参数为 delta
+ ///
+ public event Action OnPositionUpdateEvent;
- ///
- /// 恢复系数
- ///
- [Export] public float RecoveryCoefficient = 25f;
+ ///
+ /// 恢复系数
+ ///
+ [Export] public float RecoveryCoefficient = 25f;
- ///
- /// 抖动开关
- ///
- public bool EnableShake { get; set; } = true;
+ ///
+ /// 抖动开关
+ ///
+ public bool EnableShake { get; set; } = true;
- ///
- /// 镜头跟随鼠标进度 (0 - 1)
- ///
- public float FollowsMouseAmount = 0.15f;
+ ///
+ /// 镜头跟随鼠标进度 (0 - 1)
+ ///
+ public float FollowsMouseAmount = 0.15f;
- ///
- /// 相机跟随目标
- ///
- private Role _followTarget;
+ ///
+ /// 相机跟随目标
+ ///
+ private Role _followTarget;
- ///
- /// SubViewportContainer 中的像素偏移, 因为游戏开启了完美像素, SubViewport 节点下的相机运动会造成非常大的抖动,
- /// 为了解决这个问题, 在 SubViewport 父节点中对 SubViewport 进行整体偏移, 以抵消相机造成的巨大抖动
- ///
- public Vector2 PixelOffset { get; private set; }
+ ///
+ /// SubViewportContainer 中的像素偏移, 因为游戏开启了完美像素, SubViewport 节点下的相机运动会造成非常大的抖动,
+ /// 为了解决这个问题, 在 SubViewport 父节点中对 SubViewport 进行整体偏移, 以抵消相机造成的巨大抖动
+ ///
+ public Vector2 PixelOffset { get; private set; }
- private long _index = 0;
-
- private Vector2 _processDistanceSquared = Vector2.Zero;
- private Vector2 _processDirection = Vector2.Zero;
- //抖动数据
- private readonly Dictionary _shakeMap = new Dictionary();
-
- private Vector2 _camPos;
- private Vector2 _shakeOffset = Vector2.Zero;
-
- private ShaderMaterial _offsetShader;
- private int lockIndex = 0;
-
- public GameCamera()
- {
- Main = this;
- }
-
- public override void _Ready()
- {
- _offsetShader = (ShaderMaterial)GameApplication.Instance.SubViewportContainer.Material;
- _camPos = GlobalPosition;
- }
-
- //_PhysicsProcess
- public override void _PhysicsProcess(double delta)
- {
- var newDelta = (float)delta;
- _Shake(newDelta);
-
- var world = World.Current;
- if (world != null && _followTarget != null && lockIndex <= 0)
- {
- var mousePosition = InputManager.CursorPosition;
- var targetPosition = _followTarget.GlobalPosition;
- if (targetPosition.DistanceSquaredTo(mousePosition) >= (60 / FollowsMouseAmount) * (60 / FollowsMouseAmount))
- {
- _camPos = targetPosition.MoveToward(mousePosition, 60);
- }
- else
- {
- _camPos = targetPosition.Lerp(mousePosition, FollowsMouseAmount);
- }
+ private long _index = 0;
+
+ private Vector2 _processDistanceSquared = Vector2.Zero;
+ private Vector2 _processDirection = Vector2.Zero;
+ //抖动数据
+ private readonly Dictionary _shakeMap = new Dictionary();
+
+ private Vector2 _camPos;
+ private Vector2 _shakeOffset = Vector2.Zero;
+
+ private ShaderMaterial _offsetShader;
+ private int lockIndex = 0;
+
+ public GameCamera()
+ {
+ Main = this;
+ }
+
+ public override void _Ready()
+ {
+ _offsetShader = (ShaderMaterial)GameApplication.Instance.SubViewportContainer.Material;
+ _camPos = GlobalPosition;
+ }
+
+ //_PhysicsProcess
+ public override void _PhysicsProcess(double delta)
+ {
+ var newDelta = (float)delta;
+ _Shake(newDelta);
+
+ var world = World.Current;
+ if (world != null && _followTarget != null && lockIndex <= 0)
+ {
+ var mousePosition = InputManager.CursorPosition;
+ var targetPosition = _followTarget.GlobalPosition;
+ if (targetPosition.DistanceSquaredTo(mousePosition) >= (60 / FollowsMouseAmount) * (60 / FollowsMouseAmount))
+ {
+ _camPos = targetPosition.MoveToward(mousePosition, 60);
+ }
+ else
+ {
+ _camPos = targetPosition.Lerp(mousePosition, FollowsMouseAmount);
+ }
- var cameraPosition = _camPos;
- var roundPos = cameraPosition.Round();
- PixelOffset = roundPos - cameraPosition;
- _offsetShader.SetShaderParameter("offset", PixelOffset);
- GlobalPosition = roundPos;
-
- Offset = _shakeOffset.Round();
-
- //调用相机更新事件
- if (OnPositionUpdateEvent != null)
- {
- OnPositionUpdateEvent(newDelta);
- }
- }
- }
+ var cameraPosition = _camPos;
+ var roundPos = cameraPosition.Round();
+ PixelOffset = roundPos - cameraPosition;
+ _offsetShader.SetShaderParameter("offset", PixelOffset);
+ GlobalPosition = roundPos;
+
+ Offset = _shakeOffset.Round();
+
+ //调用相机更新事件
+ if (OnPositionUpdateEvent != null)
+ {
+ OnPositionUpdateEvent(newDelta);
+ }
+ }
+ }
- ///
- /// 设置相机跟随目标
- ///
- public void SetFollowTarget(Role target)
- {
- _followTarget = target;
- if (target != null)
- {
- _camPos = target.GlobalPosition;
- GlobalPosition = _camPos;
- }
- }
+ ///
+ /// 设置相机跟随目标
+ ///
+ public void SetFollowTarget(Role target)
+ {
+ _followTarget = target;
+ if (target != null)
+ {
+ _camPos = target.GlobalPosition;
+ GlobalPosition = _camPos;
+ }
+ }
- ///
- /// 获取相机跟随目标
- ///
- public Role GetFollowTarget()
- {
- return _followTarget;
- }
-
- ///
- /// 设置帧抖动, 结束后自动清零, 需要每一帧调用
- ///
- /// 抖动的力度
- public void Shake(Vector2 value)
- {
- if (value.LengthSquared() > _processDistanceSquared.LengthSquared())
- {
- _processDistanceSquared = value;
- }
- }
-
- ///
- /// 添加一个单方向上的抖动, 该帧结束后自动清零
- ///
- public void DirectionalShake(Vector2 value)
- {
- _processDirection += value;
- }
-
- ///
- /// 创建一个抖动, 并设置抖动时间
- ///
- public async void CreateShake(Vector2 value, float time, bool decline = false)
- {
- if (time > 0)
- {
- value.X = Mathf.Abs(value.X);
- value.Y = Mathf.Abs(value.Y);
- var tempIndex = _index++;
- var sceneTreeTimer = GetTree().CreateTimer(time);
- if (decline)
- {
- _shakeMap[tempIndex] = new ShakeData(value, true, value.Length() / time);
- }
- else
- {
- _shakeMap[tempIndex] = new ShakeData(value, false, 0);
- }
+ ///
+ /// 获取相机跟随目标
+ ///
+ public Role GetFollowTarget()
+ {
+ return _followTarget;
+ }
+
+ ///
+ /// 设置帧抖动, 结束后自动清零, 需要每一帧调用
+ ///
+ /// 抖动的力度
+ public void Shake(Vector2 value)
+ {
+ if (value.LengthSquared() > _processDistanceSquared.LengthSquared())
+ {
+ _processDistanceSquared = value;
+ }
+ }
+
+ ///
+ /// 添加一个单方向上的抖动, 该帧结束后自动清零
+ ///
+ public void DirectionalShake(Vector2 value)
+ {
+ _processDirection += value;
+ }
+
+ ///
+ /// 创建一个抖动, 并设置抖动时间
+ ///
+ public async void CreateShake(Vector2 value, float time, bool decline = false)
+ {
+ if (time > 0)
+ {
+ value.X = Mathf.Abs(value.X);
+ value.Y = Mathf.Abs(value.Y);
+ var tempIndex = _index++;
+ var sceneTreeTimer = GetTree().CreateTimer(time);
+ if (decline)
+ {
+ _shakeMap[tempIndex] = new ShakeData(value, true, value.Length() / time);
+ }
+ else
+ {
+ _shakeMap[tempIndex] = new ShakeData(value, false, 0);
+ }
- await ToSignal(sceneTreeTimer, Timer.SignalName.Timeout);
- _shakeMap.Remove(tempIndex);
- }
- }
+ await ToSignal(sceneTreeTimer, Timer.SignalName.Timeout);
+ _shakeMap.Remove(tempIndex);
+ }
+ }
- ///
- /// 播放玩家死亡特写镜头
- ///
- public void PlayPlayerDieFeatures()
- {
-
- }
+ ///
+ /// 播放玩家死亡特写镜头
+ ///
+ public void PlayPlayerDieFeatures()
+ {
+
+ }
- ///
- /// 锁住相机视角移动
- ///
- public void LockCamera()
- {
- lockIndex++;
- }
+ ///
+ /// 锁住相机视角移动
+ ///
+ public void LockCamera()
+ {
+ lockIndex++;
+ }
- ///
- /// 解锁相机视角移动
- ///
- public void UnLockCamera()
- {
- lockIndex--;
- }
-
- //抖动调用
- private void _Shake(float delta)
- {
- if (EnableShake)
- {
- var distance = _CalculateDistanceSquared(delta);
- if (distance == Vector2.Zero)
- {
- _shakeOffset += _processDirection - Offset / 2f;
- }
- else
- {
- distance = new Vector2(Mathf.Sqrt(Mathf.Abs(distance.X)), Mathf.Sqrt(Mathf.Abs(distance.Y)));
- var offset = Offset;
- _shakeOffset += _processDirection + new Vector2(
- (float)GD.RandRange(-distance.X, distance.X) - offset.X,
- (float)GD.RandRange(-distance.Y, distance.Y) - offset.Y
- );
- }
+ ///
+ /// 解锁相机视角移动
+ ///
+ public void UnLockCamera()
+ {
+ lockIndex--;
+ }
+
+ //抖动调用
+ private void _Shake(float delta)
+ {
+ if (EnableShake)
+ {
+ var distance = _CalculateDistanceSquared(delta);
+ if (distance == Vector2.Zero)
+ {
+ _shakeOffset += _processDirection - Offset / 2f;
+ }
+ else
+ {
+ distance = new Vector2(Mathf.Sqrt(Mathf.Abs(distance.X)), Mathf.Sqrt(Mathf.Abs(distance.Y)));
+ var offset = Offset;
+ _shakeOffset += _processDirection + new Vector2(
+ (float)GD.RandRange(-distance.X, distance.X) - offset.X,
+ (float)GD.RandRange(-distance.Y, distance.Y) - offset.Y
+ );
+ }
- _processDistanceSquared = Vector2.Zero;
- _processDirection = _processDirection.Lerp(Vector2.Zero, RecoveryCoefficient * delta);
- }
- else
- {
- _shakeOffset = _shakeOffset.Lerp(Vector2.Zero, RecoveryCoefficient * delta);
- }
- }
+ _processDistanceSquared = Vector2.Zero;
+ _processDirection = _processDirection.Lerp(Vector2.Zero, RecoveryCoefficient * delta);
+ }
+ else
+ {
+ _shakeOffset = _shakeOffset.Lerp(Vector2.Zero, RecoveryCoefficient * delta);
+ }
+ }
- //计算相机需要抖动的值
- private Vector2 _CalculateDistanceSquared(float delta)
- {
- var temp = Vector2.Zero;
- float length = 0;
+ //计算相机需要抖动的值
+ private Vector2 _CalculateDistanceSquared(float delta)
+ {
+ var temp = Vector2.Zero;
+ float length = 0;
- foreach (var keyValuePair in _shakeMap)
- {
- var shakeData = keyValuePair.Value;
- var tempLength = shakeData.Value.LengthSquared();
- if (tempLength > length)
- {
- length = tempLength;
- temp = shakeData.Value;
- if (shakeData.Decline)
- {
- shakeData.Value = shakeData.Value.MoveToward(Vector2.Zero, shakeData.DataDelta * delta);
- //Debug.Log("shakeData.Value: " + shakeData.Value + ", _processDistanceSquared: " + _processDistanceSquared);
- }
- }
- }
+ foreach (var keyValuePair in _shakeMap)
+ {
+ var shakeData = keyValuePair.Value;
+ var tempLength = shakeData.Value.LengthSquared();
+ if (tempLength > length)
+ {
+ length = tempLength;
+ temp = shakeData.Value;
+ if (shakeData.Decline)
+ {
+ shakeData.Value = shakeData.Value.MoveToward(Vector2.Zero, shakeData.DataDelta * delta);
+ //Debug.Log("shakeData.Value: " + shakeData.Value + ", _processDistanceSquared: " + _processDistanceSquared);
+ }
+ }
+ }
- //return temp;
- return _processDistanceSquared.LengthSquared() > length ? _processDistanceSquared : temp;
- }
+ //return temp;
+ return _processDistanceSquared.LengthSquared() > length ? _processDistanceSquared : temp;
+ }
}
diff --git a/DungeonShooting_Godot/src/game/common/NodeAnimation.cs b/DungeonShooting_Godot/src/game/common/NodeAnimation.cs
new file mode 100644
index 0000000..cb36e32
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/common/NodeAnimation.cs
@@ -0,0 +1,98 @@
+
+using System;
+using System.Collections;
+using Godot;
+
+public static class NodeAnimation
+{
+ ///
+ /// 将物体渐变显示
+ ///
+ /// 指定对象
+ /// 时间, 单位: 秒
+ /// 完成回调
+ public static void PlayShowAnimation(this ActivityObject activityObject, float time, Action finish = null)
+ {
+ activityObject.StartCoroutine(_PlayShowAnimation(activityObject, time, finish));
+ }
+
+ ///
+ /// 将物体渐变隐藏
+ ///
+ /// 指定对象
+ /// 时间, 单位: 秒
+ /// 完成回调
+ public static void PlayHideAnimation(this ActivityObject activityObject, float time, Action finish = null)
+ {
+ activityObject.StartCoroutine(_PlayAlphaAnimation(activityObject, time, finish));
+ }
+
+ private static IEnumerator _PlayShowAnimation(ActivityObject activityObject, float time, Action action)
+ {
+ activityObject.Visible = true;
+ var modulateA = activityObject.Modulate.A;
+ var speed = (1f - modulateA) / time;
+ while (modulateA < 1f)
+ {
+ modulateA += speed * (float)activityObject.GetProcessDeltaTime();
+ var color = activityObject.Modulate;
+ color.A = modulateA;
+ activityObject.Modulate = color;
+ yield return null;
+ }
+
+ if (action != null)
+ {
+ action();
+ }
+ }
+
+ private static IEnumerator _PlayAlphaAnimation(ActivityObject activityObject, float time, Action action)
+ {
+ var modulateA = activityObject.Modulate.A;
+ var speed = modulateA / time;
+ while (modulateA > 0f)
+ {
+ modulateA -= speed * (float)activityObject.GetProcessDeltaTime();
+ var color = activityObject.Modulate;
+ color.A = modulateA;
+ activityObject.Modulate = color;
+ yield return null;
+ }
+ activityObject.Visible = false;
+
+ if (action != null)
+ {
+ action();
+ }
+ }
+
+ ///
+ /// 播放相机缩放动画
+ ///
+ /// 相机对象
+ /// 目标缩放值
+ /// 速度
+ /// 完成回调
+ public static void PlayZoomAnimation(this GameCamera camera, Vector2 targetZoom, float speed, Action finish = null)
+ {
+ GameApplication.Instance.StartCoroutine(_StartZoomAnimation(camera, targetZoom, speed, finish));
+ }
+
+ private static IEnumerator _StartZoomAnimation(GameCamera camera, Vector2 targetZoom, float speed, Action finish)
+ {
+ var currZoom = camera.Zoom;
+
+ while (targetZoom != currZoom)
+ {
+ currZoom = currZoom.MoveToward(targetZoom, speed * (float)camera.GetProcessDeltaTime());
+ camera.Zoom = currZoom;
+ yield return null;
+ }
+
+ if (finish != null)
+ {
+ finish();
+ }
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/common/component/force/TwistForce.cs b/DungeonShooting_Godot/src/game/common/component/force/TwistForce.cs
new file mode 100644
index 0000000..e5519f1
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/common/component/force/TwistForce.cs
@@ -0,0 +1,42 @@
+
+using Godot;
+
+///
+/// 扭曲运动外力
+///
+public class TwistForce : ExternalForce
+{
+ ///
+ /// 移动方向, 弧度制
+ ///
+ public float MoveRotation { get; set; }
+
+ ///
+ /// 周期时间缩放
+ ///
+ public float CycleTimeScale { get; set; } = 7;
+
+ ///
+ /// 扭曲强度
+ ///
+ public float Strength { get; set; } = 50;
+
+ ///
+ /// 时间偏移
+ ///
+ public float TimeOffset { get; set; }
+
+ public TwistForce() : base(nameof(TwistForce))
+ {
+ AutoDestroy = false;
+ }
+
+ public override void PhysicsProcess(float delta)
+ {
+ TimeOffset += delta * CycleTimeScale;
+ var sin = Mathf.Sin(TimeOffset);
+ Velocity = new Vector2(0, sin * Strength).Rotated(MoveRotation);
+ }
+
+
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/data/EditorObject.cs b/DungeonShooting_Godot/src/game/data/EditorObject.cs
new file mode 100644
index 0000000..efeb117
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/data/EditorObject.cs
@@ -0,0 +1,58 @@
+using Godot;
+
+namespace Config;
+
+public partial class ExcelConfig
+{
+ public partial class EditorObject
+ {
+ private bool _initFlag;
+ private bool _isActivity;
+
+ ///
+ /// 判断是否是 ActivityObject 物体
+ ///
+ public bool IsActivity()
+ {
+ if (!_initFlag)
+ {
+ _initFlag = true;
+ _isActivity = !Prefab.StartsWith("res://");
+ }
+
+ return _isActivity;
+ }
+
+ ///
+ /// 获取物体真实名称
+ ///
+ public string GetRealName()
+ {
+ if (IsActivity())
+ {
+ var activityBase = ActivityBase_Map[Prefab];
+ return activityBase.Name;
+ }
+
+ return Name;
+ }
+
+ ///
+ /// 加载地牢编辑器中自定义对象的图标
+ ///
+ public Texture2D GetIcon()
+ {
+ if (IsActivity())
+ {
+ var activityBase = ActivityBase_Map[Prefab];
+ return ResourceManager.LoadTexture2D(activityBase.Icon);
+ }
+
+ if (string.IsNullOrEmpty(Icon))
+ {
+ return null;
+ }
+ return ResourceManager.LoadTexture2D(Icon);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/data/GameSave.cs b/DungeonShooting_Godot/src/game/data/GameSave.cs
new file mode 100644
index 0000000..a884b46
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/data/GameSave.cs
@@ -0,0 +1,65 @@
+
+using System.IO;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Godot;
+
+public class GameSave
+{
+ ///
+ /// 是否全屏
+ ///
+ [JsonInclude]
+ public bool FullScreen = false;
+
+ ///
+ /// 背景音乐音量, (0 - 1)
+ ///
+ [JsonInclude]
+ public float BgmVolume = 0.5f;
+
+ ///
+ /// 音效音量, (0 - 1)
+ ///
+ [JsonInclude]
+ public float SfxVolume = 0.5f;
+
+ public void Init()
+ {
+ if (FullScreen)
+ {
+ DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen);
+ }
+ else
+ {
+ DisplayServer.WindowSetMode(DisplayServer.WindowMode.Windowed);
+ }
+
+ SoundManager.SetBusValue(BUS.BGM, BgmVolume);
+ SoundManager.SetBusValue(BUS.SFX, SfxVolume);
+ }
+
+ public void Save()
+ {
+ var options = new JsonSerializerOptions();
+ options.WriteIndented = true;
+ var serialize = JsonSerializer.Serialize(this, options);
+ File.WriteAllText(GameConfig.GameSaveFile, serialize);
+ }
+
+ public static GameSave Load()
+ {
+ GameSave save;
+ if (!File.Exists(GameConfig.GameSaveFile))
+ {
+ save = new GameSave();
+ save.Save();
+ }
+ else
+ {
+ save = JsonSerializer.Deserialize(File.ReadAllText(GameConfig.GameSaveFile));
+ }
+
+ return save;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/effects/AutoDestroyParticles.cs b/DungeonShooting_Godot/src/game/effects/AutoDestroyParticles.cs
index efffc2f..b7c2cd5 100644
--- a/DungeonShooting_Godot/src/game/effects/AutoDestroyParticles.cs
+++ b/DungeonShooting_Godot/src/game/effects/AutoDestroyParticles.cs
@@ -1,5 +1,4 @@
-
-using Godot;
+using Godot;
using Godot.Collections;
///
diff --git a/DungeonShooting_Godot/src/game/effects/Blood.cs b/DungeonShooting_Godot/src/game/effects/Blood.cs
index ff21809..a905284 100644
--- a/DungeonShooting_Godot/src/game/effects/Blood.cs
+++ b/DungeonShooting_Godot/src/game/effects/Blood.cs
@@ -5,41 +5,41 @@
///
public partial class Blood : CpuParticles2D
{
- private float _timer;
-
- public override void _Ready()
- {
- Emitting = true;
- ReadyStop();
- }
+ private float _timer;
+
+ public override void _Ready()
+ {
+ Emitting = true;
+ ReadyStop();
+ }
- public override void _Process(double delta)
- {
- _timer += (float)delta;
- if (_timer > 15f)
- {
- if (_timer > 60f)
- {
- QueueFree();
- }
- else
- {
- var color = Modulate;
- color.A = Mathf.Lerp(1, 0, (_timer - 15f) / 45f);
- Modulate = color;
- }
- }
- }
+ public override void _Process(double delta)
+ {
+ _timer += (float)delta;
+ if (_timer > 15f)
+ {
+ if (_timer > 60f)
+ {
+ QueueFree();
+ }
+ else
+ {
+ var color = Modulate;
+ color.A = Mathf.Lerp(1, 0, (_timer - 15f) / 45f);
+ Modulate = color;
+ }
+ }
+ }
- private async void ReadyStop()
- {
- var timer = GetTree().CreateTimer(Lifetime - 0.05f);
- await ToSignal(timer, "timeout");
- Emitting = false;
- SetPhysicsProcess(false);
- SetProcessInput(false);
- SetProcessInternal(false);
- SetProcessUnhandledInput(false);
- SetProcessUnhandledKeyInput(false);
- }
+ private async void ReadyStop()
+ {
+ var timer = GetTree().CreateTimer(Lifetime - 0.05f);
+ await ToSignal(timer, "timeout");
+ Emitting = false;
+ SetPhysicsProcess(false);
+ SetProcessInput(false);
+ SetProcessInternal(false);
+ SetProcessUnhandledInput(false);
+ SetProcessUnhandledKeyInput(false);
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/event/EventEnum.cs b/DungeonShooting_Godot/src/game/event/EventEnum.cs
index dd3a2b6..da71afb 100644
--- a/DungeonShooting_Godot/src/game/event/EventEnum.cs
+++ b/DungeonShooting_Godot/src/game/event/EventEnum.cs
@@ -7,6 +7,11 @@
public enum EventEnum
{
///
+ /// 切换玩家角色, 参数为
+ ///
+ OnChangePlayerRole,
+
+ ///
/// 敌人死亡, 参数为死亡的敌人的实例, 参数类型为
///
OnEnemyDie,
diff --git a/DungeonShooting_Godot/src/game/hall/DungeonEntrance.cs b/DungeonShooting_Godot/src/game/hall/DungeonEntrance.cs
index 65a156c..b57462a 100644
--- a/DungeonShooting_Godot/src/game/hall/DungeonEntrance.cs
+++ b/DungeonShooting_Godot/src/game/hall/DungeonEntrance.cs
@@ -15,7 +15,7 @@
if (body is Player)
{
// 验证该组是否满足生成地牢的条件
- var config = GameApplication.Instance.DungeonConfig;
+ var config = GameApplication.Instance.FirstDungeonConfig;
var result = DungeonManager.CheckDungeon(config.GroupName);
if (result.HasError)
{
diff --git a/DungeonShooting_Godot/src/game/hall/Hall.cs b/DungeonShooting_Godot/src/game/hall/Hall.cs
index 6b9bbe0..c1c6963 100644
--- a/DungeonShooting_Godot/src/game/hall/Hall.cs
+++ b/DungeonShooting_Godot/src/game/hall/Hall.cs
@@ -6,17 +6,17 @@
///
public partial class Hall : World
{
- ///
- /// 玩家出生标记
- ///
- [Export]
- public Marker2D BirthMark;
+ ///
+ /// 玩家出生标记
+ ///
+ [Export]
+ public Marker2D BirthMark;
- [Export]
- public Sprite2D BgSprite;
-
- ///
- /// 房间数据, 该数据时虚拟出来的, 并不是配置文件读取出来的
- ///
- public RoomInfo RoomInfo { get; set; }
+ [Export]
+ public Sprite2D BgSprite;
+
+ ///
+ /// 房间数据, 该数据时虚拟出来的, 并不是配置文件读取出来的
+ ///
+ public RoomInfo RoomInfo { get; set; }
}
diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
index c749d3d..b3c8fc7 100644
--- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
+++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
@@ -6,6 +6,7 @@
public const string icon_png = "res://icon.png";
public const string default_env_tres = "res://default_env.tres";
public const string default_bus_layout_tres = "res://default_bus_layout.tres";
+ public const string GameSave_json = "res://GameSave.json";
public const string prefab_Cursor_tscn = "res://prefab/Cursor.tscn";
public const string prefab_ui_Main_tscn = "res://prefab/ui/Main.tscn";
public const string prefab_ui_TileSetEditorCombination_tscn = "res://prefab/ui/TileSetEditorCombination.tscn";
@@ -41,6 +42,7 @@
public const string prefab_ui_TileSetEditorProject_tscn = "res://prefab/ui/TileSetEditorProject.tscn";
public const string prefab_ui_EditorManager_tscn = "res://prefab/ui/EditorManager.tscn";
public const string prefab_ui_EditorTips_tscn = "res://prefab/ui/EditorTips.tscn";
+ public const string prefab_ui_Victory_tscn = "res://prefab/ui/Victory.tscn";
public const string prefab_ui_TileSetEditorTerrain_tscn = "res://prefab/ui/TileSetEditorTerrain.tscn";
public const string prefab_ui_EditorColorPicker_tscn = "res://prefab/ui/EditorColorPicker.tscn";
public const string prefab_ui_RoomUI_tscn = "res://prefab/ui/RoomUI.tscn";
@@ -67,12 +69,9 @@
public const string prefab_role_shopBoss_ShopBoss0001_tscn = "res://prefab/role/shopBoss/ShopBoss0001.tscn";
public const string prefab_role_template_AiTemplate_tscn = "res://prefab/role/template/AiTemplate.tscn";
public const string prefab_role_template_RoleTemplate_tscn = "res://prefab/role/template/RoleTemplate.tscn";
- public const string prefab_role_enemy_Enemy0006_tscn = "res://prefab/role/enemy/Enemy0006.tscn";
public const string prefab_role_enemy_Enemy0001_tscn = "res://prefab/role/enemy/Enemy0001.tscn";
public const string prefab_role_enemy_Enemy0002_tscn = "res://prefab/role/enemy/Enemy0002.tscn";
- public const string prefab_role_enemy_Enemy0003_tscn = "res://prefab/role/enemy/Enemy0003.tscn";
- public const string prefab_role_enemy_Enemy0004_tscn = "res://prefab/role/enemy/Enemy0004.tscn";
- public const string prefab_role_enemy_Enemy0005_tscn = "res://prefab/role/enemy/Enemy0005.tscn";
+ public const string prefab_room_RoomExit_tscn = "res://prefab/room/RoomExit.tscn";
public const string prefab_box_TreasureBox0001_tscn = "res://prefab/box/TreasureBox0001.tscn";
public const string prefab_test_MoveComponent_tscn = "res://prefab/test/MoveComponent.tscn";
public const string prefab_shell_Shell0002_tscn = "res://prefab/shell/Shell0002.tscn";
@@ -89,6 +88,8 @@
public const string prefab_effect_enemy_EnemyBlood0001_tscn = "res://prefab/effect/enemy/EnemyBlood0001.tscn";
public const string prefab_effect_enemy_EnemyDead0001_tscn = "res://prefab/effect/enemy/EnemyDead0001.tscn";
public const string prefab_effect_enemy_EnemyDead0002_tscn = "res://prefab/effect/enemy/EnemyDead0002.tscn";
+ public const string prefab_effect_enemy_EnemyBlood0004_tscn = "res://prefab/effect/enemy/EnemyBlood0004.tscn";
+ public const string prefab_effect_enemy_EnemyBlood0003_tscn = "res://prefab/effect/enemy/EnemyBlood0003.tscn";
public const string prefab_effect_enemy_EnemyBlood0002_tscn = "res://prefab/effect/enemy/EnemyBlood0002.tscn";
public const string prefab_effect_common_Effect1_tscn = "res://prefab/effect/common/Effect1.tscn";
public const string prefab_effect_common_Trail0001_tscn = "res://prefab/effect/common/Trail0001.tscn";
@@ -131,6 +132,8 @@
public const string prefab_item_Item0003_tscn = "res://prefab/item/Item0003.tscn";
public const string prefab_item_Item0054_tscn = "res://prefab/item/Item0054.tscn";
public const string prefab_item_Item0015_tscn = "res://prefab/item/Item0015.tscn";
+ public const string prefab_bullet_summons_Summons0001_tscn = "res://prefab/bullet/summons/Summons0001.tscn";
+ public const string prefab_bullet_special_SpecialBullet0001_tscn = "res://prefab/bullet/special/SpecialBullet0001.tscn";
public const string prefab_bullet_laser_Laser0001_tscn = "res://prefab/bullet/laser/Laser0001.tscn";
public const string prefab_bullet_laser_Laser0002_tscn = "res://prefab/bullet/laser/Laser0002.tscn";
public const string prefab_bullet_normal_Bullet0006_tscn = "res://prefab/bullet/normal/Bullet0006.tscn";
@@ -187,13 +190,9 @@
public const string resource_spriteFrames_weapon_Weapon0001_tres = "res://resource/spriteFrames/weapon/Weapon0001.tres";
public const string resource_spriteFrames_role_Enemy0001_tres = "res://resource/spriteFrames/role/Enemy0001.tres";
public const string resource_spriteFrames_role_ShopBoss0001_tres = "res://resource/spriteFrames/role/ShopBoss0001.tres";
- public const string resource_spriteFrames_role_Enemy0006_tres = "res://resource/spriteFrames/role/Enemy0006.tres";
public const string resource_spriteFrames_role_Role_tip_tres = "res://resource/spriteFrames/role/Role_tip.tres";
- public const string resource_spriteFrames_role_Enemy0004_tres = "res://resource/spriteFrames/role/Enemy0004.tres";
- public const string resource_spriteFrames_role_Enemy0005_tres = "res://resource/spriteFrames/role/Enemy0005.tres";
public const string resource_spriteFrames_role_Enemy0002_tres = "res://resource/spriteFrames/role/Enemy0002.tres";
public const string resource_spriteFrames_role_Role0001_tres = "res://resource/spriteFrames/role/Role0001.tres";
- public const string resource_spriteFrames_role_Enemy0003_tres = "res://resource/spriteFrames/role/Enemy0003.tres";
public const string resource_spriteFrames_shell_Shell0004_tres = "res://resource/spriteFrames/shell/Shell0004.tres";
public const string resource_spriteFrames_shell_Shell0002_tres = "res://resource/spriteFrames/shell/Shell0002.tres";
public const string resource_spriteFrames_shell_Shell0003_tres = "res://resource/spriteFrames/shell/Shell0003.tres";
@@ -219,6 +218,7 @@
public const string resource_config_BulletBase_json = "res://resource/config/BulletBase.json";
public const string resource_config_AiAttackAttr_json = "res://resource/config/AiAttackAttr.json";
public const string resource_config_ActivityMaterial_json = "res://resource/config/ActivityMaterial.json";
+ public const string resource_config_EditorObject_json = "res://resource/config/EditorObject.json";
public const string resource_config_WeaponBase_json = "res://resource/config/WeaponBase.json";
public const string resource_config_Sound_json = "res://resource/config/Sound.json";
public const string resource_config_BuffPropBase_json = "res://resource/config/BuffPropBase.json";
@@ -386,17 +386,11 @@
public const string resource_sprite_role_role0002_eat_eat_png = "res://resource/sprite/role/role0002/eat/eat.png";
public const string resource_sprite_role_role0002_run_Sprite_png = "res://resource/sprite/role/role0002/run/Sprite.png";
public const string resource_sprite_role_shopBoss0001_ShopBoss0001_png = "res://resource/sprite/role/shopBoss0001/ShopBoss0001.png";
- public const string resource_sprite_role_enemy0003_enemy0003_png = "res://resource/sprite/role/enemy0003/enemy0003.png";
- public const string resource_sprite_role_enemy0003_enemy0003_Icon_png = "res://resource/sprite/role/enemy0003/enemy0003_Icon.png";
- public const string resource_sprite_role_enemy0003_enemy0003_Debris_png = "res://resource/sprite/role/enemy0003/enemy0003_Debris.png";
- public const string resource_sprite_role_enemy0004_enemy0004_png = "res://resource/sprite/role/enemy0004/enemy0004.png";
- public const string resource_sprite_role_enemy0004_enemy0004_Debris_png = "res://resource/sprite/role/enemy0004/enemy0004_Debris.png";
- public const string resource_sprite_role_enemy0004_enemy0004_Icon_png = "res://resource/sprite/role/enemy0004/enemy0004_Icon.png";
+ public const string resource_sprite_role_dle_liquid_enemy0003_png = "res://resource/sprite/role/dle_liquid/enemy0003.png";
+ public const string resource_sprite_role_dle_liquid_enemy0002_png = "res://resource/sprite/role/dle_liquid/enemy0002.png";
+ public const string resource_sprite_role_dle_liquid_enemy0004_png = "res://resource/sprite/role/dle_liquid/enemy0004.png";
public const string resource_sprite_role_dle_liquid_enemy0001_Icon_liquid_png = "res://resource/sprite/role/dle_liquid/enemy0001_Icon_liquid.png";
public const string resource_sprite_role_boss_a025c8ecde4f0a7d88eee741f369c286_png = "res://resource/sprite/role/boss/a025c8ecde4f0a7d88eee741f369c286.png";
- public const string resource_sprite_role_enemy0005_enemy0005_png = "res://resource/sprite/role/enemy0005/enemy0005.png";
- public const string resource_sprite_role_enemy0005_enemy0005_Debris_png = "res://resource/sprite/role/enemy0005/enemy0005_Debris.png";
- public const string resource_sprite_role_enemy0005_enemy0005_Icon_png = "res://resource/sprite/role/enemy0005/enemy0005_Icon.png";
public const string resource_sprite_role_enemy0002_enemy0001_png = "res://resource/sprite/role/enemy0002/enemy0001.png";
public const string resource_sprite_role_enemy0002_Enemy0002_png = "res://resource/sprite/role/enemy0002/Enemy0002.png";
public const string resource_sprite_role_enemy0002_Enemy0002_dead_png = "res://resource/sprite/role/enemy0002/Enemy0002_dead.png";
@@ -450,16 +444,9 @@
public const string resource_sprite_role_common_Role_query_png = "res://resource/sprite/role/common/Role_query.png";
public const string resource_sprite_role_common_Role_shadow1_png = "res://resource/sprite/role/common/Role_shadow1.png";
public const string resource_sprite_role_common_Role_notify_png = "res://resource/sprite/role/common/Role_notify.png";
- public const string resource_sprite_role_enemy0007_enemy005_png = "res://resource/sprite/role/enemy0007/enemy005.png";
- public const string resource_sprite_role_enemy0007_enemy0006_Debris_png = "res://resource/sprite/role/enemy0007/enemy0006_Debris.png";
- public const string resource_sprite_role_enemy0007_enemy0005_Icon_png = "res://resource/sprite/role/enemy0007/enemy0005_Icon.png";
- public const string resource_sprite_role_enemy0007_dle_png = "res://resource/sprite/role/enemy0007/dle.png";
public const string resource_sprite_role_enemy0001_enemy0001_png = "res://resource/sprite/role/enemy0001/enemy0001.png";
public const string resource_sprite_role_enemy0001_enemy0001_Icon副本_png = "res://resource/sprite/role/enemy0001/enemy0001_Icon - 副本.png";
public const string resource_sprite_role_enemy0001_enemy0001_Debris_png = "res://resource/sprite/role/enemy0001/enemy0001_Debris.png";
- public const string resource_sprite_role_enemy0006_enemy0005_png = "res://resource/sprite/role/enemy0006/enemy0005.png";
- public const string resource_sprite_role_enemy0006_enemy0006_Debris_png = "res://resource/sprite/role/enemy0006/enemy0006_Debris.png";
- public const string resource_sprite_role_enemy0006_enemy0005_Icon_png = "res://resource/sprite/role/enemy0006/enemy0005_Icon.png";
public const string resource_sprite_box_TreasureBox0001_icon_png = "res://resource/sprite/box/TreasureBox0001_icon.png";
public const string resource_sprite_box_TreasureBox0001_png = "res://resource/sprite/box/TreasureBox0001.png";
public const string resource_sprite_shootFire_ShotFire0001_png = "res://resource/sprite/shootFire/ShotFire0001.png";
@@ -655,6 +642,8 @@
public const string resource_sprite_item_hall_c_item_42_png = "res://resource/sprite/item/hall_c/item _42.png";
public const string resource_sprite_noise_Noise0001_png = "res://resource/sprite/noise/Noise0001.png";
public const string resource_sprite_noise_Noise0002_png = "res://resource/sprite/noise/Noise0002.png";
+ public const string resource_sprite_bullet_summons_Summons0001_png = "res://resource/sprite/bullet/summons/Summons0001.png";
+ public const string resource_sprite_bullet_special_SpecialBullet0001_png = "res://resource/sprite/bullet/special/SpecialBullet0001.png";
public const string resource_sprite_bullet_laser_Laser0001_png = "res://resource/sprite/bullet/laser/Laser0001.png";
public const string resource_sprite_bullet_normal_bullet0009_png = "res://resource/sprite/bullet/normal/bullet0009.png";
public const string resource_sprite_bullet_normal_bullet0008_png = "res://resource/sprite/bullet/normal/bullet0008.png";
diff --git a/DungeonShooting_Godot/src/game/manager/SoundManager.cs b/DungeonShooting_Godot/src/game/manager/SoundManager.cs
index 2195543..5a551b7 100644
--- a/DungeonShooting_Godot/src/game/manager/SoundManager.cs
+++ b/DungeonShooting_Godot/src/game/manager/SoundManager.cs
@@ -22,7 +22,7 @@
/// 全局音效音量, 范围 0 - 1
///
public static float SoundVolume { get; set; } = 0.4f;
-
+
private static Stack _streamPlayer2DStack = new Stack();
private static Stack _streamPlayerStack = new Stack();
private static HashSet _playingSoundResourceList = new HashSet();
@@ -60,6 +60,7 @@
_playingSoundResourceList.Add(path);
var sound = ResourceManager.Load(path);
Stream = sound;
+
Bus = Enum.GetName(typeof(BUS), 1);
Play();
}
@@ -91,13 +92,44 @@
///
public partial class GameAudioPlayer : AudioStreamPlayer
{
+ ///
+ /// 默认音量
+ ///
+ public float DefaultVolume { get; set; } = 1;
+
+ ///
+ /// 资源名称
+ ///
public string SoundResourceName { get; set; }
+
public override void _Ready()
{
Finished += OnPlayFinish;
}
///
+ /// 慢慢过渡到停止播放
+ ///
+ public void TransitionToStop()
+ {
+ TransitionTo(0, 1.5f, OnPlayFinish);
+ }
+
+ ///
+ /// 过渡到指定音量
+ ///
+ public void TransitionTo(float volume, float duration, Action finish = null)
+ {
+ var tween = CreateTween();
+ tween.TweenProperty(this, "volume_db", LinearToDb(volume), duration);
+ if (finish != null)
+ {
+ tween.TweenCallback(Callable.From(finish));
+ }
+ tween.Play();
+ }
+
+ ///
/// 停止播放, 并回收节点
///
public void StopPlay()
@@ -105,7 +137,15 @@
Stop();
OnPlayFinish();
}
-
+
+ ///
+ /// 设置音量, (0 - 1)
+ ///
+ public void SetVolume(float volume)
+ {
+ VolumeDb = LinearToDb(volume);
+ }
+
private void OnPlayFinish()
{
GetParent().RemoveChild(this);
@@ -119,22 +159,69 @@
{
_playingSoundResourceList.Clear();
}
-
+
///
/// 播放声音 用于bgm
///
- /// bgm路径
- /// 音量
- public static GameAudioPlayer PlayMusic(string soundName, float volume = 0.5f)
+ /// sound表路径
+ public static GameAudioPlayer PlayMusic(string soundId)
{
- var sound = ResourceManager.Load(soundName);
- var soundNode = GetAudioPlayerInstance();
- GameApplication.Instance.GlobalNodeRoot.AddChild(soundNode);
- soundNode.Stream = sound;
- soundNode.Bus = Enum.GetName(typeof(BUS), 0);
- soundNode.VolumeDb = volume;
- soundNode.Play();
- return soundNode;
+ if (ExcelConfig.Sound_Map.TryGetValue(soundId, out var soundConfig))
+ {
+ var sound = ResourceManager.Load(soundConfig.Path);
+ var soundNode = GetAudioPlayerInstance(soundConfig.Volume);
+ GameApplication.Instance.GlobalNodeRoot.AddChild(soundNode);
+ soundNode.Stream = sound;
+ soundNode.Bus = Enum.GetName(typeof(BUS), BUS.BGM);
+ soundNode.VolumeDb = LinearToDb(soundConfig.Volume);
+ soundNode.Play();
+ return soundNode;
+ }
+
+ return null;
+ }
+
+ ///
+ /// 播放声音 用于bgm
+ ///
+ /// sound表路径
+ /// 重写音量 (0 - 1)
+ public static GameAudioPlayer PlayMusic(string soundId, float volume)
+ {
+ if (ExcelConfig.Sound_Map.TryGetValue(soundId, out var soundConfig))
+ {
+ var sound = ResourceManager.Load(soundConfig.Path);
+ var soundNode = GetAudioPlayerInstance(soundConfig.Volume);
+ GameApplication.Instance.GlobalNodeRoot.AddChild(soundNode);
+ soundNode.Stream = sound;
+ soundNode.Bus = Enum.GetName(typeof(BUS), BUS.BGM);
+ soundNode.VolumeDb = LinearToDb(volume);
+ soundNode.Play();
+ return soundNode;
+ }
+
+ return null;
+ }
+
+ ///
+ /// 播放过渡音效, 从0音量到默认音量, 用于bgm
+ ///
+ public static GameAudioPlayer PlayTransitionMusic(string soundId, float duration)
+ {
+ if (ExcelConfig.Sound_Map.TryGetValue(soundId, out var soundConfig))
+ {
+ var sound = ResourceManager.Load(soundConfig.Path);
+ var soundNode = GetAudioPlayerInstance(soundConfig.Volume);
+ GameApplication.Instance.GlobalNodeRoot.AddChild(soundNode);
+ soundNode.Stream = sound;
+ soundNode.Bus = Enum.GetName(typeof(BUS), BUS.BGM);
+ soundNode.VolumeDb = LinearToDb(0);
+ soundNode.Play();
+ soundNode.TransitionTo(soundConfig.Volume, duration);
+ return soundNode;
+ }
+
+ return null;
}
///
@@ -145,11 +232,11 @@
public static GameAudioPlayer PlaySoundEffect(string soundName, float volume = 1f)
{
var sound = ResourceManager.Load(soundName);
- var soundNode = GetAudioPlayerInstance();
+ var soundNode = GetAudioPlayerInstance(volume);
GameApplication.Instance.GlobalNodeRoot.AddChild(soundNode);
soundNode.Stream = sound;
soundNode.Bus = Enum.GetName(typeof(BUS), 1);
- soundNode.VolumeDb = Mathf.LinearToDb(Mathf.Clamp(volume, 0, 1));
+ soundNode.VolumeDb = LinearToDb(Mathf.Clamp(volume, 0, 1));
soundNode.Play();
return soundNode;
}
@@ -185,13 +272,13 @@
{
GameApplication.Instance.GlobalNodeRoot.AddChild(soundNode);
}
-
+
soundNode.GlobalPosition = pos;
- soundNode.VolumeDb = Mathf.LinearToDb(Mathf.Clamp(volume * SoundVolume, 0, 1));
+ soundNode.VolumeDb = LinearToDb(Mathf.Clamp(volume * SoundVolume, 0, 1));
soundNode.PlaySoundByResource(soundName, delayTime);
return soundNode;
}
-
+
///
/// 根据音效配置表Id播放音效
///
@@ -200,8 +287,12 @@
/// 触发播放音效的角色, 因为 Npc 产生的音效声音更小, 可以传 null
public static GameAudioPlayer2D PlaySoundByConfig(string id, Vector2 viewPosition, Role triggerRole = null)
{
- var sound = ExcelConfig.Sound_Map[id];
- return PlaySoundByConfig(sound, viewPosition, triggerRole);
+ if (ExcelConfig.Sound_Map.TryGetValue(id, out var sound))
+ {
+ return PlaySoundByConfig(sound, viewPosition, triggerRole);
+ }
+
+ return null;
}
///
@@ -228,10 +319,14 @@
/// 触发播放音效的角色, 因为 Npc 产生的音效声音更小, 可以传 null
public static GameAudioPlayer2D PlaySoundByConfigDelay(string id, Vector2 viewPosition, float delayTime, Role triggerRole = null)
{
- var sound = ExcelConfig.Sound_Map[id];
- return PlaySoundByConfigDelay(sound, viewPosition, delayTime, triggerRole);
+ if (ExcelConfig.Sound_Map.TryGetValue(id, out var sound))
+ {
+ return PlaySoundByConfigDelay(sound, viewPosition, delayTime, triggerRole);
+ }
+
+ return null;
}
-
+
///
/// 根据音效配置延时播放音效
///
@@ -267,14 +362,20 @@
///
/// 获取音频播放节点
///
- private static GameAudioPlayer GetAudioPlayerInstance()
+ private static GameAudioPlayer GetAudioPlayerInstance(float volume)
{
+ GameAudioPlayer audio;
if (_streamPlayerStack.Count > 0)
{
- return _streamPlayerStack.Pop();
+ audio = _streamPlayerStack.Pop();
+ }
+ else
+ {
+ audio = new GameAudioPlayer();
}
- return new GameAudioPlayer();
+ audio.DefaultVolume = volume;
+ return audio;
}
///
@@ -305,11 +406,39 @@
///
public static float CalcRoleVolume(float volume, Role role)
{
- if (role is not Player)
+ if (role != null && role is not Player)
{
return volume * 0.4f;
}
return volume;
}
+
+ public static float LinearToDb(float v)
+ {
+ float volumen_db = 0;
+ if (v <= 0)
+ {
+ volumen_db = -61;
+ }
+ else
+ {
+ volumen_db = 20 * Mathf.Log(v) / MathF.Log(10);
+ }
+
+ return volumen_db;
+ }
+
+ public static void SetBusValue(BUS type, float value)
+ {
+ float v = LinearToDb(value);
+ if (type == BUS.BGM)
+ {
+ AudioServer.SetBusVolumeDb(1, v);
+ }
+ else
+ {
+ AudioServer.SetBusVolumeDb(2, v);
+ }
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs b/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs
index 64a0079..221ab70 100644
--- a/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs
+++ b/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs
@@ -39,6 +39,7 @@
public const string TileSetEditorProject = "TileSetEditorProject";
public const string EditorManager = "EditorManager";
public const string EditorTips = "EditorTips";
+ public const string Victory = "Victory";
public const string TileSetEditorTerrain = "TileSetEditorTerrain";
public const string EditorColorPicker = "EditorColorPicker";
public const string RoomUI = "RoomUI";
@@ -1677,6 +1678,54 @@
}
///
+ /// 创建 Victory, 并返回UI实例, 该函数不会打开 Ui
+ ///
+ public static UI.Victory.VictoryPanel Create_Victory()
+ {
+ return CreateUi(UiNames.Victory);
+ }
+
+ ///
+ /// 打开 Victory, 并返回UI实例
+ ///
+ public static UI.Victory.VictoryPanel Open_Victory()
+ {
+ return OpenUi(UiNames.Victory);
+ }
+
+ ///
+ /// 隐藏 Victory 的所有实例
+ ///
+ public static void Hide_Victory()
+ {
+ var uiInstance = Get_Victory_Instance();
+ foreach (var uiPanel in uiInstance)
+ {
+ uiPanel.HideUi();
+ }
+ }
+
+ ///
+ /// 销毁 Victory 的所有实例
+ ///
+ public static void Destroy_Victory()
+ {
+ var uiInstance = Get_Victory_Instance();
+ foreach (var uiPanel in uiInstance)
+ {
+ uiPanel.Destroy();
+ }
+ }
+
+ ///
+ /// 获取所有 Victory 的实例, 如果没有实例, 则返回一个空数组
+ ///
+ public static UI.Victory.VictoryPanel[] Get_Victory_Instance()
+ {
+ return GetUiInstance(nameof(UI.Victory.Victory));
+ }
+
+ ///
/// 创建 TileSetEditorTerrain, 并返回UI实例, 该函数不会打开 Ui
///
public static UI.TileSetEditorTerrain.TileSetEditorTerrainPanel Create_TileSetEditorTerrain()
diff --git a/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs b/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs
index 21e909a..d75faa4 100644
--- a/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs
+++ b/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs
@@ -96,26 +96,53 @@
{
if (Generator.BattleRoomInfos.Count == Config.BattleRoomCount / (Config.RewardRoomCount + 1) * (Generator.RewardRoomInfos.Count + 1)) //奖励房间
{
- return DungeonRoomType.Reward;
+ if (RoomGroup.RewardList.Count > 0)
+ {
+ return DungeonRoomType.Reward;
+ }
+
+ return DungeonRoomType.Battle;
}
}
+
if (Generator.ShopRoomInfos.Count < Config.ShopRoomCount)
{
+ //原本条件
if (Generator.BattleRoomInfos.Count == Config.BattleRoomCount / (Config.ShopRoomCount + 1) * (Generator.ShopRoomInfos.Count + 1)) //商店
{
- return DungeonRoomType.Shop;
+ if (RoomGroup.ShopList.Count > 0)
+ {
+ return DungeonRoomType.Shop;
+ }
+
+ return DungeonRoomType.Battle;
+ }
+ else if (Generator.BattleRoomInfos.Count == Config.BattleRoomCount) //商店
+ {
+ if (RoomGroup.ShopList.Count > 0)
+ {
+ return DungeonRoomType.Shop;
+ }
+
+ return DungeonRoomType.Battle;
}
}
}
if (Generator.BattleRoomInfos.Count >= Config.BattleRoomCount) //战斗房间已满
{
- if (Generator.BossRoomInfos.Count < Config.BossRoomCount) //最后一个房间是boss房间
+ if ((Generator.BattleRoomInfos.Count >= Config.BattleRoomCount + 1 && RoomGroup.BossList.Count == 0) ||
+ Config.BossRoomCount == 0)
+ {
+ return DungeonRoomType.Outlet;
+ }
+ else if (Generator.BossRoomInfos.Count < Config.BossRoomCount) //最后一个房间是boss房间
{
if (RoomGroup.BossList.Count == 0) //没有预设boss房间
{
return DungeonRoomType.Battle;
}
+
//生成boss房间
return DungeonRoomType.Boss;
}
diff --git a/DungeonShooting_Godot/src/game/room/Dungeon.cs b/DungeonShooting_Godot/src/game/room/Dungeon.cs
index b94144b..cd8e6f2 100644
--- a/DungeonShooting_Godot/src/game/room/Dungeon.cs
+++ b/DungeonShooting_Godot/src/game/room/Dungeon.cs
@@ -1,4 +1,3 @@
-
using Godot;
///
@@ -6,17 +5,28 @@
///
public partial class Dungeon : World
{
- public override void _Ready()
- {
- base._Ready();
- Color = Colors.Black;
- }
+ ///
+ /// 地牢配置
+ ///
+ public DungeonConfig DungeonConfig { get; set; }
+
+ ///
+ /// 地牢房间组
+ ///
+ public DungeonRoomGroup RoomGroup { get; set; }
- ///
- /// 初始化 TileMap 中的层级
- ///
- public void InitLayer()
- {
- MapLayerManager.InitMapLayer(TileRoot);
- }
-}
+ public override void _Ready()
+ {
+ base._Ready();
+ //Color = Colors.Black;
+ Debug.Log("[临时处理]: 这里设置房间迷雾");
+ }
+
+ ///
+ /// 初始化 TileMap 中的层级
+ ///
+ public void InitLayer()
+ {
+ MapLayerManager.InitMapLayer(TileRoot);
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
index eb38790..1713f61 100644
--- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs
+++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections;
+using Config;
using Godot;
///
@@ -37,7 +38,7 @@
/// 当前使用的配置
///
public DungeonConfig CurrConfig { get; private set; }
-
+
///
/// 当前玩家所在游戏世界对象
///
@@ -47,7 +48,12 @@
/// 自动图块配置
///
public AutoTileConfig AutoTileConfig { get; private set; }
-
+
+ ///
+ /// 加载角色ID
+ ///
+ public string LoadRoleId { get; set; }
+
private UiBase _prevUi;
private DungeonTileMap _dungeonTileMap;
private DungeonGenerator _dungeonGenerator;
@@ -56,10 +62,11 @@
private float _checkEnemyTimer = 0;
//用于记录玩家上一个所在区域
private AffiliationArea _affiliationAreaFlag;
+ private Role _cachePlayer;
-
- public DungeonManager()
+ public DungeonManager(string loadRoleId)
{
+ LoadRoleId = loadRoleId;
//绑定事件
EventManager.AddEventListener(EventEnum.OnPlayerFirstEnterRoom, OnPlayerFirstEnterRoom);
EventManager.AddEventListener(EventEnum.OnPlayerEnterRoom, OnPlayerEnterRoom);
@@ -92,7 +99,7 @@
ClearWorld();
CurrWorld.QueueFree();
}
-
+
//销毁池中所有物体
ObjectPool.DisposeAllItem();
@@ -371,6 +378,7 @@
player.Collision.Disabled = true;
}
+ CurrWorld.OnUnloadSuccess();
DestroyWorld();
yield return 0;
FogMaskHandler.ClearRecordRoom();
@@ -378,6 +386,8 @@
BrushImageData.ClearBrushData();
QueueRedraw();
+ yield return new WaitForSeconds(3);
+
//鼠标还原
GameApplication.Instance.Cursor.SetGuiMode(true);
yield return 0;
@@ -452,6 +462,8 @@
yield return 0;
//创建世界场景
var dungeon = (Dungeon)CreateNewWorld(_dungeonGenerator.Random, ResourcePath.scene_Dungeon_tscn);
+ dungeon.DungeonConfig = _dungeonGenerator.Config;
+ dungeon.RoomGroup = _dungeonGenerator.RoomGroup;
dungeon.InitLayer();
//初始化房间 World 字段
foreach (var roomInfo in _dungeonGenerator.RoomInfos)
@@ -474,9 +486,20 @@
yield return 0;
//初始化所有房间
yield return _dungeonGenerator.EachRoomCoroutine(InitRoom);
+
+ Debug.Log("[临时处理]: 关闭房间迷雾");
+ CurrWorld.FogMaskRoot.Visible = false;
+ //房间背景颜色
+ RenderingServer.SetDefaultClearColor(_dungeonGenerator.RoomGroup.BgColor);
+
//播放bgm
- //SoundManager.PlayMusic(ResourcePath.resource_sound_bgm_Intro_ogg, -17f);
+ if (!string.IsNullOrEmpty(_dungeonGenerator.RoomGroup.SoundId) && ExcelConfig.Sound_Map.ContainsKey(_dungeonGenerator.RoomGroup.SoundId))
+ {
+ CurrWorld.PlayBgm(_dungeonGenerator.RoomGroup.SoundId);
+ }
+
+ GameCamera.Main.FollowsMouseAmount = 0.15f;
//地牢加载即将完成
yield return _dungeonGenerator.EachRoomCoroutine(info => info.OnReady());
@@ -485,14 +508,18 @@
UiManager.Open_RoomUI();
yield return 0;
+ //创建自定义物体
+ _dungeonGenerator.EachRoom(OnInitCustomObject);
+ yield return 0;
+
//初始房间创建玩家标记
var playerBirthMark = StartRoomInfo.RoomPreinstall.GetSpecialMark(SpecialMarkType.BirthPoint);
//创建玩家
- var player = CurrWorld.Player;
+ var player = CurrWorld.Player ?? _cachePlayer;
if (player == null)
{
- player = ActivityObject.Create(ActivityObject.Ids.Id_role0001);
+ player = ActivityObject.Create(LoadRoleId);
player.Name = "Player";
}
if (playerBirthMark != null)
@@ -500,6 +527,8 @@
player.Position = playerBirthMark.Position;
}
+ _cachePlayer = null;
+
player.World = CurrWorld;
player.PutDown(RoomLayerEnum.YSortLayer);
CurrWorld.SetCurrentPlayer(player);
@@ -507,6 +536,7 @@
yield return 0;
player.Collision.Disabled = false;
+ GameCamera.Main.Zoom = Vector2.One;
GameApplication.Instance.Cursor.SetGuiMode(false);
//派发进入地牢事件
EventManager.EmitEvent(EventEnum.OnEnterDungeon);
@@ -514,6 +544,8 @@
IsInDungeon = true;
QueueRedraw();
yield return 0;
+
+ CurrWorld.OnLoadSuccess();
if (finish != null)
{
finish();
@@ -537,6 +569,11 @@
if (!keepPlayer)
{
CurrWorld.SetCurrentPlayer(null);
+ if (_cachePlayer != null)
+ {
+ _cachePlayer.Destroy();
+ _cachePlayer = null;
+ }
}
else
{
@@ -545,10 +582,17 @@
player.GetParent().RemoveChild(player);
player.World = null;
player.Collision.Disabled = true;
+ _cachePlayer = player;
}
+ yield return 0;
+
+ CurrWorld.OnUnloadSuccess();
DestroyWorld();
yield return 0;
+ //还原房间背景颜色
+ RenderingServer.SetDefaultClearColor(Colors.Black);
+
FogMaskHandler.ClearRecordRoom();
LiquidBrushManager.ClearData();
BrushImageData.ClearBrushData();
@@ -564,6 +608,50 @@
}
}
+ //初始化自定义物体
+ private void OnInitCustomObject(RoomInfo info)
+ {
+ var tileInfo = info.RoomSplit.TileInfo;
+ if (tileInfo.NormalLayerObjects != null)
+ {
+ foreach (var objectInfo in tileInfo.NormalLayerObjects)
+ {
+ CreateCustomObject(info, objectInfo, RoomLayerEnum.NormalLayer);
+ }
+ }
+
+ if (tileInfo.YSortLayerObjects != null)
+ {
+ foreach (var objectInfo in tileInfo.YSortLayerObjects)
+ {
+ CreateCustomObject(info, objectInfo, RoomLayerEnum.YSortLayer);
+ }
+ }
+ }
+
+ private void CreateCustomObject(RoomInfo roomInfo, RoomObjectInfo info, RoomLayerEnum layer)
+ {
+ if (ExcelConfig.EditorObject_Map.TryGetValue(info.Id, out var editorObject))
+ {
+ if (editorObject.IsActivity())
+ {
+ var activityObject = ActivityObject.Create(editorObject.Prefab);
+ activityObject.Position = roomInfo.ToGlobalPosition(new Vector2(info.X, info.Y));
+ activityObject.PutDown(layer);
+ }
+ else
+ {
+ var node = ResourceManager.LoadAndInstantiate(editorObject.Prefab);
+ node.Position = roomInfo.ToGlobalPosition(new Vector2(info.X, info.Y));
+ node.AddToActivityRoot(layer);
+ }
+ }
+ else
+ {
+ Debug.LogError($"创建CustomObject没有找到物体配置: {info.Id}!");
+ }
+ }
+
// 初始化房间
private void InitRoom(RoomInfo roomInfo)
{
@@ -852,6 +940,7 @@
///
private void OnPlayerFirstEnterRoom(object o)
{
+ _checkEnemyTimer = 0;
var room = (RoomInfo)o;
room.OnFirstEnter();
//如果关门了, 那么房间外的敌人就会丢失目标
diff --git a/DungeonShooting_Godot/src/game/room/RoomDoor.cs b/DungeonShooting_Godot/src/game/room/RoomDoor.cs
index 6054f80..8921af4 100644
--- a/DungeonShooting_Godot/src/game/room/RoomDoor.cs
+++ b/DungeonShooting_Godot/src/game/room/RoomDoor.cs
@@ -7,106 +7,106 @@
[Tool]
public partial class RoomDoor : ActivityObject
{
- ///
- /// 门的方向
- ///
- public DoorDirection Direction => _door.Direction;
-
- ///
- /// 门是否关闭
- ///
- public bool IsClose { get; private set; }
-
- private RoomDoorInfo _door;
- private bool waitDisabledCollision = false;
- private AnimatedSprite2D _animatedDown;
+ ///
+ /// 门的方向
+ ///
+ public DoorDirection Direction => _door.Direction;
+
+ ///
+ /// 门是否关闭
+ ///
+ public bool IsClose { get; private set; }
+
+ private RoomDoorInfo _door;
+ private bool waitDisabledCollision = false;
+ private AnimatedSprite2D _animatedDown;
- public override void OnInit()
- {
- AnimatedSprite.AnimationFinished += OnAnimationFinished;
- }
+ public override void OnInit()
+ {
+ AnimatedSprite.AnimationFinished += OnAnimationFinished;
+ }
- ///
- /// 初始化调用
- ///
- public void Init(RoomDoorInfo doorInfo)
- {
- _door = doorInfo;
- IsClose = false;
- if (doorInfo.Direction == DoorDirection.E || doorInfo.Direction == DoorDirection.W)
- {
- _animatedDown = GetNode("AnimatedSpriteDown");
- }
+ ///
+ /// 初始化调用
+ ///
+ public void Init(RoomDoorInfo doorInfo)
+ {
+ _door = doorInfo;
+ IsClose = false;
+ if (doorInfo.Direction == DoorDirection.E || doorInfo.Direction == DoorDirection.W)
+ {
+ _animatedDown = GetNode("AnimatedSpriteDown");
+ }
- OpenDoorHandler();
- }
+ OpenDoorHandler();
+ }
- ///
- /// 打开当前的门
- ///
- public void OpenDoor()
- {
- IsClose = false;
- //Visible = false;
- waitDisabledCollision = true;
- if (AnimatedSprite.SpriteFrames.HasAnimation(AnimatorNames.OpenDoor))
- {
- AnimatedSprite.Play(AnimatorNames.OpenDoor);
- }
+ ///
+ /// 打开当前的门
+ ///
+ public void OpenDoor()
+ {
+ IsClose = false;
+ //Visible = false;
+ waitDisabledCollision = true;
+ if (AnimatedSprite.SpriteFrames.HasAnimation(AnimatorNames.OpenDoor))
+ {
+ AnimatedSprite.Play(AnimatorNames.OpenDoor);
+ }
- if (_animatedDown != null && _animatedDown.SpriteFrames.HasAnimation(AnimatorNames.OpenDoor))
- {
- _animatedDown.Play(AnimatorNames.OpenDoor);
- }
- }
+ if (_animatedDown != null && _animatedDown.SpriteFrames.HasAnimation(AnimatorNames.OpenDoor))
+ {
+ _animatedDown.Play(AnimatorNames.OpenDoor);
+ }
+ }
- ///
- /// 关闭当前的门
- ///
- public void CloseDoor()
- {
- IsClose = true;
- //Visible = true;
- Collision.Disabled = false;
+ ///
+ /// 关闭当前的门
+ ///
+ public void CloseDoor()
+ {
+ IsClose = true;
+ //Visible = true;
+ Collision.Disabled = false;
- if (AnimatedSprite.SpriteFrames.HasAnimation(AnimatorNames.CloseDoor))
- {
- AnimatedSprite.Play(AnimatorNames.CloseDoor);
- }
+ if (AnimatedSprite.SpriteFrames.HasAnimation(AnimatorNames.CloseDoor))
+ {
+ AnimatedSprite.Play(AnimatorNames.CloseDoor);
+ }
- if (_animatedDown != null)
- {
- _animatedDown.Visible = false;
- }
+ if (_animatedDown != null)
+ {
+ _animatedDown.Visible = false;
+ }
- if (Direction == DoorDirection.E || Direction == DoorDirection.W)
- {
- ZIndex = MapLayer.CustomMiddleLayer2;
- }
- }
+ if (Direction == DoorDirection.E || Direction == DoorDirection.W)
+ {
+ ZIndex = MapLayer.CustomMiddleLayer2;
+ }
+ }
- private void OnAnimationFinished()
- {
- if (!IsClose && waitDisabledCollision) //开门动画播放完成
- {
- waitDisabledCollision = false;
- if (_animatedDown != null)
- {
- _animatedDown.Visible = true;
- }
+ private void OnAnimationFinished()
+ {
+ if (!IsClose && waitDisabledCollision) //开门动画播放完成
+ {
+ waitDisabledCollision = false;
+ if (_animatedDown != null)
+ {
+ _animatedDown.Visible = true;
+ }
- if (Direction == DoorDirection.E || Direction == DoorDirection.W)
- {
- ZIndex = 0;
- }
- OpenDoorHandler();
- }
- }
+ if (Direction == DoorDirection.E || Direction == DoorDirection.W)
+ {
+ ZIndex = 0;
+ }
+ OpenDoorHandler();
+ }
+ }
- private void OpenDoorHandler()
- {
- Collision.Disabled = true;
- //调整门的层级
- //ZIndex = MapLayer.AutoFloorLayer;
- }
+ private void OpenDoorHandler()
+ {
+ Collision.Disabled = true;
+ //调整门的层级
+ //ZIndex = MapLayer.AutoFloorLayer;
+ }
}
diff --git a/DungeonShooting_Godot/src/game/room/RoomExit.cs b/DungeonShooting_Godot/src/game/room/RoomExit.cs
new file mode 100644
index 0000000..d91a995
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/room/RoomExit.cs
@@ -0,0 +1,60 @@
+
+using Godot;
+
+///
+/// 地牢房间出口
+///
+public partial class RoomExit : Area2D
+{
+ public override void _Ready()
+ {
+ BodyEntered += OnBodyEntered;
+ }
+
+ private void OnBodyEntered(Node body)
+ {
+ if (body is Role role)
+ {
+ //Debug.Log("::RoomExit::OnBodyEntered");
+ var gameApplication = GameApplication.Instance;
+
+ if (gameApplication.DungeonManager.IsEditorMode) //编辑器模式下下一层就是当前层, 相当于重新开始
+ {
+ EditorPlayManager.Restart();
+ }
+ else
+ {
+ var nextName = gameApplication.GetNextDungeonGroup(gameApplication.DungeonManager.CurrConfig.GroupName);
+ if (string.IsNullOrEmpty(nextName)) //没有下一层, 表示已经通关
+ {
+ World.Current.Pause = true;
+ var openVictory = UiManager.Open_Victory();
+ openVictory.Callback = () =>
+ {
+ //先直接返回大厅, 后面再补充流程
+ UiManager.Open_Loading();
+ GameApplication.Instance.DungeonManager.LoadRoleId = ActivityObject.Ids.Id_role0001;
+ GameApplication.Instance.DungeonManager.ExitDungeon(false, () =>
+ {
+ GameApplication.Instance.DungeonManager.LoadHall(() =>
+ {
+ World.Current.Pause = false;
+ UiManager.Destroy_Loading();
+ });
+ });
+ };
+ }
+ else //有下一层
+ {
+ var config = gameApplication.GetDungeonConfig(nextName, gameApplication.DungeonManager.CurrConfig.DungeonLayer + 1);
+
+ UiManager.Open_Loading();
+ GameApplication.Instance.DungeonManager.RestartDungeon(true, config, () =>
+ {
+ UiManager.Destroy_Loading();
+ });
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/room/SceneManager.cs b/DungeonShooting_Godot/src/game/room/SceneManager.cs
index e8f359c..7454070 100644
--- a/DungeonShooting_Godot/src/game/room/SceneManager.cs
+++ b/DungeonShooting_Godot/src/game/room/SceneManager.cs
@@ -6,14 +6,14 @@
///
public static class SceneManager
{
-
- ///
- /// 加载场景
- ///
- /// 场景路径
- public static void LoadScene(string path)
- {
- //var packedScene = ResourceManager.Load(ResourcePath.scene_Room_tscn).Instantiate();
- //SceneRoot.AddChild(RoomManager);
- }
+
+ ///
+ /// 加载场景
+ ///
+ /// 场景路径
+ public static void LoadScene(string path)
+ {
+ //var packedScene = ResourceManager.Load(ResourcePath.scene_Room_tscn).Instantiate();
+ //SceneRoot.AddChild(RoomManager);
+ }
}
diff --git a/DungeonShooting_Godot/src/game/ui/pauseMenu/PauseMenuPanel.cs b/DungeonShooting_Godot/src/game/ui/pauseMenu/PauseMenuPanel.cs
index 12750a2..ddf6482 100644
--- a/DungeonShooting_Godot/src/game/ui/pauseMenu/PauseMenuPanel.cs
+++ b/DungeonShooting_Godot/src/game/ui/pauseMenu/PauseMenuPanel.cs
@@ -76,7 +76,7 @@
else //正常重新开始
{
UiManager.Open_Loading();
- GameApplication.Instance.DungeonManager.RestartDungeon(false, GameApplication.Instance.DungeonConfig, () =>
+ GameApplication.Instance.DungeonManager.RestartDungeon(false, GameApplication.Instance.FirstDungeonConfig, () =>
{
UiManager.Destroy_Loading();
});
diff --git a/DungeonShooting_Godot/src/game/ui/roomUI/InteractiveTipBarHandler.cs b/DungeonShooting_Godot/src/game/ui/roomUI/InteractiveTipBarHandler.cs
index 6f175e9..e585e88 100644
--- a/DungeonShooting_Godot/src/game/ui/roomUI/InteractiveTipBarHandler.cs
+++ b/DungeonShooting_Godot/src/game/ui/roomUI/InteractiveTipBarHandler.cs
@@ -63,18 +63,20 @@
else
{
var result = (CheckInteractiveResult)o;
- var interactiveItem = World.Current.Player.InteractiveItem;
- //if (interactiveItem is Weapon)
- var icon = result.GetIcon();
- if (icon != null)
+ if (result.Target is ActivityObject interactiveItem)
{
- _interactiveTarget = interactiveItem;
- //显示互动提示
- ShowBar(result.Target, result.Target.ActivityBase.Name, icon);
- }
- else
- {
- _interactiveTarget = null;
+ //if (interactiveItem is Weapon)
+ var icon = result.GetIcon();
+ if (icon != null)
+ {
+ _interactiveTarget = interactiveItem;
+ //显示互动提示
+ ShowBar(interactiveItem, interactiveItem.ActivityBase.Name, icon);
+ }
+ else
+ {
+ _interactiveTarget = null;
+ }
}
}
}
diff --git a/DungeonShooting_Godot/src/game/ui/roomUI/LifeBarHandler.cs b/DungeonShooting_Godot/src/game/ui/roomUI/LifeBarHandler.cs
index 00f0fd2..9e3cf79 100644
--- a/DungeonShooting_Godot/src/game/ui/roomUI/LifeBarHandler.cs
+++ b/DungeonShooting_Godot/src/game/ui/roomUI/LifeBarHandler.cs
@@ -12,6 +12,7 @@
private bool _refreshHpFlag = false;
private bool _refreshGoldFlag = false;
+ private Role _player;
public LifeBarHandler(RoomUI.LifeBar lifeBar)
{
_bar = lifeBar;
@@ -42,6 +43,12 @@
public void Process(float delta)
{
+ if (!_refreshGoldFlag && World.Current != null && _player != World.Current.Player)
+ {
+ _player = World.Current.Player;
+ _refreshHpFlag = true;
+ }
+
if (_refreshHpFlag)
{
_refreshHpFlag = false;
@@ -68,6 +75,10 @@
private void HandlerRefreshLife()
{
var player = World.Current.Player;
+ if (player == null)
+ {
+ return;
+ }
if (player.MaxHp % 2 != 0)
{
Debug.LogError("玩家血量不是偶数!");
@@ -108,7 +119,13 @@
private void HandlerRefreshGold()
{
- _bar.L_Gold.L_GoldText.Instance.Text = World.Current.Player.RoleState.Gold.ToString();
+ var player = World.Current.Player;
+ if (player == null)
+ {
+ return;
+ }
+
+ _bar.L_Gold.L_GoldText.Instance.Text = player.RoleState.Gold.ToString();
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/ui/setting/Setting.cs b/DungeonShooting_Godot/src/game/ui/setting/Setting.cs
index 141775f..6d2618f 100644
--- a/DungeonShooting_Godot/src/game/ui/setting/Setting.cs
+++ b/DungeonShooting_Godot/src/game/ui/setting/Setting.cs
@@ -19,30 +19,17 @@
private ColorRect _L_ColorRect;
///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.Back
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.TextureRect
///
- public Back L_Back
+ public TextureRect L_TextureRect
{
get
{
- if (_L_Back == null) _L_Back = new Back((SettingPanel)this, GetNode("Back"));
- return _L_Back;
+ if (_L_TextureRect == null) _L_TextureRect = new TextureRect((SettingPanel)this, GetNode("TextureRect"));
+ return _L_TextureRect;
}
}
- private Back _L_Back;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.Title
- ///
- public Title L_Title
- {
- get
- {
- if (_L_Title == null) _L_Title = new Title((SettingPanel)this, GetNode("Title"));
- return _L_Title;
- }
- }
- private Title _L_Title;
+ private TextureRect _L_TextureRect;
///
/// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer
@@ -77,16 +64,16 @@
}
///
- /// 类型: , 路径: Setting.Back
+ /// 类型: , 路径: Setting.TextureRect
///
- public class Back : UiNode
+ public class TextureRect : UiNode
{
- public Back(SettingPanel uiPanel, Godot.Button node) : base(uiPanel, node) { }
- public override Back Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate());
+ public TextureRect(SettingPanel uiPanel, Godot.TextureRect node) : base(uiPanel, node) { }
+ public override TextureRect Clone() => new (UiPanel, (Godot.TextureRect)Instance.Duplicate());
}
///
- /// 类型: , 路径: Setting.Title
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.Title
///
public class Title : UiNode
{
@@ -95,60 +82,7 @@
}
///
- /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.VideoItem
- ///
- public class VideoItem : UiNode
- {
- public VideoItem(SettingPanel uiPanel, Godot.Button node) : base(uiPanel, node) { }
- public override VideoItem Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.InputItem
- ///
- public class InputItem : UiNode
- {
- public InputItem(SettingPanel uiPanel, Godot.Button node) : base(uiPanel, node) { }
- public override InputItem Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.SettingMenu
- ///
- public class SettingMenu : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.VideoItem
- ///
- public VideoItem L_VideoItem
- {
- get
- {
- if (_L_VideoItem == null) _L_VideoItem = new VideoItem(UiPanel, Instance.GetNode("VideoItem"));
- return _L_VideoItem;
- }
- }
- private VideoItem _L_VideoItem;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.InputItem
- ///
- public InputItem L_InputItem
- {
- get
- {
- if (_L_InputItem == null) _L_InputItem = new InputItem(UiPanel, Instance.GetNode("InputItem"));
- return _L_InputItem;
- }
- }
- private InputItem _L_InputItem;
-
- public SettingMenu(SettingPanel uiPanel, Godot.VBoxContainer node) : base(uiPanel, node) { }
- public override SettingMenu Clone() => new (UiPanel, (Godot.VBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.VideoSetting.FullScreen.Name
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.FullScreen.Name
///
public class Name : UiNode
{
@@ -157,7 +91,7 @@
}
///
- /// 类型: , 路径: Setting.ScrollContainer.VideoSetting.FullScreen.CheckBox
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.FullScreen.CheckBox
///
public class CheckBox : UiNode
{
@@ -166,12 +100,12 @@
}
///
- /// 类型: , 路径: Setting.ScrollContainer.VideoSetting.FullScreen
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.FullScreen
///
public class FullScreen : UiNode
{
///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.VideoSetting.Name
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.Name
///
public Name L_Name
{
@@ -184,7 +118,7 @@
private Name _L_Name;
///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.VideoSetting.CheckBox
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.CheckBox
///
public CheckBox L_CheckBox
{
@@ -201,19 +135,138 @@
}
///
- /// 类型: , 路径: Setting.ScrollContainer.VideoSetting.Back
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.FullScreen2.Label
///
- public class Back_1 : UiNode
+ public class Label : UiNode
{
- public Back_1(SettingPanel uiPanel, Godot.Button node) : base(uiPanel, node) { }
- public override Back_1 Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate());
+ public Label(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
+ public override Label Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
}
///
- /// 类型: , 路径: Setting.ScrollContainer.VideoSetting
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.FullScreen2.BGM
///
- public class VideoSetting : UiNode
+ public class BGM : UiNode
{
+ public BGM(SettingPanel uiPanel, Godot.HSlider node) : base(uiPanel, node) { }
+ public override BGM Clone() => new (UiPanel, (Godot.HSlider)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.FullScreen2
+ ///
+ public class FullScreen2 : UiNode
+ {
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.Label
+ ///
+ public Label L_Label
+ {
+ get
+ {
+ if (_L_Label == null) _L_Label = new Label(UiPanel, Instance.GetNode("Label"));
+ return _L_Label;
+ }
+ }
+ private Label _L_Label;
+
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.BGM
+ ///
+ public BGM L_BGM
+ {
+ get
+ {
+ if (_L_BGM == null) _L_BGM = new BGM(UiPanel, Instance.GetNode("BGM"));
+ return _L_BGM;
+ }
+ }
+ private BGM _L_BGM;
+
+ public FullScreen2(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
+ public override FullScreen2 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.FullScreen3.Label
+ ///
+ public class Label_1 : UiNode
+ {
+ public Label_1(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
+ public override Label_1 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.FullScreen3.SFX
+ ///
+ public class SFX : UiNode
+ {
+ public SFX(SettingPanel uiPanel, Godot.HSlider node) : base(uiPanel, node) { }
+ public override SFX Clone() => new (UiPanel, (Godot.HSlider)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.FullScreen3
+ ///
+ public class FullScreen3 : UiNode
+ {
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.Label
+ ///
+ public Label_1 L_Label
+ {
+ get
+ {
+ if (_L_Label == null) _L_Label = new Label_1(UiPanel, Instance.GetNode("Label"));
+ return _L_Label;
+ }
+ }
+ private Label_1 _L_Label;
+
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.SFX
+ ///
+ public SFX L_SFX
+ {
+ get
+ {
+ if (_L_SFX == null) _L_SFX = new SFX(UiPanel, Instance.GetNode("SFX"));
+ return _L_SFX;
+ }
+ }
+ private SFX _L_SFX;
+
+ public FullScreen3(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
+ public override FullScreen3 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu.Back
+ ///
+ public class Back : UiNode
+ {
+ public Back(SettingPanel uiPanel, Godot.Button node) : base(uiPanel, node) { }
+ public override Back Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: Setting.ScrollContainer.SettingMenu
+ ///
+ public class SettingMenu : UiNode
+ {
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Title
+ ///
+ public Title L_Title
+ {
+ get
+ {
+ if (_L_Title == null) _L_Title = new Title(UiPanel, Instance.GetNode("Title"));
+ return _L_Title;
+ }
+ }
+ private Title _L_Title;
+
///
/// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.FullScreen
///
@@ -228,997 +281,46 @@
private FullScreen _L_FullScreen;
///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Back
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.FullScreen2
///
- public Back_1 L_Back
+ public FullScreen2 L_FullScreen2
{
get
{
- if (_L_Back == null) _L_Back = new Back_1(UiPanel, Instance.GetNode("Back"));
- return _L_Back;
+ if (_L_FullScreen2 == null) _L_FullScreen2 = new FullScreen2(UiPanel, Instance.GetNode("FullScreen2"));
+ return _L_FullScreen2;
}
}
- private Back_1 _L_Back;
-
- public VideoSetting(SettingPanel uiPanel, Godot.VBoxContainer node) : base(uiPanel, node) { }
- public override VideoSetting Clone() => new (UiPanel, (Godot.VBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Tip
- ///
- public class Tip : UiNode
- {
- public Tip(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Tip Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key.Name
- ///
- public class Name_1 : UiNode
- {
- public Name_1(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_1 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key.Value
- ///
- public class Value : UiNode
- {
- public Value(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key
- ///
- public class Key : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_1 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_1(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_1 _L_Name;
+ private FullScreen2 _L_FullScreen2;
///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.FullScreen3
///
- public Value L_Value
+ public FullScreen3 L_FullScreen3
{
get
{
- if (_L_Value == null) _L_Value = new Value(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
+ if (_L_FullScreen3 == null) _L_FullScreen3 = new FullScreen3(UiPanel, Instance.GetNode("FullScreen3"));
+ return _L_FullScreen3;
}
}
- private Value _L_Value;
-
- public Key(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key2.Name
- ///
- public class Name_2 : UiNode
- {
- public Name_2(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_2 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key2.Value
- ///
- public class Value_1 : UiNode
- {
- public Value_1(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_1 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key2
- ///
- public class Key2 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_2 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_2(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_2 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_1 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_1(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_1 _L_Value;
-
- public Key2(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key2 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key3.Name
- ///
- public class Name_3 : UiNode
- {
- public Name_3(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_3 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key3.Value
- ///
- public class Value_2 : UiNode
- {
- public Value_2(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_2 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key3
- ///
- public class Key3 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_3 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_3(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_3 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_2 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_2(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_2 _L_Value;
-
- public Key3(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key3 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key4.Name
- ///
- public class Name_4 : UiNode
- {
- public Name_4(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_4 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key4.Value
- ///
- public class Value_3 : UiNode
- {
- public Value_3(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_3 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key4
- ///
- public class Key4 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_4 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_4(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_4 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_3 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_3(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_3 _L_Value;
-
- public Key4(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key4 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key5.Name
- ///
- public class Name_5 : UiNode
- {
- public Name_5(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_5 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key5.Value
- ///
- public class Value_4 : UiNode
- {
- public Value_4(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_4 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key5
- ///
- public class Key5 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_5 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_5(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_5 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_4 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_4(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_4 _L_Value;
-
- public Key5(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key5 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key6.Name
- ///
- public class Name_6 : UiNode
- {
- public Name_6(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_6 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key6.Value
- ///
- public class Value_5 : UiNode
- {
- public Value_5(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_5 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key6
- ///
- public class Key6 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_6 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_6(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_6 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_5 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_5(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_5 _L_Value;
-
- public Key6(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key6 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key7.Name
- ///
- public class Name_7 : UiNode
- {
- public Name_7(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_7 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key7.Value
- ///
- public class Value_6 : UiNode
- {
- public Value_6(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_6 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key7
- ///
- public class Key7 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_7 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_7(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_7 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_6 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_6(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_6 _L_Value;
-
- public Key7(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key7 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key8.Name
- ///
- public class Name_8 : UiNode
- {
- public Name_8(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_8 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key8.Value
- ///
- public class Value_7 : UiNode
- {
- public Value_7(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_7 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key8
- ///
- public class Key8 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_8 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_8(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_8 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_7 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_7(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_7 _L_Value;
-
- public Key8(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key8 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key11.Name
- ///
- public class Name_9 : UiNode
- {
- public Name_9(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_9 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key11.Value
- ///
- public class Value_8 : UiNode
- {
- public Value_8(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_8 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key11
- ///
- public class Key11 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_9 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_9(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_9 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_8 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_8(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_8 _L_Value;
-
- public Key11(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key11 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key9.Name
- ///
- public class Name_10 : UiNode
- {
- public Name_10(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_10 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key9.Value
- ///
- public class Value_9 : UiNode
- {
- public Value_9(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_9 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key9
- ///
- public class Key9 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_10 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_10(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_10 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_9 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_9(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_9 _L_Value;
-
- public Key9(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key9 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key10.Name
- ///
- public class Name_11 : UiNode
- {
- public Name_11(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_11 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key10.Value
- ///
- public class Value_10 : UiNode
- {
- public Value_10(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_10 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key10
- ///
- public class Key10 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_11 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_11(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_11 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_10 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_10(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_10 _L_Value;
-
- public Key10(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key10 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key12.Name
- ///
- public class Name_12 : UiNode
- {
- public Name_12(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_12 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key12.Value
- ///
- public class Value_11 : UiNode
- {
- public Value_11(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_11 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key12
- ///
- public class Key12 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_12 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_12(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_12 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_11 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_11(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_11 _L_Value;
-
- public Key12(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key12 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key13.Name
- ///
- public class Name_13 : UiNode
- {
- public Name_13(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_13 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key13.Value
- ///
- public class Value_12 : UiNode
- {
- public Value_12(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_12 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key13
- ///
- public class Key13 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_13 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_13(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_13 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_12 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_12(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_12 _L_Value;
-
- public Key13(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key13 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key14.Name
- ///
- public class Name_14 : UiNode
- {
- public Name_14(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Name_14 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key14.Value
- ///
- public class Value_13 : UiNode
- {
- public Value_13(SettingPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Value_13 Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Key14
- ///
- public class Key14 : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Name
- ///
- public Name_14 L_Name
- {
- get
- {
- if (_L_Name == null) _L_Name = new Name_14(UiPanel, Instance.GetNode("Name"));
- return _L_Name;
- }
- }
- private Name_14 _L_Name;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Value
- ///
- public Value_13 L_Value
- {
- get
- {
- if (_L_Value == null) _L_Value = new Value_13(UiPanel, Instance.GetNode("Value"));
- return _L_Value;
- }
- }
- private Value_13 _L_Value;
-
- public Key14(SettingPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
- public override Key14 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting.Back
- ///
- public class Back_2 : UiNode
- {
- public Back_2(SettingPanel uiPanel, Godot.Button node) : base(uiPanel, node) { }
- public override Back_2 Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate());
- }
-
- ///
- /// 类型: , 路径: Setting.ScrollContainer.KeySetting
- ///
- public class KeySetting : UiNode
- {
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Tip
- ///
- public Tip L_Tip
- {
- get
- {
- if (_L_Tip == null) _L_Tip = new Tip(UiPanel, Instance.GetNode("Tip"));
- return _L_Tip;
- }
- }
- private Tip _L_Tip;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key
- ///
- public Key L_Key
- {
- get
- {
- if (_L_Key == null) _L_Key = new Key(UiPanel, Instance.GetNode("Key"));
- return _L_Key;
- }
- }
- private Key _L_Key;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key2
- ///
- public Key2 L_Key2
- {
- get
- {
- if (_L_Key2 == null) _L_Key2 = new Key2(UiPanel, Instance.GetNode("Key2"));
- return _L_Key2;
- }
- }
- private Key2 _L_Key2;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key3
- ///
- public Key3 L_Key3
- {
- get
- {
- if (_L_Key3 == null) _L_Key3 = new Key3(UiPanel, Instance.GetNode("Key3"));
- return _L_Key3;
- }
- }
- private Key3 _L_Key3;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key4
- ///
- public Key4 L_Key4
- {
- get
- {
- if (_L_Key4 == null) _L_Key4 = new Key4(UiPanel, Instance.GetNode("Key4"));
- return _L_Key4;
- }
- }
- private Key4 _L_Key4;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key5
- ///
- public Key5 L_Key5
- {
- get
- {
- if (_L_Key5 == null) _L_Key5 = new Key5(UiPanel, Instance.GetNode("Key5"));
- return _L_Key5;
- }
- }
- private Key5 _L_Key5;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key6
- ///
- public Key6 L_Key6
- {
- get
- {
- if (_L_Key6 == null) _L_Key6 = new Key6(UiPanel, Instance.GetNode("Key6"));
- return _L_Key6;
- }
- }
- private Key6 _L_Key6;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key7
- ///
- public Key7 L_Key7
- {
- get
- {
- if (_L_Key7 == null) _L_Key7 = new Key7(UiPanel, Instance.GetNode("Key7"));
- return _L_Key7;
- }
- }
- private Key7 _L_Key7;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key8
- ///
- public Key8 L_Key8
- {
- get
- {
- if (_L_Key8 == null) _L_Key8 = new Key8(UiPanel, Instance.GetNode("Key8"));
- return _L_Key8;
- }
- }
- private Key8 _L_Key8;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key11
- ///
- public Key11 L_Key11
- {
- get
- {
- if (_L_Key11 == null) _L_Key11 = new Key11(UiPanel, Instance.GetNode("Key11"));
- return _L_Key11;
- }
- }
- private Key11 _L_Key11;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key9
- ///
- public Key9 L_Key9
- {
- get
- {
- if (_L_Key9 == null) _L_Key9 = new Key9(UiPanel, Instance.GetNode("Key9"));
- return _L_Key9;
- }
- }
- private Key9 _L_Key9;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key10
- ///
- public Key10 L_Key10
- {
- get
- {
- if (_L_Key10 == null) _L_Key10 = new Key10(UiPanel, Instance.GetNode("Key10"));
- return _L_Key10;
- }
- }
- private Key10 _L_Key10;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key12
- ///
- public Key12 L_Key12
- {
- get
- {
- if (_L_Key12 == null) _L_Key12 = new Key12(UiPanel, Instance.GetNode("Key12"));
- return _L_Key12;
- }
- }
- private Key12 _L_Key12;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key13
- ///
- public Key13 L_Key13
- {
- get
- {
- if (_L_Key13 == null) _L_Key13 = new Key13(UiPanel, Instance.GetNode("Key13"));
- return _L_Key13;
- }
- }
- private Key13 _L_Key13;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Key14
- ///
- public Key14 L_Key14
- {
- get
- {
- if (_L_Key14 == null) _L_Key14 = new Key14(UiPanel, Instance.GetNode("Key14"));
- return _L_Key14;
- }
- }
- private Key14 _L_Key14;
+ private FullScreen3 _L_FullScreen3;
///
/// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.ScrollContainer.Back
///
- public Back_2 L_Back
+ public Back L_Back
{
get
{
- if (_L_Back == null) _L_Back = new Back_2(UiPanel, Instance.GetNode("Back"));
+ if (_L_Back == null) _L_Back = new Back(UiPanel, Instance.GetNode("Back"));
return _L_Back;
}
}
- private Back_2 _L_Back;
+ private Back _L_Back;
- public KeySetting(SettingPanel uiPanel, Godot.VBoxContainer node) : base(uiPanel, node) { }
- public override KeySetting Clone() => new (UiPanel, (Godot.VBoxContainer)Instance.Duplicate());
+ public SettingMenu(SettingPanel uiPanel, Godot.VBoxContainer node) : base(uiPanel, node) { }
+ public override SettingMenu Clone() => new (UiPanel, (Godot.VBoxContainer)Instance.Duplicate());
}
///
@@ -1239,32 +341,6 @@
}
private SettingMenu _L_SettingMenu;
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.VideoSetting
- ///
- public VideoSetting L_VideoSetting
- {
- get
- {
- if (_L_VideoSetting == null) _L_VideoSetting = new VideoSetting(UiPanel, Instance.GetNode("VideoSetting"));
- return _L_VideoSetting;
- }
- }
- private VideoSetting _L_VideoSetting;
-
- ///
- /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Setting.KeySetting
- ///
- public KeySetting L_KeySetting
- {
- get
- {
- if (_L_KeySetting == null) _L_KeySetting = new KeySetting(UiPanel, Instance.GetNode("KeySetting"));
- return _L_KeySetting;
- }
- }
- private KeySetting _L_KeySetting;
-
public ScrollContainer(SettingPanel uiPanel, Godot.ScrollContainer node) : base(uiPanel, node) { }
public override ScrollContainer Clone() => new (UiPanel, (Godot.ScrollContainer)Instance.Duplicate());
}
@@ -1276,19 +352,54 @@
public ColorRect S_ColorRect => L_ColorRect;
///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.Title
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.TextureRect
///
- public Title S_Title => L_Title;
+ public TextureRect S_TextureRect => L_TextureRect;
///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.VideoItem
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.Title
///
- public VideoItem S_VideoItem => L_ScrollContainer.L_SettingMenu.L_VideoItem;
+ public Title S_Title => L_ScrollContainer.L_SettingMenu.L_Title;
///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.InputItem
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.FullScreen.Name
///
- public InputItem S_InputItem => L_ScrollContainer.L_SettingMenu.L_InputItem;
+ public Name S_Name => L_ScrollContainer.L_SettingMenu.L_FullScreen.L_Name;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.FullScreen.CheckBox
+ ///
+ public CheckBox S_CheckBox => L_ScrollContainer.L_SettingMenu.L_FullScreen.L_CheckBox;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.FullScreen
+ ///
+ public FullScreen S_FullScreen => L_ScrollContainer.L_SettingMenu.L_FullScreen;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.FullScreen2.BGM
+ ///
+ public BGM S_BGM => L_ScrollContainer.L_SettingMenu.L_FullScreen2.L_BGM;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.FullScreen2
+ ///
+ public FullScreen2 S_FullScreen2 => L_ScrollContainer.L_SettingMenu.L_FullScreen2;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.FullScreen3.SFX
+ ///
+ public SFX S_SFX => L_ScrollContainer.L_SettingMenu.L_FullScreen3.L_SFX;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.FullScreen3
+ ///
+ public FullScreen3 S_FullScreen3 => L_ScrollContainer.L_SettingMenu.L_FullScreen3;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu.Back
+ ///
+ public Back S_Back => L_ScrollContainer.L_SettingMenu.L_Back;
///
/// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.SettingMenu
@@ -1296,101 +407,6 @@
public SettingMenu S_SettingMenu => L_ScrollContainer.L_SettingMenu;
///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.VideoSetting.FullScreen.CheckBox
- ///
- public CheckBox S_CheckBox => L_ScrollContainer.L_VideoSetting.L_FullScreen.L_CheckBox;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.VideoSetting.FullScreen
- ///
- public FullScreen S_FullScreen => L_ScrollContainer.L_VideoSetting.L_FullScreen;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.VideoSetting
- ///
- public VideoSetting S_VideoSetting => L_ScrollContainer.L_VideoSetting;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Tip
- ///
- public Tip S_Tip => L_ScrollContainer.L_KeySetting.L_Tip;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key
- ///
- public Key S_Key => L_ScrollContainer.L_KeySetting.L_Key;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key2
- ///
- public Key2 S_Key2 => L_ScrollContainer.L_KeySetting.L_Key2;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key3
- ///
- public Key3 S_Key3 => L_ScrollContainer.L_KeySetting.L_Key3;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key4
- ///
- public Key4 S_Key4 => L_ScrollContainer.L_KeySetting.L_Key4;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key5
- ///
- public Key5 S_Key5 => L_ScrollContainer.L_KeySetting.L_Key5;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key6
- ///
- public Key6 S_Key6 => L_ScrollContainer.L_KeySetting.L_Key6;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key7
- ///
- public Key7 S_Key7 => L_ScrollContainer.L_KeySetting.L_Key7;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key8
- ///
- public Key8 S_Key8 => L_ScrollContainer.L_KeySetting.L_Key8;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key11
- ///
- public Key11 S_Key11 => L_ScrollContainer.L_KeySetting.L_Key11;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key9
- ///
- public Key9 S_Key9 => L_ScrollContainer.L_KeySetting.L_Key9;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key10
- ///
- public Key10 S_Key10 => L_ScrollContainer.L_KeySetting.L_Key10;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key12
- ///
- public Key12 S_Key12 => L_ScrollContainer.L_KeySetting.L_Key12;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key13
- ///
- public Key13 S_Key13 => L_ScrollContainer.L_KeySetting.L_Key13;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting.Key14
- ///
- public Key14 S_Key14 => L_ScrollContainer.L_KeySetting.L_Key14;
-
- ///
- /// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer.KeySetting
- ///
- public KeySetting S_KeySetting => L_ScrollContainer.L_KeySetting;
-
- ///
/// 场景中唯一名称的节点, 节点类型: , 节点路径: Setting.ScrollContainer
///
public ScrollContainer S_ScrollContainer => L_ScrollContainer;
diff --git a/DungeonShooting_Godot/src/game/ui/setting/SettingPanel.cs b/DungeonShooting_Godot/src/game/ui/setting/SettingPanel.cs
index f633a8b..7cf7c8d 100644
--- a/DungeonShooting_Godot/src/game/ui/setting/SettingPanel.cs
+++ b/DungeonShooting_Godot/src/game/ui/setting/SettingPanel.cs
@@ -1,46 +1,49 @@
+using Config;
using Godot;
namespace UI.Setting;
public partial class SettingPanel : Setting
{
-
public override void OnCreateUi()
{
if (PrevUi != null)
{
//返回上一级UI
- L_Back.Instance.Pressed += () =>
+ S_Back.Instance.Pressed += () =>
{
OpenPrevUi();
};
}
+ else
+ {
+ S_Back.Instance.Pressed += () =>
+ {
+ Destroy();
+ };
+ }
- //视频设置
- S_VideoItem.Instance.Pressed += () =>
+ //声音设置BGM
+ S_BGM.Instance.ValueChanged += (double v) =>
{
- S_SettingMenu.Instance.Visible = false;
- S_VideoSetting.Instance.Visible = true;
+ var value = (float)v;
+ GameApplication.Instance.GameSave.BgmVolume = value;
+ SoundManager.SetBusValue(BUS.BGM, value);
};
- //键位设置
- S_InputItem.Instance.Pressed += () =>
+ //声音设置SFX
+ S_SFX.Instance.ValueChanged += (double v) =>
{
- S_SettingMenu.Instance.Visible = false;
- S_KeySetting.Instance.Visible = true;
+ var value = (float)v;
+ GameApplication.Instance.GameSave.SfxVolume = value;
+ SoundManager.SetBusValue(BUS.SFX, value);
};
- //视频设置返回
- S_VideoSetting.L_Back.Instance.Pressed += () =>
+ //声音设置设置BGM SFX的值
+ S_SFX.Instance.VisibilityChanged += () =>
{
- S_SettingMenu.Instance.Visible = true;
- S_VideoSetting.Instance.Visible = false;
+ S_BGM.Instance.Value = GameApplication.Instance.GameSave.BgmVolume;
+ S_SFX.Instance.Value = GameApplication.Instance.GameSave.SfxVolume;
};
- //键位设置返回
- S_KeySetting.L_Back.Instance.Pressed += () =>
- {
- S_SettingMenu.Instance.Visible = true;
- S_KeySetting.Instance.Visible = false;
- };
-
+
//---------------------- 视频设置 -----------------------------
//全屏属性
S_FullScreen.L_CheckBox.Instance.ButtonPressed = DisplayServer.WindowGetMode() == DisplayServer.WindowMode.Fullscreen;
@@ -50,13 +53,14 @@
public override void OnDestroyUi()
{
-
+ GameApplication.Instance.GameSave.Save();
}
//切换全屏/非全屏
private void OnChangeFullScreen()
{
var checkBox = S_FullScreen.L_CheckBox.Instance;
+ GameApplication.Instance.GameSave.FullScreen = checkBox.ButtonPressed;
if (checkBox.ButtonPressed)
{
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen);
diff --git a/DungeonShooting_Godot/src/game/ui/settlement/SettlementPanel.cs b/DungeonShooting_Godot/src/game/ui/settlement/SettlementPanel.cs
index f88c7f7..cf7401c 100644
--- a/DungeonShooting_Godot/src/game/ui/settlement/SettlementPanel.cs
+++ b/DungeonShooting_Godot/src/game/ui/settlement/SettlementPanel.cs
@@ -29,7 +29,7 @@
else //正常重新开始
{
UiManager.Open_Loading();
- GameApplication.Instance.DungeonManager.RestartDungeon(false, GameApplication.Instance.DungeonConfig, () =>
+ GameApplication.Instance.DungeonManager.RestartDungeon(false, GameApplication.Instance.FirstDungeonConfig, () =>
{
UiManager.Destroy_Loading();
});
@@ -57,4 +57,4 @@
}
}
-}
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/ui/victory/Victory.cs b/DungeonShooting_Godot/src/game/ui/victory/Victory.cs
new file mode 100644
index 0000000..3c7352c
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/ui/victory/Victory.cs
@@ -0,0 +1,73 @@
+namespace UI.Victory;
+
+///
+/// Ui代码, 该类是根据ui场景自动生成的, 请不要手动编辑该类, 以免造成代码丢失
+///
+public abstract partial class Victory : UiBase
+{
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Victory.Label
+ ///
+ public Label L_Label
+ {
+ get
+ {
+ if (_L_Label == null) _L_Label = new Label((VictoryPanel)this, GetNode("Label"));
+ return _L_Label;
+ }
+ }
+ private Label _L_Label;
+
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Victory.Button
+ ///
+ public Button L_Button
+ {
+ get
+ {
+ if (_L_Button == null) _L_Button = new Button((VictoryPanel)this, GetNode("Button"));
+ return _L_Button;
+ }
+ }
+ private Button _L_Button;
+
+
+ public Victory() : base(nameof(Victory))
+ {
+ }
+
+ public sealed override void OnInitNestedUi()
+ {
+
+ }
+
+ ///
+ /// 类型: , 路径: Victory.Label
+ ///
+ public class Label : UiNode
+ {
+ public Label(VictoryPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
+ public override Label Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: Victory.Button
+ ///
+ public class Button : UiNode
+ {
+ public Button(VictoryPanel uiPanel, Godot.Button node) : base(uiPanel, node) { }
+ public override Button Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate());
+ }
+
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Victory.Label
+ ///
+ public Label S_Label => L_Label;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: Victory.Button
+ ///
+ public Button S_Button => L_Button;
+
+}
diff --git a/DungeonShooting_Godot/src/game/ui/victory/VictoryPanel.cs b/DungeonShooting_Godot/src/game/ui/victory/VictoryPanel.cs
new file mode 100644
index 0000000..3dd8237
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/ui/victory/VictoryPanel.cs
@@ -0,0 +1,27 @@
+using System;
+using Godot;
+
+namespace UI.Victory;
+
+public partial class VictoryPanel : Victory
+{
+ public Action Callback;
+
+ public override void OnCreateUi()
+ {
+ S_Button.Instance.Pressed += () =>
+ {
+ if (Callback != null)
+ {
+ Destroy();
+ Callback();
+ }
+ };
+ }
+
+ public override void OnDestroyUi()
+ {
+
+ }
+
+}
diff --git a/DungeonShooting_Godot/src/game/world/World.cs b/DungeonShooting_Godot/src/game/world/World.cs
index f5a32fd..88a5f29 100644
--- a/DungeonShooting_Godot/src/game/world/World.cs
+++ b/DungeonShooting_Godot/src/game/world/World.cs
@@ -17,7 +17,7 @@
///
/// 当前操作的玩家
///
- public Player Player { get; private set; }
+ public Role Player { get; private set; }
///
/// //对象根节点
@@ -34,6 +34,11 @@
///
public TileMap TileRoot;
+ ///
+ /// 背景音乐播放器
+ ///
+ public SoundManager.GameAudioPlayer BgmAudio { get; private set; }
+
public Node2D StaticSpriteRoot;
public Node2D AffiliationAreaRoot;
public Node2D FogMaskRoot;
@@ -50,13 +55,21 @@
if (_pause != value)
{
_pause = value;
- if (value)
+ if (value) //暂停
{
ProcessMode = ProcessModeEnum.WhenPaused;
+ if (BgmAudio != null)
+ {
+ BgmAudio.SetVolume(BgmAudio.DefaultVolume * 0.4f);
+ }
}
- else
+ else //取消暂停
{
ProcessMode = ProcessModeEnum.Inherit;
+ if (BgmAudio != null)
+ {
+ BgmAudio.SetVolume(BgmAudio.DefaultVolume);
+ }
}
}
}
@@ -127,12 +140,39 @@
///
/// 设置当前操作的玩家对象
///
- public void SetCurrentPlayer(Player player)
+ public void SetCurrentPlayer(Role player)
{
+ var flag = Player == player;
Player = player;
//设置相机和鼠标跟随玩家
GameCamera.Main.SetFollowTarget(player);
GameApplication.Instance.Cursor.SetMountRole(player);
+
+ if (!flag)
+ {
+ //通知角色改变
+ EventManager.EmitEvent(EventEnum.OnChangePlayerRole, player);
+ OnChangePlayerRole(player);
+ }
+ }
+
+ private void OnChangePlayerRole(Role player)
+ {
+ }
+
+ public void PlayBgm(string soundId)
+ {
+ StopBgm();
+ BgmAudio = SoundManager.PlayTransitionMusic(soundId, 1);
+ }
+
+ public void StopBgm()
+ {
+ if (BgmAudio != null && BgmAudio.Playing)
+ {
+ BgmAudio.TransitionToStop();
+ BgmAudio = null;
+ }
}
///
@@ -142,6 +182,10 @@
/// 目标
public void NotifyEnemyTarget(Role self, ActivityObject target)
{
+ if (self.AffiliationArea == null)
+ {
+ return;
+ }
foreach (var role in Role_InstanceList)
{
if (role != self && !role.IsDestroyed && role.AffiliationArea == self.AffiliationArea && role is AiRole enemy && !self.IsEnemy(enemy))
@@ -164,7 +208,7 @@
{
return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
}
-
+
public void StopCoroutine(long coroutineId)
{
ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
@@ -199,4 +243,19 @@
OnRoleDieEvent(role);
}
}
-}
\ No newline at end of file
+
+ ///
+ /// 世界加载完成回调
+ ///
+ public virtual void OnLoadSuccess()
+ {
+ }
+
+ ///
+ /// 世界卸载完成回调
+ ///
+ public virtual void OnUnloadSuccess()
+ {
+ StopBgm();
+ }
+}
diff --git a/DungeonShooting_Godot/src/test/TestActivity.cs b/DungeonShooting_Godot/src/test/TestActivity.cs
index 343aabf..eb8eca0 100644
--- a/DungeonShooting_Godot/src/test/TestActivity.cs
+++ b/DungeonShooting_Godot/src/test/TestActivity.cs
@@ -2,46 +2,46 @@
public partial class TestActivity : ActivityObject
{
- public override void OnInit()
- {
- EnableVerticalMotion = false;
- }
+ public override void OnInit()
+ {
+ EnableVerticalMotion = false;
+ }
- protected override void Process(float delta)
- {
- if (Input.IsActionJustPressed("fire"))
- {
- Altitude = 100;
- }
+ protected override void Process(float delta)
+ {
+ if (Input.IsActionJustPressed("fire"))
+ {
+ Altitude = 100;
+ }
- if (Input.IsActionJustPressed("interactive"))
- {
- EnableVerticalMotion = !EnableVerticalMotion;
- }
- }
+ if (Input.IsActionJustPressed("interactive"))
+ {
+ EnableVerticalMotion = !EnableVerticalMotion;
+ }
+ }
- protected override void OnFallToGround()
- {
- Debug.Log("OnFallToGround");
- }
+ protected override void OnFallToGround()
+ {
+ Debug.Log("OnFallToGround");
+ }
- protected override void OnFirstFallToGround()
- {
- Debug.Log("OnFirstFallToGround");
- }
+ protected override void OnFirstFallToGround()
+ {
+ Debug.Log("OnFirstFallToGround");
+ }
- protected override void OnThrowStart()
- {
- Debug.Log("OnThrowStart");
- }
+ protected override void OnThrowStart()
+ {
+ Debug.Log("OnThrowStart");
+ }
- protected override void OnThrowMaxHeight(float height)
- {
- Debug.Log("OnThrowMaxHeight: " + height);
- }
+ protected override void OnThrowMaxHeight(float height)
+ {
+ Debug.Log("OnThrowMaxHeight: " + height);
+ }
- protected override void OnThrowOver()
- {
- Debug.Log("OnThrowOver");
- }
+ protected override void OnThrowOver()
+ {
+ Debug.Log("OnThrowOver");
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/test/TestLoadTileSetConfig.cs b/DungeonShooting_Godot/src/test/TestLoadTileSetConfig.cs
index 7ec33f1..cfbe529 100644
--- a/DungeonShooting_Godot/src/test/TestLoadTileSetConfig.cs
+++ b/DungeonShooting_Godot/src/test/TestLoadTileSetConfig.cs
@@ -56,7 +56,7 @@
//加载房间配置信息
var asText = ResourceManager.LoadText("res://" + GameConfig.RoomTileSetDir + GameConfig.TileSetConfigFile);
_tileSetConfig = JsonSerializer.Deserialize>(asText);
-
+
//加载所有数据
foreach (var tileSetSplit in _tileSetConfig)
{
diff --git a/DungeonShooting_Godot/src/test/TestMask.cs b/DungeonShooting_Godot/src/test/TestMask.cs
index 2954320..9f5e17e 100644
--- a/DungeonShooting_Godot/src/test/TestMask.cs
+++ b/DungeonShooting_Godot/src/test/TestMask.cs
@@ -6,173 +6,173 @@
public partial class TestMask : Node2D
{
- [Export]
- public Polygon2D PolygonNode;
+ [Export]
+ public Polygon2D PolygonNode;
- public List Result = new List();
- public override void _Ready()
- {
- //Geometry2D.
- // var point = new Vector2[]
- // {
- // new Vector2(0, 0),
- // new Vector2(0, 500),
- // new Vector2(500, 500),
- // new Vector2(500, 0)
- // };
- // Result = Geometry2D.ClipPolygons(point, new Vector2[]
- // {
- // new Vector2(20, 20),
- // new Vector2(20, 100),
- // new Vector2(90, 50),
- // });
- //PolygonNode.Polygon = clipPolygons[0];
- }
+ public List Result = new List();
+ public override void _Ready()
+ {
+ //Geometry2D.
+ // var point = new Vector2[]
+ // {
+ // new Vector2(0, 0),
+ // new Vector2(0, 500),
+ // new Vector2(500, 500),
+ // new Vector2(500, 0)
+ // };
+ // Result = Geometry2D.ClipPolygons(point, new Vector2[]
+ // {
+ // new Vector2(20, 20),
+ // new Vector2(20, 100),
+ // new Vector2(90, 50),
+ // });
+ //PolygonNode.Polygon = clipPolygons[0];
+ }
- public override void _Process(double delta)
- {
- //if (Input.IsActionJustPressed("fire"))
- if (Input.IsActionPressed("fire") || Input.IsActionJustPressed("roll"))
- {
- var time = DateTime.Now;
- RunTest();
- Debug.Log("用时: " + (DateTime.Now - time).TotalMilliseconds);
- }
+ public override void _Process(double delta)
+ {
+ //if (Input.IsActionJustPressed("fire"))
+ if (Input.IsActionPressed("fire") || Input.IsActionJustPressed("roll"))
+ {
+ var time = DateTime.Now;
+ RunTest();
+ Debug.Log("用时: " + (DateTime.Now - time).TotalMilliseconds);
+ }
- if (Input.IsActionJustPressed("meleeAttack"))
- {
- for (var i = 0; i < Result.Count; i++)
- {
- var temp = Result[i];
- Result[i] = StreamlineVertices3(temp, 10, Mathf.DegToRad(15));
- Debug.Log($"优化前: {temp.Length}, 优化后: {Result[i].Length}");
- }
- }
+ if (Input.IsActionJustPressed("meleeAttack"))
+ {
+ for (var i = 0; i < Result.Count; i++)
+ {
+ var temp = Result[i];
+ Result[i] = StreamlineVertices3(temp, 10, Mathf.DegToRad(15));
+ Debug.Log($"优化前: {temp.Length}, 优化后: {Result[i].Length}");
+ }
+ }
- if (Input.IsActionJustPressed("exchangeWeapon"))
- {
- Result.Clear();
- }
- QueueRedraw();
- }
+ if (Input.IsActionJustPressed("exchangeWeapon"))
+ {
+ Result.Clear();
+ }
+ QueueRedraw();
+ }
- private void RunTest()
- {
- var position = GetGlobalMousePosition();
- var circle = GetCircle(position, 50, 10);
- //先检测有没有碰撞
- var flag = false;
- for (var i = 0; i < Result.Count; i++)
- {
- var p = Result[i];
- if (CollisionPolygon(p, circle))
- {
- flag = true;
- var mergePolygons = Geometry2D.MergePolygons(p, circle);
- Result.RemoveAt(i);
- for (var j = 0; j < mergePolygons.Count; j++)
- {
- Result.Add(mergePolygons[j]);
- //Result.Add(StreamlineVertices(mergePolygons[j], 50));
- //Result.Add(StreamlineVertices2(mergePolygons[j], Mathf.DegToRad(5)));
- //Result.Add(StreamlineVertices3(mergePolygons[j], 20, Mathf.DegToRad(15)));
- }
- break;
- }
- }
+ private void RunTest()
+ {
+ var position = GetGlobalMousePosition();
+ var circle = GetCircle(position, 50, 10);
+ //先检测有没有碰撞
+ var flag = false;
+ for (var i = 0; i < Result.Count; i++)
+ {
+ var p = Result[i];
+ if (CollisionPolygon(p, circle))
+ {
+ flag = true;
+ var mergePolygons = Geometry2D.MergePolygons(p, circle);
+ Result.RemoveAt(i);
+ for (var j = 0; j < mergePolygons.Count; j++)
+ {
+ Result.Add(mergePolygons[j]);
+ //Result.Add(StreamlineVertices(mergePolygons[j], 50));
+ //Result.Add(StreamlineVertices2(mergePolygons[j], Mathf.DegToRad(5)));
+ //Result.Add(StreamlineVertices3(mergePolygons[j], 20, Mathf.DegToRad(15)));
+ }
+ break;
+ }
+ }
- if (!flag)
- {
- Result.Add(circle);
- //Result.Add(StreamlineVertices2(circle, Mathf.DegToRad(5)));
- }
- }
-
- private Vector2[] StreamlineVertices3(Vector2[] polygon, float d, float r)
- {
- if (polygon.Length <= 3)
- {
- return polygon;
- }
-
- float v = d * d;
- List list = new List();
- Vector2 tempPoint = polygon[0];
- Vector2 tempPoint2 = polygon[1];
- list.Add(tempPoint);
- float tr = tempPoint.AngleToPoint(tempPoint2);
- float delta = 0;
- for (var i = 1; i < polygon.Length; i++)
- {
- var curr = polygon[i];
- var prev = polygon[i > 0 ? i - 1 : polygon.Length - 1];
- var next = polygon[i < polygon.Length - 1 ? i + 1 : 0];
- if (prev.DistanceSquaredTo(next) > v)
- {
- //list.Add(curr);
-
- var angle = curr.AngleToPoint(next);
- delta += angle - tr;
- if (Mathf.Abs(delta) >= r)
- {
- Debug.Log(i + ", 偏差角度: " + Mathf.RadToDeg(delta));
- tr = angle;
- delta = 0;
- //var result = Geometry2D.GetClosestPointToSegmentUncapped(curr, tempPoint, tempPoint2);
- tempPoint = curr;
- //tempPoint2 = next;
- list.Add(tempPoint);
- }
- }
- }
+ if (!flag)
+ {
+ Result.Add(circle);
+ //Result.Add(StreamlineVertices2(circle, Mathf.DegToRad(5)));
+ }
+ }
+
+ private Vector2[] StreamlineVertices3(Vector2[] polygon, float d, float r)
+ {
+ if (polygon.Length <= 3)
+ {
+ return polygon;
+ }
+
+ float v = d * d;
+ List list = new List();
+ Vector2 tempPoint = polygon[0];
+ Vector2 tempPoint2 = polygon[1];
+ list.Add(tempPoint);
+ float tr = tempPoint.AngleToPoint(tempPoint2);
+ float delta = 0;
+ for (var i = 1; i < polygon.Length; i++)
+ {
+ var curr = polygon[i];
+ var prev = polygon[i > 0 ? i - 1 : polygon.Length - 1];
+ var next = polygon[i < polygon.Length - 1 ? i + 1 : 0];
+ if (prev.DistanceSquaredTo(next) > v)
+ {
+ //list.Add(curr);
+
+ var angle = curr.AngleToPoint(next);
+ delta += angle - tr;
+ if (Mathf.Abs(delta) >= r)
+ {
+ Debug.Log(i + ", 偏差角度: " + Mathf.RadToDeg(delta));
+ tr = angle;
+ delta = 0;
+ //var result = Geometry2D.GetClosestPointToSegmentUncapped(curr, tempPoint, tempPoint2);
+ tempPoint = curr;
+ //tempPoint2 = next;
+ list.Add(tempPoint);
+ }
+ }
+ }
- return list.ToArray();
- }
+ return list.ToArray();
+ }
- private bool CollisionPolygon(Vector2[] polygon1, Vector2[] polygon2)
- {
- for (int shape = 0; shape < 2; shape++)
- {
- if (shape == 1)
- {
- Vector2[] tmp = polygon1;
- polygon1 = polygon2;
- polygon2 = tmp;
- }
+ private bool CollisionPolygon(Vector2[] polygon1, Vector2[] polygon2)
+ {
+ for (int shape = 0; shape < 2; shape++)
+ {
+ if (shape == 1)
+ {
+ Vector2[] tmp = polygon1;
+ polygon1 = polygon2;
+ polygon2 = tmp;
+ }
- for (int a = 0; a < polygon1.Length; a++)
- {
- int b = (a + 1) % polygon1.Length;
- float axisX = -(polygon1[b].Y - polygon1[a].Y);
- float axisY = polygon1[b].X - polygon1[a].X;
+ for (int a = 0; a < polygon1.Length; a++)
+ {
+ int b = (a + 1) % polygon1.Length;
+ float axisX = -(polygon1[b].Y - polygon1[a].Y);
+ float axisY = polygon1[b].X - polygon1[a].X;
- float mina = float.MaxValue;
- float maxa = float.MinValue;
- for (int p = 0; p < polygon1.Length; p++)
- {
- float t = polygon1[p].X * axisX + polygon1[p].Y * axisY;
- mina = Math.Min(mina, t);
- maxa = Math.Max(maxa, t);
- }
+ float mina = float.MaxValue;
+ float maxa = float.MinValue;
+ for (int p = 0; p < polygon1.Length; p++)
+ {
+ float t = polygon1[p].X * axisX + polygon1[p].Y * axisY;
+ mina = Math.Min(mina, t);
+ maxa = Math.Max(maxa, t);
+ }
- float minb = float.MaxValue;
- float maxb = float.MinValue;
- for (int p = 0; p < polygon2.Length; p++)
- {
- float t = polygon2[p].X * axisX + polygon2[p].Y * axisY;
- minb = Math.Min(minb, t);
- maxb = Math.Max(maxb, t);
- }
+ float minb = float.MaxValue;
+ float maxb = float.MinValue;
+ for (int p = 0; p < polygon2.Length; p++)
+ {
+ float t = polygon2[p].X * axisX + polygon2[p].Y * axisY;
+ minb = Math.Min(minb, t);
+ maxb = Math.Max(maxb, t);
+ }
- if (maxa < minb || mina > maxb)
- return false;
- }
- }
+ if (maxa < minb || mina > maxb)
+ return false;
+ }
+ }
- return true;
- }
+ return true;
+ }
- private Vector2[] GetCircle(Vector2 position, float radius, int vertexCount)
+ private Vector2[] GetCircle(Vector2 position, float radius, int vertexCount)
{
Vector2[] vertices = new Vector2[vertexCount];
@@ -186,22 +186,22 @@
return vertices;
}
- public override void _Draw()
- {
- if (Result != null)
- {
- foreach (var vector2s in Result)
- {
- var list = vector2s.ToList();
- list.Add(vector2s[0]);
- DrawPolyline(list.ToArray(), Colors.Red);
- foreach (var vector2 in list)
- {
- DrawCircle(vector2, 2, Colors.Green);
- }
- }
- //DrawColoredPolygon(Result[1], Colors.Red);
- }
-
- }
+ public override void _Draw()
+ {
+ if (Result != null)
+ {
+ foreach (var vector2s in Result)
+ {
+ var list = vector2s.ToList();
+ list.Add(vector2s[0]);
+ DrawPolyline(list.ToArray(), Colors.Red);
+ foreach (var vector2 in list)
+ {
+ DrawCircle(vector2, 2, Colors.Green);
+ }
+ }
+ //DrawColoredPolygon(Result[1], Colors.Red);
+ }
+
+ }
}
diff --git a/DungeonShooting_Godot/src/test/TestNavigation2.cs b/DungeonShooting_Godot/src/test/TestNavigation2.cs
index c98ff85..5a01dc4 100644
--- a/DungeonShooting_Godot/src/test/TestNavigation2.cs
+++ b/DungeonShooting_Godot/src/test/TestNavigation2.cs
@@ -2,52 +2,52 @@
public partial class TestNavigation2 : Node2D
{
- private Node2D _navigation2D;
+ private Node2D _navigation2D;
- private Sprite2D _enemy;
- private NavigationAgent2D _navigationAgent2D;
+ private Sprite2D _enemy;
+ private NavigationAgent2D _navigationAgent2D;
- public override void _Ready()
- {
- _navigation2D = GetNode("Node2D");
- _enemy = _navigation2D.GetNode("Enemy");
- _navigationAgent2D = _enemy.GetNode("NavigationAgent2D");
+ public override void _Ready()
+ {
+ _navigation2D = GetNode("Node2D");
+ _enemy = _navigation2D.GetNode("Enemy");
+ _navigationAgent2D = _enemy.GetNode("NavigationAgent2D");
- _navigationAgent2D.TargetPosition = GetGlobalMousePosition();
+ _navigationAgent2D.TargetPosition = GetGlobalMousePosition();
- }
+ }
- public override void _PhysicsProcess(double delta)
- {
- if (_navigationAgent2D.IsNavigationFinished())
- {
- return;
- }
-
- var pos = _navigationAgent2D.GetNextPathPosition();
- _enemy.GlobalPosition = _enemy.GlobalPosition.MoveToward(pos, 400 * (float)delta);
+ public override void _PhysicsProcess(double delta)
+ {
+ if (_navigationAgent2D.IsNavigationFinished())
+ {
+ return;
+ }
+
+ var pos = _navigationAgent2D.GetNextPathPosition();
+ _enemy.GlobalPosition = _enemy.GlobalPosition.MoveToward(pos, 400 * (float)delta);
- }
+ }
- public override void _Process(double delta)
- {
- QueueRedraw();
- }
+ public override void _Process(double delta)
+ {
+ QueueRedraw();
+ }
- public override void _Draw()
- {
- var points = _navigationAgent2D.GetCurrentNavigationPath();
- if (points != null && points.Length >= 2)
- {
- DrawPolyline(points, Colors.Red);
- //DrawMultiline(points, Colors.Red);
- }
- }
+ public override void _Draw()
+ {
+ var points = _navigationAgent2D.GetCurrentNavigationPath();
+ if (points != null && points.Length >= 2)
+ {
+ DrawPolyline(points, Colors.Red);
+ //DrawMultiline(points, Colors.Red);
+ }
+ }
- private void _on_Timer_timeout()
- {
- var target = GetGlobalMousePosition();
- _navigationAgent2D.TargetPosition = target;
- }
+ private void _on_Timer_timeout()
+ {
+ var target = GetGlobalMousePosition();
+ _navigationAgent2D.TargetPosition = target;
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/test/TestNavigationPolygon.cs b/DungeonShooting_Godot/src/test/TestNavigationPolygon.cs
index 9e9c199..33320e3 100644
--- a/DungeonShooting_Godot/src/test/TestNavigationPolygon.cs
+++ b/DungeonShooting_Godot/src/test/TestNavigationPolygon.cs
@@ -5,28 +5,28 @@
///
public partial class TestNavigationPolygon : Node2D
{
- public override void _Ready()
- {
- var nv = GetNode("NavigationRegion2D");
+ public override void _Ready()
+ {
+ var nv = GetNode("NavigationRegion2D");
- var navpoy = nv.NavigationPolygon;
- var outlines = navpoy.Outlines;
- var polygons = navpoy.Polygons;
- var vertices = navpoy.Vertices;
+ var navpoy = nv.NavigationPolygon;
+ var outlines = navpoy.Outlines;
+ var polygons = navpoy.Polygons;
+ var vertices = navpoy.Vertices;
- var polygon = new NavigationPolygon();
- // polygon.Vertices = new Vector2[]
- // {
- // new Vector2(0,0), new Vector2(200,200), new Vector2(200, 0), new Vector2(0, 200),
- // new Vector2(50,50), new Vector2(150,150), new Vector2(150, 50), new Vector2(50, 150)
- // };
- // polygon.AddPolygon(new int[] { 0, 2, 1, 3 });
- // polygon.AddPolygon(new int[] { 4, 6, 5, 7 });
+ var polygon = new NavigationPolygon();
+ // polygon.Vertices = new Vector2[]
+ // {
+ // new Vector2(0,0), new Vector2(200,200), new Vector2(200, 0), new Vector2(0, 200),
+ // new Vector2(50,50), new Vector2(150,150), new Vector2(150, 50), new Vector2(50, 150)
+ // };
+ // polygon.AddPolygon(new int[] { 0, 2, 1, 3 });
+ // polygon.AddPolygon(new int[] { 4, 6, 5, 7 });
- polygon.AddOutline(new [] { new Vector2(0,0), new Vector2(200, 0), new Vector2(200,200), new Vector2(0, 200) });
- polygon.AddOutline(new [] { new Vector2(50,50), new Vector2(150, 50), new Vector2(150,150), new Vector2(50, 150) });
- polygon.MakePolygonsFromOutlines();
-
- nv.NavigationPolygon = polygon;
- }
+ polygon.AddOutline(new [] { new Vector2(0,0), new Vector2(200, 0), new Vector2(200,200), new Vector2(0, 200) });
+ polygon.AddOutline(new [] { new Vector2(50,50), new Vector2(150, 50), new Vector2(150,150), new Vector2(50, 150) });
+ polygon.MakePolygonsFromOutlines();
+
+ nv.NavigationPolygon = polygon;
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/test/TestPerfectPixelScene.cs b/DungeonShooting_Godot/src/test/TestPerfectPixelScene.cs
index 583d4e1..1878e8a 100644
--- a/DungeonShooting_Godot/src/test/TestPerfectPixelScene.cs
+++ b/DungeonShooting_Godot/src/test/TestPerfectPixelScene.cs
@@ -3,79 +3,79 @@
public partial class TestPerfectPixelScene : Node2D
{
- public enum HandlerType
- {
- UnHandler,
- NormalHandler,
- OffsetHandler
- }
+ public enum HandlerType
+ {
+ UnHandler,
+ NormalHandler,
+ OffsetHandler
+ }
- [Export]
- public CharacterBody2D Player;
+ [Export]
+ public CharacterBody2D Player;
- [Export]
- public Label FpsLabel;
-
- [Export]
- public Camera2D Camera2D;
+ [Export]
+ public Label FpsLabel;
+
+ [Export]
+ public Camera2D Camera2D;
- [Export]
- public float Speed = 50;
+ [Export]
+ public float Speed = 50;
- [Export]
- public float CameraRecoveryScale = 5;
+ [Export]
+ public float CameraRecoveryScale = 5;
- [Export]
- public SubViewportContainer SubViewportContainer;
+ [Export]
+ public SubViewportContainer SubViewportContainer;
- [Export]
- public HandlerType Type;
-
- private ShaderMaterial _shaderMaterial;
- private Vector2 _cameraPos;
+ [Export]
+ public HandlerType Type;
+
+ private ShaderMaterial _shaderMaterial;
+ private Vector2 _cameraPos;
- public override void _Ready()
- {
- if (SubViewportContainer != null)
- {
- _shaderMaterial = (ShaderMaterial)SubViewportContainer.Material;
- }
- }
+ public override void _Ready()
+ {
+ if (SubViewportContainer != null)
+ {
+ _shaderMaterial = (ShaderMaterial)SubViewportContainer.Material;
+ }
+ }
- public override void _Process(double delta)
- {
- InputManager.Update((float)delta);
+ public override void _Process(double delta)
+ {
+ InputManager.Update((float)delta);
-
- }
+
+ }
- public override void _PhysicsProcess(double delta)
- {
- FpsLabel.Text = "FPS: " + Engine.GetFramesPerSecond();
- Player.Velocity = InputManager.MoveAxis * Speed;
- Player.MoveAndSlide();
+ public override void _PhysicsProcess(double delta)
+ {
+ FpsLabel.Text = "FPS: " + Engine.GetFramesPerSecond();
+ Player.Velocity = InputManager.MoveAxis * Speed;
+ Player.MoveAndSlide();
- var playerPos = Player.GlobalPosition;
- //_cameraPos = playerPos;
- _cameraPos = _cameraPos.MoveToward(playerPos, playerPos.DistanceTo(_cameraPos) * (float)delta * CameraRecoveryScale);
+ var playerPos = Player.GlobalPosition;
+ //_cameraPos = playerPos;
+ _cameraPos = _cameraPos.MoveToward(playerPos, playerPos.DistanceTo(_cameraPos) * (float)delta * CameraRecoveryScale);
- if (Type == HandlerType.UnHandler)
- {
- Camera2D.GlobalPosition = _cameraPos;
- }
- else if (Type == HandlerType.NormalHandler)
- {
- Camera2D.GlobalPosition = _cameraPos.Round();
- }
- else if (Type == HandlerType.OffsetHandler)
- {
- if (_shaderMaterial != null)
- {
- var cameraPosition = _cameraPos;
- var offset = cameraPosition.Round() - cameraPosition;
- _shaderMaterial.SetShaderParameter("offset", offset);
- Camera2D.GlobalPosition = cameraPosition.Round();
- }
- }
- }
+ if (Type == HandlerType.UnHandler)
+ {
+ Camera2D.GlobalPosition = _cameraPos;
+ }
+ else if (Type == HandlerType.NormalHandler)
+ {
+ Camera2D.GlobalPosition = _cameraPos.Round();
+ }
+ else if (Type == HandlerType.OffsetHandler)
+ {
+ if (_shaderMaterial != null)
+ {
+ var cameraPosition = _cameraPos;
+ var offset = cameraPosition.Round() - cameraPosition;
+ _shaderMaterial.SetShaderParameter("offset", offset);
+ Camera2D.GlobalPosition = cameraPosition.Round();
+ }
+ }
+ }
}