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();
}
}