diff --git "a/DungeonShooting_Document/\345\274\200\345\217\221\346\227\245\345\277\227.md" "b/DungeonShooting_Document/\345\274\200\345\217\221\346\227\245\345\277\227.md" index d7a93f1..36afd4a 100644 --- "a/DungeonShooting_Document/\345\274\200\345\217\221\346\227\245\345\277\227.md" +++ "b/DungeonShooting_Document/\345\274\200\345\217\221\346\227\245\345\277\227.md" @@ -1,5 +1,27 @@ --- +### 2023-10-20 +项目从Godot4.1升级到4.2bate, 使用了部分新功能以提升视觉效果, 本月主要完善`Role`的动作和提升地牢视觉效果, 项目已正式开源 +将项目的Ui框架抽成一个单独的Ui插件, 命名为`DsUi` +近一个半月主要工作内容如下: +* 项目已经开启2Dhdr, 也就是辉光效果, 现在子弹, 开火特效等都有了高光效果 +* 敌人子弹添加红色描边, 更加容易区分敌方子弹 +* 未被拾起的武器现在也能正常开火, 调用`Weapon.Trigger()`, 也就是在地上开火 +* 玩家新增翻滚动作, 移动时按下鼠标右键就可以向运动方向翻滚移动一段距离, 并且期间无敌 +* 新增武器近战攻击动作, 按空格键, 近战可以抵消地方子弹 +* 新增近战武器反弹敌方子弹的功能 +* 新增`Role`击退效果, 被子弹击中, 武器近战等都可以击退`Role`对象, 但是玩家不能被击退 +* 新增房间迷雾功能, 未探索的房间完全变暗, 当玩家第一次进入时迷雾消散, 并开始刷怪, 当玩家离开房间时房间稍微变暗 +* 新增敌人是否显示瞄准辅助线, 开火时是否可以移动, 锁定目标时是否可以旋转枪口朝向的配置 +* 新增`debug`浮动窗口, 用于游戏中查看日志, 代码日志改用`Debug.Log()`和`Debug.LogError()`函数 +* 更换玩家, 门等游戏素材 +* 游戏暂停功能, 按下`esc`键可以呼出暂停菜单 +* 游戏自适应分辨率, 新增全屏设置 +* 修复房间关门后, 物体到达房间门连接处会被判断离开房间的bug +* 修复拾起敌人掉落的汤姆逊冲锋枪第一次按扳机有概率无法开火的bug +* 修复房间门会在消灭所有敌人之前打开的bug + +--- ### 2023-09-06 经过两个月漫长的开发, 新版地牢编辑器初版已经开发完成, 目的为了更加方便开发者和玩家制作地图, 新版地牢编辑器提供功能如下: * 地牢项目管理功能, 可以管理地牢组和房间, 支持房间预览, 支持显示异常房间, 房间支持配置权重 diff --git a/DungeonShooting_ExcelTool/DungeonShooting_ExcelTool.csproj b/DungeonShooting_ExcelTool/DungeonShooting_ExcelTool.csproj index 9a963c3..d171c69 100644 --- a/DungeonShooting_ExcelTool/DungeonShooting_ExcelTool.csproj +++ b/DungeonShooting_ExcelTool/DungeonShooting_ExcelTool.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 enable enable diff --git a/DungeonShooting_ExcelTool/ExcelGenerator.cs b/DungeonShooting_ExcelTool/ExcelGenerator.cs index b400039..d76af05 100644 --- a/DungeonShooting_ExcelTool/ExcelGenerator.cs +++ b/DungeonShooting_ExcelTool/ExcelGenerator.cs @@ -578,9 +578,20 @@ return false; } - return cell.BooleanCellValue; + if (cell.CellType == CellType.Boolean) + { + return cell.BooleanCellValue; + } + + var value = cell.StringCellValue; + if (string.IsNullOrWhiteSpace(value)) + { + return false; + } + + return bool.Parse(value); } - + private static MappingData ConvertToType(string str, int depth = 0) { if (Regex.IsMatch(str, "^\\w+$")) diff --git a/DungeonShooting_Godot/DungeonShooting.csproj b/DungeonShooting_Godot/DungeonShooting.csproj index e36028f..65ee589 100644 --- a/DungeonShooting_Godot/DungeonShooting.csproj +++ b/DungeonShooting_Godot/DungeonShooting.csproj @@ -1,4 +1,4 @@ - + net7.0 true diff --git a/DungeonShooting_Godot/DungeonShooting.csproj.old b/DungeonShooting_Godot/DungeonShooting.csproj.old new file mode 100644 index 0000000..e36028f --- /dev/null +++ b/DungeonShooting_Godot/DungeonShooting.csproj.old @@ -0,0 +1,11 @@ + + + net7.0 + true + + + + + + + \ No newline at end of file diff --git a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.deps.json b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.deps.json index df88148..98c2130 100644 --- a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.deps.json +++ b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.deps.json @@ -1,12 +1,12 @@ { "runtimeTarget": { - "name": ".NETCoreApp,Version=v6.0/win-x64", + "name": ".NETCoreApp,Version=v7.0/win-x64", "signature": "" }, "compilationOptions": {}, "targets": { - ".NETCoreApp,Version=v6.0": {}, - ".NETCoreApp,Version=v6.0/win-x64": { + ".NETCoreApp,Version=v7.0": {}, + ".NETCoreApp,Version=v7.0/win-x64": { "DungeonShooting_ExcelTool/1.0.0": { "dependencies": { "NPOI": "2.6.0" diff --git a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.dll b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.dll index d8ba4b8..f91239a 100644 --- a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.dll +++ b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.dll Binary files differ diff --git a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.exe b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.exe index bb1931a..9c2c323 100644 --- a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.exe +++ b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.exe Binary files differ diff --git a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.pdb b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.pdb index a963cf3..86422eb 100644 --- a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.pdb +++ b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.pdb Binary files differ diff --git a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.runtimeconfig.json b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.runtimeconfig.json index e7b3b03..398903e 100644 --- a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.runtimeconfig.json +++ b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.runtimeconfig.json @@ -1,9 +1,9 @@ { "runtimeOptions": { - "tfm": "net6.0", + "tfm": "net7.0", "framework": { "name": "Microsoft.NETCore.App", - "version": "6.0.0" + "version": "7.0.0" }, "configProperties": { "System.Reflection.Metadata.MetadataUpdater.IsSupported": false diff --git a/DungeonShooting_Godot/excel/excelFile/ActivityObject.xlsx b/DungeonShooting_Godot/excel/excelFile/ActivityObject.xlsx index dbdd157..508bcd9 100644 --- a/DungeonShooting_Godot/excel/excelFile/ActivityObject.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/ActivityObject.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx b/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx new file mode 100644 index 0000000..152aabd --- /dev/null +++ b/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/Sound.xlsx b/DungeonShooting_Godot/excel/excelFile/Sound.xlsx index b2185d4..a17d8a7 100644 --- a/DungeonShooting_Godot/excel/excelFile/Sound.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/Sound.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/Weapon.xlsx b/DungeonShooting_Godot/excel/excelFile/Weapon.xlsx index bba5663..7602be4 100644 --- a/DungeonShooting_Godot/excel/excelFile/Weapon.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/Weapon.xlsx Binary files differ diff --git a/DungeonShooting_Godot/prefab/bullet/Bullet0001.tscn b/DungeonShooting_Godot/prefab/bullet/Bullet0001.tscn index 0a44b2f..858cd81 100644 --- a/DungeonShooting_Godot/prefab/bullet/Bullet0001.tscn +++ b/DungeonShooting_Godot/prefab/bullet/Bullet0001.tscn @@ -13,6 +13,7 @@ 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 [sub_resource type="ShaderMaterial" id="ShaderMaterial_qhkgc"] resource_local_to_scene = true @@ -23,6 +24,7 @@ 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 [sub_resource type="SpriteFrames" id="SpriteFrames_5wvmf"] animations = [{ @@ -51,7 +53,6 @@ material = SubResource("ShaderMaterial_w5w0i") [node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] -modulate = Color(1.6, 1.6, 1.6, 1) material = SubResource("ShaderMaterial_qhkgc") sprite_frames = SubResource("SpriteFrames_5wvmf") diff --git a/DungeonShooting_Godot/prefab/bullet/Bullet0002.tscn b/DungeonShooting_Godot/prefab/bullet/Bullet0002.tscn index 1cb086c..7ff1c64 100644 --- a/DungeonShooting_Godot/prefab/bullet/Bullet0002.tscn +++ b/DungeonShooting_Godot/prefab/bullet/Bullet0002.tscn @@ -13,6 +13,7 @@ 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 [sub_resource type="ShaderMaterial" id="ShaderMaterial_p0wfd"] resource_local_to_scene = true @@ -23,6 +24,7 @@ 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 [sub_resource type="CircleShape2D" id="CircleShape2D_0vxfv"] radius = 3.0 diff --git a/DungeonShooting_Godot/prefab/map/RoomDoor_E.tscn b/DungeonShooting_Godot/prefab/map/RoomDoor_E.tscn index b40786c..3a07eb2 100644 --- a/DungeonShooting_Godot/prefab/map/RoomDoor_E.tscn +++ b/DungeonShooting_Godot/prefab/map/RoomDoor_E.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=7 format=3 uid="uid://yhewdkpru0up"] +[gd_scene load_steps=8 format=3 uid="uid://yhewdkpru0up"] [ext_resource type="Script" path="res://src/game/room/RoomDoor.cs" id="1_4c6sw"] [ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_lwx51"] -[ext_resource type="SpriteFrames" uid="uid://3ps6h2f54qa5" path="res://resource/spriteFrames/other/RoomDoor_EW.tres" id="3_pjvd8"] +[ext_resource type="SpriteFrames" uid="uid://3ps6h2f54qa5" path="res://resource/spriteFrames/other/RoomDoor_E_Up.tres" id="3_pjvd8"] +[ext_resource type="SpriteFrames" uid="uid://b34tddsmqnj8s" path="res://resource/spriteFrames/other/RoomDoor_E_Down.tres" id="4_ln8k4"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_yvwpk"] resource_local_to_scene = true @@ -40,10 +41,21 @@ [node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] material = SubResource("ShaderMaterial_t4ayq") -position = Vector2(0, -8) +position = Vector2(9, -10) sprite_frames = ExtResource("3_pjvd8") -animation = &"closeDoor" +animation = &"openDoor" autoplay = "default" +frame = 4 +frame_progress = 1.0 + +[node name="AnimatedSpriteDown" type="AnimatedSprite2D" parent="."] +material = SubResource("ShaderMaterial_t4ayq") +position = Vector2(9, -10) +sprite_frames = ExtResource("4_ln8k4") +animation = &"openDoor" +autoplay = "default" +frame = 4 +frame_progress = 1.0 [node name="Collision" type="CollisionShape2D" parent="."] position = Vector2(0, 4) diff --git a/DungeonShooting_Godot/prefab/map/RoomDoor_N.tscn b/DungeonShooting_Godot/prefab/map/RoomDoor_N.tscn index 461cf04..52a7d64 100644 --- a/DungeonShooting_Godot/prefab/map/RoomDoor_N.tscn +++ b/DungeonShooting_Godot/prefab/map/RoomDoor_N.tscn @@ -2,14 +2,14 @@ [ext_resource type="Script" path="res://src/game/room/RoomDoor.cs" id="1_220be"] [ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_h5ru6"] -[ext_resource type="SpriteFrames" uid="uid://xs72aopsgpg6" path="res://resource/spriteFrames/other/RoomDoor_NS.tres" id="3_apluc"] +[ext_resource type="SpriteFrames" uid="uid://xs72aopsgpg6" path="res://resource/spriteFrames/other/RoomDoor_N.tres" id="3_apluc"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_yvwpk"] resource_local_to_scene = true shader = ExtResource("2_h5ru6") shader_parameter/blend = Color(0, 0, 0, 0.470588) shader_parameter/schedule = 1.0 -shader_parameter/alpha = 1.0 +shader_parameter/modulate = Color(1, 1, 1, 1) shader_parameter/show_outline = false shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false @@ -19,7 +19,7 @@ shader = ExtResource("2_h5ru6") shader_parameter/blend = Color(1, 1, 1, 1) shader_parameter/schedule = 0.0 -shader_parameter/alpha = 1.0 +shader_parameter/modulate = Color(1, 1, 1, 1) shader_parameter/show_outline = false shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false @@ -42,8 +42,10 @@ material = SubResource("ShaderMaterial_t4ayq") position = Vector2(0, -8) sprite_frames = ExtResource("3_apluc") -animation = &"openDoor" +animation = &"closeDoor" autoplay = "default" +frame = 4 +frame_progress = 1.0 [node name="Collision" type="CollisionShape2D" parent="."] position = Vector2(0, -3.5) diff --git a/DungeonShooting_Godot/prefab/map/RoomDoor_S.tscn b/DungeonShooting_Godot/prefab/map/RoomDoor_S.tscn index b8cd815..6c07aba 100644 --- a/DungeonShooting_Godot/prefab/map/RoomDoor_S.tscn +++ b/DungeonShooting_Godot/prefab/map/RoomDoor_S.tscn @@ -2,14 +2,14 @@ [ext_resource type="Script" path="res://src/game/room/RoomDoor.cs" id="1_f3qbq"] [ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_6vvcd"] -[ext_resource type="SpriteFrames" uid="uid://xs72aopsgpg6" path="res://resource/spriteFrames/other/RoomDoor_NS.tres" id="3_at5v2"] +[ext_resource type="SpriteFrames" uid="uid://ciqijjxup5356" path="res://resource/spriteFrames/other/RoomDoor_S.tres" id="3_hhmd5"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_yvwpk"] resource_local_to_scene = true shader = ExtResource("2_6vvcd") shader_parameter/blend = Color(0, 0, 0, 0.470588) shader_parameter/schedule = 1.0 -shader_parameter/alpha = 1.0 +shader_parameter/modulate = Color(1, 1, 1, 1) shader_parameter/show_outline = false shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false @@ -19,7 +19,7 @@ shader = ExtResource("2_6vvcd") shader_parameter/blend = Color(1, 1, 1, 1) shader_parameter/schedule = 0.0 -shader_parameter/alpha = 1.0 +shader_parameter/modulate = Color(1, 1, 1, 1) shader_parameter/show_outline = false shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false @@ -41,8 +41,11 @@ [node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] material = SubResource("ShaderMaterial_t4ayq") position = Vector2(0, -8) -sprite_frames = ExtResource("3_at5v2") +sprite_frames = ExtResource("3_hhmd5") +animation = &"openDoor" autoplay = "default" +frame = 4 +frame_progress = 1.0 [node name="Collision" type="CollisionShape2D" parent="."] position = Vector2(0, -3.5) diff --git a/DungeonShooting_Godot/prefab/map/RoomDoor_W.tscn b/DungeonShooting_Godot/prefab/map/RoomDoor_W.tscn index 855e540..d3c5a08 100644 --- a/DungeonShooting_Godot/prefab/map/RoomDoor_W.tscn +++ b/DungeonShooting_Godot/prefab/map/RoomDoor_W.tscn @@ -1,15 +1,16 @@ -[gd_scene load_steps=7 format=3 uid="uid://wmedlesabvr3"] +[gd_scene load_steps=8 format=3 uid="uid://wmedlesabvr3"] [ext_resource type="Script" path="res://src/game/room/RoomDoor.cs" id="1_agux2"] [ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_wx2w3"] -[ext_resource type="SpriteFrames" uid="uid://3ps6h2f54qa5" path="res://resource/spriteFrames/other/RoomDoor_EW.tres" id="3_a2hvw"] +[ext_resource type="SpriteFrames" uid="uid://cpdt5ywrsruu3" path="res://resource/spriteFrames/other/RoomDoor_W_Up.tres" id="3_veggu"] +[ext_resource type="SpriteFrames" uid="uid://qq3h0mh4r12i" path="res://resource/spriteFrames/other/RoomDoor_W_Down.tres" id="4_dnjb6"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_yvwpk"] resource_local_to_scene = true shader = ExtResource("2_wx2w3") shader_parameter/blend = Color(0, 0, 0, 0.470588) shader_parameter/schedule = 1.0 -shader_parameter/alpha = 1.0 +shader_parameter/modulate = Color(1, 1, 1, 1) shader_parameter/show_outline = false shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false @@ -19,7 +20,7 @@ shader = ExtResource("2_wx2w3") shader_parameter/blend = Color(1, 1, 1, 1) shader_parameter/schedule = 0.0 -shader_parameter/alpha = 1.0 +shader_parameter/modulate = Color(1, 1, 1, 1) shader_parameter/show_outline = false shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false @@ -40,9 +41,21 @@ [node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] material = SubResource("ShaderMaterial_t4ayq") -position = Vector2(0, -8) -sprite_frames = ExtResource("3_a2hvw") +position = Vector2(-9, -10) +sprite_frames = ExtResource("3_veggu") +animation = &"openDoor" autoplay = "default" +frame = 4 +frame_progress = 1.0 + +[node name="AnimatedSpriteDown" type="AnimatedSprite2D" parent="."] +material = SubResource("ShaderMaterial_t4ayq") +position = Vector2(-9, -10) +sprite_frames = ExtResource("4_dnjb6") +animation = &"openDoor" +autoplay = "default" +frame = 4 +frame_progress = 1.0 [node name="Collision" type="CollisionShape2D" parent="."] position = Vector2(0, 4) diff --git a/DungeonShooting_Godot/prefab/role/Enemy0001.tscn b/DungeonShooting_Godot/prefab/role/Enemy0001.tscn index 46e01b2..866f829 100644 --- a/DungeonShooting_Godot/prefab/role/Enemy0001.tscn +++ b/DungeonShooting_Godot/prefab/role/Enemy0001.tscn @@ -14,6 +14,7 @@ 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 [sub_resource type="ShaderMaterial" id="ShaderMaterial_k8mt5"] resource_local_to_scene = true @@ -24,6 +25,7 @@ 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 [node name="Enemy0001" node_paths=PackedStringArray("HurtArea", "HurtCollision", "MountPoint", "BackMountPoint", "InteractiveArea", "InteractiveCollision", "MeleeAttackArea", "MeleeAttackCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_5po38")] collision_layer = 16 diff --git a/DungeonShooting_Godot/prefab/ui/Setting.tscn b/DungeonShooting_Godot/prefab/ui/Setting.tscn index c6b1075..85242df 100644 --- a/DungeonShooting_Godot/prefab/ui/Setting.tscn +++ b/DungeonShooting_Godot/prefab/ui/Setting.tscn @@ -285,7 +285,7 @@ [node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key12"] layout_mode = 2 -text = "空格" +text = "鼠标右键" [node name="Key13" type="HBoxContainer" parent="ScrollContainer/KeySetting"] custom_minimum_size = Vector2(600, 0) @@ -300,7 +300,7 @@ [node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key13"] layout_mode = 2 -text = "鼠标右键" +text = "空格" [node name="Back" type="Button" parent="ScrollContainer/KeySetting"] layout_mode = 2 diff --git a/DungeonShooting_Godot/prefab/weapon/WeaponTemplate.tscn b/DungeonShooting_Godot/prefab/weapon/WeaponTemplate.tscn index 81179a1..7b22ce1 100644 --- a/DungeonShooting_Godot/prefab/weapon/WeaponTemplate.tscn +++ b/DungeonShooting_Godot/prefab/weapon/WeaponTemplate.tscn @@ -11,6 +11,7 @@ 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 [sub_resource type="ShaderMaterial" id="ShaderMaterial_o36tv"] resource_local_to_scene = true @@ -21,6 +22,7 @@ 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 [sub_resource type="Animation" id="Animation_x136i"] length = 0.001 @@ -79,6 +81,7 @@ [node name="GripPoint" type="Marker2D" parent="."] [node name="Collision" type="CollisionShape2D" parent="."] +visible = false [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { diff --git a/DungeonShooting_Godot/resource/config/AiAttackAttr.json b/DungeonShooting_Godot/resource/config/AiAttackAttr.json new file mode 100644 index 0000000..010c512 --- /dev/null +++ b/DungeonShooting_Godot/resource/config/AiAttackAttr.json @@ -0,0 +1,68 @@ +[ + { + "Id": "0001", + "Remark": "", + "FiringStand": true, + "ShowSubline": false, + "LockingTime": 1, + "LockAngleTime": 0, + "AttackLockAngle": true, + "BulletSpeedScale": 0.4, + "AmmoConsumptionProbability": 0 + }, + { + "Id": "0002", + "Remark": "", + "FiringStand": true, + "ShowSubline": false, + "LockingTime": 2, + "LockAngleTime": 0, + "AttackLockAngle": false, + "BulletSpeedScale": 0.35, + "AmmoConsumptionProbability": 0 + }, + { + "Id": "0003", + "Remark": "", + "FiringStand": true, + "ShowSubline": false, + "LockingTime": 1, + "LockAngleTime": 0, + "AttackLockAngle": false, + "BulletSpeedScale": 0.35, + "AmmoConsumptionProbability": 0 + }, + { + "Id": "0004", + "Remark": "\u79FB\u52A8\u5C04\u51FB", + "FiringStand": false, + "ShowSubline": false, + "LockingTime": 0.7, + "LockAngleTime": 0, + "AttackLockAngle": true, + "BulletSpeedScale": 0.35, + "AmmoConsumptionProbability": 0 + }, + { + "Id": "0005", + "Remark": "\u4F7F\u7528\u8FDC\u8DDD\u79BB\u6B66\u5668", + "FiringStand": true, + "ShowSubline": true, + "LockingTime": 1.5, + "LockAngleTime": 0.5, + "AttackLockAngle": true, + "BulletSpeedScale": 0.5, + "AmmoConsumptionProbability": 0 + }, + { + "Id": "0006", + "Remark": "", + "FiringStand": true, + "ShowSubline": false, + "LockingTime": 0.5, + "LockAngleTime": 0.5, + "AttackLockAngle": false, + "BulletSpeedScale": 0.35, + "AmmoConsumptionProbability": 0 + } +] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/config/Weapon.json b/DungeonShooting_Godot/resource/config/Weapon.json index 57bbf71..11a4daf 100644 --- a/DungeonShooting_Godot/resource/config/Weapon.json +++ b/DungeonShooting_Godot/resource/config/Weapon.json @@ -88,9 +88,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0002", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0002", @@ -181,9 +179,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 0.5, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0001" }, { "Id": "0003", @@ -275,9 +271,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0004", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0004", @@ -369,9 +363,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 0.4, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0002" }, { "Id": "0005", @@ -462,9 +454,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0006", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0006", @@ -555,9 +545,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 1, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0003" }, { "Id": "0007", @@ -645,9 +633,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0008", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0008", @@ -735,9 +721,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 0.7, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0004" }, { "Id": "0009", @@ -828,9 +812,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0010", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0010", @@ -921,9 +903,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 1.5, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0005" }, { "Id": "0011", @@ -1014,9 +994,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0012", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0012", @@ -1107,9 +1085,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 0.5, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0004" }, { "Id": "0013", @@ -1200,9 +1176,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0014", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0014", @@ -1293,8 +1267,6 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 0.5, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0006" } ] \ 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 f5cded9..d9e69c2 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json @@ -1,40 +1,40 @@ { "TestGroup1": { - "GroupName": "TestGroup1", - "BattleList": [ - { - "ErrorType": 0, - "Path": "resource/map/tileMaps/TestGroup1/battle/Battle1" - }, - { - "ErrorType": 0, - "Path": "resource/map/tileMaps/TestGroup1/battle/Battle2" - }, - { - "ErrorType": 0, - "Path": "resource/map/tileMaps/TestGroup1/battle/Battle3" - } - ], - "InletList": [ - { - "ErrorType": 0, - "Path": "resource/map/tileMaps/TestGroup1/inlet/Start1" - }, - { - "ErrorType": 0, - "Path": "resource/map/tileMaps/TestGroup1/inlet/Start2" - } - ], - "OutletList": [ - { - "ErrorType": 0, - "Path": "resource/map/tileMaps/TestGroup1/outlet/End1" - } - ], - "BossList": [], - "RewardList": [], - "ShopList": [], - "EventList": [], - "Remark": "\u6D4B\u8BD5\u7EC4" + "GroupName": "TestGroup1", + "BattleList": [ + { + "ErrorType": 0, + "Path": "resource/map/tileMaps/TestGroup1/battle/Battle1" + }, + { + "ErrorType": 0, + "Path": "resource/map/tileMaps/TestGroup1/battle/Battle2" + }, + { + "ErrorType": 0, + "Path": "resource/map/tileMaps/TestGroup1/battle/Battle3" + } + ], + "InletList": [ + { + "ErrorType": 0, + "Path": "resource/map/tileMaps/TestGroup1/inlet/Start1" + }, + { + "ErrorType": 0, + "Path": "resource/map/tileMaps/TestGroup1/inlet/Start2" + } + ], + "OutletList": [ + { + "ErrorType": 0, + "Path": "resource/map/tileMaps/TestGroup1/outlet/End1" + } + ], + "BossList": [], + "RewardList": [], + "ShopList": [], + "EventList": [], + "Remark": "\u6D4B\u8BD5\u7EC4" } -} +} \ No newline at end of file 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 fd75129..582ee5f 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":-76,"Y":35},"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":-79,"Y":46},"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":-75,"Y":2},"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":-75,"Y":67},"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":-73,"Y":-18},"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":-76,"Y":21},"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":-74,"Y":-30},"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 +[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":19,"Y":2},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":-76,"Y":35},"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":-79,"Y":46},"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":-75,"Y":2},"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":-75,"Y":67},"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":-73,"Y":-18},"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":-76,"Y":21},"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":-74,"Y":-30},"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}]},{"Position":{"X":-16,"Y":16},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0005","CurrAmmon":"10","ResidueAmmo":"10"},"Altitude":0,"VerticalSpeed":0}]}]]}] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/material/Blend.gdshader b/DungeonShooting_Godot/resource/material/Blend.gdshader index f83601b..f952fc5 100644 --- a/DungeonShooting_Godot/resource/material/Blend.gdshader +++ b/DungeonShooting_Godot/resource/material/Blend.gdshader @@ -4,8 +4,7 @@ uniform vec4 blend : source_color = vec4(1.0, 1.0, 1.0, 1.0); //混合度 uniform float schedule : hint_range(0.0, 1.0) = 0.0; -//透明度 -//uniform float alpha : hint_range(0.0, 1.0) = 1.0; +// uniform vec4 modulate : source_color = vec4(1.0, 1.0, 1.0, 1.0); //------------------ 轮廓相关 -------------- @@ -13,15 +12,18 @@ //轮廓颜色 uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0); //是否是彩虹轮廓 -uniform bool outline_rainbow = false; +uniform bool outline_rainbow = false; +//轮廓是否使用 blend +uniform bool outline_use_blend = true; + //彩虹轮廓变化周期 const float frequency = 0.25; const float light_offset = 0.5; void fragment() { + float a = COLOR.a; //显示轮廓 - if (show_outline) { - vec4 color = texture(TEXTURE, UV); + if (show_outline && a == 0.0) { vec2 size = TEXTURE_PIXEL_SIZE; float outline; outline = texture(TEXTURE, UV + vec2(-size.x, 0)).a; @@ -29,25 +31,28 @@ outline += texture(TEXTURE, UV + vec2(size.x, 0)).a; outline += texture(TEXTURE, UV + vec2(0, -size.y)).a; outline = min(outline, 1.0); - - if (color.a == 0.0 && outline > 0.0) { - vec4 animated_line_color = vec4( - light_offset + sin(2.0 * 3.14 * frequency * TIME), - light_offset + sin(2.0 * 3.14 * frequency * TIME + radians(120.0)), - light_offset + sin(2.0 * 3.14 * frequency * TIME + radians(240.0)), - 1.0 - ); - + if (outline > 0.0) { if (outline_rainbow){ - COLOR = mix(color, animated_line_color, 1); + vec4 animated_line_color = vec4( + light_offset + sin(2.0 * 3.14 * frequency * TIME), + light_offset + sin(2.0 * 3.14 * frequency * TIME + radians(120.0)), + light_offset + sin(2.0 * 3.14 * frequency * TIME + radians(240.0)), + 1.0 + ); + COLOR = mix(COLOR, animated_line_color, 1); + a = animated_line_color.a; } else { - COLOR = mix(color, outline_color , 1); + COLOR = mix(COLOR, outline_color , 1); + a = outline_color.a; } } + if (outline_use_blend) { + COLOR = mix(COLOR, blend, schedule); + } + } else { //非轮廓 + COLOR = mix(COLOR, blend, schedule); } - vec4 col = mix(COLOR, blend, schedule); - col = mix(vec4(0.0, 0.0, 0.0, 0.0), col, COLOR.a); - col *= modulate; - COLOR = col; + COLOR.a *= a; + COLOR *= modulate; } diff --git a/DungeonShooting_Godot/resource/sprite/map/door.png b/DungeonShooting_Godot/resource/sprite/map/door.png new file mode 100644 index 0000000..5a02887 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/map/door.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/map/door.png.import b/DungeonShooting_Godot/resource/sprite/map/door.png.import new file mode 100644 index 0000000..d2fa145 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/map/door.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://f7d7qsdxqx28" +path="res://.godot/imported/door.png-df89cda31b3be3b13dd6a96afcb773e6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/sprite/map/door.png" +dest_files=["res://.godot/imported/door.png-df89cda31b3be3b13dd6a96afcb773e6.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/other/RoomDoor_EW.tres b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_EW.tres deleted file mode 100644 index 2c7c77e..0000000 --- a/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_EW.tres +++ /dev/null @@ -1,161 +0,0 @@ -[gd_resource type="SpriteFrames" load_steps=22 format=3 uid="uid://3ps6h2f54qa5"] - -[ext_resource type="Texture2D" uid="uid://dviv44fhwvkb1" path="res://resource/sprite/map/door1_down.png" id="1_peglf"] - -[sub_resource type="AtlasTexture" id="AtlasTexture_5m6ya"] -atlas = ExtResource("1_peglf") -region = Rect2(144, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_kmhtl"] -atlas = ExtResource("1_peglf") -region = Rect2(128, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_umaop"] -atlas = ExtResource("1_peglf") -region = Rect2(112, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_aqex7"] -atlas = ExtResource("1_peglf") -region = Rect2(96, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_hdocg"] -atlas = ExtResource("1_peglf") -region = Rect2(80, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_aiymw"] -atlas = ExtResource("1_peglf") -region = Rect2(64, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_8f7dv"] -atlas = ExtResource("1_peglf") -region = Rect2(32, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_iv82l"] -atlas = ExtResource("1_peglf") -region = Rect2(16, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_ycmnv"] -atlas = ExtResource("1_peglf") -region = Rect2(0, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_o7xw0"] -atlas = ExtResource("1_peglf") -region = Rect2(144, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_j8iw2"] -atlas = ExtResource("1_peglf") -region = Rect2(0, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_823if"] -atlas = ExtResource("1_peglf") -region = Rect2(16, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_7hyae"] -atlas = ExtResource("1_peglf") -region = Rect2(32, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_6lhu3"] -atlas = ExtResource("1_peglf") -region = Rect2(48, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_a026j"] -atlas = ExtResource("1_peglf") -region = Rect2(64, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_wfjf7"] -atlas = ExtResource("1_peglf") -region = Rect2(80, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_rhj60"] -atlas = ExtResource("1_peglf") -region = Rect2(96, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_06y08"] -atlas = ExtResource("1_peglf") -region = Rect2(112, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_1200j"] -atlas = ExtResource("1_peglf") -region = Rect2(128, 48, 16, 48) - -[sub_resource type="AtlasTexture" id="AtlasTexture_mbnbx"] -atlas = ExtResource("1_peglf") -region = Rect2(144, 48, 16, 48) - -[resource] -animations = [{ -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_5m6ya") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_kmhtl") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_umaop") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_aqex7") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_hdocg") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_aiymw") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_8f7dv") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_iv82l") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_ycmnv") -}], -"loop": false, -"name": &"closeDoor", -"speed": 20.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_o7xw0") -}], -"loop": false, -"name": &"default", -"speed": 20.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_j8iw2") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_823if") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_7hyae") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_6lhu3") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_a026j") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_wfjf7") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_rhj60") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_06y08") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_1200j") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_mbnbx") -}], -"loop": false, -"name": &"openDoor", -"speed": 20.0 -}] diff --git a/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_E_Down.tres b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_E_Down.tres new file mode 100644 index 0000000..9669b44 --- /dev/null +++ b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_E_Down.tres @@ -0,0 +1,98 @@ +[gd_resource type="SpriteFrames" load_steps=13 format=3 uid="uid://b34tddsmqnj8s"] + +[ext_resource type="Texture2D" uid="uid://f7d7qsdxqx28" path="res://resource/sprite/map/door.png" id="1_nc77d"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_4o2e1"] +atlas = ExtResource("1_nc77d") +region = Rect2(128, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_d1gjl"] +atlas = ExtResource("1_nc77d") +region = Rect2(96, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_g4rm7"] +atlas = ExtResource("1_nc77d") +region = Rect2(64, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_5d5bq"] +atlas = ExtResource("1_nc77d") +region = Rect2(32, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ekma7"] +atlas = ExtResource("1_nc77d") +region = Rect2(0, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_7y01b"] +atlas = ExtResource("1_nc77d") +region = Rect2(128, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_jm1e2"] +atlas = ExtResource("1_nc77d") +region = Rect2(0, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_1bb60"] +atlas = ExtResource("1_nc77d") +region = Rect2(32, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_oylje"] +atlas = ExtResource("1_nc77d") +region = Rect2(64, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_truep"] +atlas = ExtResource("1_nc77d") +region = Rect2(96, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_lfr82"] +atlas = ExtResource("1_nc77d") +region = Rect2(128, 104, 32, 52) + +[resource] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_4o2e1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_d1gjl") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_g4rm7") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_5d5bq") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ekma7") +}], +"loop": false, +"name": &"closeDoor", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_7y01b") +}], +"loop": false, +"name": &"default", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_jm1e2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_1bb60") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_oylje") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_truep") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_lfr82") +}], +"loop": false, +"name": &"openDoor", +"speed": 10.0 +}] diff --git a/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_E_Up.tres b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_E_Up.tres new file mode 100644 index 0000000..8e74aa6 --- /dev/null +++ b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_E_Up.tres @@ -0,0 +1,98 @@ +[gd_resource type="SpriteFrames" load_steps=13 format=3 uid="uid://3ps6h2f54qa5"] + +[ext_resource type="Texture2D" uid="uid://f7d7qsdxqx28" path="res://resource/sprite/map/door.png" id="2_u3fum"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_8f67t"] +atlas = ExtResource("2_u3fum") +region = Rect2(128, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qlja2"] +atlas = ExtResource("2_u3fum") +region = Rect2(96, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_glno6"] +atlas = ExtResource("2_u3fum") +region = Rect2(64, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_frnbt"] +atlas = ExtResource("2_u3fum") +region = Rect2(32, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_2ytfc"] +atlas = ExtResource("2_u3fum") +region = Rect2(0, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_oyi3c"] +atlas = ExtResource("2_u3fum") +region = Rect2(128, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_e68us"] +atlas = ExtResource("2_u3fum") +region = Rect2(0, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_e7wqp"] +atlas = ExtResource("2_u3fum") +region = Rect2(32, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qcket"] +atlas = ExtResource("2_u3fum") +region = Rect2(64, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_genp5"] +atlas = ExtResource("2_u3fum") +region = Rect2(96, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_krdph"] +atlas = ExtResource("2_u3fum") +region = Rect2(128, 52, 32, 52) + +[resource] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_8f67t") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_qlja2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_glno6") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_frnbt") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_2ytfc") +}], +"loop": false, +"name": &"closeDoor", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_oyi3c") +}], +"loop": false, +"name": &"default", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_e68us") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_e7wqp") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_qcket") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_genp5") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_krdph") +}], +"loop": false, +"name": &"openDoor", +"speed": 10.0 +}] diff --git a/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_N.tres b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_N.tres new file mode 100644 index 0000000..1d7086c --- /dev/null +++ b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_N.tres @@ -0,0 +1,98 @@ +[gd_resource type="SpriteFrames" load_steps=13 format=3 uid="uid://xs72aopsgpg6"] + +[ext_resource type="Texture2D" uid="uid://f7d7qsdxqx28" path="res://resource/sprite/map/door.png" id="1_6mlq3"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_jiqrp"] +atlas = ExtResource("1_6mlq3") +region = Rect2(288, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_id4d1"] +atlas = ExtResource("1_6mlq3") +region = Rect2(256, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_dun04"] +atlas = ExtResource("1_6mlq3") +region = Rect2(224, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_1rfr2"] +atlas = ExtResource("1_6mlq3") +region = Rect2(192, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_c8ka5"] +atlas = ExtResource("1_6mlq3") +region = Rect2(160, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_3jbbr"] +atlas = ExtResource("1_6mlq3") +region = Rect2(288, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_xuwj8"] +atlas = ExtResource("1_6mlq3") +region = Rect2(160, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_xx0rn"] +atlas = ExtResource("1_6mlq3") +region = Rect2(192, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_5h1on"] +atlas = ExtResource("1_6mlq3") +region = Rect2(224, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_rwd5l"] +atlas = ExtResource("1_6mlq3") +region = Rect2(256, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_wov8g"] +atlas = ExtResource("1_6mlq3") +region = Rect2(288, 0, 32, 52) + +[resource] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_jiqrp") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_id4d1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_dun04") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_1rfr2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_c8ka5") +}], +"loop": false, +"name": &"closeDoor", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_3jbbr") +}], +"loop": false, +"name": &"default", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_xuwj8") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_xx0rn") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_5h1on") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_rwd5l") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_wov8g") +}], +"loop": false, +"name": &"openDoor", +"speed": 10.0 +}] diff --git a/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_NS.tres b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_NS.tres deleted file mode 100644 index dfc5109..0000000 --- a/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_NS.tres +++ /dev/null @@ -1,155 +0,0 @@ -[gd_resource type="SpriteFrames" load_steps=21 format=3 uid="uid://xs72aopsgpg6"] - -[ext_resource type="Texture2D" uid="uid://dviv44fhwvkb1" path="res://resource/sprite/map/door1_down.png" id="1_ugffo"] - - -[sub_resource type="AtlasTexture" id="AtlasTexture_77i3w"] -atlas = ExtResource("1_ugffo") -region = Rect2(256, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_112lq"] -atlas = ExtResource("1_ugffo") -region = Rect2(224, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_2ojr8"] -atlas = ExtResource("1_ugffo") -region = Rect2(192, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_q58ag"] -atlas = ExtResource("1_ugffo") -region = Rect2(160, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_ghweb"] -atlas = ExtResource("1_ugffo") -region = Rect2(128, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_28y4l"] -atlas = ExtResource("1_ugffo") -region = Rect2(96, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_0fk5y"] -atlas = ExtResource("1_ugffo") -region = Rect2(64, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_eu8jg"] -atlas = ExtResource("1_ugffo") -region = Rect2(32, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_rw4x5"] -atlas = ExtResource("1_ugffo") -region = Rect2(0, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_5dlkq"] -atlas = ExtResource("1_ugffo") -region = Rect2(256, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_dnc85"] -atlas = ExtResource("1_ugffo") -region = Rect2(0, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_8wepo"] -atlas = ExtResource("1_ugffo") -region = Rect2(32, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_s2c1g"] -atlas = ExtResource("1_ugffo") -region = Rect2(64, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_umj5m"] -atlas = ExtResource("1_ugffo") -region = Rect2(96, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_sceep"] -atlas = ExtResource("1_ugffo") -region = Rect2(128, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_0vntu"] -atlas = ExtResource("1_ugffo") -region = Rect2(160, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_66ox7"] -atlas = ExtResource("1_ugffo") -region = Rect2(192, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_o2uxo"] -atlas = ExtResource("1_ugffo") -region = Rect2(224, 0, 32, 32) - -[sub_resource type="AtlasTexture" id="AtlasTexture_m6v3e"] -atlas = ExtResource("1_ugffo") -region = Rect2(256, 0, 32, 32) - -[resource] -animations = [{ -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_77i3w") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_112lq") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_2ojr8") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_q58ag") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_ghweb") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_28y4l") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_0fk5y") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_eu8jg") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_rw4x5") -}], -"loop": false, -"name": &"closeDoor", -"speed": 20.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_5dlkq") -}], -"loop": false, -"name": &"default", -"speed": 20.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_dnc85") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_8wepo") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_s2c1g") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_umj5m") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_sceep") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_0vntu") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_66ox7") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_o2uxo") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_m6v3e") -}], -"loop": false, -"name": &"openDoor", -"speed": 20.0 -}] diff --git a/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_S.tres b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_S.tres new file mode 100644 index 0000000..5988cc3 --- /dev/null +++ b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_S.tres @@ -0,0 +1,98 @@ +[gd_resource type="SpriteFrames" load_steps=13 format=3 uid="uid://ciqijjxup5356"] + +[ext_resource type="Texture2D" uid="uid://f7d7qsdxqx28" path="res://resource/sprite/map/door.png" id="1_46oik"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_w2vr1"] +atlas = ExtResource("1_46oik") +region = Rect2(128, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_3akio"] +atlas = ExtResource("1_46oik") +region = Rect2(96, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_xxpwm"] +atlas = ExtResource("1_46oik") +region = Rect2(64, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_vjx8u"] +atlas = ExtResource("1_46oik") +region = Rect2(32, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_clyvp"] +atlas = ExtResource("1_46oik") +region = Rect2(0, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_1vfst"] +atlas = ExtResource("1_46oik") +region = Rect2(128, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8wrb5"] +atlas = ExtResource("1_46oik") +region = Rect2(0, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_nwt0b"] +atlas = ExtResource("1_46oik") +region = Rect2(32, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ohokj"] +atlas = ExtResource("1_46oik") +region = Rect2(64, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_wqsd1"] +atlas = ExtResource("1_46oik") +region = Rect2(96, 0, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_i6sro"] +atlas = ExtResource("1_46oik") +region = Rect2(128, 0, 32, 52) + +[resource] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_w2vr1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_3akio") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_xxpwm") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_vjx8u") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_clyvp") +}], +"loop": false, +"name": &"closeDoor", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_1vfst") +}], +"loop": false, +"name": &"default", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_8wrb5") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_nwt0b") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ohokj") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_wqsd1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_i6sro") +}], +"loop": false, +"name": &"openDoor", +"speed": 10.0 +}] diff --git a/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_W_Down.tres b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_W_Down.tres new file mode 100644 index 0000000..86fc6ad --- /dev/null +++ b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_W_Down.tres @@ -0,0 +1,98 @@ +[gd_resource type="SpriteFrames" load_steps=13 format=3 uid="uid://qq3h0mh4r12i"] + +[ext_resource type="Texture2D" uid="uid://f7d7qsdxqx28" path="res://resource/sprite/map/door.png" id="1_b4js3"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_526no"] +atlas = ExtResource("1_b4js3") +region = Rect2(288, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_84kmd"] +atlas = ExtResource("1_b4js3") +region = Rect2(256, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_km4i6"] +atlas = ExtResource("1_b4js3") +region = Rect2(224, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_wtul1"] +atlas = ExtResource("1_b4js3") +region = Rect2(192, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_vbu5n"] +atlas = ExtResource("1_b4js3") +region = Rect2(160, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_yxx5v"] +atlas = ExtResource("1_b4js3") +region = Rect2(288, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_4ncdo"] +atlas = ExtResource("1_b4js3") +region = Rect2(160, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_bxfu1"] +atlas = ExtResource("1_b4js3") +region = Rect2(192, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8082a"] +atlas = ExtResource("1_b4js3") +region = Rect2(224, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_mjuqg"] +atlas = ExtResource("1_b4js3") +region = Rect2(256, 104, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_rc634"] +atlas = ExtResource("1_b4js3") +region = Rect2(288, 104, 32, 52) + +[resource] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_526no") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_84kmd") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_km4i6") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_wtul1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_vbu5n") +}], +"loop": false, +"name": &"closeDoor", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_yxx5v") +}], +"loop": false, +"name": &"default", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_4ncdo") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_bxfu1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8082a") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_mjuqg") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_rc634") +}], +"loop": false, +"name": &"openDoor", +"speed": 10.0 +}] diff --git a/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_W_Up.tres b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_W_Up.tres new file mode 100644 index 0000000..6c18e9e --- /dev/null +++ b/DungeonShooting_Godot/resource/spriteFrames/other/RoomDoor_W_Up.tres @@ -0,0 +1,98 @@ +[gd_resource type="SpriteFrames" load_steps=13 format=3 uid="uid://cpdt5ywrsruu3"] + +[ext_resource type="Texture2D" uid="uid://f7d7qsdxqx28" path="res://resource/sprite/map/door.png" id="2_klr41"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_skb20"] +atlas = ExtResource("2_klr41") +region = Rect2(288, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_dk55p"] +atlas = ExtResource("2_klr41") +region = Rect2(256, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_78qdb"] +atlas = ExtResource("2_klr41") +region = Rect2(224, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_sqirq"] +atlas = ExtResource("2_klr41") +region = Rect2(192, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_c65nc"] +atlas = ExtResource("2_klr41") +region = Rect2(160, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_6tswf"] +atlas = ExtResource("2_klr41") +region = Rect2(288, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_hg8wo"] +atlas = ExtResource("2_klr41") +region = Rect2(160, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qkhur"] +atlas = ExtResource("2_klr41") +region = Rect2(192, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_6rqcm"] +atlas = ExtResource("2_klr41") +region = Rect2(224, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_y0tub"] +atlas = ExtResource("2_klr41") +region = Rect2(256, 52, 32, 52) + +[sub_resource type="AtlasTexture" id="AtlasTexture_w8xe5"] +atlas = ExtResource("2_klr41") +region = Rect2(288, 52, 32, 52) + +[resource] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_skb20") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_dk55p") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_78qdb") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_sqirq") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_c65nc") +}], +"loop": false, +"name": &"closeDoor", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_6tswf") +}], +"loop": false, +"name": &"default", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_hg8wo") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_qkhur") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_6rqcm") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_y0tub") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_w8xe5") +}], +"loop": false, +"name": &"openDoor", +"speed": 10.0 +}] diff --git a/DungeonShooting_Godot/src/config/ExcelConfig.cs b/DungeonShooting_Godot/src/config/ExcelConfig.cs index 86550d4..6416ead 100644 --- a/DungeonShooting_Godot/src/config/ExcelConfig.cs +++ b/DungeonShooting_Godot/src/config/ExcelConfig.cs @@ -17,6 +17,15 @@ public static Dictionary ActivityObject_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; } + + /// /// Sound.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同 /// public static List Sound_List { get; private set; } @@ -45,6 +54,7 @@ _init = true; _InitActivityObjectConfig(); + _InitAiAttackAttrConfig(); _InitSoundConfig(); _InitWeaponConfig(); @@ -64,10 +74,28 @@ } catch (Exception e) { - Debug.LogError(e.ToString()); + GD.PrintErr(e.ToString()); throw new Exception("初始化表'ActivityObject'失败!"); } } + 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 _InitSoundConfig() { try @@ -82,7 +110,7 @@ } catch (Exception e) { - Debug.LogError(e.ToString()); + GD.PrintErr(e.ToString()); throw new Exception("初始化表'Sound'失败!"); } } @@ -100,7 +128,7 @@ } catch (Exception e) { - Debug.LogError(e.ToString()); + GD.PrintErr(e.ToString()); throw new Exception("初始化表'Weapon'失败!"); } } @@ -150,10 +178,15 @@ item.AiUseAttribute = Weapon_Map[item.__AiUseAttribute]; } + if (!string.IsNullOrEmpty(item.__AiAttackAttr)) + { + item.AiAttackAttr = AiAttackAttr_Map[item.__AiAttackAttr]; + } + } catch (Exception e) { - Debug.LogError(e.ToString()); + GD.PrintErr(e.ToString()); throw new Exception("初始化'Weapon'引用其他表数据失败, 当前行id: " + item.Id); } } diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs b/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs new file mode 100644 index 0000000..0dceead --- /dev/null +++ b/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs @@ -0,0 +1,88 @@ +using System.Text.Json.Serialization; +using System.Collections.Generic; + +namespace Config; + +public static partial class ExcelConfig +{ + public class AiAttackAttr + { + /// + /// Id + /// + [JsonInclude] + public string Id; + + /// + /// 备注 + /// + [JsonInclude] + public string Remark; + + /// + /// 开火时是否站立不动 + /// + [JsonInclude] + public bool FiringStand; + + /// + /// 是否显示射击辅助线 + /// + [JsonInclude] + public bool ShowSubline; + + /// + /// Ai属性
+ /// 目标锁定时间, 也就是瞄准目标多久才会开火, (单位: 秒) + ///
+ [JsonInclude] + public float LockingTime; + + /// + /// 从锁定目标到开火前有多少时间不能够改变枪口角度
+ /// 这个值必须小于LockingTime
+ /// 如果为0, 则不会锁定开火角度
+ /// (单位: 秒) + ///
+ [JsonInclude] + public float LockAngleTime; + + /// + /// 开火时是否锁定枪口角度 + /// + [JsonInclude] + public bool AttackLockAngle; + + /// + /// Ai属性
+ /// Ai使用该武器发射的子弹速度缩放比 + ///
+ [JsonInclude] + public float BulletSpeedScale; + + /// + /// Ai属性
+ /// Ai使用该武器消耗弹药的概率, (0 - 1) + ///
+ [JsonInclude] + public float AmmoConsumptionProbability; + + /// + /// 返回浅拷贝出的新对象 + /// + public AiAttackAttr Clone() + { + var inst = new AiAttackAttr(); + inst.Id = Id; + inst.Remark = Remark; + inst.FiringStand = FiringStand; + inst.ShowSubline = ShowSubline; + inst.LockingTime = LockingTime; + inst.LockAngleTime = LockAngleTime; + inst.AttackLockAngle = AttackLockAngle; + inst.BulletSpeedScale = BulletSpeedScale; + inst.AmmoConsumptionProbability = AmmoConsumptionProbability; + return inst; + } + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_Weapon.cs b/DungeonShooting_Godot/src/config/ExcelConfig_Weapon.cs index 2496449..c9dd584 100644 --- a/DungeonShooting_Godot/src/config/ExcelConfig_Weapon.cs +++ b/DungeonShooting_Godot/src/config/ExcelConfig_Weapon.cs @@ -392,25 +392,10 @@ public Weapon AiUseAttribute; /// - /// Ai属性
- /// 目标锁定时间, 也就是瞄准目标多久才会开火, (单位: 秒) + /// Ai使用该武器开火时的一些额外配置属性
+ /// 玩家使用的武器不需要填写该字段 ///
- [JsonInclude] - public float AiTargetLockingTime; - - /// - /// Ai属性
- /// Ai使用该武器发射的子弹速度缩放比 - ///
- [JsonInclude] - public float AiBulletSpeedScale; - - /// - /// Ai属性
- /// Ai使用该武器消耗弹药的概率, (0 - 1) - ///
- [JsonInclude] - public float AiAmmoConsumptionProbability; + public AiAttackAttr AiAttackAttr; /// /// 返回浅拷贝出的新对象 @@ -480,9 +465,7 @@ inst.BeLoadedSoundDelayTime = BeLoadedSoundDelayTime; inst.OtherSoundMap = OtherSoundMap; inst.AiUseAttribute = AiUseAttribute; - inst.AiTargetLockingTime = AiTargetLockingTime; - inst.AiBulletSpeedScale = AiBulletSpeedScale; - inst.AiAmmoConsumptionProbability = AiAmmoConsumptionProbability; + inst.AiAttackAttr = AiAttackAttr; return inst; } } @@ -509,5 +492,8 @@ [JsonInclude] public string __AiUseAttribute; + [JsonInclude] + public string __AiAttackAttr; + } } \ 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 3a6a47a..03cead3 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -753,7 +753,22 @@ { var component = new T(); _components.Add(new KeyValuePair(typeof(T), component)); - component.ActivityInstance = this; + component.Master = this; + component.Ready(); + component.OnEnable(); + return component; + } + + /// + /// 往当前物体上挂载一个组件 + /// + public Component AddComponent(Type type) + { + var component = (Component)Activator.CreateInstance(type); + _components.Add(new KeyValuePair(type, component)); + component.Master = this; + component.Ready(); + component.OnEnable(); return component; } @@ -877,14 +892,8 @@ { if (IsDestroyed) return; var temp = arr[i].Value; - if (temp != null && temp.ActivityInstance == this && temp.Enable) + if (temp != null && temp.Master == this && temp.Enable) { - if (!temp.IsReady) - { - temp.Ready(); - temp.IsReady = true; - } - temp.Process(newDelta); } } @@ -893,12 +902,6 @@ { if (MoveController.Enable) { - if (!MoveController.IsReady) - { - MoveController.Ready(); - MoveController.IsReady = true; - } - MoveController.Process(newDelta); } } @@ -1089,14 +1092,8 @@ { if (IsDestroyed) return; var temp = arr[i].Value; - if (temp != null && temp.ActivityInstance == this && temp.Enable) + if (temp != null && temp.Master == this && temp.Enable) { - if (!temp.IsReady) - { - temp.Ready(); - temp.IsReady = true; - } - temp.PhysicsProcess(newDelta); } } @@ -1105,12 +1102,6 @@ { if (MoveController.Enable) { - if (!MoveController.IsReady) - { - MoveController.Ready(); - MoveController.IsReady = true; - } - MoveController.PhysicsProcess(newDelta); } } @@ -1140,7 +1131,7 @@ { if (IsDestroyed) return; var temp = arr[i].Value; - if (temp != null && temp.ActivityInstance == this && temp.Enable) + if (temp != null && temp.Master == this && temp.Enable) { temp.DebugDraw(); } diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs index 8b3dd8a..3ff5957 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs @@ -1,8 +1,6 @@ using Config; -/// -/// 根据配置表注册物体, 该类是自动生成的, 请不要手动编辑! -/// +// 根据配置表注册物体, 该类是自动生成的, 请不要手动编辑! public partial class ActivityObject { /// diff --git a/DungeonShooting_Godot/src/framework/activity/Component.cs b/DungeonShooting_Godot/src/framework/activity/Component.cs index ec1897d..a33d5e2 100644 --- a/DungeonShooting_Godot/src/framework/activity/Component.cs +++ b/DungeonShooting_Godot/src/framework/activity/Component.cs @@ -1,24 +1,36 @@ +using System; using System.Collections; using Godot; /// /// 组件基类, 用于挂载到游戏物体上, 相比于原生 Node 更加轻量化, 实例化 Component 不会创建额外的 Node, 可以大量添加组件 /// +public abstract class Component : Component where T : ActivityObject +{ + /// + /// 当前组件所挂载的游戏对象 + /// + public new T Master => (T)base.Master; +} + +/// +/// 组件基类, 用于挂载到游戏物体上, 相比于原生 Node 更加轻量化, 实例化 Component 不会创建额外的 Node, 可以大量添加组件 +/// public abstract class Component : IProcess, IDestroy, ICoroutine { /// /// 当前组件所挂载的游戏对象 /// - public ActivityObject ActivityInstance { get; internal set; } + public ActivityObject Master { get; internal set; } /// /// 当前组件所挂载的物体的坐标 /// public Vector2 Position { - get => ActivityInstance.Position; - set => ActivityInstance.Position = value; + get => Master.Position; + set => Master.Position = value; } /// @@ -26,8 +38,8 @@ /// public Vector2 GlobalPosition { - get => ActivityInstance.GlobalPosition; - set => ActivityInstance.GlobalPosition = value; + get => Master.GlobalPosition; + set => Master.GlobalPosition = value; } /// @@ -35,8 +47,8 @@ /// public Vector2 Scale { - get => ActivityInstance.Scale; - set => ActivityInstance.Scale = value; + get => Master.Scale; + set => Master.Scale = value; } /// @@ -44,8 +56,8 @@ /// public Vector2 GlobalScale { - get => ActivityInstance.GlobalScale; - set => ActivityInstance.GlobalScale = value; + get => Master.GlobalScale; + set => Master.GlobalScale = value; } /// @@ -53,8 +65,8 @@ /// public float Rotation { - get => ActivityInstance.Rotation; - set => ActivityInstance.Rotation = value; + get => Master.Rotation; + set => Master.Rotation = value; } /// @@ -62,8 +74,8 @@ /// public float GlobalRotation { - get => ActivityInstance.GlobalRotation; - set => ActivityInstance.GlobalRotation = value; + get => Master.GlobalRotation; + set => Master.GlobalRotation = value; } /// @@ -71,8 +83,8 @@ /// public float RotationDegrees { - get => ActivityInstance.RotationDegrees; - set => ActivityInstance.RotationDegrees = value; + get => Master.RotationDegrees; + set => Master.RotationDegrees = value; } /// @@ -80,8 +92,8 @@ /// public float GlobalRotationDegrees { - get => ActivityInstance.GlobalRotationDegrees; - set => ActivityInstance.GlobalRotationDegrees = value; + get => Master.GlobalRotationDegrees; + set => Master.GlobalRotationDegrees = value; } /// @@ -89,8 +101,8 @@ /// public int ZIndex { - get => ActivityInstance.ZIndex; - set => ActivityInstance.ZIndex = value; + get => Master.ZIndex; + set => Master.ZIndex = value; } /// @@ -98,22 +110,26 @@ /// public bool Visible { - get => ActivityInstance.Visible; - set => ActivityInstance.Visible = value; + get => Master.Visible; + set => Master.Visible = value; } /// /// 挂载物体的动画节点 /// - public AnimatedSprite2D AnimatedSprite2D => ActivityInstance.AnimatedSprite; + public AnimatedSprite2D AnimatedSprite => Master.AnimatedSprite; /// /// 挂载物体的阴影节点 /// - public Sprite2D ShadowSprite => ActivityInstance.ShadowSprite; + public Sprite2D ShadowSprite => Master.ShadowSprite; /// /// 挂载物体的碰撞器节点 /// - public CollisionShape2D Collision => ActivityInstance.Collision; + public CollisionShape2D Collision => Master.Collision; + /// + /// 移动控制器 + /// + public MoveController MoveController => Master.MoveController; /// /// 是否启用当前组件, 如果禁用, 则不会调用 Process 和 PhysicsProcess @@ -125,14 +141,14 @@ { if (!_enable && value) { + _enable = true; OnEnable(); } else if (_enable && !value) { + _enable = false; OnDisable(); } - - _enable = value; } } @@ -144,12 +160,7 @@ public bool IsDestroyed { get; private set; } /// - /// 是否调用过 Ready 函数 - /// - public bool IsReady { get; set; } - - /// - /// 第一次调用 Process 或 PhysicsProcess 之前调用 + /// 初始化时调用 /// public virtual void Ready() { @@ -210,27 +221,122 @@ } IsDestroyed = true; - ActivityInstance.RemoveComponent(this); + Master.RemoveComponent(this); OnDestroy(); } + public T AddComponent() where T : Component, new() + { + return Master.AddComponent(); + } + + public Component AddComponent(Type type) + { + return Master.AddComponent(type); + } + + public T GetComponent() where T : Component, new() + { + return Master.GetComponent(); + } + + public Component GetComponent(Type type) + { + return Master.GetComponent(type); + } + + public void RemoveComponent(Component component) + { + Master.RemoveComponent(component); + } + + public void AddChild(Node node) + { + Master.AddChild(node); + } + + public void RemoveChild(Node node) + { + Master.RemoveChild(node); + } + + public int GetChildCount() + { + return Master.GetChildCount(); + } + + public Node GetNode(NodePath path) + { + return Master.GetNode(path); + } + + public T GetNode(NodePath path) where T : class + { + return Master.GetNode(path); + } + + public Node GetNodeOrNull(NodePath path) + { + return Master.GetNodeOrNull(path); + } + + public T GetNodeOrNull(NodePath path) where T : class + { + return Master.GetNodeOrNull(path); + } + + public Node GetParent() + { + return Master.GetParent(); + } + + public T GetParent() where T : class + { + return Master.GetParent(); + } + + public void Reparent(Node node) + { + Master.Reparent(node); + } + + public float GetProcessDeltaTime() + { + return (float)Master.GetProcessDeltaTime(); + } + + public float GetPhysicsProcessDeltaTime() + { + return (float)Master.GetPhysicsProcessDeltaTime(); + } + + public Vector2 GetGlobalMousePosition() + { + return Master.GetGlobalMousePosition(); + } + + public Vector2 GetLocalMousePosition() + { + return Master.GetLocalMousePosition(); + } + public long StartCoroutine(IEnumerator able) { - return ActivityInstance.StartCoroutine(able); + return Master.StartCoroutine(able); } public void StopCoroutine(long coroutineId) { - ActivityInstance.StopCoroutine(coroutineId); + Master.StopCoroutine(coroutineId); } public bool IsCoroutineOver(long coroutineId) { - return ActivityInstance.IsCoroutineOver(coroutineId); + return Master.IsCoroutineOver(coroutineId); } public void StopAllCoroutine() { - ActivityInstance.StopAllCoroutine(); + Master.StopAllCoroutine(); } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs b/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs index 36167b1..9056451 100644 --- a/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs +++ b/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs @@ -18,7 +18,7 @@ /// 这个速度就是物体当前物理帧移动的真实速率, 该速度由物理帧循环计算, 并不会马上更新 /// 该速度就是 BasisVelocity + 外力总和 /// - public Vector2 Velocity => ActivityInstance.Velocity; + public Vector2 Velocity => Master.Velocity; /// /// 物体的基础移动速率 @@ -267,7 +267,7 @@ { if (_basisVelocity == Vector2.Zero && _forceList.Count == 0) { - ActivityInstance.Velocity = Vector2.Zero; + Master.Velocity = Vector2.Zero; return; } @@ -304,13 +304,13 @@ //处理旋转 if (rotationSpeed != 0) { - ActivityInstance.Rotation += rotationSpeed * delta; + Master.Rotation += rotationSpeed * delta; } //衰减旋转速率 for (var i = 0; i < _forceList.Count; i++) { var force = _forceList[i]; - if (force.RotationResistance != 0 && (force.EnableResistanceInTheAir || !ActivityInstance.IsThrowing)) + if (force.RotationResistance != 0 && (force.EnableResistanceInTheAir || !Master.IsThrowing)) { force.RotationSpeed = Mathf.MoveToward(force.RotationSpeed, 0, force.RotationResistance * delta); } @@ -322,10 +322,10 @@ if (finallyVelocity != Vector2.Zero) { //计算移动 - ActivityInstance.Velocity = finallyVelocity; - ActivityInstance.MoveAndSlide(); + Master.Velocity = finallyVelocity; + Master.MoveAndSlide(); //新速度 - var newVelocity = ActivityInstance.Velocity; + var newVelocity = Master.Velocity; if (newVelocity.X == 0f && _basisVelocity.X * finallyVelocity.X > 0) { @@ -338,13 +338,13 @@ } //是否撞到物体 - var collision = ActivityInstance.GetLastSlideCollision(); + var collision = Master.GetLastSlideCollision(); if (collision != null) //执行反弹操作 { var no = collision.GetNormal().Rotated(Mathf.Pi * 0.5f); newVelocity = (finallyVelocity - _basisVelocity).Reflect(no); var length = _forceList.Count; - var v = newVelocity / (length / ActivityInstance.BounceStrength); + var v = newVelocity / (length / Master.BounceStrength); for (var i = 0; i < _forceList.Count; i++) { _forceList[i].Velocity = v; @@ -365,7 +365,7 @@ ); //力速度衰减 - if (force.VelocityResistance != 0 && (force.EnableResistanceInTheAir || !ActivityInstance.IsThrowing)) + if (force.VelocityResistance != 0 && (force.EnableResistanceInTheAir || !Master.IsThrowing)) { force.Velocity = force.Velocity.MoveToward(Vector2.Zero, force.VelocityResistance * delta); } @@ -375,7 +375,7 @@ } else { - ActivityInstance.Velocity = Vector2.Zero; + Master.Velocity = Vector2.Zero; } } @@ -389,33 +389,33 @@ { //绘制力大小和方向 - if (ActivityInstance is Bullet) //不绘制子弹的力 + if (Master is Bullet) //不绘制子弹的力 { return; } var globalRotation = GlobalRotation; - var flag = ActivityInstance.Scale.Y < 0; + var flag = Master.Scale.Y < 0; if (flag) { - ActivityInstance.DrawLine(Vector2.Zero, (BasisVelocity * new Vector2(1, -1)).Rotated(-globalRotation), + Master.DrawLine(Vector2.Zero, (BasisVelocity * new Vector2(1, -1)).Rotated(-globalRotation), Colors.Yellow); } else { - ActivityInstance.DrawLine(Vector2.Zero, BasisVelocity.Rotated(-globalRotation), Colors.Yellow); + Master.DrawLine(Vector2.Zero, BasisVelocity.Rotated(-globalRotation), Colors.Yellow); } foreach (var force in _forceList) { if (flag) { - ActivityInstance.DrawLine(Vector2.Zero, (force.Velocity * new Vector2(1, -1)).Rotated(globalRotation), + Master.DrawLine(Vector2.Zero, (force.Velocity * new Vector2(1, -1)).Rotated(globalRotation), Colors.YellowGreen); } else { - ActivityInstance.DrawLine(Vector2.Zero, force.Velocity.Rotated(-globalRotation), Colors.YellowGreen); + Master.DrawLine(Vector2.Zero, force.Velocity.Rotated(-globalRotation), Colors.YellowGreen); } } } diff --git a/DungeonShooting_Godot/src/framework/activity/components/StateController.cs b/DungeonShooting_Godot/src/framework/activity/components/StateController.cs index d3c1e20..bb1bbd8 100644 --- a/DungeonShooting_Godot/src/framework/activity/components/StateController.cs +++ b/DungeonShooting_Godot/src/framework/activity/components/StateController.cs @@ -60,7 +60,7 @@ return; } - stateBase.Master = ActivityInstance as T; + stateBase.Master = Master as T; stateBase.StateController = this; _states.Add(stateBase.State, stateBase); } diff --git a/DungeonShooting_Godot/src/framework/generator/ExcelGenerator.cs b/DungeonShooting_Godot/src/framework/generator/ExcelGenerator.cs index cd72216..ee59049 100644 --- a/DungeonShooting_Godot/src/framework/generator/ExcelGenerator.cs +++ b/DungeonShooting_Godot/src/framework/generator/ExcelGenerator.cs @@ -56,9 +56,7 @@ } var str = $"using Config;\n\n"; - str += $"/// \n"; - str += $"/// 根据配置表注册物体, 该类是自动生成的, 请不要手动编辑!\n"; - str += $"/// \n"; + str += $"// 根据配置表注册物体, 该类是自动生成的, 请不要手动编辑!\n"; str += $"public partial class ActivityObject\n"; str += $"{{\n"; diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs index d390aef..409eeab 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) { Debug.Log($"执行第{_currWaveIndex}波"); - _coroutineId = GameApplication.Instance.World.StartCoroutine(RunMark(WaveList[_currWaveIndex])); + _coroutineId = World.Current.StartCoroutine(RunMark(WaveList[_currWaveIndex])); _currWaveIndex++; } } @@ -268,7 +268,7 @@ } Debug.Log($"执行第{_currWaveIndex}波"); - _coroutineId = GameApplication.Instance.World.StartCoroutine(RunMark(WaveList[_currWaveIndex])); + _coroutineId = World.Current.StartCoroutine(RunMark(WaveList[_currWaveIndex])); _currWaveIndex++; } @@ -347,7 +347,7 @@ /// public bool IsCurrWaveOver() { - return _coroutineId < 0 || GameApplication.Instance.IsCoroutineOver(_coroutineId); + return _coroutineId < 0 || World.Current.IsCoroutineOver(_coroutineId); } //创建物体 @@ -396,7 +396,7 @@ IsDestroyed = true; if (_coroutineId >= 0) { - GameApplication.Instance.StopCoroutine(_coroutineId); + World.Current.StopCoroutine(_coroutineId); } WaveList.Clear(); diff --git a/DungeonShooting_Godot/src/game/activity/bullet/Bullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/Bullet.cs index e14b273..0cf2a33 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/Bullet.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/Bullet.cs @@ -43,9 +43,9 @@ public int MaxHarm { get; set; } = 4; /// - /// 发射该子弹的角色 + /// 发射该子弹的角色是否是Ai /// - public Role Trigger { get; private set; } + public bool TriggerRoleIsAi { get; set; } // 最大飞行距离 private float MaxDistance; @@ -59,28 +59,28 @@ /// /// 初始化子弹属性 /// - /// 触发开火的角色 + /// 触发开火的角色 /// 射出该子弹的武器 /// 速度 /// 最大飞行距离 /// 位置 /// 角度 /// 攻击目标层级 - public void Init(Role trigger, Weapon weapon, float speed, float maxDistance, Vector2 position, float rotation, uint targetLayer) + public void Init(bool triggerIsAi, Weapon weapon, float speed, float maxDistance, Vector2 position, float rotation, uint targetLayer) { - Trigger = trigger; + TriggerRoleIsAi = triggerIsAi; Weapon = weapon; Role = weapon.Master; AttackLayer = targetLayer; CollisionArea.AreaEntered += OnArea2dEntered; - if (trigger != null && !trigger.IsAi) //只有玩家使用该武器才能获得正常速度的子弹 + if (!triggerIsAi) //只有玩家使用该武器才能获得正常速度的子弹 { FlySpeed = speed; } else { - FlySpeed = speed * weapon.AiUseAttribute.AiBulletSpeedScale; + FlySpeed = speed * weapon.AiUseAttribute.AiAttackAttr.BulletSpeedScale; } MaxDistance = maxDistance; Position = position; @@ -163,7 +163,7 @@ //击退 if (role is not Player) //目标不是玩家才会触发击退 { - var attr = Trigger != null && !Trigger.IsAi ? Weapon.PlayerUseAttribute : Weapon.AiUseAttribute; + var attr = TriggerRoleIsAi ? Weapon.AiUseAttribute : Weapon.PlayerUseAttribute; var repel = Utils.Random.RandomConfigRange(attr.RepelRnage); role.MoveController.AddForce(Vector2.FromAngle(BasisVelocity.Angle()) * repel, repel * 2); } diff --git a/DungeonShooting_Godot/src/game/activity/package/Package.cs b/DungeonShooting_Godot/src/game/activity/package/Package.cs index ca1ad16..378f7ef 100644 --- a/DungeonShooting_Godot/src/game/activity/package/Package.cs +++ b/DungeonShooting_Godot/src/game/activity/package/Package.cs @@ -4,19 +4,12 @@ /// /// 物体背包类 /// -public class Package : IDestroy where T : ActivityObject, IPackageItem +public class Package : Component where T : ActivityObject, IPackageItem { /// /// 当前使用对象改变时回调 /// public event Action ChangeActiveItemEvent; - - public bool IsDestroyed { get; private set; } - - /// - /// 归属者 - /// - public Role Master { get; private set; } /// /// 当前使用的物体对象 @@ -54,12 +47,6 @@ /// public T[] ItemSlot { get; private set; } - public Package(Role master, int capacity) - { - Master = master; - SetCapacity(capacity); - } - /// /// 修改物体背包容量 /// @@ -466,14 +453,8 @@ return null; } - public void Destroy() + public override void OnDestroy() { - if (IsDestroyed) - { - return; - } - - IsDestroyed = true; for (var i = 0; i < ItemSlot.Length; i++) { var activityObject = ItemSlot[i]; diff --git a/DungeonShooting_Godot/src/game/activity/role/Role.cs b/DungeonShooting_Godot/src/game/activity/role/Role.cs index d3ed357..7269052 100644 --- a/DungeonShooting_Godot/src/game/activity/role/Role.cs +++ b/DungeonShooting_Godot/src/game/activity/role/Role.cs @@ -43,9 +43,14 @@ /// 攻击目标的碰撞器所属层级, 数据源自于: /// public uint AttackLayer { get; set; } = PhysicsLayer.Wall; + + /// + /// 该角色敌对目标的碰撞器所属层级, 数据源自于: + /// + public uint EnemyLayer { get; set; } = PhysicsLayer.Enemy; /// - /// 携带的被动道具包裹 + /// 携带的被动道具列表 /// public List BuffPropPack { get; } = new List(); @@ -254,6 +259,11 @@ /// 是否处于近战攻击中 /// public bool IsMeleeAttack { get; private set; } + + /// + /// 瞄准辅助线, 需要手动调用 InitSubLine() 初始化 + /// + public SubLine SubLine { get; private set; } //翻滚冷却计时器 private float _rollCoolingTimer = 0; @@ -402,8 +412,11 @@ public override void OnInit() { - ActivePropsPack = new Package(this, 1); - WeaponPack = new Package(this, 4); + ActivePropsPack = AddComponent>(); + ActivePropsPack.SetCapacity(1); + WeaponPack = AddComponent>(); + WeaponPack.SetCapacity(4); + _startScale = Scale; MountPoint.Master = this; @@ -437,7 +450,7 @@ } //看向目标 - if (LookTarget != null) + if (LookTarget != null && MountLookTarget) { Vector2 pos = LookTarget.GlobalPosition; //脸的朝向 @@ -450,12 +463,8 @@ { Face = FaceDirection.Left; } - - if (MountLookTarget) - { - //枪口跟随目标 - MountPoint.SetLookAt(pos); - } + //枪口跟随目标 + MountPoint.SetLookAt(pos); } //检查可互动的物体 @@ -564,6 +573,19 @@ } /// + /// 初始化瞄准辅助线 + /// + public void InitSubLine() + { + if (SubLine != null) + { + return; + } + + SubLine = AddComponent(); + } + + /// /// 当武器放到后背时调用, 用于设置武器位置和角度 /// /// 武器实例 @@ -630,19 +652,18 @@ public void LookTargetPosition(Vector2 pos) { LookTarget = null; - //脸的朝向 - var gPos = GlobalPosition; - if (pos.X > gPos.X && Face == FaceDirection.Left) - { - Face = FaceDirection.Right; - } - else if (pos.X < gPos.X && Face == FaceDirection.Right) - { - Face = FaceDirection.Left; - } - if (MountLookTarget) { + //脸的朝向 + var gPos = GlobalPosition; + 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); } @@ -936,7 +957,7 @@ _meleeAttackTimer = RoleState.MeleeAttackTime; MountLookTarget = false; - WeaponPack.ActiveItem.TriggerMeleeAttack(this); + //WeaponPack.ActiveItem.TriggerMeleeAttack(this); //播放近战动画 PlayAnimation_MeleeAttack(() => { @@ -1181,4 +1202,35 @@ { _rollCoolingTimer = RoleState.RollTime; } + + /// + /// 返回当前角色是否是玩家 + /// + public bool IsPlayer() + { + return this == Player.Current; + } + + /// + /// 是否是玩家的敌人 + /// + public bool IsEnemyWithPlayer() + { + return CollisionWithMask(Player.Current.EnemyLayer); + } + + /// + /// 将 Role 子节点的旋转角度转换为正常的旋转角度
+ /// 因为 Role 受到 Face 影响, 会出现转向动作, 所以需要该函数来转换旋转角度 + ///
+ /// 角度, 弧度制 + public float ConvertRotation(float rotation) + { + if (Face == FaceDirection.Right) + { + return rotation; + } + + return Mathf.Pi - rotation; + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/SubLine.cs b/DungeonShooting_Godot/src/game/activity/role/SubLine.cs new file mode 100644 index 0000000..33bd409 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/SubLine.cs @@ -0,0 +1,176 @@ + +using System.Collections; +using Godot; + +/// +/// 瞄准辅助线 +/// +public class SubLine : Component +{ + /// + /// 是否正在播放警告闪烁动画 + /// + public bool IsPlayWarnAnimation => _cid > 0; + + private Line2D _line2D; + private RayCast2D _rayCast2D; + + private bool _enableSubLine; + private float _range; + private long _cid; + private Color _color = Colors.Orange; + + public override void Ready() + { + //初始化瞄准辅助线 + _line2D = new Line2D(); + _line2D.Width = 1; + AddChild(_line2D); + + _rayCast2D = new RayCast2D(); + _rayCast2D.CollisionMask = PhysicsLayer.Wall; + AddChild(_rayCast2D); + + Master.WeaponPack.ChangeActiveItemEvent += OnChangeWeapon; + } + + public override void OnEnable() + { + OnChangeWeapon(Master.WeaponPack.ActiveItem); + } + + public override void OnDisable() + { + _enableSubLine = false; + _line2D.Visible = false; + _rayCast2D.Enabled = false; + if (_cid > 0) + { + StopCoroutine(_cid); + } + } + + /// + /// 设置线条颜色 + /// + public void SetColor(Color color) + { + _color = color; + _line2D.DefaultColor = color; + } + + /// + /// 播放闪烁警告动画 + /// + /// 持续时间 + public void PlayWarnAnimation(float time) + { + if (_cid > 0) + { + StopCoroutine(_cid); + } + + _cid = StartCoroutine(RunWarnAnimation(time)); + } + + private IEnumerator RunWarnAnimation(float time) + { + var now = 0f; + var t = 0f; + var b = false; + while (now < time) + { + var delta = GetProcessDeltaTime(); + now += delta; + t += delta; + if (t >= 0.08f) + { + t %= 0.08f; + _line2D.DefaultColor = b ? Colors.Orange : Colors.Red; + b = !b; + } + yield return null; + } + + _line2D.DefaultColor = _color; + _cid = 0; + } + + //切换武器 + private void OnChangeWeapon(Weapon weapon) + { + if (!Enable) + { + return; + } + if (weapon == null) + { + _enableSubLine = false; + } + else + { + _enableSubLine = true; + if (_cid > 0) + { + StopCoroutine(_cid); + _cid = 0; + } + _range = Utils.GetConfigRangeEnd(weapon.Attribute.BulletDistanceRange); + _line2D.DefaultColor = _color; + } + } + + public override void PhysicsProcess(float delta) + { + if (_enableSubLine) + { + _line2D.Visible = true; + _rayCast2D.Enabled = true; + UpdateSubLine(); + } + else + { + _line2D.Visible = false; + _rayCast2D.Enabled = false; + } + } + + public override void OnDestroy() + { + _line2D.QueueFree(); + _rayCast2D.QueueFree(); + Master.WeaponPack.ChangeActiveItemEvent -= OnChangeWeapon; + } + + private void UpdateSubLine() + { + var master = Master; + var weapon = master.WeaponPack.ActiveItem; + float length; + var firePointGlobalPosition = weapon.FirePoint.GlobalPosition; + if (_rayCast2D.IsColliding()) + { + length = firePointGlobalPosition.DistanceTo(_rayCast2D.GetCollisionPoint()); + } + else + { + length = _range; + } + + var r = master.ConvertRotation(master.MountPoint.RealRotation); + //更新 Ray 的位置角度 + _rayCast2D.GlobalPosition = firePointGlobalPosition; + _rayCast2D.TargetPosition = new Vector2(_range, 0); + _rayCast2D.Rotation = r; + + //计算 line2D 的点 + var position = _line2D.ToLocal(firePointGlobalPosition); + Vector2 position2 = Vector2.FromAngle(r) * length; + + _line2D.Points = new Vector2[] + { + position, + position + position2 + }; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs new file mode 100644 index 0000000..62bc132 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs @@ -0,0 +1,43 @@ + +/// +/// 调用 Enemy.EnemyAttack() 函数返回的结果 +/// +public enum AiAttackState +{ + /// + /// 未触发 EnemyAttack() + /// + None, + /// + /// 触发切换武器 + /// + ExchangeWeapon, + /// + /// 没有弹药了 + /// + NoAmmo, + /// + /// 换弹中 + /// + Reloading, + /// + /// 触发换弹 + /// + TriggerReload, + /// + /// 没有武器 + /// + NoWeapon, + /// + /// 正在锁定目标中 + /// + LockingTime, + /// + /// 攻击间隙时间 + /// + AttackInterval, + /// + /// 成功触发攻击 + /// + Attack, +} \ 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 c333c8c..4736952 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs @@ -11,6 +11,7 @@ #endregion +using System; using Godot; /// @@ -20,6 +21,11 @@ public partial class Enemy : Role { /// + /// 目标是否在视野内 + /// + public bool TargetInView { get; set; } = true; + + /// /// 敌人身上的状态机控制器 /// public StateController StateController { get; private set; } @@ -54,10 +60,13 @@ /// public Marker2D NavigationPoint { get; private set; } - //开火间隙时间 - private float _enemyAttackTimer = 0; - //目标在视野内的时间 - private float _targetInViewTime = 0; + /// + /// Ai攻击状态, 调用 EnemyAttack() 函数后会刷新 + /// + public AiAttackState AttackState { get; private set; } + + //锁定目标时间 + private float _lockTargetTime = 0; public override void OnInit() { @@ -66,6 +75,7 @@ StateController = AddComponent>(); AttackLayer = PhysicsLayer.Wall | PhysicsLayer.Prop | PhysicsLayer.Player; + EnemyLayer = PhysicsLayer.Player; Camp = CampEnum.Camp2; RoleState.MoveSpeed = 20; @@ -140,19 +150,85 @@ protected override void Process(float delta) { base.Process(delta); - _enemyAttackTimer -= delta; //目标在视野内的时间 var currState = StateController.CurrState; if (currState == AiStateEnum.AiSurround || currState == AiStateEnum.AiFollowUp) { - _targetInViewTime += delta; + var weapon = WeaponPack.ActiveItem; + if (weapon != null) + { + if (weapon.GetBeLoadedStateState() >= 2 && !weapon.IsAttackIntervalTime()) //必须在可以开火时记录时间 + { + _lockTargetTime += delta; + } + else + { + _lockTargetTime = 0; + } + + if (AttackState == AiAttackState.LockingTime) //锁定玩家状态 + { + var aiLockRemainderTime = weapon.GetAiLockRemainderTime(); + MountLookTarget = aiLockRemainderTime >= weapon.Attribute.AiAttackAttr.LockAngleTime; + //更新瞄准辅助线 + if (weapon.Attribute.AiAttackAttr.ShowSubline) + { + if (SubLine == null) + { + InitSubLine(); + } + else + { + SubLine.Enable = true; + } + + //播放警告删掉动画 + if (!SubLine.IsPlayWarnAnimation && aiLockRemainderTime <= 0.5f) + { + SubLine.PlayWarnAnimation(0.5f); + } + } + } + else + { + //关闭辅助线 + if (SubLine != null) + { + SubLine.Enable = false; + } + + if (AttackState == AiAttackState.Attack || AttackState == AiAttackState.AttackInterval) + { + if (weapon.Attribute.AiAttackAttr.AttackLockAngle) //开火时锁定枪口角度 + { + //连发状态锁定角度 + MountLookTarget = !(weapon.GetContinuousCount() > 0 || weapon.GetAttackTimer() > 0); + } + else + { + MountLookTarget = true; + } + } + else + { + MountLookTarget = true; + } + } + } + else + { + MountLookTarget = true; + _lockTargetTime = 0; + } } else { - _targetInViewTime = 0; + MountLookTarget = true; + _lockTargetTime = 0; } + //拾起武器操作 EnemyPickUpWeapon(); } @@ -277,58 +353,20 @@ return false; } - + /// /// Ai触发的攻击 /// - public void EnemyAttack(float delta) + public void EnemyAttack() { var weapon = WeaponPack.ActiveItem; if (weapon != null) { - if (weapon.IsTotalAmmoEmpty()) //当前武器弹药打空 - { - //切换到有子弹的武器 - var index = WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty()); - if (index != -1) - { - WeaponPack.ExchangeByIndex(index); - } - else //所有子弹打光 - { - - } - } - else if (weapon.Reloading) //换弹中 - { - - } - else if (weapon.IsAmmoEmpty()) //弹夹已经打空 - { - Reload(); - } - else if (_targetInViewTime >= weapon.Attribute.AiTargetLockingTime) //正常射击 - { - if (weapon.GetDelayedAttackTime() > 0) - { - Attack(); - } - else - { - if (weapon.Attribute.ContinuousShoot) //连发 - { - Attack(); - } - else //单发 - { - if (_enemyAttackTimer <= 0) - { - _enemyAttackTimer = 60f / weapon.Attribute.StartFiringSpeed; - Attack(); - } - } - } - } + AttackState = weapon.AiTriggerAttackState(); + } + else //没有武器 + { + AttackState = AiAttackState.NoWeapon; } } @@ -456,4 +494,20 @@ } } + /// + /// 获取锁定目标的时间 + /// + public float GetLockTime() + { + return _lockTargetTime; + } + + /// + /// 强制设置锁定目标时间 + /// + public void SetLockTargetTime(float time) + { + _lockTargetTime = time; + } + } diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs index e0953eb..50003ec 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs @@ -6,12 +6,6 @@ /// public class AiFollowUpState : StateBase { - - /// - /// 目标是否在视野内 - /// - public bool IsInView; - //导航目标点刷新计时器 private float _navigationUpdateTimer = 0; private float _navigationInterval = 0.3f; @@ -23,7 +17,7 @@ public override void Enter(AiStateEnum prev, params object[] args) { _navigationUpdateTimer = 0; - IsInView = true; + Master.TargetInView = true; } public override void Process(float delta) @@ -75,11 +69,20 @@ if (!Master.NavigationAgent2D.IsNavigationFinished()) { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - masterPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; + if (weapon == null || !weapon.Attribute.AiAttackAttr.FiringStand || + (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)) + { + //计算移动 + var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); + Master.AnimatedSprite.Play(AnimatorNames.Run); + Master.BasisVelocity = (nextPos - masterPosition - Master.NavigationPoint.Position).Normalized() * + Master.RoleState.MoveSpeed; + } + else + { + Master.AnimatedSprite.Play(AnimatorNames.Idle); + Master.BasisVelocity = Vector2.Zero; + } } else { @@ -89,21 +92,22 @@ //检测玩家是否在视野内 if (Master.IsInTailAfterViewRange(playerPos)) { - IsInView = !Master.TestViewRayCast(playerPos); + Master.TargetInView = !Master.TestViewRayCast(playerPos); //关闭射线检测 Master.TestViewRayCastOver(); } else { - IsInView = false; + Master.TargetInView = false; } - if (IsInView) + //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑 + if (Master.TargetInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack) { if (inAttackRange) //在攻击范围内 { //发起攻击 - Master.EnemyAttack(delta); + Master.EnemyAttack(); //距离够近, 可以切换到环绕模式 if (Master.GlobalPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Utils.GetConfigRangeStart(weapon.Attribute.BulletDistanceRange), 2) * 0.7f) @@ -112,7 +116,7 @@ } } } - else + else //不在视野中 { ChangeState(AiStateEnum.AiTailAfter); } diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs index 1e7f4c4..321419f 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs @@ -6,11 +6,6 @@ /// public class AiSurroundState : StateBase { - /// - /// 目标是否在视野内 - /// - public bool IsInView = true; - //是否移动结束 private bool _isMoveOver; @@ -32,7 +27,7 @@ public override void Enter(AiStateEnum prev, params object[] args) { - IsInView = true; + Master.TargetInView = true; _isMoveOver = true; _pauseTimer = 0; _moveFlag = false; @@ -61,16 +56,20 @@ //检测玩家是否在视野内 if (Master.IsInTailAfterViewRange(playerPos)) { - IsInView = !Master.TestViewRayCast(playerPos); + Master.TargetInView = !Master.TestViewRayCast(playerPos); //关闭射线检测 Master.TestViewRayCastOver(); } else { - IsInView = false; + Master.TargetInView = false; } - if (IsInView) + //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑 + if (Master.TargetInView || + (weapon != null && weapon.Attribute.AiAttackAttr.FiringStand && + (Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack) + )) { if (_pauseTimer >= 0) { @@ -101,11 +100,11 @@ { _moveFlag = true; //计算移动 - var pos = Master.GlobalPosition; var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; + Master.BasisVelocity = + (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * + Master.RoleState.MoveSpeed; } else { @@ -120,13 +119,23 @@ } else { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; + //判断开火状态, 进行移动 + if (weapon == null || !weapon.Attribute.AiAttackAttr.FiringStand || + (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)) + { //正常移动 + //计算移动 + var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); + Master.AnimatedSprite.Play(AnimatorNames.Run); + Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() * + Master.RoleState.MoveSpeed; + } + else //站立不动 + { + Master.AnimatedSprite.Play(AnimatorNames.Idle); + Master.BasisVelocity = Vector2.Zero; + } } - + if (_prevPos.DistanceSquaredTo(pos) <= 0.01f) { _lockTimer += delta; @@ -147,7 +156,7 @@ else { //发起攻击 - Master.EnemyAttack(delta); + Master.EnemyAttack(); } } } diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs index 455e4ae..87b21aa 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs @@ -63,11 +63,21 @@ if (!Master.NavigationAgent2D.IsNavigationFinished()) { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; + var weapon = Master.WeaponPack.ActiveItem; + if (weapon == null || !weapon.Attribute.AiAttackAttr.FiringStand || + (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)) + { + //计算移动 + var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); + Master.AnimatedSprite.Play(AnimatorNames.Run); + Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * + Master.RoleState.MoveSpeed; + } + else + { + Master.AnimatedSprite.Play(AnimatorNames.Idle); + Master.BasisVelocity = Vector2.Zero; + } } else { diff --git a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs index 48bec61..e067187 100644 --- a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs +++ b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs @@ -40,6 +40,7 @@ IsAi = false; StateController = AddComponent>(); AttackLayer = PhysicsLayer.Wall | PhysicsLayer.Prop | PhysicsLayer.Enemy; + EnemyLayer = EnemyLayer = PhysicsLayer.Enemy; Camp = CampEnum.Camp1; MaxHp = 6; @@ -62,6 +63,8 @@ StateController.Register(new PlayerRollState()); //默认状态 StateController.ChangeStateInstant(PlayerStateEnum.Idle); + + //InitSubLine(); } protected override void Process(float delta) @@ -142,6 +145,7 @@ if (StateController.CurrState != PlayerStateEnum.Roll) //不能是翻滚状态 { Attack(); + // //测试用,触发房间内地上的武器开火 // var weaponArray = AffiliationArea.FindEnterItems(o => o is Weapon); // foreach (Weapon activityObject in weaponArray) // { diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs index 03ab172..3bead8a 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs @@ -145,10 +145,20 @@ /// public bool NoMasterCanTrigger { get; set; } = true; - //-------------------------------------------------------------------------------------------- + /// + /// 上一次触发改武器开火的角色是否是Ai + /// + public bool TriggerRoleIsAi { get; private set; } - //触发按下扳机的角色 - private Role _attackTrigger; + /// + /// 上一次触发改武器开火的触发开火攻击的层级, 数据源自于: + /// + public long TriggerRoleAttackLayer { get; private set; } + + //-------------------------------------------------------------------------------------------- + + //用于记录是否有角色操作过这把武器 + private bool _triggerRoleFlag = false; //是否按下 private bool _triggerFlag = false; @@ -181,7 +191,7 @@ private float _upTimer = 0; //连发次数 - private float _continuousCount = 0; + private int _continuousCount = 0; //连发状态记录 private bool _continuousShootFlag = false; @@ -205,7 +215,7 @@ private float _reloadTimer = 0; //单独换弹设置下的换弹状态, 0: 未换弹, 1: 装第一颗子弹之前, 2: 单独装弹中, 3: 单独装弹完成 - private byte _aloneReloadState = 0; + private byte _aloneReloadState = 3; //单独换弹状态下是否强制结束换弹过程 private bool _aloneReloadStop = false; @@ -434,7 +444,7 @@ //这把武器被扔在地上, 或者当前武器没有被使用 //if (Master == null || Master.WeaponPack.ActiveItem != this) - if (Master != null && Master.WeaponPack.ActiveItem != this) //在背上 + if ((Master != null && Master.WeaponPack.ActiveItem != this) || !_triggerRoleFlag) //在背上, 或者被扔出去了 { //_triggerTimer _triggerTimer = _triggerTimer > 0 ? _triggerTimer - delta : 0; @@ -455,7 +465,7 @@ if (_dirtyFlag) { _dirtyFlag = false; - _aloneReloadState = 0; + //_aloneReloadState = 0; StopReload(); _attackFlag = false; _continuousCount = 0; @@ -672,28 +682,40 @@ { return Master == null && GetParent() == GameApplication.Instance.World.NormalLayer; } - + /// /// 扳机函数, 调用即视为按下扳机 /// - /// 按下扳机的角色, 如果传 null, 则视为走火 - public void Trigger(Role trigger) + /// 按下扳机的角色, 如果传 null, 则视为走火 + public void Trigger(Role triggerRole) { //不能触发扳机 if (!NoMasterCanTrigger && Master == null) return; //这一帧已经按过了, 不需要再按下 if (_triggerFlag) return; - + + //更新武器属性信息 _triggerFlag = true; - _attackTrigger = trigger; + _triggerRoleFlag = true; + if (triggerRole != null) + { + TriggerRoleIsAi = triggerRole.IsAi; + TriggerRoleAttackLayer = triggerRole.AttackLayer; + _weaponAttribute = TriggerRoleIsAi ? _aiWeaponAttribute : _playerWeaponAttribute; + } + else if (Master != null) + { + TriggerRoleIsAi = Master.IsAi; + TriggerRoleAttackLayer = Master.AttackLayer; + _weaponAttribute = TriggerRoleIsAi ? _aiWeaponAttribute : _playerWeaponAttribute; + } //是否第一帧按下 var justDown = _downTimer == 0; - if (_beLoadedState == 0 || _beLoadedState == -1) //需要执行上膛操作 { - if (justDown && !Reloading && trigger != null) + if (justDown && !Reloading && triggerRole != null) { if (CurrAmmo <= 0) { @@ -763,7 +785,7 @@ else if (CurrAmmo <= 0) //子弹不够 { fireFlag = false; - if (justDown && trigger != null) + if (justDown && triggerRole != null) { //第一帧按下, 触发换弹 Reload(); @@ -808,10 +830,7 @@ } } } - - _attackFlag = true; } - } } } @@ -848,6 +867,38 @@ { return _delayedTime; } + + /// + /// 获取当前需要连发弹药的数量, 配置了 ContinuousCountRange 时生效 + /// + public int GetContinuousCount() + { + return _continuousCount; + } + + /// + /// 获取攻击冷却计时时间, 等于 0 表示冷却完成 + /// + public float GetAttackTimer() + { + return _attackTimer; + } + + /// + /// 返回是否是攻击间隙时间 + /// + public bool IsAttackIntervalTime() + { + return _attackTimer > 0 || _triggerTimer > 0; + } + + /// + /// 获取上膛状态,-1: 等待执行自动上膛 , 0: 未上膛, 1: 上膛中, 2: 已经完成上膛 + /// + public sbyte GetBeLoadedStateState() + { + return _beLoadedState; + } /// /// 刚按下扳机 @@ -897,12 +948,13 @@ /// private void TriggerFire() { + _attackFlag = true; _noAttackTime = 0; //减子弹数量 if (_playerWeaponAttribute != _weaponAttribute) //Ai使用该武器, 有一定概率不消耗弹药 { - if (Utils.Random.RandomRangeFloat(0, 1) < _weaponAttribute.AiAmmoConsumptionProbability) //触发消耗弹药 + if (Utils.Random.RandomRangeFloat(0, 1) < _weaponAttribute.AiAttackAttr.AmmoConsumptionProbability) //触发消耗弹药 { CurrAmmo -= UseAmmoCount(); } @@ -1013,13 +1065,13 @@ } } - /// - /// 触发武器的近战攻击 - /// - public void TriggerMeleeAttack(Role trigger) - { - - } + // /// + // /// 触发武器的近战攻击 + // /// + // public virtual void TriggerMeleeAttack(Role trigger) + // { + // + // } /// /// 获取武器攻击的目标层级 @@ -1027,6 +1079,10 @@ /// public uint GetAttackLayer() { + if (TriggerRoleAttackLayer > 0) + { + return (uint)TriggerRoleAttackLayer; + } return Master != null ? Master.AttackLayer : Role.DefaultAttackLayer; } @@ -1159,6 +1215,15 @@ public void StopReload() { _aloneReloadState = 0; + if (_beLoadedState == -1) + { + _beLoadedState = 0; + } + else if (_beLoadedState == 1) + { + _beLoadedState = 2; + } + Reloading = false; _reloadTimer = 0; _reloadUseTime = 0; @@ -1703,25 +1768,25 @@ _triggerTimer = 0; } GetParent().RemoveChild(this); - CollisionLayer = _tempLayer; + _triggerRoleFlag = false; _weaponAttribute = _playerWeaponAttribute; + CollisionLayer = _tempLayer; AnimatedSprite.Position = _tempAnimatedSpritePosition; //清除 Ai 拾起标记 RemoveSign(SignNames.AiFindWeaponSign); + //停止换弹 + if (Reloading) + { + StopReload(); + } OnRemove(Master); } public void OnPickUpItem() { Pickup(); - if (Master.IsAi) - { - _weaponAttribute = _aiWeaponAttribute; - } - else - { - _weaponAttribute = _playerWeaponAttribute; - } + _triggerRoleFlag = true; + _weaponAttribute = Master.IsAi ? _aiWeaponAttribute : _playerWeaponAttribute; //停止动画 AnimationPlayer.Stop(); //清除泛白效果 @@ -1850,11 +1915,11 @@ deviationAngle = Master.RoleState.CallCalcBulletDeviationAngleEvent(this, deviationAngle); } - var attackLayer = _attackTrigger != null ? _attackTrigger.AttackLayer : GetAttackLayer(); + var attackLayer = GetAttackLayer(); //创建子弹 var bullet = Create(bulletId); bullet.Init( - _attackTrigger, + TriggerRoleIsAi, this, speed, distance, @@ -1869,12 +1934,188 @@ } //-------------------------------- Ai相关 ----------------------------- + + /// + /// Ai 调用, 刷新 Ai 攻击状态并返回, 并不会调用相应的函数 + /// + public AiAttackState AiRefreshAttackState() + { + AiAttackState flag; + if (IsTotalAmmoEmpty()) //当前武器弹药打空 + { + //切换到有子弹的武器 + var index = Master.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty()); + if (index != -1) + { + flag = AiAttackState.ExchangeWeapon; + } + else //所有子弹打光 + { + flag = AiAttackState.NoAmmo; + } + } + else if (Reloading) //换弹中 + { + flag = AiAttackState.TriggerReload; + } + else if (IsAmmoEmpty()) //弹夹已经打空 + { + flag = AiAttackState.Reloading; + } + else if (_beLoadedState == 0 || _beLoadedState == -1) //需要上膛 + { + flag = AiAttackState.AttackInterval; + } + else if (_beLoadedState == 1) //上膛中 + { + flag = AiAttackState.AttackInterval; + } + else if (_continuousCount >= 1) //连发中 + { + flag = AiAttackState.Attack; + } + else if (IsAttackIntervalTime()) //开火间隙 + { + flag = AiAttackState.AttackInterval; + } + else + { + var enemy = (Enemy)Master; + if (enemy.GetLockTime() >= Attribute.AiAttackAttr.LockingTime) //正常射击 + { + if (GetDelayedAttackTime() > 0) + { + flag = AiAttackState.Attack; + } + else + { + if (Attribute.ContinuousShoot) //连发 + { + flag = AiAttackState.Attack; + } + else //单发 + { + flag = AiAttackState.Attack; + } + } + } + else //锁定时间没到 + { + flag = AiAttackState.LockingTime; + } + } + + return flag; + } + + /// + /// Ai调用, 触发扣动扳机, 并返回攻击状态 + /// + public AiAttackState AiTriggerAttackState() + { + AiAttackState flag; + if (IsTotalAmmoEmpty()) //当前武器弹药打空 + { + //切换到有子弹的武器 + var index = Master.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty()); + if (index != -1) + { + flag = AiAttackState.ExchangeWeapon; + Master.WeaponPack.ExchangeByIndex(index); + } + else //所有子弹打光 + { + flag = AiAttackState.NoAmmo; + } + } + else if (Reloading) //换弹中 + { + flag = AiAttackState.TriggerReload; + } + else if (IsAmmoEmpty()) //弹夹已经打空 + { + flag = AiAttackState.Reloading; + Reload(); + } + else if (_beLoadedState == 0 || _beLoadedState == -1) //需要上膛 + { + flag = AiAttackState.AttackInterval; + if (_attackTimer <= 0) + { + Master.Attack(); + } + } + else if (_beLoadedState == 1) //上膛中 + { + flag = AiAttackState.AttackInterval; + } + else if (_continuousCount >= 1) //连发中 + { + flag = AiAttackState.Attack; + } + else if (IsAttackIntervalTime()) //开火间隙 + { + flag = AiAttackState.AttackInterval; + } + else + { + var enemy = (Enemy)Master; + if (enemy.GetLockTime() >= Attribute.AiAttackAttr.LockingTime) //正常射击 + { + if (GetDelayedAttackTime() > 0) + { + flag = AiAttackState.Attack; + enemy.Attack(); + if (_attackFlag) + { + enemy.SetLockTargetTime(0); + } + } + else + { + if (Attribute.ContinuousShoot) //连发 + { + flag = AiAttackState.Attack; + enemy.Attack(); + if (_attackFlag) + { + enemy.SetLockTargetTime(0); + } + } + else //单发 + { + flag = AiAttackState.Attack; + enemy.Attack(); + if (_attackFlag) + { + enemy.SetLockTargetTime(0); + } + } + } + } + else //锁定时间没到 + { + flag = AiAttackState.LockingTime; + } + } + + return flag; + } /// - /// 获取 Ai 对于该武器的评分, 评分越高, 代表 Ai 会越优先选择该武器, 如果为 -1, 则表示 Ai 不会使用该武器 + /// 获取Ai锁定目标的剩余时间 /// - public float GetAiScore() + /// + public float GetAiLockRemainderTime() { - return 1; + return Attribute.AiAttackAttr.LockingTime - ((Enemy)Master).GetLockTime(); } + + // /// + // /// 获取 Ai 对于该武器的评分, 评分越高, 代表 Ai 会越优先选择该武器, 如果为 -1, 则表示 Ai 不会使用该武器 + // /// + // public float GetAiScore() + // { + // return 1; + // } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs b/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs index b8e288f..f74575e 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs @@ -28,4 +28,19 @@ { ShootBullet(fireRotation, Attribute.BulletId); } + + // //测试用, 敌人被消灭时触发手上武器开火 + // protected override void OnRemove(Role master) + // { + // base.OnRemove(master); + // + // if (master.IsDie && master.IsEnemyWithPlayer()) + // { + // this.CallDelay(0, () => + // { + // Debug.Log("敌人扔掉武器触发攻击"); + // Trigger(master); + // }); + // } + // } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs index d04d4a5..40f2ec7 100644 --- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs +++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs @@ -149,6 +149,7 @@ public const string resource_sprite_effects_weapon_KnifeHit1_png = "res://resource/sprite/effects/weapon/KnifeHit1.png"; public const string resource_sprite_effects_weapon_MeleeAttack1_png = "res://resource/sprite/effects/weapon/MeleeAttack1.png"; public const string resource_sprite_effects_weapon_ShotFire_png = "res://resource/sprite/effects/weapon/ShotFire.png"; + public const string resource_sprite_map_door_png = "res://resource/sprite/map/door.png"; public const string resource_sprite_map_door1_down_png = "res://resource/sprite/map/door1_down.png"; public const string resource_sprite_map_PreviewTransition_png = "res://resource/sprite/map/PreviewTransition.png"; public const string resource_sprite_map_PreviewTransition2_png = "res://resource/sprite/map/PreviewTransition2.png"; @@ -279,8 +280,12 @@ public const string resource_spriteFrames_bullet_Bullet0002_tres = "res://resource/spriteFrames/bullet/Bullet0002.tres"; public const string resource_spriteFrames_bullet_Bullet0003_tres = "res://resource/spriteFrames/bullet/Bullet0003.tres"; public const string resource_spriteFrames_effect_KnifeHit1_tres = "res://resource/spriteFrames/effect/KnifeHit1.tres"; - public const string resource_spriteFrames_other_RoomDoor_EW_tres = "res://resource/spriteFrames/other/RoomDoor_EW.tres"; - public const string resource_spriteFrames_other_RoomDoor_NS_tres = "res://resource/spriteFrames/other/RoomDoor_NS.tres"; + public const string resource_spriteFrames_other_RoomDoor_E_Down_tres = "res://resource/spriteFrames/other/RoomDoor_E_Down.tres"; + public const string resource_spriteFrames_other_RoomDoor_E_Up_tres = "res://resource/spriteFrames/other/RoomDoor_E_Up.tres"; + public const string resource_spriteFrames_other_RoomDoor_N_tres = "res://resource/spriteFrames/other/RoomDoor_N.tres"; + public const string resource_spriteFrames_other_RoomDoor_S_tres = "res://resource/spriteFrames/other/RoomDoor_S.tres"; + public const string resource_spriteFrames_other_RoomDoor_W_Down_tres = "res://resource/spriteFrames/other/RoomDoor_W_Down.tres"; + public const string resource_spriteFrames_other_RoomDoor_W_Up_tres = "res://resource/spriteFrames/other/RoomDoor_W_Up.tres"; public const string resource_spriteFrames_prop_active_ActiveProp5000_tres = "res://resource/spriteFrames/prop/active/ActiveProp5000.tres"; public const string resource_spriteFrames_prop_active_ActiveProp5001_tres = "res://resource/spriteFrames/prop/active/ActiveProp5001.tres"; public const string resource_spriteFrames_prop_buff_BuffProp0001_tres = "res://resource/spriteFrames/prop/buff/BuffProp0001.tres"; diff --git a/DungeonShooting_Godot/src/game/room/RoomDoor.cs b/DungeonShooting_Godot/src/game/room/RoomDoor.cs index da15cae..4d15411 100644 --- a/DungeonShooting_Godot/src/game/room/RoomDoor.cs +++ b/DungeonShooting_Godot/src/game/room/RoomDoor.cs @@ -19,6 +19,7 @@ private RoomDoorInfo _door; private bool waitDisabledCollision = false; + private AnimatedSprite2D _animatedDown; public override void OnInit() { @@ -32,6 +33,10 @@ { _door = doorInfo; IsClose = false; + if (doorInfo.Direction == DoorDirection.E || doorInfo.Direction == DoorDirection.W) + { + _animatedDown = GetNode("AnimatedSpriteDown"); + } OpenDoorHandler(); } @@ -47,6 +52,11 @@ { AnimatedSprite.Play(AnimatorNames.OpenDoor); } + + if (_animatedDown != null && _animatedDown.SpriteFrames.HasAnimation(AnimatorNames.OpenDoor)) + { + _animatedDown.Play(AnimatorNames.OpenDoor); + } } /// @@ -64,16 +74,36 @@ _door.Navigation.CloseNavigationNode.Enabled = true; _door.Navigation.CloseNavigationNode.Visible = true; } - + if (AnimatedSprite.SpriteFrames.HasAnimation(AnimatorNames.CloseDoor)) { AnimatedSprite.Play(AnimatorNames.CloseDoor); } + + if (_animatedDown != null && _animatedDown.SpriteFrames.HasAnimation(AnimatorNames.CloseDoor)) + { + _animatedDown.Play(AnimatorNames.CloseDoor); + } + //调整门的层级 switch (Direction) { case DoorDirection.E: + ZIndex = GameConfig.TopMapLayer; + if (_animatedDown != null) + { + _animatedDown.ZIndex = GameConfig.TopMapLayer; + } + + break; case DoorDirection.W: + ZIndex = GameConfig.TopMapLayer; + if (_animatedDown != null) + { + _animatedDown.ZIndex = GameConfig.TopMapLayer; + } + + break; case DoorDirection.S: ZIndex = GameConfig.TopMapLayer; break; @@ -103,6 +133,33 @@ _door.Navigation.CloseNavigationNode.Visible = false; } //调整门的层级 - ZIndex = GameConfig.FloorMapLayer; + //ZIndex = GameConfig.FloorMapLayer; + + //调整门的层级 + switch (Direction) + { + case DoorDirection.E: + ZIndex = GameConfig.MiddleMapLayer; + if (_animatedDown != null) + { + _animatedDown.ZIndex = GameConfig.TopMapLayer; + } + + break; + case DoorDirection.W: + ZIndex = GameConfig.MiddleMapLayer; + if (_animatedDown != null) + { + _animatedDown.ZIndex = GameConfig.TopMapLayer; + } + + break; + case DoorDirection.S: + ZIndex = GameConfig.TopMapLayer; + break; + case DoorDirection.N: + ZIndex = GameConfig.MiddleMapLayer; + break; + } } } \ No newline at end of file diff --git a/README.md b/README.md index c25219d..8949983 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -一款由Godot开发的地牢射击类型的游戏, 脚本语言使用的是C#, 当前项目使用的Godot版本: Godot_v4.2dev +一款由Godot开发的地牢射击类型的游戏, 脚本语言使用的是C#, 当前项目使用的Godot版本: Godot_v4.2 --- ### 游戏定义