首页 > 其他分享 >lua 游戏架构 之 游戏 AI (九)ai_mgr Ai管理

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

时间:2024-07-26 17:54:34浏览次数:14  
标签:end 游戏 AI self mgr ai ._ 组件

定义`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

标签:end,游戏,AI,self,mgr,ai,._,组件
From: https://blog.csdn.net/heyuchang666/article/details/140714679

相关文章

  • 灭火器检测算法:防患未然,精准高效,AI智能守护加油站消防安全
    随着科技的飞速发展和安全意识的不断提升,加油站作为易燃易爆场所,其消防安全管理显得尤为重要。其中,消防灭火器的有效部署和及时维护是保障加油站安全的关键环节。近年来,AI技术在消防安全领域的应用日益广泛,特别是加油站消防灭火器检测AI算法的研发与应用,为加油站的消防安全管理提......
  • 超火爆AI工具——Vozo:一键重写视频脚本、重新配音!
    最近有一款短视频工具——VozoAI非常火热,上线即登ProductHunt榜首,且已蝉联3天。它的全名是VozoRewrite&Redub,Rewrite意味着重新编写,Redub代表重新配音,它能够根据提示词,重新生成视频脚本并能够通过克隆原说话人声音,为视频生成新的配音,外加同步口型!今天就带大家一起来了解......
  • LayaAir3.x 物理2D碰撞事件
    const{regClass,property}=Laya;@regClass()exportclassPlayerBulletextendsLaya.Script{declareowner:Laya.Sprite;private_body:Laya.RigidBody;onAwake():void{this._body=this.owner.getComponent(Laya.RigidBody);......
  • 【P3150 pb的游戏(1)】
    pb的游戏(1)题目背景有一天pb和zs玩游戏你需要帮zs求出每局的胜败情况。题目描述游戏规则是这样的:先手对给出的数进行分割,分割成两个正整数,之后接着后手选择留下两个数中的其中一个。两人轮流操作,直到一方无法操作,另一方胜利。现在要你求出......
  • OpenAI深夜发布 SearchGPT:进军大模型搜索领域,挑战谷歌与 Perplexity!
    近期,AI领域竞争愈发激烈,不仅大模型发布频繁,还不断带来新的产品体验。刚刚,OpenAI正式发布了其大模型搜索产品SearchGPT。链接:https://chatgpt.com/searchSamAltman在X上表示:“我们认为搜索功能还有改进的空间。我们推出了一个名为SearchGPT的新原型产品。我......
  • Spring Boot 对接文心一言,实现ai抠图实例
    上篇文章:SpringBoot对接文心一言讲述了在springboot项目中如何集成文心一言。现在我们来做个实例,实现AI抠图。文心一言的抠图功能通常需要通过调用文心一言的API来实现。在SpringBoot项目中,你可以通过RestTemplate或者WebClient来发起HTTP请求调用文心一言的API。实......
  • Python,Pyinstaller打包含taichi模块的程序
    Python版本3.9、taichi版本1.7.1,pyinstaller版本6.9.0问题描述:正常Pyinstaller打包后报错[Taichi]version1.7.1,llvm15.0.1,commit0f143b2f,win,python3.9.19[Taichi]Startingonarch=x64Traceback(mostrecentcalllast):File"taichi\lang\_wrap_inspec......
  • Python从零开始制做文字游戏(荒岛求生)
    文章目录前言开发游戏《荒岛求生》游戏大纲背景内容通关条件游戏过程探索荒岛购买物资休息总结代码开发定义变量当前代码引入背景故事当前代码循环问题解决:函数当前代码制作延时当前代码制作a函数(探索荒岛阶段)展示数......
  • 【提交ACM出版 | EI&Scopus检索稳定 | 高录用】2024年数字经济,区块链与人工智能国际学
    2024年数字经济,区块链与人工智能国际学术会议(DEBAI2024)为第五届大数据与社会科学国际学术会议(ICBDSS2024)的分会,将于2024年8月23-25日在中国-广州隆重举行。为了让更多的学者有机会参与会议分享交流经验。本次会议主要围绕“数字经济,区块链与人工智能等研究领域展开讨论......
  • ElasticSearch第1讲(4万字详解 Linux下安装、原生调用、API调用超全总结、Painless、IK
    ElasticSearch官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started.html非官方中文文档:https://learnku.com/docs/elasticsearch73/7.3极简概括:基于ApacheLucene构建开源的分布式搜索引擎。解决问题:MySQLlike中文全文搜索不走索引......