From 35b91f46622d0700061af04c9769b12c95aaea68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=AB=E6=AC=A3=E6=B5=B7?= Date: Sun, 23 Feb 2025 14:20:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1485 +++++++++++++++++++++++++++++------------------------ 1 file changed, 807 insertions(+), 678 deletions(-) diff --git a/README.md b/README.md index f66d0e9..2352c75 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,112 @@ # KunpoLib -基于 Cocos Creator 3.0+ 的游戏开发工具库,提供了一系列实用的功能模块,帮助开发者快速构建高质量的游戏项目。 +基于 Cocos Creator 3.0+ 的一套游戏框架,提供了一系列实用模块,帮助开发者快速构建高质量的游戏项目。 项目持续优化中,敬请期待~~ -## 特性 +## 目录 +- [模块](#模块) +- [安装kunpocc](#安装kunpocc) +- [项目基础配置](#项目基础配置) +- [使用方法](#使用方法) + - [一、UI 系统](#一ui-系统) + - [UI 装饰器使用](#ui-装饰器使用) + - [创建窗口](#创建窗口) + - [二、实体组件系统(EC)](#二实体组件系统ec) + - [creator插件`kunpo-ec`](#creator插件kunpo-ec) + - [重点接口说明](#重点接口说明) + - [使用](#使用) + - [三、网络模块](#三-网络模块) + - [HTTP 请求](#http-请求) + - [请求方法](#请求方法) + - [参数说明](#参数说明) + - [响应处理](#响应处理) + - [四、四叉树碰撞检测](#四四叉树碰撞检测) + - [基本概念](#基本概念) + - [使用示例](#使用示例) + - [形状操作](#形状操作) + - [性能优化建议](#性能优化建议) + - [五、行为树系统](#五行为树系统) + - [行为树基本概念](#行为树基本概念) + - [行为树使用示例](#行为树使用示例) + - [常用节点](#常用节点) + - [注意事项](#注意事项) + - [六、资源加载工具](#六资源加载工具) + - [资源加载器](#资源加载器) + - [资源池](#资源池) + - [七、条件显示节点](#七条件显示节点用来处理游戏中的提示红点信息) + - [定义条件](#定义条件) + - [节点关联条件](#节点关联条件) + - [八、全局事件系统](#八-全局事件系统) + - [九、全局计时器](#九全局计时器) + - [十、平台相关](#十平台相关) + - [平台类型](#平台类型) + - [平台判断](#平台判断) + - [使用示例](#使用示例-2) + - [十一、屏幕](#十一屏幕) + - [十二、工具类](#十二工具类) + - [数学工具 (MathTool)](#数学工具-mathtool) + - [MD5 加密](#md5-加密) + +## 模块 + +- **UI 系统 (基于 FairyGUI)** + + * 灵活的 UI 装饰器(配合插件 `kunpo-fgui` 使用,一键导出界面配置,省时省力省代码) + + * 控制窗口之间的相互关系(eg: 打开界面时,是隐藏/关闭前一个界面,还是隐藏/关闭所有界面) + + * 多窗口组管理 + + * 顶部显示金币钻石的资源栏(header),一次实现,多界面复用, + + * 支持不同界面使用不同 header -- **UI 系统** - - 基于 FairyGUI 的窗口管理系统 - - 灵活的 UI 装饰器 (装饰器需配合 creator插件 kunpo-fgui使用) - - 窗口分组管理 - - 窗口顶部资源栏(Header)管理 -- **全局工具** - - 全局事件系统 - - 全局计时器 - - 平台适配工具 - - 调试模式支持 -- **网络模块** - - HTTP 请求管理 - - 任务队列 - - 完整的请求响应接口 -- **数据结构** - - 四叉树(支持碰撞检测) - - 矩形碰撞 - - 圆形碰撞 - - 多边形碰撞 -- **行为树系统** - - 完整的行为树实现 - - 支持多种节点类型 - - Action(动作节点) - - Composite(组合节点) - - Condition(条件节点) - - Decorator(装饰节点) - - 黑板数据共享 - - Ticker 系统 - **EC 框架** - - 实体组件系统 - - 组件池优化 - - 实体管理器 + + * 不同实体上的组件更新顺序管理(`只根据注册的组件更新顺序更新,跟实体无关`) + + - 灵活的EC装饰器 (配合插件 `kunpo-ec` 使用,配置实体组件信息,一键导出) + - 支持多世界(多战斗场景,互不影响) + - 区分数据组件和逻辑组件,只更新逻辑组件 + +- **网络模块 (Http)** + - HTTP 请求管理 + - 完整的请求响应接口 + +- **四叉树(碰撞查询)** + + * 矩形碰撞 + * 圆形碰撞 + * 多边形碰撞 + +- **行为树系统** + - 用来实现复杂的怪物行为 + - **资源管理** - * 资源加载 - * 资源池 -- 条件显示节点系统 (用来处理游戏中的提示红点信息) + * 资源加载后放入资源池 + * 资源池 可通过路径或者uuid获取资源 + * 只适合手动管理资源,单无论加载多少次,卸载一次后删除 + +- **条件显示节点系统 (用来处理游戏中的提示红点信息)** + + * 主要是解耦用,条件单独实现,节点关联单条件或者多个条件 + +- **全局事件系统 `GlobalEvent`** + +- **全局计时器 `GlobalTimer`** + +- **平台相关 `Platform`** + +- **屏幕尺寸 `Screen`** + +- **数据结构** + + - 二叉堆(`BinaryHeap` 最大、最小堆) + - 单向(`LinkedList`)、双向链表 (`DoublyLinkedList`) + - 栈(`Stack`) + +- **适配相关 `Adapter` (不需要关心) ** ## 安装kunpocc @@ -82,7 +147,7 @@ npm install kunpocc ## 使用方法 -### 一、UI 系统使用 +### 一、UI 系统 > 注:UI制作需要使用 FairyGUI,[FairyGUI官方文档](https://www.fairygui.com/docs/editor) @@ -240,645 +305,7 @@ npm install kunpocc -### 二、 全局事件系统 - -```typescript -import { GlobalEvent } from 'kunpocc'; - -// 添加事件监听 -GlobalEvent.add('eventName', (arg1, arg2) => { - console.log('事件触发:', arg1, arg2); -}, this); - -// 添加一次性事件监听 -GlobalEvent.addOnce('oneTimeEvent', (data) => { - console.log('一次性事件触发:', data); -}, this); - -// 发送事件 -GlobalEvent.send('eventName', 'arg1', 'arg2'); - -// 发送事件到指定目标 -GlobalEvent.sendToTarget('eventName', target, 'arg1', 'arg2'); - -// 移除事件监听 -GlobalEvent.remove('eventName', callback, this); - -// 移除指定目标的所有事件监听 -GlobalEvent.removeByTarget(this); - -// 移除指定事件名和目标的事件监听 -GlobalEvent.removeByNameAndTarget('eventName', this); -``` - - - -### 三、全局计时器 - -```typescript -import { GlobalTimer } from 'kunpocc'; - -// 启动一次性定时器(2秒后执行) -const timerId1 = GlobalTimer.startTimer(() => { - console.log('2秒后执行一次'); -}, 2); - -// 启动循环定时器(每3秒执行一次,执行5次) -const timerId2 = GlobalTimer.startTimer(() => { - console.log('每3秒执行一次,总共执行5次'); -}, 3, 5); - -// 启动无限循环定时器(每1秒执行一次) -const timerId3 = GlobalTimer.startTimer(() => { - console.log('每1秒执行一次,无限循环'); -}, 1, -1); - -// 停止定时器 -GlobalTimer.stopTimer(timerId1); -GlobalTimer.stopTimer(timerId2); -GlobalTimer.stopTimer(timerId3); -``` - -注意事项: -- 定时器的时间间隔单位为秒 -- loop 参数说明: - - 0:执行一次 - - 正整数 n:执行 n 次 - - -1:无限循环 - -### 四、 网络模块 - -#### *HTTP 请求* - -```typescript -import { HttpManager, IHttpEvent, HttpResponseType } from 'kunpocc'; - -// 1. 使用回调方式处理响应 -const event: IHttpEvent = { - name: "login", - onComplete: (response) => { - console.log('请求成功:', response.data); - }, - onError: (response) => { - console.log('请求失败:', response.error); - } -}; - -// POST 请求 -HttpManager.post( - "https://api.example.com/login", - { username: "test", password: "123456" }, - "json", // 响应类型:'json' | 'text' | 'arraybuffer' - event, - ["Content-Type", "application/json"], // 请求头 - 5 // 超时时间(秒) -); - -// GET 请求 -HttpManager.get( - "https://api.example.com/users", - { id: 1 }, - "json", - event -); - -// 2. 使用全局事件方式处理响应 -GlobalEvent.add(HttpManager.HttpEvent, (result, response) => { - if (result === "succeed") { - console.log('请求成功:', response.data); - } else { - console.log('请求失败:', response.error); - } -}, this); - -// 发送请求(不传入 event 参数) -HttpManager.post("https://api.example.com/data", { /* data */ }); -``` - -#### *请求方法* -- `post(url, data, responseType?, event?, headers?, timeout?)` -- `get(url, data, responseType?, event?, headers?, timeout?)` -- `put(url, data, responseType?, event?, headers?, timeout?)` -- `head(url, data, responseType?, event?, headers?, timeout?)` - -#### *参数说明* -- `url`: 请求地址 -- `data`: 请求数据 -- `responseType`: 响应类型(可选,默认 'json') - - `'json'`: JSON 格式 - - `'text'`: 文本格式 - - `'arraybuffer'`: 二进制数据 -- `event`: 请求事件回调(可选) -- `headers`: 请求头(可选) -- `timeout`: 超时时间,单位秒(可选,0表示不超时) - -#### *响应处理* -1. 回调方式(通过 IHttpEvent): -```typescript -const event: IHttpEvent = { - name: "自定义名称", - data?: "自定义数据", // 可选 - onComplete: (response) => { - // 成功回调 - }, - onError: (response) => { - // 失败回调 - } -}; -``` - -2. 全局事件方式: -```typescript -GlobalEvent.add(HttpManager.HttpEvent, (result, response) => { - // result: "succeed" | "fail" - // response: IHttpResponse -}, this); -``` - -### 五、行为树系统 - -> 行为树是一个强大的 AI 决策系统,用于实现复杂的游戏 AI 行为。 - -#### *基本概念* - -1. 节点状态 -```typescript -enum Status { - SUCCESS, // 成功 - FAILURE, // 失败 - RUNNING // 运行中 -} -``` - -2. 节点类型 -- **动作节点 (Action)**:执行具体行为的叶子节点 -- **组合节点 (Composite)**:控制子节点执行顺序的节点 -- **条件节点 (Condition)**:判断条件的节点 -- **装饰节点 (Decorator)**:修饰其他节点行为的节点 - -#### *使用示例* - -```typescript -import { - BehaviorTree, - Sequence, - Selector, - Parallel, - Success, - Failure, - WaitTime, - Agent, - Blackboard -} from 'kunpocc'; - -// 1. 创建行为树 -const tree = new BehaviorTree( - new Sequence( // 顺序节点:按顺序执行所有子节点 - new WaitTime(2), // 等待2秒 - new Selector( // 选择节点:选择一个可执行的子节点 - new Success(() => { - console.log("执行成功动作"); - }), - new Failure(() => { - console.log("执行失败动作"); - }) - ) - ) -); - -// 2. 创建代理和黑板 -const agent = new Agent(); // AI代理 -const blackboard = new Blackboard(); // 共享数据黑板 - -// 3. 执行行为树 -tree.tick(agent, blackboard); -``` - -#### *常用节点* - -1. 组合节点 - - ```typescript - // 顺序节点:按顺序执行所有子节点,直到遇到失败或运行中的节点 - new Sequence(childNode1, childNode2, childNode3); - - // 选择节点:选择第一个成功或运行中的子节点 - new Selector(childNode1, childNode2, childNode3); - - // 并行节点:同时执行所有子节点 - new Parallel(childNode1, childNode2, childNode3); - - // 记忆顺序节点:记住上次执行的位置 - new MemSequence(childNode1, childNode2, childNode3); - - // 记忆选择节点:记住上次执行的位置 - new MemSelector(childNode1, childNode2, childNode3); - - // 随机选择节点:随机选择一个子节点执行 - new RandomSelector(childNode1, childNode2, childNode3); - ``` - -2. 动作节点 - - ```typescript - // 成功节点 - new Success(() => { - // 执行动作 - }); - - // 失败节点 - new Failure(() => { - // 执行动作 - }); - - // 运行中节点 - new Running(() => { - // 持续执行的动作 - }); - - // 等待节点 - new WaitTime(2); // 等待2秒 - new WaitTicks(5); // 等待5个tick - ``` - -3. 使用黑板共享数据 - - ```typescript - // 在节点中使用黑板 - class CustomAction extends Action { - tick(ticker: Ticker): Status { - // 获取数据 - const data = ticker.blackboard.get("key"); - - // 设置数据 - ticker.blackboard.set("key", "value"); - - return Status.SUCCESS; - } - } - ``` - - -#### *注意事项* - -1. 节点状态说明: - - `SUCCESS`:节点执行成功 - - `FAILURE`:节点执行失败 - - `RUNNING`:节点正在执行中 -2. 组合节点特性: - - `Sequence`:所有子节点返回 SUCCESS 才返回 SUCCESS - - `Selector`:任一子节点返回 SUCCESS 就返回 SUCCESS - - `Parallel`:并行执行所有子节点 - - `MemSequence/MemSelector`:会记住上次执行位置 -3. 性能优化: - - 使用黑板共享数据,避免重复计算 - - 合理使用记忆节点,减少重复执行 - - 控制行为树的深度,避免过于复杂 - - - -### 六、平台相关 - -> Platform 类提供了游戏运行平台的相关信息和判断方法。 - -#### *平台类型* - -```typescript -import { Platform, PlatformType } from 'kunpocc'; - -// 平台类型枚举 -enum PlatformType { - Android = 1, // 安卓 - IOS, // iOS - HarmonyOS, // 鸿蒙 - WX, // 微信小游戏 - Alipay, // 支付宝小游戏 - Bytedance, // 字节小游戏 - HuaweiQuick, // 华为快游戏 - Browser // 浏览器 -} - -// 获取当前平台类型 -const currentPlatform = Platform.platform; -``` - -#### *平台判断* - -```typescript -import { Platform } from 'kunpocc'; - -// 原生平台判断 -if (Platform.isNative) { - console.log('当前是原生平台'); -} - -// 移动平台判断 -if (Platform.isMobile) { - console.log('当前是移动平台'); -} - -// 原生移动平台判断 -if (Platform.isNativeMobile) { - console.log('当前是原生移动平台'); -} - -// 具体平台判断 -if (Platform.isAndroid) { - console.log('当前是安卓平台'); -} - -if (Platform.isIOS) { - console.log('当前是iOS平台'); -} - -if (Platform.isHarmonyOS) { - console.log('当前是鸿蒙系统'); -} - -// 小游戏平台判断 -if (Platform.isWX) { - console.log('当前是微信小游戏'); -} - -if (Platform.isAlipay) { - console.log('当前是支付宝小游戏'); -} - -if (Platform.isBytedance) { - console.log('当前是字节小游戏'); -} - -if (Platform.isHuaweiQuick) { - console.log('当前是华为快游戏'); -} - -// 浏览器判断 -if (Platform.isBrowser) { - console.log('当前是浏览器环境'); -} -``` - -#### *使用示例* - -```typescript -import { Platform, PlatformType } from 'kunpocc'; - -// 根据平台类型执行不同逻辑 -switch (Platform.platform) { - case PlatformType.Android: - // 安卓平台特定逻辑 - break; - case PlatformType.IOS: - // iOS平台特定逻辑 - break; - case PlatformType.WX: - // 微信小游戏特定逻辑 - break; - default: - // 其他平台逻辑 - break; -} - -// 针对不同平台进行适配 -if (Platform.isNativeMobile) { - // 原生移动平台的处理 - if (Platform.isAndroid) { - // 安卓特有功能 - } else if (Platform.isIOS) { - // iOS特有功能 - } -} else if (Platform.isWX || Platform.isAlipay || Platform.isBytedance) { - // 小游戏平台的处理 -} else { - // 浏览器平台的处理 -} -``` - -### 七、四叉树碰撞检测 - -> 四叉树是一种用于高效进行空间划分和碰撞检测的数据结构。 - -#### *基本概念* - -1. 形状类型 - - ```typescript - import { QuadTree, Box, Circle, Polygon } from 'kunpocc'; - - // 1. 矩形 - const box = new Box(x, y, width, height, tag); - - // 2. 圆形 - const circle = new Circle(x, y, radius, tag); - - // 3. 多边形 - const points = [v2(x1, y1), v2(x2, y2), v2(x3, y3)]; - const polygon = new Polygon(points, tag); - ``` - -2. 配置参数 - - ```typescript - // 四叉树配置 - const QTConfig = { - MAX_SHAPES: 12, // 每个节点最大形状数量 - MAX_LEVELS: 5, // 最大深度 - } - ``` - - -#### *使用示例* - -1. 创建和初始化 - - ```typescript - import { QuadTree, Box, rect } from 'kunpocc'; - - // 创建四叉树(参数:区域范围,层级,绘制组件) - const bounds = rect(0, 0, 800, 600); // x, y, width, height - const quadTree = new QuadTree(bounds); - - // 添加形状 - const player = new Box(100, 100, 50, 50, 1); // 玩家碰撞体,tag=1 - const enemy = new Circle(200, 200, 25, 2); // 敌人碰撞体,tag=2 - quadTree.insert(player); - quadTree.insert(enemy); - ``` - -2. 碰撞检测 - - ```typescript - // 检测指定形状与特定标签的碰撞 - const collisions = quadTree.collide(player, 2); // 检测玩家与 tag=2 的形状碰撞 - if (collisions.length > 0) { - console.log('发生碰撞!'); - for (const target of collisions) { - // 处理碰撞逻辑 - } - } - ``` - -3. 动态更新 - - ```typescript - // 在游戏循环中更新四叉树 - function update() { - // 更新形状位置 - player.position = v2(newX, newY); - enemy.position = v2(newX, newY); - - // 更新四叉树 - quadTree.update(); - - // 检测碰撞 - const collisions = quadTree.collide(player, 2); - } - ``` - -4. 清理 - - ```typescript - // 清理四叉树 - quadTree.clear(); - ``` - - -#### *形状操作* - -1. 位置和缩放 - - ```typescript - // 设置位置 - shape.position = v2(x, y); - - // 设置缩放 - shape.scale = 1.5; - - // 获取包围盒 - const boundingBox = shape.getBoundingBox(); - ``` - -2. 特定形状操作 - - ```typescript - // 矩形重置 - box.resetPoints(x, y, width, height); - - // 圆形半径 - circle.radius = newRadius; - - // 多边形顶点 - polygon.points = newPoints; - ``` - - -#### *性能优化建议* - -1. 合理设置配置参数: - - `MAX_SHAPES`:较小的值会导致更频繁的分裂,较大的值会降低查询效率 - - `MAX_LEVELS`:控制树的最大深度,防止过度分割 - -2. 碰撞检测优化: - - 使用合适的标签系统,只检测需要的碰撞 - - 根据游戏需求选择合适的形状(圆形计算最快) - - 避免使用过于复杂的多边形 - -3. 更新策略: - - 仅在必要时更新四叉树 - - 对于静态物体,可以使用单独的四叉树 - - 动态物体频繁更新时,考虑使用更大的边界范围 - -### 八、工具类 - -#### *数学工具 (MathTool)* - -```typescript -import { MathTool } from 'kunpocc'; - -// 1. 数值限制 -// 将数值限制在指定范围内 -const value = MathTool.clampf(75, 0, 100); // 返回75,因为在0-100范围内 -const value2 = MathTool.clampf(150, 0, 100); // 返回100,因为超出上限 -const value3 = MathTool.clampf(-50, 0, 100); // 返回0,因为低于下限 - -// 2. 随机数生成 -// 生成指定范围内的整数(包含边界值) -const randomInt = MathTool.rand(1, 10); // 返回1到10之间的整数 - -// 生成指定范围内的浮点数(包含最小值,不包含最大值) -const randomFloat = MathTool.randRange(0, 1); // 返回0到1之间的浮点数 - -// 3. 角度与弧度转换 -// 角度转弧度 -const radian = MathTool.rad(90); // 90度转换为弧度:约1.57 - -// 弧度转角度 -const degree = MathTool.deg(Math.PI); // π弧度转换为角度:180 - -// 4. 平滑过渡 -// 用于实现数值的平滑变化,常用于相机跟随、UI动画等 -const smoothValue = MathTool.smooth( - 0, // 起始值 - 100, // 目标值 - 0.16, // 已经过时间(秒) - 0.3 // 响应时间(秒) -); // 返回一个平滑过渡的中间值 -``` - -使用说明: - -1. `clampf(value: number, min: number, max: number): number` - - 将数值限制在指定范围内 - - 如果小于最小值,返回最小值 - - 如果大于最大值,返回最大值 - - 否则返回原值 - -2. `rand(min: number, max: number): number` - - 生成指定范围内的随机整数 - - 包含最小值和最大值 - - 常用于随机选择、随机掉落等场景 - -3. `randRange(min: number, max: number): number` - - 生成指定范围内的随机浮点数 - - 包含最小值,不包含最大值 - - 常用于需要精确浮点随机数的场景 - -4. `rad(angle: number): number` - - 将角度转换为弧度 - - 计算公式:angle * Math.PI / 180 - -5. `deg(radian: number): number` - - 将弧度转换为角度 - - 计算公式:radian * 180 / Math.PI - -6. `smooth(current: number, target: number, elapsedTime: number, responseTime: number): number` - - 计算平滑过渡的值 - - current: 当前值 - - target: 目标值 - - elapsedTime: 已经过时间(秒) - - responseTime: 响应时间(秒) - - 常用于实现平滑的相机移动、UI动画等 - -#### *MD5 加密* - -```typescript -import { md5 } from 'kunpocc'; - -// 字符串 MD5 加密 -const hash = md5('Hello, World!'); -console.log(hash); // 输出32位MD5哈希值 - -// 注意: -// 1. 输入必须是字符串类型 -// 2. 不能传入 undefined 或 null -try { - md5(null); // 将抛出错误 -} catch (error) { - console.error('MD5输入不能为null或undefined'); -} -``` - -### 九、实体组件系统(EC) +### 二、实体组件系统(EC) * 不使用creator官方的挂载脚本的方式,有以下几个原因 > 1. node挂脚本的方式效率低 @@ -1414,7 +841,375 @@ try { -### 十、资源加载工具 +### 三、 网络模块 + +#### *HTTP 请求* + +```typescript +import { HttpManager, IHttpEvent, HttpResponseType } from 'kunpocc'; + +// 1. 使用回调方式处理响应 +const event: IHttpEvent = { + name: "login", + onComplete: (response) => { + console.log('请求成功:', response.data); + }, + onError: (response) => { + console.log('请求失败:', response.error); + } +}; + +// POST 请求 +HttpManager.post( + "https://api.example.com/login", + { username: "test", password: "123456" }, + "json", // 响应类型:'json' | 'text' | 'arraybuffer' + event, + ["Content-Type", "application/json"], // 请求头 + 5 // 超时时间(秒) +); + +// GET 请求 +HttpManager.get( + "https://api.example.com/users", + { id: 1 }, + "json", + event +); + +// 2. 使用全局事件方式处理响应 +GlobalEvent.add(HttpManager.HttpEvent, (result, response) => { + if (result === "succeed") { + console.log('请求成功:', response.data); + } else { + console.log('请求失败:', response.error); + } +}, this); + +// 发送请求(不传入 event 参数) +HttpManager.post("https://api.example.com/data", { /* data */ }); +``` + +#### *请求方法* +- `post(url, data, responseType?, event?, headers?, timeout?)` +- `get(url, data, responseType?, event?, headers?, timeout?)` +- `put(url, data, responseType?, event?, headers?, timeout?)` +- `head(url, data, responseType?, event?, headers?, timeout?)` + +#### *参数说明* +- `url`: 请求地址 +- `data`: 请求数据 +- `responseType`: 响应类型(可选,默认 'json') + - `'json'`: JSON 格式 + - `'text'`: 文本格式 + - `'arraybuffer'`: 二进制数据 +- `event`: 请求事件回调(可选) +- `headers`: 请求头(可选) +- `timeout`: 超时时间,单位秒(可选,0表示不超时) + +#### *响应处理* +1. 回调方式(通过 IHttpEvent): +```typescript +const event: IHttpEvent = { + name: "自定义名称", + data?: "自定义数据", // 可选 + onComplete: (response) => { + // 成功回调 + }, + onError: (response) => { + // 失败回调 + } +}; +``` + +2. 全局事件方式: +```typescript +GlobalEvent.add(HttpManager.HttpEvent, (result, response) => { + // result: "succeed" | "fail" + // response: IHttpResponse +}, this); +``` + + + +### 四、四叉树碰撞检测 + +> 四叉树是一种用于高效进行空间划分和碰撞检测的数据结构。 + +#### *基本概念* + +1. 形状类型 + + ```typescript + import { QuadTree, Box, Circle, Polygon } from 'kunpocc'; + + // 1. 矩形 + const box = new Box(x, y, width, height, tag); + + // 2. 圆形 + const circle = new Circle(x, y, radius, tag); + + // 3. 多边形 + const points = [v2(x1, y1), v2(x2, y2), v2(x3, y3)]; + const polygon = new Polygon(points, tag); + ``` + +2. 配置参数 + + ```typescript + // 四叉树配置 + const QTConfig = { + MAX_SHAPES: 12, // 每个节点最大形状数量 + MAX_LEVELS: 5, // 最大深度 + } + ``` + + +#### *使用示例* + +1. 创建和初始化 + + ```typescript + import { QuadTree, Box, rect } from 'kunpocc'; + + // 创建四叉树(参数:区域范围,层级,绘制组件) + const bounds = rect(0, 0, 800, 600); // x, y, width, height + const quadTree = new QuadTree(bounds); + + // 添加形状 + const player = new Box(100, 100, 50, 50, 1); // 玩家碰撞体,tag=1 + const enemy = new Circle(200, 200, 25, 2); // 敌人碰撞体,tag=2 + quadTree.insert(player); + quadTree.insert(enemy); + ``` + +2. 碰撞检测 + + ```typescript + // 检测指定形状与特定标签的碰撞 + const collisions = quadTree.collide(player, 2); // 检测玩家与 tag=2 的形状碰撞 + if (collisions.length > 0) { + console.log('发生碰撞!'); + for (const target of collisions) { + // 处理碰撞逻辑 + } + } + ``` + +3. 动态更新 + + ```typescript + // 在游戏循环中更新四叉树 + function update() { + // 更新形状位置 + player.position = v2(newX, newY); + enemy.position = v2(newX, newY); + + // 更新四叉树 + quadTree.update(); + + // 检测碰撞 + const collisions = quadTree.collide(player, 2); + } + ``` + +4. 清理 + + ```typescript + // 清理四叉树 + quadTree.clear(); + ``` + + +#### *形状操作* + +1. 位置和缩放 + + ```typescript + // 设置位置 + shape.position = v2(x, y); + + // 设置缩放 + shape.scale = 1.5; + + // 获取包围盒 + const boundingBox = shape.getBoundingBox(); + ``` + +2. 特定形状操作 + + ```typescript + // 矩形重置 + box.resetPoints(x, y, width, height); + + // 圆形半径 + circle.radius = newRadius; + + // 多边形顶点 + polygon.points = newPoints; + ``` + + +#### *性能优化建议* + +1. 合理设置配置参数: + - `MAX_SHAPES`:较小的值会导致更频繁的分裂,较大的值会降低查询效率 + - `MAX_LEVELS`:控制树的最大深度,防止过度分割 + +2. 碰撞检测优化: + - 使用合适的标签系统,只检测需要的碰撞 + - 根据游戏需求选择合适的形状(圆形计算最快) + - 避免使用过于复杂的多边形 + +3. 更新策略: + - 仅在必要时更新四叉树 + - 对于静态物体,可以使用单独的四叉树 + - 动态物体频繁更新时,考虑使用更大的边界范围 + + +### 五、行为树系统 + +> 行为树是一个强大的 AI 决策系统,用于实现复杂的游戏 AI 行为。 + +#### *行为树基本概念* + +1. 节点状态 +```typescript +enum Status { + SUCCESS, // 成功 + FAILURE, // 失败 + RUNNING // 运行中 +} +``` + +2. 节点类型 +- **动作节点 (Action)**:执行具体行为的叶子节点 +- **组合节点 (Composite)**:控制子节点执行顺序的节点 +- **条件节点 (Condition)**:判断条件的节点 +- **装饰节点 (Decorator)**:修饰其他节点行为的节点 + +#### *行为树使用示例* + +```typescript +import { + BehaviorTree, + Sequence, + Selector, + Parallel, + Success, + Failure, + WaitTime, + Agent, + Blackboard +} from 'kunpocc'; + +// 1. 创建行为树 +const tree = new BehaviorTree( + new Sequence( // 顺序节点:按顺序执行所有子节点 + new WaitTime(2), // 等待2秒 + new Selector( // 选择节点:选择一个可执行的子节点 + new Success(() => { + console.log("执行成功动作"); + }), + new Failure(() => { + console.log("执行失败动作"); + }) + ) + ) +); + +// 2. 创建代理和黑板 +const agent = new Agent(); // AI代理 +const blackboard = new Blackboard(); // 共享数据黑板 + +// 3. 执行行为树 +tree.tick(agent, blackboard); +``` + +#### *常用节点* + +1. 组合节点 + + ```typescript + // 顺序节点:按顺序执行所有子节点,直到遇到失败或运行中的节点 + new Sequence(childNode1, childNode2, childNode3); + + // 选择节点:选择第一个成功或运行中的子节点 + new Selector(childNode1, childNode2, childNode3); + + // 并行节点:同时执行所有子节点 + new Parallel(childNode1, childNode2, childNode3); + + // 记忆顺序节点:记住上次执行的位置 + new MemSequence(childNode1, childNode2, childNode3); + + // 记忆选择节点:记住上次执行的位置 + new MemSelector(childNode1, childNode2, childNode3); + + // 随机选择节点:随机选择一个子节点执行 + new RandomSelector(childNode1, childNode2, childNode3); + ``` + +2. 动作节点 + + ```typescript + // 成功节点 + new Success(() => { + // 执行动作 + }); + + // 失败节点 + new Failure(() => { + // 执行动作 + }); + + // 运行中节点 + new Running(() => { + // 持续执行的动作 + }); + + // 等待节点 + new WaitTime(2); // 等待2秒 + new WaitTicks(5); // 等待5个tick + ``` + +3. 使用黑板共享数据 + + ```typescript + // 在节点中使用黑板 + class CustomAction extends Action { + tick(ticker: Ticker): Status { + // 获取数据 + const data = ticker.blackboard.get("key"); + + // 设置数据 + ticker.blackboard.set("key", "value"); + + return Status.SUCCESS; + } + } + ``` + + +#### *注意事项* + +1. 节点状态说明: + - `SUCCESS`:节点执行成功 + - `FAILURE`:节点执行失败 + - `RUNNING`:节点正在执行中 +2. 组合节点特性: + - `Sequence`:所有子节点返回 SUCCESS 才返回 SUCCESS + - `Selector`:任一子节点返回 SUCCESS 就返回 SUCCESS + - `Parallel`:并行执行所有子节点 + - `MemSequence/MemSelector`:会记住上次执行位置 +3. 性能优化: + - 使用黑板共享数据,避免重复计算 + - 合理使用记忆节点,减少重复执行 + - 控制行为树的深度,避免过于复杂 + + + +### 六、资源加载工具 #### *资源加载器* @@ -1475,9 +1270,343 @@ public static releaseUUID(uuid: string): void public static releaseAll(): void ``` -### 十、条件显示节点系统 +### 七、条件显示节点(用来处理游戏中的提示红点信息) + +#### *定义条件* + +```typescript +// 定义条件类型枚举 +enum ConditionType { + condition1, + condition2, + condition3, +} + +// 定义条件 +@conditionClass(ConditionType.condition1) +export class Condition1 extends kunpo.ConditionBase { + protected onInit(): void { + // 监听条件发生变化, 则调用一次 this.tryUpdate(); + kunpo.GlobalEvent.add("condition1", () => { + this.tryUpdate(); + }, this); + } + + protected evaluate(): boolean { + //TODO:: 根据条件数据,返回true or false + return true; + } +} +``` + +#### *节点关联条件* + +```typescript +/** 任意一个满足 显示节点 */ +new kunpo.ConditionAnyNode(fgui.GObject, ConditionType.condition1, ConditionType.condition2); + +/** 所有条件都满足 显示节点 */ +new kunpo.ConditionAllNode(fgui.GObject, ConditionType.Condition1, ConditionType.Condition2, ConditionType.Condition3); +``` + + + +### 八、 全局事件系统 + +```typescript +import { GlobalEvent } from 'kunpocc'; + +// 添加事件监听 +GlobalEvent.add('eventName', (arg1, arg2) => { + console.log('事件触发:', arg1, arg2); +}, this); + +// 添加一次性事件监听 +GlobalEvent.addOnce('oneTimeEvent', (data) => { + console.log('一次性事件触发:', data); +}, this); + +// 发送事件 +GlobalEvent.send('eventName', 'arg1', 'arg2'); + +// 发送事件到指定目标 +GlobalEvent.sendToTarget('eventName', target, 'arg1', 'arg2'); + +// 移除事件监听 +GlobalEvent.remove('eventName', callback, this); + +// 移除指定目标的所有事件监听 +GlobalEvent.removeByTarget(this); + +// 移除指定事件名和目标的事件监听 +GlobalEvent.removeByNameAndTarget('eventName', this); +``` + + + +### 九、全局计时器 + +```typescript +import { GlobalTimer } from 'kunpocc'; + +// 启动一次性定时器(2秒后执行) +const timerId1 = GlobalTimer.startTimer(() => { + console.log('2秒后执行一次'); +}, 2); + +// 启动循环定时器(每3秒执行一次,执行5次) +const timerId2 = GlobalTimer.startTimer(() => { + console.log('每3秒执行一次,总共执行5次'); +}, 3, 5); + +// 启动无限循环定时器(每1秒执行一次) +const timerId3 = GlobalTimer.startTimer(() => { + console.log('每1秒执行一次,无限循环'); +}, 1, -1); + +// 停止定时器 +GlobalTimer.stopTimer(timerId1); +GlobalTimer.stopTimer(timerId2); +GlobalTimer.stopTimer(timerId3); +``` + +注意事项: +- 定时器的时间间隔单位为秒 +- loop 参数说明: + - 0:执行一次 + - 正整数 n:执行 n 次 + - -1:无限循环 + +### 十、平台相关 + +> Platform 类提供了游戏运行平台的相关信息和判断方法。 + +#### *平台类型* + +```typescript +import { Platform, PlatformType } from 'kunpocc'; + +// 平台类型枚举 +enum PlatformType { + Android = 1, // 安卓 + IOS, // iOS + HarmonyOS, // 鸿蒙 + WX, // 微信小游戏 + Alipay, // 支付宝小游戏 + Bytedance, // 字节小游戏 + HuaweiQuick, // 华为快游戏 + Browser // 浏览器 +} + +// 获取当前平台类型 +const currentPlatform = Platform.platform; +``` + +#### *平台判断* + +```typescript +import { Platform } from 'kunpocc'; + +// 原生平台判断 +if (Platform.isNative) { + console.log('当前是原生平台'); +} + +// 移动平台判断 +if (Platform.isMobile) { + console.log('当前是移动平台'); +} + +// 原生移动平台判断 +if (Platform.isNativeMobile) { + console.log('当前是原生移动平台'); +} + +// 具体平台判断 +if (Platform.isAndroid) { + console.log('当前是安卓平台'); +} + +if (Platform.isIOS) { + console.log('当前是iOS平台'); +} + +if (Platform.isHarmonyOS) { + console.log('当前是鸿蒙系统'); +} + +// 小游戏平台判断 +if (Platform.isWX) { + console.log('当前是微信小游戏'); +} + +if (Platform.isAlipay) { + console.log('当前是支付宝小游戏'); +} + +if (Platform.isBytedance) { + console.log('当前是字节小游戏'); +} + +if (Platform.isHuaweiQuick) { + console.log('当前是华为快游戏'); +} + +// 浏览器判断 +if (Platform.isBrowser) { + console.log('当前是浏览器环境'); +} +``` + +#### *使用示例* + +```typescript +import { Platform, PlatformType } from 'kunpocc'; + +// 根据平台类型执行不同逻辑 +switch (Platform.platform) { + case PlatformType.Android: + // 安卓平台特定逻辑 + break; + case PlatformType.IOS: + // iOS平台特定逻辑 + break; + case PlatformType.WX: + // 微信小游戏特定逻辑 + break; + default: + // 其他平台逻辑 + break; +} + +// 针对不同平台进行适配 +if (Platform.isNativeMobile) { + // 原生移动平台的处理 + if (Platform.isAndroid) { + // 安卓特有功能 + } else if (Platform.isIOS) { + // iOS特有功能 + } +} else if (Platform.isWX || Platform.isAlipay || Platform.isBytedance) { + // 小游戏平台的处理 +} else { + // 浏览器平台的处理 +} +``` + + +### 十一、屏幕 + +```typescript +/** 屏幕宽度 */ +public static ScreenWidth: number; +/** 屏幕高度 */ +public static ScreenHeight: number; +/** 设计分辨率宽 */ +public static DesignWidth: number; +/** 设计分辨率高 */ +public static DesignHeight: number; +/** 安全区外一侧的高度 或 宽度 */ +public static SafeAreaHeight: number; +/** 安全区的宽度 */ +public static SafeWidth: number; +/** 安全区的高度 */ +public static SafeHeight: number; +``` + + + +### 十二、工具类 + +#### *数学工具 (MathTool)* + +```typescript +import { MathTool } from 'kunpocc'; + +// 1. 数值限制 +// 将数值限制在指定范围内 +const value = MathTool.clampf(75, 0, 100); // 返回75,因为在0-100范围内 +const value2 = MathTool.clampf(150, 0, 100); // 返回100,因为超出上限 +const value3 = MathTool.clampf(-50, 0, 100); // 返回0,因为低于下限 + +// 2. 随机数生成 +// 生成指定范围内的整数(包含边界值) +const randomInt = MathTool.rand(1, 10); // 返回1到10之间的整数 + +// 生成指定范围内的浮点数(包含最小值,不包含最大值) +const randomFloat = MathTool.randRange(0, 1); // 返回0到1之间的浮点数 + +// 3. 角度与弧度转换 +// 角度转弧度 +const radian = MathTool.rad(90); // 90度转换为弧度:约1.57 + +// 弧度转角度 +const degree = MathTool.deg(Math.PI); // π弧度转换为角度:180 + +// 4. 平滑过渡 +// 用于实现数值的平滑变化,常用于相机跟随、UI动画等 +const smoothValue = MathTool.smooth( + 0, // 起始值 + 100, // 目标值 + 0.16, // 已经过时间(秒) + 0.3 // 响应时间(秒) +); // 返回一个平滑过渡的中间值 +``` + +使用说明: + +1. `clampf(value: number, min: number, max: number): number` + - 将数值限制在指定范围内 + - 如果小于最小值,返回最小值 + - 如果大于最大值,返回最大值 + - 否则返回原值 + +2. `rand(min: number, max: number): number` + - 生成指定范围内的随机整数 + - 包含最小值和最大值 + - 常用于随机选择、随机掉落等场景 + +3. `randRange(min: number, max: number): number` + - 生成指定范围内的随机浮点数 + - 包含最小值,不包含最大值 + - 常用于需要精确浮点随机数的场景 + +4. `rad(angle: number): number` + - 将角度转换为弧度 + - 计算公式:angle * Math.PI / 180 + +5. `deg(radian: number): number` + - 将弧度转换为角度 + - 计算公式:radian * 180 / Math.PI + +6. `smooth(current: number, target: number, elapsedTime: number, responseTime: number): number` + - 计算平滑过渡的值 + - current: 当前值 + - target: 目标值 + - elapsedTime: 已经过时间(秒) + - responseTime: 响应时间(秒) + - 常用于实现平滑的相机移动、UI动画等 + +#### *MD5 加密* + +```typescript +import { md5 } from 'kunpocc'; + +// 字符串 MD5 加密 +const hash = md5('Hello, World!'); +console.log(hash); // 输出32位MD5哈希值 + +// 注意: +// 1. 输入必须是字符串类型 +// 2. 不能传入 undefined 或 null +try { + md5(null); // 将抛出错误 +} catch (error) { + console.error('MD5输入不能为null或undefined'); +} +``` ## 类型支持