From 7a757d53f43d048126b5a85433f92f87b21dd1d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=9D=8Exl?= <1911159016@qq.com> Date: Wed, 10 Apr 2024 13:54:46 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E5=AE=8C=E5=96=84Ai=E6=94=B9?= =?UTF-8?q?=E5=8F=98=E9=98=B5=E8=90=A5=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DungeonShooting_Document/开发日志.md | 16 ++++- .../Test1/inlet/Start2/Preinstall.json | 2 +- .../sprite/role/enemy0007/enemy005.png.import | 6 +- .../src/game/activity/role/CampEnum.cs | 4 ++ .../src/game/activity/role/Role.cs | 12 +++- .../src/game/activity/role/ai/AiRole.cs | 70 +++++++++++++++++++ .../role/ai/state/AiTailAfterState.cs | 8 ++- .../src/game/activity/role/enemy/Enemy.cs | 38 ---------- .../src/game/activity/role/player/Player.cs | 2 + 9 files changed, 112 insertions(+), 46 deletions(-) diff --git a/DungeonShooting_Document/开发日志.md b/DungeonShooting_Document/开发日志.md index 63f6444d..37b00f15 100644 --- a/DungeonShooting_Document/开发日志.md +++ b/DungeonShooting_Document/开发日志.md @@ -1,9 +1,23 @@ +--- + +### 2024-4- + +主要工作内容如下: + +* 新版大厅仍在制作中, 目前美术正在整理素材 +* 新增武器轮盘功能, 游戏中按下`Tab`即可显示轮盘, 鼠标悬停可以选择武器, 轮盘最多可以同时显示6把武器, 超过6把武器就会显示翻页按钮, 鼠标悬停在指定武器上时按下`Space`可以快速扔掉武器 +* 新增图鉴功能, 目前只是初版图鉴, 可显示武器, 道具, 怪物的介绍信息 +* + + + --- ### 2024-2-25 -游戏正式起名为《枪火地牢》! +游戏暂定名为《枪火地牢》 项目从4.2升级到4.2.1, 本次更新大量内容, 地牢编辑器2.0, 游戏大厅, 奖励房间, 自定义地牢生成规则, 地牢装饰等, 所以开发周期来到了两个半月 主要工作内容如下: + * 地牢编辑器2.0正式支持47格Tile的平铺地形, 完整的新增功能: * 新增TileSet编辑器, 功能如下: * 导入外部图像, 并进行裁剪 diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/Preinstall.json index 2a724e18..ba6a2a97 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/Preinstall.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start2/Preinstall.json @@ -1 +1 @@ -[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":true,"WaveList":[[{"Position":{"X":-81,"Y":25},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":31,"Y":32},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0004","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0003","CurrAmmon":"12","ResidueAmmo":"12"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-54,"Y":20},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":105,"Y":32},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0005","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0003","CurrAmmon":"12","ResidueAmmo":"12"},"Altitude":0,"VerticalSpeed":0}]}]]}] \ No newline at end of file +[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":true,"WaveList":[[{"Position":{"X":-81,"Y":25},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":31,"Y":32},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0004","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0003","CurrAmmon":"12","ResidueAmmo":"12"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-54,"Y":20},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":5.551115E-14}]}]]}] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy005.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy005.png.import index 29d6eb0a..7c10fb01 100644 --- a/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy005.png.import +++ b/DungeonShooting_Godot/resource/sprite/role/enemy0007/enemy005.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://bft65nd80tlju" -path="res://.godot/imported/enemy005.png-5f308aab472c7f7817c38753a7889f10.ctex" +path="res://.godot/imported/enemy005.png-36beaed69baad591e8b54a29a147644f.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://resource/sprite/role/enemy006/enemy005.png" -dest_files=["res://.godot/imported/enemy005.png-5f308aab472c7f7817c38753a7889f10.ctex"] +source_file="res://resource/sprite/role/enemy0007/enemy005.png" +dest_files=["res://.godot/imported/enemy005.png-36beaed69baad591e8b54a29a147644f.ctex"] [params] diff --git a/DungeonShooting_Godot/src/game/activity/role/CampEnum.cs b/DungeonShooting_Godot/src/game/activity/role/CampEnum.cs index 6ba2bb7d..d09f763b 100644 --- a/DungeonShooting_Godot/src/game/activity/role/CampEnum.cs +++ b/DungeonShooting_Godot/src/game/activity/role/CampEnum.cs @@ -25,4 +25,8 @@ public enum CampEnum /// 阵营4, 敌人3 /// Camp4, + /// + /// 阵营5, 敌人4 + /// + Camp5, } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/Role.cs b/DungeonShooting_Godot/src/game/activity/role/Role.cs index 27c7d34b..4cac9bd9 100644 --- a/DungeonShooting_Godot/src/game/activity/role/Role.cs +++ b/DungeonShooting_Godot/src/game/activity/role/Role.cs @@ -385,7 +385,7 @@ public abstract partial class Role : ActivityObject /// 触发伤害的对象, 为 null 表示不存在对象或者对象已经被销毁 /// 受到的伤害 /// 伤害角度(弧度制) - /// 是否受到真实伤害, 如果为false, 则表示该伤害被互动格挡掉了 + /// 是否受到真实伤害, 如果为false, 则表示该伤害被护盾格挡掉了 protected virtual void OnHit(ActivityObject target, int damage, float angle, bool realHarm) { } @@ -1047,6 +1047,16 @@ public abstract partial class Role : ActivityObject /// public bool IsEnemy(Role other) { + if (this == other) + { + return false; + } + + if (Camp == CampEnum.None || other.Camp == CampEnum.None) + { + return true; + } + if (other.Camp == Camp || other.Camp == CampEnum.Peace || Camp == CampEnum.Peace) { return false; diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs b/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs index 8d5e16aa..238abe88 100644 --- a/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs +++ b/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs @@ -507,6 +507,67 @@ public abstract partial class AiRole : Role HasMoveDesire = v; } + protected override void OnHit(ActivityObject target, int damage, float angle, bool realHarm) + { + //受到伤害 + var state = StateController.CurrState; + if (state == AIStateEnum.AiNormal) + { + LookTarget = target; + if (target is Role role) + { + _attackTarget = role; + } + //判断是否进入通知状态 + if (World.Role_InstanceList.FindIndex(role => + role is AiRole aiRole && + aiRole != this && !aiRole.IsDie && aiRole.AffiliationArea == AffiliationArea && + aiRole.StateController.CurrState == AIStateEnum.AiNormal) != -1) + { + //进入惊讶状态, 然后再进入通知状态 + StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiNotify); + } + else + { + //进入惊讶状态, 然后再进入跟随状态 + StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiTailAfter); + } + } + else if (state == AIStateEnum.AiLeaveFor) + { + LookTarget = target; + if (target is Role role) + { + _attackTarget = role; + } + StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiTailAfter); + } + else if (state == AIStateEnum.AiFindAmmo) + { + if (LookTarget == null) + { + LookTarget = target; + if (target is Role role) + { + _attackTarget = role; + } + var findAmmo = (AiFindAmmoState)StateController.CurrStateBase; + StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiFindAmmo, findAmmo.TargetWeapon); + } + } + else if (state != AIStateEnum.AiAstonished && state != AIStateEnum.AiNotify) + { + if (TargetHasOcclusion || !TargetInView) + { + LookTarget = target; + if (target is Role role) + { + _attackTarget = role; + } + } + } + } + private void OnViewAreaBodyEntered(Node2D node) { if (node is Role role) @@ -525,6 +586,15 @@ public abstract partial class AiRole : Role private Role RefreshAttackTargets(Role prevRole) { + if (LookTarget is Role role && !role.IsDestroyed && IsEnemy(role)) + { + if (!TestViewRayCast(role.GetCenterPosition())) + { + TestViewRayCastOver(); + return role; + } + } + if (_viewTargets.Count == 0) { return null; diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs index 0f349ef8..3cd816fa 100644 --- a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs @@ -54,12 +54,16 @@ public class AiTailAfterState : StateBase { //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽 - if (Master.LookTarget == null) + var target = Master.GetAttackTarget(); + if (target == null) { + Master.LookTarget = null; ChangeState(AIStateEnum.AiNormal); return; } - var playerPos = Master.LookTarget.GetCenterPosition(); + + Master.LookTarget = target; + var playerPos = target.GetCenterPosition(); //更新玩家位置 if (_navigationUpdateTimer <= 0) diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs index 82237bc7..1607962e 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs @@ -162,44 +162,6 @@ public partial class Enemy : AiRole return base.IsAllWeaponTotalAmmoEmpty(); } - protected override void OnHit(ActivityObject target, int damage, float angle, bool realHarm) - { - //受到伤害 - var state = StateController.CurrState; - if (state == AIStateEnum.AiNormal) - { - LookTarget = target; - //判断是否进入通知状态 - if (World.Role_InstanceList.FindIndex(role => - role is AiRole enemy && - enemy != this && !enemy.IsDie && enemy.AffiliationArea == AffiliationArea && - enemy.StateController.CurrState == AIStateEnum.AiNormal) != -1) - { - //进入惊讶状态, 然后再进入通知状态 - StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiNotify); - } - else - { - //进入惊讶状态, 然后再进入跟随状态 - StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiTailAfter); - } - } - else if (state == AIStateEnum.AiLeaveFor) - { - LookTarget = target; - StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiTailAfter); - } - else if (state == AIStateEnum.AiFindAmmo) - { - if (LookTarget == null) - { - LookTarget = target; - var findAmmo = (AiFindAmmoState)StateController.CurrStateBase; - StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiFindAmmo, findAmmo.TargetWeapon); - } - } - } - /// /// 从标记出生时调用, 预加载波不会调用 /// diff --git a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs index 57fec73c..c42b9fbc 100644 --- a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs +++ b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs @@ -304,6 +304,8 @@ public partial class Player : Role //血量为0, 扔掉所有武器 if (Hp <= 0) { + BasisVelocity = Vector2.Zero; + Velocity = Vector2.Zero; ThrowAllWeapon(); } }