lua 游戏架构 之 游戏 AI (三)ai_attack
这段Lua脚本定义了一个名为 `ai_attack` 的类,继承自 `ai_base` 类。
lua 游戏架构 之 游戏 AI (一)ai_base-CSDN博客文章浏览阅读119次。定义了一套接口和属性,可以基于这个基础类派生出具有特定行为的AI组件。例如,可以创建追逐敌人的AI、巡逻的AI或使用特定策略的AI等,都继承自这个基础类https://blog.csdn.net/heyuchang666/article/details/140624481?spm=1001.2014.3001.5501
这个类用于处理游戏中AI的攻击逻辑。以下是对代码的详细解释:
1. **引入基类**:
- `local BASE = require("logic/entity/ai/ai_base").ai_base;` 这行代码引入了基类 `ai_base`。
2. **定义 `ai_attack` 类**:
- `ai_attack = class("ai_attack", BASE);` 这行代码定义了 `ai_attack` 类并指定其基类为 `BASE`。
3. **构造函数 (`ctor`)**:
- `function ai_attack:ctor(entity)` 构造函数接受一个 `entity` 参数,并设置 `_type` 属性为 `eAType_ATTACK`。
4. **`IsValid` 方法**:
- 这个方法用于验证AI是否可以执行攻击。它检查实体是否死亡、是否可以攻击、是否是特定类型的实体等条件。
5. **`CanAttackNoneTarget` 方法**:
- 这个方法用于判断是否可以攻击没有目标的情况,当前实现返回 `false`。
6. **`OnEnter` 方法**:
- 当AI组件进入激活状态时执行。该方法处理目标定位、实体朝向调整、攻击开始逻辑等。
- 如果实体有目标并且速度大于0,则计算目标和实体之间的旋转角度,并设置实体面向目标。
7. **`OnLeave` 方法**:
- 当AI组件离开激活状态时执行。该方法处理停止攻击的逻辑,并恢复实体的移动能力。
8. **`OnUpdate` 方法**:
- 每帧调用,用于更新AI状态。如果基类的 `OnUpdate` 方法返回 `false`,则当前方法也返回 `false`。
9. **`OnLogic` 方法**:
- 逻辑更新方法,用于处理技能序列、检查攻击持续时间等。
- 如果技能序列有效且是当前技能的子技能,则执行相关逻辑。
- 检查自攻击开始以来的时间是否已经超过技能的持续时间,如果是,则返回 `false`。
10. **创建组件函数**:
- `function create_component(entity, priority)` 这个函数用于创建 `ai_attack` 类的新实例,传入一个实体和一个优先级。
代码中的一些关键函数和方法:
- `IsDead()`:检查实体是否死亡。
- `CanAttack()`:检查实体是否可以攻击。
- `GetEntityType()`:获取实体的类型。
- `GetMapEnter()`:获取地图进入的状态。
- `Test(eEBAttack)`:测试实体的行为是否包含攻击行为。
- `CanUse()`:检查技能是否可以使用。
- `IsPlayer()`:检查目标是否是玩家。
- `GetRadius()`:获取实体的半径。
- `vec3_sub1()`:计算两个向量的差。
- `vec3_len()`:计算向量的长度。
- `vec3_angle1()`:计算两个向量之间的夹角。
- `SetFaceDir()`:设置实体的面向方向。
- `StartAttack()`:开始攻击。
- `StopAttack()`:停止攻击。
- `FinishAttack()`:完成攻击。
这个脚本为游戏中的AI提供了一个攻击行为的基础框架,可以根据具体游戏的需求进行扩展和修改。
----------------------------------------------------------------local require = requirelocal BASE = require("logic/entity/ai/ai_base").ai_base;------------------------------------------------------
ai_attack = class("ai_attack", BASE);
function ai_attack:ctor(entity)self._type = eAType_ATTACK;
endfunction ai_attack:IsValid()local entity = self._entity;if entity:IsDead() or not entity:CanAttack() thenreturn false;endif entity:GetEntityType() == eET_Player and entity._DigStatus == 2 thenreturn false;endif entity:GetEntityType() == eET_Trap thenif entity._ntype ~= eEntityTrapType_AOE thenreturn false;elseif entity._curSkill and entity._curSkill:CanUse() thenreturn trueendendendif not g_game_context:GetMapEnter() thenreturn false;endif entity._behavior:Test(eEBAttack) thenreturn true;endif entity._curSkill and entity._curSkill:CanUse() thenlocal target = entity._target;if target thenif not target:IsPlayer() and target:GetEntityType() == eET_Player thenif target._behavior:Test(eEBInvisible) thenreturn false;endendlocal dist = vec3_sub1(entity._curPos, target._curPos);if (entity._curSkill._range + (entity:GetRadius() + target:GetRadius())) > vec3_len(dist) thenreturn true;endreturn false;elseif entity:GetEntityType() == eET_Player then if entity._AutoFight thenreturn falseendelseif entity:GetEntityType() == eET_Mercenary thenif entity._cfg.ultraSkill == entity._curSkill._id thenreturn trueendif entity._curSkill._specialArgs.rushInfo and not entity._hoster:IsPlayer() thenreturn trueendendendreturn self:CanAttackNoneTarget();endreturn false;
endfunction ai_attack:CanAttackNoneTarget()return false;
endfunction ai_attack:OnEnter()if BASE.OnEnter(self) thenlocal entity = self._entity;local target = entity._target;local speed = entity:GetPropertyValue(ePropID_speed);if speed > 0 and entity._target and entity._target._guid ~= entity._guid thenlocal p1 = target._curPos;local p2 = entity._curPos;local rot_y = vec3_angle1(p1, p2, { x = 1, y = 0, z = 0 });entity:SetFaceDir(0, rot_y, 0);endself._startTick = game_get_logic_time();self._skill = entity._curSkill;self._canBreak = self._skill._canBreak;self._duration = self._skill._duration;self._attacker = entity:StartAttack();self._movable = entity._movable;if not self._attacker thenreturn false;endself._entity._movable = false;return true;endreturn false;
endfunction ai_attack:OnLeave()if BASE.OnLeave(self) thenif self._canBreak and self._attacker thenself._attacker:StopAttack(false);endself._entity:FinishAttack();self._entity._movable = self._movable;return true;endreturn false;
endfunction ai_attack:OnUpdate(dTime)if not BASE.OnUpdate(self, dTime) then return false; endreturn true;
endfunction ai_attack:OnLogic(dTick)if not BASE.OnLogic(self, dTick) then return false; endlocal seq_skill = self._entity._seq_skill;if seq_skill and seq_skill.valid and seq_skill.parent == self._skill thenseq_skill.valid = false;if self._attacker thenif self._attacker:NextSequence(seq_skill.skill) thenself._duration = seq_skill.skill._duration;self._startTick = game_get_logic_time();endendendif self._skill thenif (game_get_logic_time() - self._startTick) * 1000 >= self._duration thenreturn false;endendreturn true;
endfunction create_component(entity, priority)return ai_attack.new(entity, priority);
end
相关文章:
lua 游戏架构 之 游戏 AI (三)ai_attack
这段Lua脚本定义了一个名为 ai_attack 的类,继承自 ai_base 类。 lua 游戏架构 之 游戏 AI (一)ai_base-CSDN博客文章浏览阅读119次。定义了一套接口和属性,可以基于这个基础类派生出具有特定行为的AI组件。例如,可以…...

大数据之Oracle同步Doris数据不一致问题
数据同步架构如下: 出现的问题: doris中的数据条数 源库中的数据条数 总数完全不一致。 出现问题的原因: 在Dinky中建立表结构时,缺少对主键属性的限制 primary key(ID) not enforced 加上如上语句,数据条数解决一致 …...

visual studio 问题总结
一. Visual Studio: 使用简体中文(GB2312)编码加载文件, 有些字节已用Unicode替换字符更换 解决方法:vs 工具-》选项-》文本编辑器...
go-错误码的最佳实践
一、背景 在工程开发中,我们有以下场景可以用错误码解决 我们不太方便直接将内部的错误原因暴露给外部,可以根据错误码得到对应的外部暴露消息通过设定错误码判断是客户端或者服务端的问题,避免不必要的排障浪费方便查找日志,定…...
Python面试题:使用Matplotlib和Seaborn进行数据可视化
使用Matplotlib和Seaborn进行数据可视化是数据分析中非常重要的一部分。以下示例展示了如何使用这两个库来创建各种图表,包括基本的线图、柱状图、散点图和高级的分类数据可视化图表。 安装 Matplotlib 和 Seaborn 如果你还没有安装这两个库,可以使用以…...

模拟实现c++中的vector模版
目录 一vector简述: 二vector的一些接口函数: 1初始化: 2.vector增长: 3vector增删查改: 三vector模拟实现部分主要函数: 1.size,capacity,empty,clear接口: 2.reverse的实现࿱…...
uniapp安卓通过绝对路径获取文件
uniapp安卓通过绝对路径获取文件 在uniapp中,如果你想要访问安卓设备上的文件,你需要使用uniapp提供的plus.io API。这个API允许你在应用内访问设备的文件系统。 以下是一个示例代码,展示了如何使用plus.io API来获取文件: fun…...
Known框架实战演练——进销存业务单据
本文介绍如何实现进销存管理系统的业务单据模块,业务单据模块包括采购进货单、采购退货单、销售出货单、销售退货单4个菜单页面。由于进销单据字段大同小异,因此设计共用一个页面组件类。 项目代码:JxcLite开源地址: https://git…...

解决npm依赖树冲突的方法以及npm ERR! code ERESOLVE错误的解决方案
一、问题描述 在使用ng new myapp --skip-install 构建Angular 项目后,尝试用npm install 安装依赖的时候报了以下错误。 (base) PS C:\Users\Administrator\Desktop\agtest\myapp> npm i npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependenc…...

Spring Boot + Spring Batch + Quartz 整合定时批量任务
博客主页: 南来_北往 系列专栏:Spring Boot实战 前言 最近一周,被借调到其他部门,赶一个紧急需求,需求内容如下: PC网页触发一条设备升级记录(下图),后台要定时批量设备更…...
C++STL简介(二)
目录 1.模拟实现string 1.string基本属性和大体框架 2.基本函数 2.1size() 2.2 [] 2.3 begin() 和end() 2.4capacity() 2.5 reserve 2.6push_back 2.7 append 2.8 2.9insert 2.10find 2.11substr 2.12 2.12 < …...
嵌入式高频面试题100道及参考答案(3万字长文)
目录 解释嵌入式系统的定义和主要特点 描述微处理器与微控制器的主要区别 什么是ARM体系结构?它在嵌入式系统中有哪些优势? 解释GPIO(通用输入输出)的工作原理 什么是ADC和DAC?它们在嵌入式系统中的作用是什么? 解释中断的概念及其在实时系统中的重要性 描述SPI(串…...

python爬虫-事件触发机制
今天想爬取一些政策,从政策服务 (smejs.cn) 这个网址爬取,html源码找不到链接地址,通过浏览器的开发者工具,点击以下红框 分析预览可知想要的链接地址的id有了,进行地址拼接就行 点击标头可以看到请求后端服务器的api地…...
LeetCode-day27-3106. 满足距离约束且字典序最小的字符串
LeetCode-day27-3106. 满足距离约束且字典序最小的字符串 题目描述示例示例1:示例2:示例3: 思路代码 题目描述 给你一个字符串 s 和一个整数 k 。 定义函数 distance(s1, s2) ,用于衡量两个长度为 n 的字符串 s1 和 s2 之间的距…...
C++中的static_cast函数
static_cast 是 C 中的一个类型转换操作符,用于在编译时进行类型转换。它主要用于基本数据类型之间的转换,以及类的指针或引用之间的向上转换(将派生类指针或引用转换为基类指针或引用)和某些情况下的向下转换(将基类指…...

从零开始学习网络安全渗透测试之基础入门篇——(二)Web架构前后端分离站Docker容器站OSS存储负载均衡CDN加速反向代理WAF防护
Web架构 Web架构是指构建和管理Web应用程序的方法和模式。随着技术的发展,Web架构也在不断演进。当前,最常用的Web架构包括以下几种: 单页面应用(SPA): 特点:所有用户界面逻辑和数据处理都包含…...
2679. 矩阵中的和
两种方法: 第一种:先对二维列表的每一列进行排序,然后对每一列的数据进行逐个比较,找出最大值。 class Solution:def matrixSum(self, nums: list[list[int]]) -> int:result0mlen(nums)nlen(nums[0])for i in range(m):nums…...
Unity Playables:下一代动画与音频序列
Unity的Playables API是一种灵活的系统,用于创建和控制动画、音频以及其他形式的连续媒体序列。它为开发者提供了一种全新的方法来处理游戏中的时间序列,包括动画、音频、特效等。本文将探讨Playables的基本概念、如何使用Playables API实现动画…...

matlab仿真 模拟调制(下)
(内容源自详解MATLAB/SIMULINK 通信系统建模与仿真 刘学勇编著第五章内容,有兴趣的读者请阅读原书) clear all ts0.001; t0:ts:10-ts; fs1/ts; dffs/length(t); msgrandi([-3 3],100,1); msg1msg*ones(1,fs/10); msg2reshape(ms…...
RabbitMQ是什么?
RabbitMQ是一个开源的消息代理软件(Message Broker),它实现了高级消息队列协议(AMQP,Advanced Message Queuing Protocol),并支持多种消息传递协议。它最初由英国的Rabbit Technologies开发&…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...

密码学基础——SM4算法
博客主页:christine-rr-CSDN博客 专栏主页:密码学 📌 【今日更新】📌 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 编辑…...
第22节 Node.js JXcore 打包
Node.js是一个开放源代码、跨平台的、用于服务器端和网络应用的运行环境。 JXcore是一个支持多线程的 Node.js 发行版本,基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行。 本文主要介绍JXcore的打包功能。 JXcore 安装 下载JXcore安装包&a…...

HTML版英语学习系统
HTML版英语学习系统 这是一个完全免费、无需安装、功能完整的英语学习工具,使用HTML CSS JavaScript实现。 功能 文本朗读练习 - 输入英文文章,系统朗读帮助练习听力和发音,适合跟读练习,模仿学习;实时词典查询 - 双…...