当前位置:   article > 正文

lua 游戏架构 之 游戏 AI (七)ai_dead

lua 游戏架构 之 游戏 AI (七)ai_dead

定义一个名为`ai_dead`的类,继承自`ai_base`类。这个类用于处理游戏中AI在死亡状态下的行为逻辑。以下是对代码的具体解释:

1. **引入基类**:
   - 使用`require`函数引入`ai_base`类,作为基础类。

2. **定义`ai_dead`类**:
   - 使用`class`关键字定义了`ai_dead`类,并继承自`BASE`(即`ai_base`)。

3. **构造函数 (`ctor`)**:
   - 构造函数接受一个`entity`参数,并设置`_type`属性为`eAType_DEAD`,表示死亡的行为。

4. **`IsValid` 方法**:
   - 这个方法用于验证AI是否应该处于死亡状态。它首先调用基类的`IsValid`方法,然后检查实体是否死亡。

5. **`OnEnter` 方法**:

  •      - 当AI组件进入激活状态时执行。如果基类的`OnEnter`方法返回`true`,则执行以下操作:
  •      - 重置`_fadeOut`和`_slowMotion`标志。
  •      - 检查并重置玩家的自动普通攻击状态。
  •      - 隐藏实体的称号节点。
  •      - 检查并重置玩家的超级模式状态。
  •      - 检查并重置骑乘状态。
  •      - 如果实体不是宠物或技能类型,播放死亡动作列表。
  •      - 锁定实体动画。
  •      - 处理同步RPC和发送死亡命令。
  •      - 处理玩家死亡后的界面逻辑,如复活界面和宠物状态。
  •      - 清理死亡实体的仇恨列表和战斗时间。

6. **`OnLeave` 方法**: 当AI组件离开激活状态时执行。如果基类的`OnLeave`方法返回`true`,则解锁实体动画。

7. **`OnLogic` 方法**: 逻辑更新方法。如果基类的`OnLogic`方法返回`true`,则根据时间间隔处理死亡逻辑,如淡出效果、实体销毁等。

8. **创建组件函数**: `create_component`函数用于创建`ai_dead`类的新实例,传入一个实体和一个优先级。

代码中的一些关键点:

  • - `IsDead()`:检查实体是否死亡。
  • - `ShowTitleNode()`:显示或隐藏实体的称号节点。
  • - `SuperMode()`:处理玩家的超级模式。
  • - `OnRideMode()`:处理玩家的骑乘模式。
  • - `PlayActionList()`:播放一系列动作。
  • - `LockAni()`:锁定实体的动画。
  • - `Show()`:控制实体的显示与隐藏。
  • - `Destory()`:销毁实体。
  • - `CanRelease()`:检查实体是否可以释放。

`OnEnter` 方法的逻辑流程:

  • - 调用基类的`OnEnter`方法,如果返回`true`,则继续。
  • - 重置相关动画和攻击状态。
  • - 隐藏称号节点。
  • - 检查并重置超级模式和骑乘状态。
  • - 播放死亡动作列表并锁定动画。
  • - 发送死亡同步命令和处理复活界面逻辑。
  • - 清理仇恨列表和战斗时间。

`OnLogic` 方法中,根据时间间隔处理死亡后的逻辑,如:

  • - 如果实体存活时间超过4秒,并且可以释放,则销毁实体。
  • - 如果实体存活时间超过2秒,并且可以释放,则开始淡出效果。

整体而言,`ai_dead`类的目的是在AI实体死亡时,提供一套标准的行为和逻辑处理,确保游戏内死亡状态的表现和交互符合预期。

  1. local require = require
  2. local BASE = require("logic/entity/ai/ai_base").ai_base;
  3. ------------------------------------------------------
  4. ai_dead = class("ai_dead", BASE);
  5. function ai_dead:ctor(entity)
  6. self._type = eAType_DEAD;
  7. end
  8. function ai_dead:IsValid()
  9. if not BASE.IsValid(self) then return false; end
  10. return self._entity:IsDead();
  11. end
  12. function ai_dead:OnEnter()
  13. if BASE.OnEnter(self) then
  14. self._fadeOut = false;
  15. self._slowMotion= false;
  16. local logic = game_get_logic();
  17. if logic then
  18. local player = logic:GetPlayer();
  19. if player and player:GetHero() then
  20. local hero = player:GetHero();
  21. if hero then
  22. if hero._autonormalattack then
  23. if hero._guid == self._entity._guid then
  24. hero._preautonormalattack = false;
  25. hero._autonormalattack = false;
  26. elseif self._entity._selected == self._entity._guid then
  27. hero._preautonormalattack = false;
  28. hero._autonormalattack = false;
  29. elseif hero._follow then
  30. if hero._follow._guid == self._entity._guid then
  31. hero._preautonormalattack = false;
  32. hero._autonormalattack = false;
  33. end
  34. end
  35. end
  36. end
  37. end
  38. end
  39. self._entity:ShowTitleNode(false);
  40. if self._entity:GetEntityType() == eET_Player then
  41. --清神兵状态
  42. if self._entity._superMode.valid then
  43. local hero = game_get_player_hero()
  44. if self._entity:IsPlayer() then
  45. self._entity:SuperMode(false)
  46. else
  47. self._entity:OnSuperMode(false)
  48. end
  49. end
  50. if self._entity:IsPlayer() then
  51. g_game_context:ResetLeadMode()
  52. local animation = g_game_context:GetSelectWeaponMaxAnimation()
  53. if animation then
  54. g_game_context:OnStuntAnimationChangeHandler(animation,false)
  55. end
  56. end
  57. --清骑乘
  58. local world = game_get_world()
  59. if world and not world._syncRpc then
  60. if self._entity:IsOnRide() then
  61. self._entity:OnRideMode(false, true)
  62. end
  63. end
  64. if self._entity._DIYSkill then
  65. self._entity._DIYSkill:OnReset();
  66. end
  67. end
  68. if self._entity:GetEntityType() ~= eET_Pet and self._entity:GetEntityType() ~= eET_Skill then
  69. local alist = {}
  70. table.insert(alist, {actionName = db_common.engine.defaultDeadAction, actloopTimes = 1})
  71. table.insert(alist, {actionName = db_common.engine.defaultDeadLoopAction, actloopTimes = -1})
  72. self._entity:PlayActionList(alist, 1);
  73. end
  74. self._entity:LockAni(true);
  75. local logic = game_get_logic();
  76. if logic then
  77. local world = logic:GetWorld();
  78. if world then
  79. local syncRpc = world._syncRpc;
  80. if not syncRpc then
  81. -- send cmd
  82. local entity = self._entity;
  83. if entity and entity:GetEntityType() == eET_Monster and entity._spawnID > 0 then
  84. local weaponID = g_game_context:IsInSuperMode() and 1 or 0
  85. local damageRank = g_game_context:GetMapCopyDamageRank()
  86. local args = { spawnPointID = entity._spawnID , pos = entity._curPos, weaponID = weaponID, damageRank = damageRank}
  87. sbean.sync_privatemap_kill(args)
  88. end
  89. local hero = game_get_player_hero()
  90. if hero then
  91. hero:RemoveSummoned();
  92. end
  93. end
  94. end
  95. end
  96. if self._entity:GetEntityType() == eET_Player then
  97. if logic then
  98. local player = logic:GetPlayer()
  99. local hero = nil
  100. if player then
  101. hero = player:GetHero()
  102. end
  103. local logic = game_get_logic();
  104. local world = logic:GetWorld()
  105. local PetCount = player:GetPetCount()
  106. for i = 1,tonumber(PetCount) do
  107. local Pet = player:GetPet(i)
  108. Pet:OnDead()
  109. end
  110. if g_db.db_get_is_open_revive_ui() then
  111. if hero._guid == self._entity._guid then
  112. if hero._killerId and hero._killerId < 0 then
  113. --天雷复活界面
  114. local killerID = math.abs(hero._killerId);
  115. local guid = string.split(hero._guid, "|")
  116. local playerId = tonumber(guid[2])
  117. if killerID == playerId then
  118. g_ui_mgr:OpenUI(eUIID_PlayerRevive)
  119. g_ui_mgr:RefreshUI(eUIID_PlayerRevive, true)
  120. end
  121. else
  122. g_logic:OpenReviveUI()
  123. end
  124. --log("eUIID_PlayerRevive")
  125. local MercenaryCount = player:GetMercenaryCount();
  126. for i = 1,tonumber(MercenaryCount) do
  127. local Mercenary = player:GetMercenary(i)
  128. Mercenary:OnDead()
  129. end
  130. end
  131. else
  132. if hero._guid == self._entity._guid and (game_get_map_type() == g_ARENA_SOLO or game_get_map_type() == g_TAOIST) then
  133. g_game_context:SetAutoFight(false)
  134. local MercenaryCount = player:GetMercenaryCount();
  135. for i = 1,tonumber(MercenaryCount) do
  136. local Mercenary = player:GetMercenary(i)
  137. if not Mercenary:IsDead() then
  138. local camera = logic:GetMainCamera()
  139. hero:DetachCamera()
  140. Mercenary:AttachCamera(camera);
  141. camera:UpdatePos(Mercenary._curPosE);
  142. break;
  143. end
  144. end
  145. end
  146. end
  147. if world and not world._syncRpc then
  148. self._entity:ClsHorseAi();
  149. end
  150. end
  151. end
  152. if self._entity._forceAttackTarget then
  153. self._entity._forceAttackTarget = nil;
  154. end
  155. if self._entity:GetEntityType() == eET_Mercenary then
  156. self._entity._deadTimeLine = g_get_GMTtime(game_get_time())
  157. if logic then
  158. local player = logic:GetPlayer()
  159. local hero = nil
  160. if player then
  161. hero = player:GetHero()
  162. end
  163. local logic = game_get_logic();
  164. local world = logic:GetWorld()
  165. if world._fightmap then
  166. if hero:IsDead() and (game_get_map_type() == g_ARENA_SOLO or game_get_map_type() == g_TAOIST) then
  167. local guid1 = string.split(hero._guid, "_")
  168. local guid2 = string.split(self._entity._guid, "_")
  169. if tonumber(guid1[2]) == tonumber(guid2[3]) then
  170. local MercenaryCount = player:GetMercenaryCount();
  171. for i = 1,tonumber(MercenaryCount) do
  172. local Mercenary = player:GetMercenary(i)
  173. if not Mercenary:IsDead() then
  174. local camera = logic:GetMainCamera()
  175. self._entity:DetachCamera()
  176. Mercenary:AttachCamera(camera);
  177. camera:UpdatePos(Mercenary._curPosE);
  178. break;
  179. end
  180. end
  181. end
  182. end
  183. end
  184. end
  185. self._entity:ClsEnmities();
  186. end
  187. if self._entity:GetEntityType() == eET_Player or self._entity:GetEntityType() == eET_Mercenary then
  188. self._entity:ClearFightTime();
  189. end
  190. if self._entity:GetEntityType() ~= eET_Player and self._entity:GetEntityType() ~= eET_Mercenary then
  191. --self._entity:SetHittable(false);
  192. end
  193. if self._entity:GetEntityType() == eET_Pet then
  194. local world = game_get_world();
  195. local player = game_get_player()
  196. if world and not world._syncRpc then
  197. if self._entity._hoster then
  198. local curFightSP = self._entity._hoster:GetFightSp()
  199. self._entity._hoster:UpdateFightSpCanYing(curFightSP - 1)
  200. local index = player:GetPetIdx(self._entity._guid)
  201. if index > 0 then
  202. player:RmvPet(index)
  203. end
  204. end
  205. end
  206. end
  207. return true;
  208. end
  209. return false;
  210. end
  211. function ai_dead:OnLeave()
  212. if BASE.OnLeave(self) then
  213. self._entity:LockAni(false);
  214. return true;
  215. end
  216. return false;
  217. end
  218. function ai_dead:OnLogic(dTick)
  219. if BASE.OnLogic(self, dTick) then
  220. if dTick > 0 then
  221. if self._timeTick > 4000 then
  222. if self._entity:CanRelease() then
  223. self._entity:Destory()
  224. end
  225. elseif self._timeTick > 2000 then
  226. if self._entity:CanRelease() then
  227. if not self._fadeOut then
  228. self._fadeOut = true;
  229. self._entity:Show(false, true, 2000);
  230. end
  231. end
  232. end
  233. if self._entity:GetEntityType() == eET_Pet or self._entity:GetEntityType() == eET_Skill then
  234. if self._entity:CanRelease() then
  235. self._entity:Destory()
  236. end
  237. end
  238. end
  239. return true;
  240. end
  241. return false;
  242. end
  243. function create_component(entity, priority)
  244. return ai_dead.new(entity, priority);
  245. end


 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/948679
推荐阅读
相关标签
  

闽ICP备14008679号