lua 游戏架构 之 游戏 AI (九)ai_mgr Ai管理

avatar
作者
猴君
阅读量:0

定义`ai_mgr`的类,用于管理游戏中实体的AI组件。

先定义 AI行为枚举和优先级: 

lua 游戏架构 之 游戏 AI (八)ai_tbl 行为和优先级-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/heyuchang666/article/details/140712839?spm=1001.2014.3001.5501lua 游戏架构 之 游戏 AI (一)ai_base-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/heyuchang666/article/details/140624481?spm=1001.2014.3001.5501

以下是对代码的具体解释:

1. **引入依赖**:  使用`require`函数引入全局定义和AI定义。

2. **关闭JIT编译**: 如果启用了JIT编译,则关闭它,以确保AI逻辑的一致性。

3. **定义`ai_mgr`类**: `ai_mgr`类用于管理实体的AI组件。

4. **构造函数 (`ctor`)**:

  •    - 构造函数接受一个`entity`参数,并初始化实体、子组件列表、子组件索引和当前激活的组件。
  •    - 调用`AddComponent`方法添加默认的AI组件(基础AI)。

5. **`AddComponent`方法**:

  •    - 根据传入的AI类型(`atype`),从`ai_tbl`映射表中获取对应的脚本信息。
  •    - 动态加载对应的脚本,并创建组件实例。
  •    - 将新创建的组件添加到子组件列表中,并调用其`OnAttach`方法。

6. **`RmvComponent`方法**:移除指定类型的AI组件,并调用其`OnDetach`方法。

7. **`GetActiveComp`方法**:返回当前激活的AI组件。

8. **`BuildIdx`方法**: 构建子组件索引列表,并按优先级排序。

9. **`SwitchComp`方法**:

  • 如果当前激活的组件(self._activeComp)不是新切换的组件,则先检查当前激活的组件是否开启(IsTurnOn)。如果是,则调用其OnLeave方法,使其离开当前状态。
  • 如果新切换的组件未开启,则调用其OnEnter方法,使其进入激活状态。
  • 更新当前激活的组件为新切换的组件(self._activeComp = comp)。

10. **`OnUpdate`方法**:
    - 调用当前激活的AI组件的`OnUpdate`方法,更新AI状态。

11. **`OnLogic`方法**:
    - 调用当前激活的AI组件的`OnLogic`方法,执行逻辑更新。如果逻辑更新失败,则将组件从激活状态移除。

12. **`OnStopAction`方法**:
    - 调用当前激活的AI组件的`OnStopAction`方法,停止当前动作。

13. **`OnAttackAction`方法**:
    - 调用当前激活的AI组件的`OnAttackAction`方法,处理攻击动作。

14. **`create_mgr`函数**:
    - 创建并返回一个新的`ai_mgr`实例。

代码逻辑流程:

  • - **初始化**:在实体创建时,通过`ai_mgr`的构造函数初始化AI管理器,添加默认的AI组件。
  • - **添加组件**:通过`AddComponent`方法添加新的AI组件。
  • - **移除组件**:通过`RmvComponent`方法移除不需要的AI组件。
  • - **切换组件**:在游戏运行时,通过`SwitchComp`方法根据当前情况切换到合适的AI组件。
  • - **更新和逻辑处理**:在每帧更新和逻辑处理时,调用当前激活的AI组件的相关方法。

关键点:

  • - **动态加载脚本**:通过`require`函数动态加载AI组件脚本。
  • - **组件管理**:通过`ai_tbl`映射表管理不同AI组件的脚本和优先级。
  • - **组件切换**:根据游戏逻辑和实体状态,动态切换AI组件,以实现不同的AI行为。

整体而言,这段代码为游戏中的AI组件提供了一个灵活的管理框架,根据不同的游戏场景和实体状态动态地切换和控制AI行为。
 

local require = require  require("global"); require("logic/entity/ai/ai_def");  ------------------------------------------------------ if jit then 	jit.off(true, true) end  ------------------------------------------------------ ai_mgr = class("ai_mgr"); function ai_mgr:ctor(entity) 	self._entity	= entity; 	self._childs	= { }; 	self._child_idx	= { }; 	self._activeComp 					= nil;  	-- add default ai component 	self:AddComponent(eAType_BASE);  	-- get default ai component 	self:SwitchComp(); end  function ai_mgr:AddComponent(atype) 	local ai = ai_tbl[atype]; 	if ai then 		local comp = require("logic/entity/ai/" .. ai.script); 		if comp then 			local c = comp.create_component(self._entity, ai.priority); 			if c then 				c:SetName(ai.script); 				c:OnAttach(); 			end 			self._childs[atype] = c;  			self:BuildIdx(); 		end 	end end  function ai_mgr:RmvComponent(atype) 	local c = self._childs[atype]; 	if c then 		c:OnDetach(); 	end 	self._childs[atype] = nil;  	self:BuildIdx(); end  function ai_mgr:GetActiveComp() 	return self._activeComp; end  function ai_mgr:BuildIdx() 	self._child_idx = { }; 	for k ,_ in pairs(self._childs) do 		table.insert(self._child_idx, k); 	end  	local _cmp = function(d1, d2) 		if d1 > d2 then 			return true; 		end  		return false; 	end 	table.sort(self._child_idx, _cmp); end  function ai_mgr:SwitchComp() 	if jit then 		jit.off(true, true) 	end 	if self._entity and self._entity:IsPlayer() and g_game_context:IsInPingMode() then 		return false; 	end  	for k, v in ipairs(self._child_idx) do 		local comp = self._childs[v]; 		if self._entity:IsRenderable() or (comp._priority == eAI_Priority_High) then 			if comp:Switch() then 				if self._activeComp ~= comp then 					if self._activeComp and self._activeComp:IsTurnOn() then 						self._activeComp:OnLeave(); 					end  					if not comp:IsTurnOn() then 						--if self._entity:GetEntityType()==eET_Mercenary then 							--log("entity enter ai " .. comp:GetName()); 					--	end 						comp:OnEnter(); 					end  					self._activeComp = comp; 				end  				return true; 			end 		end 	end  	return false; end  function ai_mgr:OnUpdate(dTime) 	if self._activeComp then 		if self._entity and self._entity:IsPlayer() and g_game_context:IsInPingMode() then 			return ; 		end 		self._activeComp:OnUpdate(dTime); 	end end  function ai_mgr:OnLogic(dTick) 	if self._activeComp then 		if self._entity and self._entity:IsPlayer() and g_game_context:IsInPingMode() then 			return ; 		end 		if not self._activeComp:OnLogic(dTick) then 			self._activeComp:OnLeave(); 			self._activeComp = nil;  			return false; 		end 	end  	return true; end  function ai_mgr:OnStopAction(action) 	if self._activeComp then 		self._activeComp:OnStopAction(action); 	end end  function ai_mgr:OnAttackAction(id) 	if self._activeComp then 		self._activeComp:OnAttackAction(id); 	end end  function create_mgr(entity) 	return ai_mgr.new(entity); end  

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!