diff --git a/DungeonShooting_Godot/prefab/ui/PauseMenu.tscn b/DungeonShooting_Godot/prefab/ui/PauseMenu.tscn new file mode 100644 index 0000000..421dd01 --- /dev/null +++ b/DungeonShooting_Godot/prefab/ui/PauseMenu.tscn @@ -0,0 +1,59 @@ +[gd_scene load_steps=3 format=3 uid="uid://bkq1wl66w3ais"] + +[ext_resource type="Script" path="res://src/game/ui/pauseMenu/PauseMenuPanel.cs" id="1_ef73i"] +[ext_resource type="Theme" uid="uid://drb1ajgvcih7p" path="res://resource/theme/theme1.tres" id="2_x1py5"] + +[node name="PauseMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource("1_ef73i") +Layer = 2 + +[node name="ColorRect" type="ColorRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0, 0, 0, 0.54902) + +[node name="VBoxContainer" type="VBoxContainer" 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 = -64.0 +offset_top = -79.0 +offset_right = 64.0 +offset_bottom = 79.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Continue" type="Button" parent="VBoxContainer"] +custom_minimum_size = Vector2(0, 50) +layout_mode = 2 +focus_neighbor_top = NodePath("../Exit") +focus_neighbor_bottom = NodePath("../Setting") +theme = ExtResource("2_x1py5") +text = "继续" + +[node name="Restart" type="Button" parent="VBoxContainer"] +custom_minimum_size = Vector2(0, 50) +layout_mode = 2 +focus_neighbor_top = NodePath("../Exit") +focus_neighbor_bottom = NodePath("../Setting") +theme = ExtResource("2_x1py5") +text = "重新开始" + +[node name="Exit" type="Button" parent="VBoxContainer"] +custom_minimum_size = Vector2(0, 50) +layout_mode = 2 +focus_neighbor_top = NodePath("../Exit") +focus_neighbor_bottom = NodePath("../Setting") +theme = ExtResource("2_x1py5") +text = "退出游戏" diff --git a/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json b/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json index ce8105f..d9e69c2 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json @@ -19,6 +19,10 @@ { "ErrorType": 0, "Path": "resource/map/tileMaps/TestGroup1/inlet/Start1" + }, + { + "ErrorType": 0, + "Path": "resource/map/tileMaps/TestGroup1/inlet/Start2" } ], "OutletList": [ diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json index 74763d2..30d1488 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json @@ -1 +1 @@ -[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":19,"Y":2},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":10,"Y":22},"Size":{"X":0,"Y":0},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":0,"Y":16},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0002","Weight":100,"Attr":{"CurrAmmon":"7","ResidueAmmo":"70"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":23,"Y":-24},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0004","Weight":100,"Attr":{"CurrAmmon":"180","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-35,"Y":59},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]}],[{"Position":{"X":11,"Y":38},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-15,"Y":31},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":36,"Y":36},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":35,"Y":2},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1.5,"MarkList":[{"Id":"prop0002","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-12,"Y":3},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":2,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-36,"Y":-18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":56,"Y":-24},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}]]}] \ No newline at end of file +[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":19,"Y":2},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":-38,"Y":41},"Size":{"X":0,"Y":0},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-38,"Y":55},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0002","Weight":100,"Attr":{"CurrAmmon":"7","ResidueAmmo":"70"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-38,"Y":11},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0004","Weight":100,"Attr":{"CurrAmmon":"180","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-39,"Y":69},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-38,"Y":-8},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0003","Weight":100,"Attr":{"CurrAmmon":"12","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-38,"Y":27},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0006","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-38,"Y":-28},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0007","Weight":100,"Attr":{"CurrAmmon":"60","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]}],[{"Position":{"X":55,"Y":67},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":56,"Y":24},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":56,"Y":0},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":34,"Y":23},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1.5,"MarkList":[{"Id":"prop0002","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":55,"Y":44},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":56,"Y":-24},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}]]}] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preinstall.json new file mode 100644 index 0000000..2af15f7 --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preinstall.json @@ -0,0 +1 @@ +[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":0,"Y":0},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":0,"Y":26},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]}]]}] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png new file mode 100644 index 0000000..dbbb1d3 --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png Binary files differ diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png.import b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png.import new file mode 100644 index 0000000..68d306b --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cr5tlhxfjetuf" +path="res://.godot/imported/Preview.png-8fbf34b154290497f5a1f19b421f568c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png" +dest_files=["res://.godot/imported/Preview.png-8fbf34b154290497f5a1f19b421f568c.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/map/tileMaps/TestGroup1/inlet/Start2/RoomInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/RoomInfo.json new file mode 100644 index 0000000..27eaead --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/RoomInfo.json @@ -0,0 +1 @@ +{"Position":{"X":-5,"Y":-5},"Size":{"X":10,"Y":12},"DoorAreaInfos":[{"Direction":3,"Start":0,"End":128},{"Direction":0,"Start":0,"End":160},{"Direction":1,"Start":0,"End":160}],"GroupName":"TestGroup1","RoomType":1,"RoomName":"Start2","Weight":100,"Remark":""} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/TileInfo.json new file mode 100644 index 0000000..8ba5c2f --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/TileInfo.json @@ -0,0 +1 @@ +{"NavigationList":[{"Type":0,"Points":[-56,-56,56,-56,56,96,40,96,40,48,-40,48,-40,96,-56,96]}],"Floor":[3,5,0,0,8,3,4,0,0,8,3,3,0,0,8,3,2,0,0,8,3,1,0,0,8,3,0,0,0,8,3,-1,0,0,8,3,-2,0,0,8,3,-3,0,0,8,3,-4,0,0,8,-4,5,0,0,8,-4,4,0,0,8,-4,3,0,0,8,-4,2,0,0,8,-4,1,0,0,8,-4,0,0,0,8,-4,-1,0,0,8,-4,-2,0,0,8,-4,-3,0,0,8,-4,-4,0,0,8,2,5,0,0,8,2,4,0,0,8,2,3,0,0,8,2,2,0,0,8,2,0,0,0,8,2,-1,0,0,8,2,-2,0,0,8,2,-3,0,0,8,2,-4,0,0,8,2,1,0,0,8,1,2,0,0,8,1,0,0,0,8,1,-1,0,0,8,1,-2,0,0,8,1,-3,0,0,8,1,-4,0,0,8,1,1,0,0,8,0,2,0,0,8,0,1,0,0,8,0,-1,0,0,8,0,-2,0,0,8,0,-3,0,0,8,0,-4,0,0,8,0,0,0,0,8,-1,2,0,0,8,-1,1,0,0,8,-1,0,0,0,8,-1,-2,0,0,8,-1,-3,0,0,8,-1,-4,0,0,8,-1,-1,0,0,8,-2,2,0,0,8,-2,1,0,0,8,-2,0,0,0,8,-2,-1,0,0,8,-2,-3,0,0,8,-2,-4,0,0,8,-2,-2,0,0,8,-3,5,0,0,8,-3,4,0,0,8,-3,3,0,0,8,-3,2,0,0,8,-3,1,0,0,8,-3,0,0,0,8,-3,-1,0,0,8,-3,-2,0,0,8,-3,-3,0,0,8,-3,-4,0,0,8],"Middle":[-4,-5,0,2,7,-3,-5,0,2,7,-2,-5,0,2,7,-1,-5,0,2,7,0,-5,0,2,7,1,-5,0,2,7,2,-5,0,2,7,3,-5,0,2,7],"Top":[-5,-5,0,3,4,-5,-4,0,3,3,-5,-3,0,3,3,-5,-2,0,3,3,-5,-1,0,3,3,-5,0,0,3,3,-5,1,0,3,3,-5,2,0,3,3,-5,3,0,3,3,-5,4,0,3,3,-5,5,0,3,3,-5,6,0,11,2,-4,6,0,2,2,-3,6,0,2,2,-2,3,0,1,2,-2,4,0,1,3,-2,5,0,1,3,-2,6,0,13,2,-1,3,0,2,2,0,3,0,2,2,1,3,0,3,2,1,4,0,3,3,1,5,0,3,3,1,6,0,11,2,2,6,0,2,2,3,6,0,2,2,4,-5,0,1,4,4,-4,0,1,3,4,-3,0,1,3,4,-2,0,1,3,4,-1,0,1,3,4,0,0,1,3,4,1,0,1,3,4,2,0,1,3,4,3,0,1,3,4,4,0,1,3,4,5,0,1,3,4,6,0,13,2]} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index a3481de..f96a52f 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -1133,14 +1133,17 @@ if (IsDebug) { DebugDraw(); - var arr = _components.ToArray(); - for (int i = 0; i < arr.Length; i++) + if (_components.Count > 0) { - if (IsDestroyed) return; - var temp = arr[i].Value; - if (temp != null && temp.ActivityInstance == this && temp.Enable) + var arr = _components.ToArray(); + for (int i = 0; i < arr.Length; i++) { - temp.DebugDraw(); + if (IsDestroyed) return; + var temp = arr[i].Value; + if (temp != null && temp.ActivityInstance == this && temp.Enable) + { + temp.DebugDraw(); + } } } } diff --git a/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs b/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs index e577646..36167b1 100644 --- a/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs +++ b/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs @@ -271,33 +271,33 @@ return; } - //先调用更新 - var externalForces = _forceList.ToArray(); - for (var i = 0; i < externalForces.Length; i++) - { - var force = externalForces[i]; - if (force.Enable) - { - force.PhysicsProcess(delta); - //自动销毁 - if (CheckAutoDestroy(force)) - { - _forceList.Remove(force); - externalForces[i] = null; - } - } - } - //外力总和 var finallyEf = new Vector2(); //旋转速率总和 var rotationSpeed = 0f; - foreach (var force in externalForces) + + //先调用更新 + if (_forceList.Count > 0) { - if (force != null && force.Enable) + var externalForces = _forceList.ToArray(); + for (var i = 0; i < externalForces.Length; i++) { - finallyEf += force.Velocity; - rotationSpeed += force.RotationSpeed; + var force = externalForces[i]; + if (force.Enable) + { + force.PhysicsProcess(delta); + //自动销毁 + if (CheckAutoDestroy(force)) + { + _forceList.Remove(force); + externalForces[i] = null; + } + else + { + finallyEf += force.Velocity; + rotationSpeed += force.RotationSpeed; + } + } } } diff --git a/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs b/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs index 5592d76..97abea5 100644 --- a/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs +++ b/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs @@ -15,6 +15,10 @@ /// public static void ProxyUpdateCoroutine(ref List coroutineList, float delta) { + if (coroutineList.Count == 0) + { + return; + } var pairs = coroutineList.ToArray(); for (var i = 0; i < pairs.Length; i++) { diff --git a/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs b/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs index ffdb00d..4e0addf 100644 --- a/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs +++ b/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs @@ -671,7 +671,7 @@ try { - var size = new Vector2(_tileRoot.CellQuadrantSize, _tileRoot.CellQuadrantSize); + var size = new Vector2(GameConfig.TileCellSize, GameConfig.TileCellSize); var rect = _tileRoot.GetUsedRect(); diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs index 5aef09a..92e4f00 100644 --- a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs +++ b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs @@ -251,7 +251,7 @@ if (_currWaveIndex < WaveList.Count) { GD.Print($"执行第{_currWaveIndex}波"); - _coroutineId = GameApplication.Instance.StartCoroutine(RunMark(WaveList[_currWaveIndex])); + _coroutineId = GameApplication.Instance.World.StartCoroutine(RunMark(WaveList[_currWaveIndex])); _currWaveIndex++; } } @@ -268,7 +268,7 @@ } GD.Print($"执行第{_currWaveIndex}波"); - _coroutineId = GameApplication.Instance.StartCoroutine(RunMark(WaveList[_currWaveIndex])); + _coroutineId = GameApplication.Instance.World.StartCoroutine(RunMark(WaveList[_currWaveIndex])); _currWaveIndex++; } diff --git a/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs b/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs index 23afa6b..8ddb33f 100644 --- a/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs +++ b/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs @@ -287,7 +287,6 @@ /// /// 移除指定索引的 Cell /// - /// public void RemoveByIndex(int index) { if (index < 0 || index >= _cellList.Count) diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs index 1275dd1..01d2434 100644 --- a/DungeonShooting_Godot/src/game/GameApplication.cs +++ b/DungeonShooting_Godot/src/game/GameApplication.cs @@ -36,7 +36,7 @@ /// 是否开启调试 /// [ExportGroup("Debug")] - [Export] public bool Debug = false; + [Export] public bool Debug; /// /// 鼠标指针 diff --git a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs index 4600a54..419db5c 100644 --- a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs +++ b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs @@ -254,6 +254,11 @@ GameCamera.Main.SetFollowTarget(null); BasisVelocity = Vector2.Zero; MoveController.ClearForce(); + + //暂停游戏 + GameApplication.Instance.World.Pause = true; + //弹出结算面板 + GameApplication.Instance.Cursor.SetGuiMode(true); UiManager.Open_Settlement(); } @@ -303,4 +308,10 @@ BasisVelocity = new Vector2(BasisVelocity.X, Mathf.MoveToward(BasisVelocity.Y, dir.Y * RoleState.MoveSpeed, RoleState.Acceleration * delta)); } } + + protected override void DebugDraw() + { + base.DebugDraw(); + DrawArc(new Vector2(0, -8), 50, 0, Mathf.Pi * 2f, 20, Colors.Red, 1); + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs index 34ca189..c6b93e7 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs @@ -433,7 +433,8 @@ _noAttackTime += delta; //这把武器被扔在地上, 或者当前武器没有被使用 - if (Master == null || Master.WeaponPack.ActiveItem != this) + //if (Master == null || Master.WeaponPack.ActiveItem != this) + if (Master != null && Master.WeaponPack.ActiveItem != this) //在背上 { //_triggerTimer _triggerTimer = _triggerTimer > 0 ? _triggerTimer - delta : 0; @@ -455,9 +456,7 @@ { _dirtyFlag = false; _aloneReloadState = 0; - Reloading = false; - _reloadTimer = 0; - _reloadUseTime = 0; + StopReload(); _attackFlag = false; _continuousCount = 0; _delayedTime = 0; @@ -520,7 +519,7 @@ if (Attribute.AloneReloadFinishIntervalTime <= 0) { //换弹完成 - StopReloadState(); + StopReload(); ReloadFinishHandler(); } else @@ -545,7 +544,7 @@ if (_reloadTimer <= 0) { //换弹完成 - StopReloadState(); + StopReload(); ReloadFinishHandler(); } _aloneReloadStop = false; @@ -579,7 +578,11 @@ _delayedTime += _attackTimer; _attackTimer = 0; //枪口默认角度 - RotationDegrees = -Attribute.DefaultAngle; + if (Master != null) + { + RotationDegrees = -Attribute.DefaultAngle; + } + //自动上膛 if (_beLoadedState == -1) { @@ -625,7 +628,7 @@ if (!_looseShootFlag && _continuousCount > 0 && _delayedTime <= 0 && _attackTimer <= 0) { //连发开火 - TriggerFire(_attackTrigger); + TriggerFire(); //连发最后一发打完了 if (Attribute.ManualBeLoaded && _continuousCount <= 0) { @@ -647,13 +650,16 @@ //武器身回归 //Position = Position.MoveToward(Vector2.Zero, Attribute.BacklashRegressionSpeed * delta).Rotated(Rotation); _currBacklashLength = Mathf.MoveToward(_currBacklashLength, 0, Attribute.BacklashRegressionSpeed * delta); - Position = new Vector2(_currBacklashLength, 0).Rotated(Rotation); - if (_attackTimer > 0) + if (Master != null) { - RotationDegrees = Mathf.Lerp( - _fireAngle, -Attribute.DefaultAngle, - Mathf.Clamp((_fireInterval - _attackTimer) * Attribute.UpliftAngleRestore / _fireInterval, 0, 1) - ); + Position = new Vector2(_currBacklashLength, 0).Rotated(Rotation); + if (_attackTimer > 0) + { + RotationDegrees = Mathf.Lerp( + _fireAngle, -Attribute.DefaultAngle, + Mathf.Clamp((_fireInterval - _attackTimer) * Attribute.UpliftAngleRestore / _fireInterval, 0, 1) + ); + } } } } @@ -687,7 +693,7 @@ if (_beLoadedState == 0 || _beLoadedState == -1) //需要执行上膛操作 { - if (justDown && !Reloading && Master != null) + if (justDown && !Reloading && trigger != null) { if (CurrAmmo <= 0) { @@ -757,7 +763,7 @@ else if (CurrAmmo <= 0) //子弹不够 { fireFlag = false; - if (justDown && Master != null) + if (justDown && trigger != null) { //第一帧按下, 触发换弹 Reload(); @@ -792,7 +798,7 @@ else { //开火 - TriggerFire(_attackTrigger); + TriggerFire(); //非连射模式 if (!Attribute.ContinuousShoot && Attribute.ManualBeLoaded && _continuousCount <= 0) @@ -868,7 +874,7 @@ _looseShootFlag = false; if (_chargeTime >= Attribute.MinChargeTime) //判断蓄力是否够了 { - TriggerFire(_attackTrigger); + TriggerFire(); //非连射模式 if (!Attribute.ContinuousShoot && Attribute.ManualBeLoaded && _continuousCount <= 0) { @@ -889,7 +895,7 @@ /// /// 触发开火 /// - private void TriggerFire(Role trigger) + private void TriggerFire() { _noAttackTime = 0; @@ -993,6 +999,18 @@ externalForce.RotationSpeed = -Mathf.DegToRad(40); externalForce.RotationResistance = Mathf.DegToRad(80); } + + if (IsInGround()) + { + //在地上弹药打光 + if (IsTotalAmmoEmpty()) + { + //停止动画 + AnimationPlayer.Stop(); + //清除泛白效果 + SetBlendSchedule(0); + } + } } /// @@ -1135,6 +1153,17 @@ } } + /// + /// 强制停止换弹, 或者结束换弹状态 + /// + public void StopReload() + { + _aloneReloadState = 0; + Reloading = false; + _reloadTimer = 0; + _reloadUseTime = 0; + } + //播放换弹开始音效 private void PlayBeginReloadSound() { @@ -1391,15 +1420,6 @@ } } - //停止当前的换弹状态 - private void StopReloadState() - { - _aloneReloadState = 0; - Reloading = false; - _reloadTimer = 0; - _reloadUseTime = 0; - } - /// /// 换弹计时器时间到, 执行换弹操作 /// @@ -1454,7 +1474,7 @@ ResidueAmmo = 0; } - StopReloadState(); + StopReload(); ReloadFinishHandler(); } } diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs index 5aaa8f5..96f692b 100644 --- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs +++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs @@ -9,7 +9,6 @@ public const string excel_DungeonShooting_ExcelTool_deps_json = "res://excel/DungeonShooting_ExcelTool.deps.json"; public const string excel_DungeonShooting_ExcelTool_runtimeconfig_json = "res://excel/DungeonShooting_ExcelTool.runtimeconfig.json"; public const string prefab_Cursor_tscn = "res://prefab/Cursor.tscn"; - public const string prefab_FanCollisionShape_tscn = "res://prefab/FanCollisionShape.tscn"; public const string prefab_bullet_Bullet0001_tscn = "res://prefab/bullet/Bullet0001.tscn"; public const string prefab_bullet_Bullet0002_tscn = "res://prefab/bullet/Bullet0002.tscn"; public const string prefab_bullet_Bullet0003_tscn = "res://prefab/bullet/Bullet0003.tscn"; @@ -21,6 +20,7 @@ public const string prefab_effect_weapon_BulletSmoke_tscn = "res://prefab/effect/weapon/BulletSmoke.tscn"; public const string prefab_effect_weapon_FirePart_tscn = "res://prefab/effect/weapon/FirePart.tscn"; public const string prefab_effect_weapon_MeleeAttack1_tscn = "res://prefab/effect/weapon/MeleeAttack1.tscn"; + public const string prefab_effect_weapon_MeleeAttack2_tscn = "res://prefab/effect/weapon/MeleeAttack2.tscn"; public const string prefab_effect_weapon_ShotFire_tscn = "res://prefab/effect/weapon/ShotFire.tscn"; public const string prefab_map_RoomDoor_E_tscn = "res://prefab/map/RoomDoor_E.tscn"; public const string prefab_map_RoomDoor_N_tscn = "res://prefab/map/RoomDoor_N.tscn"; @@ -63,6 +63,7 @@ public const string prefab_ui_MapEditorProject_tscn = "res://prefab/ui/MapEditorProject.tscn"; public const string prefab_ui_MapEditorSelectObject_tscn = "res://prefab/ui/MapEditorSelectObject.tscn"; public const string prefab_ui_MapEditorTools_tscn = "res://prefab/ui/MapEditorTools.tscn"; + public const string prefab_ui_PauseMenu_tscn = "res://prefab/ui/PauseMenu.tscn"; public const string prefab_ui_RoomUI_tscn = "res://prefab/ui/RoomUI.tscn"; public const string prefab_ui_Settlement_tscn = "res://prefab/ui/Settlement.tscn"; public const string prefab_weapon_Weapon0001_tscn = "res://prefab/weapon/Weapon0001.tscn"; @@ -302,6 +303,7 @@ public const string scene_Main_tscn = "res://scene/Main.tscn"; public const string scene_World_tscn = "res://scene/World.tscn"; public const string scene_test_TestCommpont_tscn = "res://scene/test/TestCommpont.tscn"; + public const string scene_test_TestCreateSector_tscn = "res://scene/test/TestCreateSector.tscn"; public const string scene_test_TestExpression_tscn = "res://scene/test/TestExpression.tscn"; public const string scene_test_TestGenerateDungeon_tscn = "res://scene/test/TestGenerateDungeon.tscn"; public const string scene_test_TestNavigation2_tscn = "res://scene/test/TestNavigation2.tscn"; diff --git a/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs b/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs index 738391c..c64b660 100644 --- a/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs +++ b/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs @@ -22,6 +22,7 @@ public const string MapEditorProject = "MapEditorProject"; public const string MapEditorSelectObject = "MapEditorSelectObject"; public const string MapEditorTools = "MapEditorTools"; + public const string PauseMenu = "PauseMenu"; public const string RoomUI = "RoomUI"; public const string Settlement = "Settlement"; } @@ -795,6 +796,54 @@ } /// + /// 创建 PauseMenu, 并返回UI实例, 该函数不会打开 Ui + /// + public static UI.PauseMenu.PauseMenuPanel Create_PauseMenu() + { + return CreateUi(UiName.PauseMenu); + } + + /// + /// 打开 PauseMenu, 并返回UI实例 + /// + public static UI.PauseMenu.PauseMenuPanel Open_PauseMenu() + { + return OpenUi(UiName.PauseMenu); + } + + /// + /// 隐藏 PauseMenu 的所有实例 + /// + public static void Hide_PauseMenu() + { + var uiInstance = Get_PauseMenu_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.HideUi(); + } + } + + /// + /// 销毁 PauseMenu 的所有实例 + /// + public static void Destroy_PauseMenu() + { + var uiInstance = Get_PauseMenu_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.Destroy(); + } + } + + /// + /// 获取所有 PauseMenu 的实例, 如果没有实例, 则返回一个空数组 + /// + public static UI.PauseMenu.PauseMenuPanel[] Get_PauseMenu_Instance() + { + return GetUiInstance(nameof(UI.PauseMenu.PauseMenu)); + } + + /// /// 创建 RoomUI, 并返回UI实例, 该函数不会打开 Ui /// public static UI.RoomUI.RoomUIPanel Create_RoomUI() diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs index 7655681..c0b9834 100644 --- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs +++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs @@ -72,7 +72,6 @@ GameApplication.Instance.StartCoroutine(RunLoadDungeonCoroutine(finish)); } - /// /// 重启地牢 /// @@ -152,6 +151,21 @@ { if (IsInDungeon) { + if (World.Pause) //已经暂停 + { + return; + } + + //暂停游戏 + if (Input.IsActionJustPressed("ui_cancel")) + { + World.Pause = true; + //鼠标改为Ui鼠标 + GameApplication.Instance.Cursor.SetGuiMode(true); + //打开暂停Ui + UiManager.Open_PauseMenu(); + } + _checkEnemyTimer += (float)delta; if (_checkEnemyTimer >= 1) { @@ -591,7 +605,7 @@ //绘制房间区域, debug 用 private void DrawRoomInfo(RoomInfo roomInfo) { - var cellSize = World.TileRoot.CellQuadrantSize; + var cellSize = GameConfig.TileCellSize; var pos1 = (roomInfo.Position + roomInfo.Size / 2) * cellSize; //绘制下一个房间 diff --git a/DungeonShooting_Godot/src/game/room/World.cs b/DungeonShooting_Godot/src/game/room/World.cs index 622803c..a11e2fd 100644 --- a/DungeonShooting_Godot/src/game/room/World.cs +++ b/DungeonShooting_Godot/src/game/room/World.cs @@ -1,10 +1,11 @@ +using System.Collections; using System.Collections.Generic; using Godot; /// /// 游戏世界 /// -public partial class World : Node2D +public partial class World : Node2D, ICoroutine { /// /// //对象根节点 @@ -73,12 +74,22 @@ public Vector2 Enemy_FindTargetPosition { get; set; } private bool _pause = false; - + private List _coroutineList; + public override void _Ready() { TileRoot.YSortEnabled = false; } + public override void _Process(double delta) + { + //协程更新 + if (_coroutineList != null) + { + ProxyCoroutineHandler.ProxyUpdateCoroutine(ref _coroutineList, (float)delta); + } + } + /// /// 获取指定层级根节点 /// @@ -95,4 +106,23 @@ return null; } + public long StartCoroutine(IEnumerator able) + { + return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able); + } + + public void StopCoroutine(long coroutineId) + { + ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId); + } + + public bool IsCoroutineOver(long coroutineId) + { + return ProxyCoroutineHandler.ProxyIsCoroutineOver(ref _coroutineList, coroutineId); + } + + public void StopAllCoroutine() + { + ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList); + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs b/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs index e44a0b6..9294497 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs @@ -800,7 +800,7 @@ //设置显示的错误cell, 会标记上红色的闪烁动画 private void SetErrorCell(Vector2I pos) { - MapEditorPanel.S_ErrorCell.Instance.Position = pos * CellQuadrantSize; + MapEditorPanel.S_ErrorCell.Instance.Position = pos * GameConfig.TileCellSize; MapEditorPanel.S_ErrorCellAnimationPlayer.Instance.Play(AnimatorNames.Show); } diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorMapMark/MapEditorMapMarkPanel.cs b/DungeonShooting_Godot/src/game/ui/mapEditorMapMark/MapEditorMapMarkPanel.cs index e4906be..41ed879 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditorMapMark/MapEditorMapMarkPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditorMapMark/MapEditorMapMarkPanel.cs @@ -462,11 +462,11 @@ S_DynamicTool.Reparent(this); S_DynamicTool.Instance.Visible = false; var markCellIndex = markCell.Index; - var markInfo = waveCell.Data[markCellIndex]; + var markInfo = waveCell.MarkGrid.GetData(markCellIndex).MarkInfo; //派发移除标记事件 EventManager.EmitEvent(EventEnum.OnDeleteMark, markInfo); waveCell.MarkGrid.RemoveByIndex(markCellIndex); - waveCell.Data.RemoveAt(markCellIndex); + waveCell.Data.Remove(markInfo); //派发数据修改事件 EventManager.EmitEvent(EventEnum.OnEditorDirty); } diff --git a/DungeonShooting_Godot/src/game/ui/pauseMenu/PauseMenu.cs b/DungeonShooting_Godot/src/game/ui/pauseMenu/PauseMenu.cs new file mode 100644 index 0000000..256a892 --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/pauseMenu/PauseMenu.cs @@ -0,0 +1,154 @@ +namespace UI.PauseMenu; + +/// +/// Ui代码, 该类是根据ui场景自动生成的, 请不要手动编辑该类, 以免造成代码丢失 +/// +public abstract partial class PauseMenu : UiBase +{ + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: PauseMenu.ColorRect + /// + public ColorRect L_ColorRect + { + get + { + if (_L_ColorRect == null) _L_ColorRect = new ColorRect((PauseMenuPanel)this, GetNode("ColorRect")); + return _L_ColorRect; + } + } + private ColorRect _L_ColorRect; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: PauseMenu.VBoxContainer + /// + public VBoxContainer L_VBoxContainer + { + get + { + if (_L_VBoxContainer == null) _L_VBoxContainer = new VBoxContainer((PauseMenuPanel)this, GetNode("VBoxContainer")); + return _L_VBoxContainer; + } + } + private VBoxContainer _L_VBoxContainer; + + + public PauseMenu() : base(nameof(PauseMenu)) + { + } + + public sealed override void OnInitNestedUi() + { + + } + + /// + /// 类型: , 路径: PauseMenu.ColorRect + /// + public class ColorRect : UiNode + { + public ColorRect(PauseMenuPanel uiPanel, Godot.ColorRect node) : base(uiPanel, node) { } + public override ColorRect Clone() => new (UiPanel, (Godot.ColorRect)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: PauseMenu.VBoxContainer.Continue + /// + public class Continue : UiNode + { + public Continue(PauseMenuPanel uiPanel, Godot.Button node) : base(uiPanel, node) { } + public override Continue Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: PauseMenu.VBoxContainer.Restart + /// + public class Restart : UiNode + { + public Restart(PauseMenuPanel uiPanel, Godot.Button node) : base(uiPanel, node) { } + public override Restart Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: PauseMenu.VBoxContainer.Exit + /// + public class Exit : UiNode + { + public Exit(PauseMenuPanel uiPanel, Godot.Button node) : base(uiPanel, node) { } + public override Exit Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: PauseMenu.VBoxContainer + /// + public class VBoxContainer : UiNode + { + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: PauseMenu.Continue + /// + public Continue L_Continue + { + get + { + if (_L_Continue == null) _L_Continue = new Continue(UiPanel, Instance.GetNode("Continue")); + return _L_Continue; + } + } + private Continue _L_Continue; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: PauseMenu.Restart + /// + public Restart L_Restart + { + get + { + if (_L_Restart == null) _L_Restart = new Restart(UiPanel, Instance.GetNode("Restart")); + return _L_Restart; + } + } + private Restart _L_Restart; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: PauseMenu.Exit + /// + public Exit L_Exit + { + get + { + if (_L_Exit == null) _L_Exit = new Exit(UiPanel, Instance.GetNode("Exit")); + return _L_Exit; + } + } + private Exit _L_Exit; + + public VBoxContainer(PauseMenuPanel uiPanel, Godot.VBoxContainer node) : base(uiPanel, node) { } + public override VBoxContainer Clone() => new (UiPanel, (Godot.VBoxContainer)Instance.Duplicate()); + } + + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: PauseMenu.ColorRect + /// + public ColorRect S_ColorRect => L_ColorRect; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: PauseMenu.VBoxContainer.Continue + /// + public Continue S_Continue => L_VBoxContainer.L_Continue; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: PauseMenu.VBoxContainer.Restart + /// + public Restart S_Restart => L_VBoxContainer.L_Restart; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: PauseMenu.VBoxContainer.Exit + /// + public Exit S_Exit => L_VBoxContainer.L_Exit; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: PauseMenu.VBoxContainer + /// + public VBoxContainer S_VBoxContainer => L_VBoxContainer; + +} diff --git a/DungeonShooting_Godot/src/game/ui/pauseMenu/PauseMenuPanel.cs b/DungeonShooting_Godot/src/game/ui/pauseMenu/PauseMenuPanel.cs new file mode 100644 index 0000000..19e06a1 --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/pauseMenu/PauseMenuPanel.cs @@ -0,0 +1,66 @@ +using Godot; + +namespace UI.PauseMenu; + +public partial class PauseMenuPanel : PauseMenu +{ + + public override void OnCreateUi() + { + S_Continue.Instance.Pressed += OnContinueClick; + S_Restart.Instance.Pressed += OnRestartClick; + S_Exit.Instance.Pressed += OnExitClick; + + if (GameApplication.Instance.DungeonManager.IsEditorMode) //在编辑器模式下打开的Ui + { + S_Exit.Instance.Text = "返回编辑器"; + } + } + + public override void Process(float delta) + { + if (Input.IsActionJustPressed("ui_cancel")) //返回游戏 + { + OnContinueClick(); + } + } + + //继续游戏 + private void OnContinueClick() + { + GameApplication.Instance.World.Pause = false; + GameApplication.Instance.Cursor.SetGuiMode(false); + Destroy(); + } + + //重新开始 + private void OnRestartClick() + { + Destroy(); + if (GameApplication.Instance.DungeonManager.IsEditorMode) //在编辑器模式下打开的Ui + { + EditorPlayManager.Restart(); + } + else //正常重新开始 + { + GameApplication.Instance.DungeonManager.RestartDungeon(GameApplication.Instance.DungeonConfig); + } + } + + //退出地牢 + private void OnExitClick() + { + Destroy(); + if (GameApplication.Instance.DungeonManager.IsEditorMode) //在编辑器模式下打开的Ui + { + EditorPlayManager.Exit(); + } + else //正常关闭Ui + { + GameApplication.Instance.DungeonManager.ExitDungeon(() => + { + UiManager.Open_Main(); + }); + } + } +}