lua 游戏架构 之 游戏 AI (四)ai_autofight_find_target

定义一个名为 `ai_autofight_find_target` 的类,继承自 `ai_base` 类。

lua 游戏架构 之 游戏 AI (一)ai_base-CSDN博客文章浏览阅读237次。定义了一套接口和属性,可以基于这个基础类派生出具有特定行为的AI组件。例如,可以创建追逐敌人的AI、巡逻的AI或使用特定策略的AI等,都继承自这个基础类https://blog.csdn.net/heyuchang666/article/details/140624481?spm=1001.2014.3001.5502

这个类用于处理游戏中AI自动战斗中寻找目标的逻辑。以下是对代码的具体解释:

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

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

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

  •    - 构造函数 `entity` 游戏实体,并设置 `_type` 属性为 `eAType_AUTOFIGHT_FIND_TARGET`,表示自动战斗中寻找目标的行为。
  •    - 初始化 `_target` 为 `nil`,用于后续存储找到的目标。

4. **`IsValid` 方法**:

  •    - 这个方法用于验证AI是否应该寻找目标。它首先检查实体是否开启了自动战斗(`_AutoFight`),是否死亡或无法攻击。
  •    - 计算警报范围 `filterdist`,可能基于实体的属性或世界配置。
  •    - 检查实体的预命令类型,如果是点击移动或摇杆移动,则返回 `false`。
  •    - 检查实体的当前技能 `_curSkill`,根据技能类型(伤害、诅咒、祝福)和相关逻辑来确定目标。

5. **`OnEnter` 方法**:
   - 当AI组件进入激活状态时执行。如果已经找到目标 `_target`,则根据当前技能设置目标或移动到目标位置。

6. **`OnLeave` 方法**:
   - 当AI组件离开激活状态时执行。清除目标 `_target`。

7. **`OnUpdate` 方法**:
   - 每帧调用,用于更新AI状态。如果基类的 `OnUpdate` 方法返回 `true`,则当前方法也返回 `true`。

8. **`OnLogic` 方法**:
   - 逻辑更新方法,如果基类的 `OnLogic` 方法返回 `true`,则当前方法返回 `false`,表示只执行一次。

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

代码中的一些关键点:

  • - `IsDead()`:检查实体是否死亡。
  • - `CanAttack()`:检查实体是否可以攻击。
  • - `GetPropertyValue(ePropID_alertRange)`:获取实体的警报范围属性。
  • - `game_get_world()`:获取游戏世界配置。
  • - `GetEnmities()`:获取实体的敌对列表。
  • - `GetRadius()`:获取实体的半径。
  • - `MoveTo()`:移动到指定位置。
  • - `SetTarget()`:设置目标实体。

这个脚本为游戏中的AI提供了一个自动战斗中寻找目标的基础框架,可以根据具体游戏的需求进行扩展和修改。

----------------------------------------------------------------local require = requirelocal BASE = require("logic/entity/ai/ai_base").ai_base;ai_autofight_find_target = class("ai_autofight_find_target", BASE);
function ai_autofight_find_target:ctor(entity)self._type		= eAType_AUTOFIGHT_FIND_TARGET;self._target	= nil;
endfunction ai_autofight_find_target:IsValid()local entity = self._entity;if not entity._AutoFight thenreturn false;endif entity:IsDead() or not entity:CanAttack() thenreturn false;endlocal filterdist = entity:GetPropertyValue(ePropID_alertRange)local world = game_get_world();if world._cfg.autofightradius thenfilterdist = world._cfg.autofightradiusendlocal r1 = entity:GetRadius();if entity._PreCommand == ePreTypeClickMove or entity._PreCommand == ePreTypeJoystickMove thenreturn false;end	if entity._curSkill thenlocal target = nil;local ignoreDist = false;local stype = entity._curSkill._cfg.type;if stype == eSE_Damage or stype == eSE_DBuff then -- 伤害、诅咒if entity._forceAttackTarget and not entity._forceAttackTarget:IsDead() thenignoreDist = true;target = entity._forceAttackTarget;elselocal enmities = entity:GetEnmities();if enmities thenlocal enmity = enmities[1];if enmity thenignoreDist = true;target = enmity;endendif not target or target._groupType == eGroupType_N thenlocal tentity = nillocal mapType = game_get_map_type();for i,v in ipairs(entity._alives[2]) dolocal r2 =  entity._alives[2][i].entity:GetRadius();local radius = r1 + r2;	if radius thenif mapType thenif mapType == g_ARENA_SOLO or mapType == g_TAOIST thenbreak;endendif entity._alives[2][i].dist < entity._curSkill._range + radius thententity = entity._alives[2][i];if entity._alives[2][i+1] and entity._alives[2][i+1].dist thenif tentity.dist <  entity._alives[2][i+1].dist thententity = entity._alives[2][i+1];elsetentity = entity._alives[2][i];endelsetentity = entity._alives[2][i];break;endelseif v.entity:GetEntityType() == eET_Player and v.dist > filterdist thenif entity._alives[2][i+1] and entity._alives[2][i+1].dist < filterdist thententity = entity._alives[2][i+1];break;	endelsetentity = entity._alives[2][i-1];break;	endend		endendif entity._groupType == eGroupType_O thenlocal nentity = tentity or entity._alives[2][1] or entity._alives[3][1]if target and nentity and nentity.entity and nentity.entity._groupType ~= eGroupType_N  thentarget = nentity.entity;elseif not ignoreDist thentarget = tentity or entity._alives[2][1];if entity._alives[3][1] thenlocal trap =  entity._alives[3][1];if trap.entity and trap.entity._traptype == eSTrapActive thentarget = entity._alives[3][1];			endendif nentity and nentity.entity._groupType == eGroupType_N and nentity.dist > db_common.droppick.AutoFightMapbuffAutoRange thentarget = nil;return false;endendelsetarget = tentity or entity._alives[2][1] -- 敌方endendendelseif stype == eSE_Buff then -- 祝福if entity._target and entity._target._guid == entity._guid thenreturn false;end self._target = entity;return true;endif target thenif ignoreDist thenif not (target:GetEntityType() == eET_Pet and (not entity._enmities or #entity._enmities <= 0)) thenself._target = target;endif not entity._target or entity._target:IsDead() thenreturn true;endreturn target._guid ~= entity._target._guid;elselocal r2 = target.entity:GetRadius();local radius = r1 + r2;if target.dist < filterdist + radius thenif not (target.entity:GetEntityType() == eET_Pet and (not entity._enmities or #entity._enmities <= 0)) thenself._target = target.entity;endif not entity._target or entity._target:IsDead() thenreturn true;endif target.dist < entity._curSkill._range + radius thenreturn false;endreturn target.entity._guid ~= entity._target._guid;endendendendreturn false;
endfunction ai_autofight_find_target:OnEnter()if BASE.OnEnter(self) thenlocal entity = self._entity;--log("ai_autofight_find_target")entity._behavior:Clear(eEBGuard);if self._target thenif entity._curSkill thenentity:SetTarget(self._target);elseentity:MoveTo(self._target._curPos);endendreturn true;endreturn false;
endfunction ai_autofight_find_target:OnLeave()if BASE.OnLeave(self) thenself._target = nil;return true;endreturn false;
endfunction ai_autofight_find_target:OnUpdate(dTime)if BASE.OnUpdate(self, dTime) thenreturn true;endreturn false;
endfunction ai_autofight_find_target:OnLogic(dTick)if BASE.OnLogic(self, dTick) thenreturn false; -- only one frameendreturn false;
endfunction create_component(entity, priority)return ai_autofight_find_target.new(entity, priority);
end


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/50744.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Docker+consul容器服务的更新与发现

1、Consul概述 &#xff08;1&#xff09;什么是服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服务的压力承载&#xff0c;服务之间调用单纯的通过接口访问。直到后来出现了多个节点…

Spark实时(三):Structured Streaming入门案例

文章目录 Structured Streaming入门案例 一、Scala代码如下 二、Java 代码如下 三、以上代码注意点如下 Structured Streaming入门案例 我们使用Structured Streaming来监控socket数据统计WordCount。这里我们使用Spark版本为3.4.3版本&#xff0c;首先在Maven pom文件中导…

在 Spring Boot 中使用 Filters 实现请求过滤和预处理

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 什么是过滤器 过滤器&#xff08;Filter&#xff09;是一种在Web应用中用于拦截和处理HTTP请求和响应的对象。 在Java Web开发中&#xff0c;过滤器是实现特定功能&#xff0c;如认证、日志记录和字符编码处…

X-AnyLabeling标注软件使用方法

第一步 下载 官方X-AnyLabeling下载地址 github&#xff1a;X-AnyLabeling 第二步 配置环境 使用conda创建新的虚拟环境 conda create -n xanylabel python3.8进入环境 conda activate xanylabel进入X-AnyLabeling文件夹内&#xff0c;运行下面内容 依赖文件系统环境运行环…

MyBatisPlus复习

目录 自定义sql swagger工具 IService批量新增 代码生成器 DB静态工具&#xff0c;hutool工具 逻辑删除 枚举处理器 Json处理器 分页 自定义sql swagger工具 IService批量新增 代码生成器 DB静态工具&#xff0c;hutool工具 逻辑删除 枚举处理器 Json处理器 分页

ks滑块验证码逆向分析与python识别

文章目录 1. 写在前面3. 接口分析3. 算法实现 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…

大模型技术:发展历程、经典模型、微调与应用[更新中...]

文章目录 一、预训练语言模型发展历程二、经典的Pre-trained任务2.1 Masked Language Modeling2.2 Next Sentence Prediction 三、Task-specific Fine-tuning 任务3.1 Single-text Classification (单句分类)3.2 Sentence-pair Classification (句子匹配/成对分类)3.3 Span Tex…

谷粒商城实战笔记-71-商品服务-API-属性分组-前端组件抽取父子组件交互

文章目录 一&#xff0c;一次性创建所有的菜单二&#xff0c;开发属性分组界面1&#xff0c;左侧三级分类树形组件2&#xff0c;右侧分组列表3&#xff0c;左右两部分通信3.1 子组件发送数据3.2&#xff0c;父组件接收数据 Vue的父子组件通信父组件向子组件传递数据子组件向父组…

【BUG】已解决:The above exception was the direct cause of the following exception:

The above exception was the direct cause of the following exception: 目录 The above exception was the direct cause of the following exception: 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c…

【杰理蓝牙开发】AC695x 音频部分

本文主要记录 杰理蓝牙audio接口的使用&#xff0c;包括ADC和DAC原理的介绍和API接口的使用。 【杰理蓝牙开发】AC695x 音频部分 0. 个人简介 && 授权须知1. ADC【音频数据采集】硬件部分1.1 单片机引脚1.2 硬件电路设计1.3 MIC 输入通路解释 2. 【DAC】音频信号编解码…

Super 4PCS配准算法

Nicolas Mellado&#xff0c;CNRS&#xff08;Centre national de la recherche scientifique&#xff0c;法国国家科学研究中心&#xff09;的研究员&#xff0c;在IRIT&#xff08;Institut de Recherche en Informatique de Toulouse&#xff0c;图卢兹计算机科学研究所&…

SAPUI5基础知识20 - 对话框和碎片(Dialogs and Fragments)

1. 背景 在 SAPUI5 中&#xff0c;Fragments 是一种轻量级的 UI 组件&#xff0c;类似于视图&#xff08;Views&#xff09;&#xff0c;但它们没有自己的控制器&#xff08;Controller&#xff09;。Fragments 通常用于定义可以在多个视图中重用的 UI 片段&#xff0c;从而提…

linux系统安装pytorch_中文地址命名实体识别案例

命名实体有关文章参考这篇文章 中文地址命名实体识别训练和预测 win10系统安装cuda环境参考这篇文章 搭建Pytorch的GPU环境超详细 1、下载python https://www.python.org/downloads/release/python-368/ 2、下载python包 https://pypi.org/search/?q=transformers 1、搜…

如何录制电脑内部声音?全方位介绍电脑录音软件:8款在线录音!(2024重新整理)

如何录制电脑内部声音&#xff1f;不管是娱乐圈还是现实生活&#xff0c;【录音】这个功能的重要性不言而喻。而电脑录音已在影视配音、音视频剪辑、会议记录、在线教育等多个领域发光发热&#xff01; 本文将为您推荐8款电脑录音软件&#xff0c;并详细介绍电脑录音的多种方式…

Python番外篇:变量是盒子还是标签

引言 前面通过几十篇文章&#xff0c;大概把Python的一些比较实用的基础做了一些介绍&#xff0c;学会这些&#xff0c;基本能应付日常的小的需求开发了&#xff0c;写一些小工具&#xff0c;提高工作的处理效率。 接下来&#xff0c;准备开始进入一个新的篇章&#xff0c;也…

C#如何引用dll动态链接库文件的注释

1、dll动态库文件项目生成属性中要勾选“XML文档文件” 注意&#xff1a;XML文件的名字切勿修改。 2、添加引用时XML文件要与DLL文件在同一个目录下。 3、如果要是添加引用的时候XML不在相同目录下&#xff0c;之后又将XML文件复制到相同的目录下&#xff0c;需要删除引用&am…

当设计模式牵手LLM

模版方法模式 何为模版设计模式 想象一下 如果我们要泡一杯茶 我们要循序渐进地 煮水温杯注水浸茶茶水入杯加点配料 如此&#xff0c;泡茶的工序就完成了&#xff0c;那么模板方法模式&#xff0c;相信各位也有了一定的概念&#xff1a;定义了一个算法的骨架&#xff0c;而…

UDP的报文结构及其注意事项

1. 概述 UDP&#xff08;User Datagram Protocol&#xff09;是一种无连接的传输层协议&#xff0c;它提供了一种简单的数据传输服务&#xff0c;不保证数据的可靠传输。在网络通信中&#xff0c;UDP通常用于一些对实时性要求较高、数据量较小、传输延迟较低的应用&#xff0c…

【JVM基础07】——类加载器-什么是类加载器?类加载器有哪些?双亲委派了解吗?

目录 1- 引言&#xff1a;类加载器1-1 类加载器是什么&#xff1f;(What)1-2 为什么要用类加载器&#xff1f; 作用&#xff1a;类加载的过程&#xff1f;(Why) 2- ⭐核心&#xff1a;类加载器详解(How)2-1 类加载器分类2-2 什么是双亲委派模型&#xff1f;2-3 为什么采用双亲委…