Compare commits
513 Commits
new
...
0121f5b363
| Author | SHA1 | Date | |
|---|---|---|---|
| 0121f5b363 | |||
| 4235e3b776 | |||
| b765e6a7a6 | |||
| 3710f7f695 | |||
| 175a6e4232 | |||
| b7ddbce7e7 | |||
| 2ef12eaed2 | |||
| 16fcaeb3f3 | |||
| c05e26b101 | |||
| ef4099b873 | |||
| 2e6a8b80a7 | |||
| bcc61c9589 | |||
| 331effddaa | |||
| 957cd6d453 | |||
| e62eecd214 | |||
| 11f1f08c1d | |||
| 91eb0c9f6e | |||
| abbe4cc6a0 | |||
| 326ceaf3d1 | |||
| 2cf554b124 | |||
| c03a655f15 | |||
| 24e6ffc110 | |||
| 6b97e67a93 | |||
| a3100c7156 | |||
| f60d727c31 | |||
| c1544365ba | |||
| b0751992f4 | |||
| 861011893a | |||
| e32a66cfc9 | |||
| d987e0806f | |||
| e1f0492f34 | |||
| d01761b604 | |||
| e011cba047 | |||
| 5ce02c95f5 | |||
| 2e24e1fc64 | |||
| 1e762fb4f7 | |||
| d67c63b768 | |||
| 8d9c7bbe0d | |||
| 2ff7aab7c2 | |||
| cbe15d4d20 | |||
| ff6091b3e2 | |||
| 1c40c10210 | |||
| cfb6819bc7 | |||
| 3f6b94af0e | |||
| 928f1dbe16 | |||
| 6571eb2ef0 | |||
| 6d5c768a30 | |||
| faae0f8005 | |||
| 2eae29f1a1 | |||
| a3e4e70d9d | |||
| 2cdb25ac58 | |||
| 94f83482fa | |||
| 4706a128f3 | |||
| 13874f3618 | |||
| d9282b7469 | |||
| d8ba69aada | |||
| 559ddfb653 | |||
| d486d87676 | |||
| d0cd9c1326 | |||
| 31eedceeb3 | |||
| 7ec02c4b9e | |||
| 9e2ae6f30f | |||
| 2e2c9d82f9 | |||
| 070346fbe4 | |||
| 7441e94419 | |||
| 43561fa1cc | |||
| 22726eed3b | |||
| c86fac4ce7 | |||
| a1a5c37ad0 | |||
| 797cf72a09 | |||
| d628829718 | |||
| f6322688dd | |||
| 5ed5579142 | |||
| 577f43042b | |||
| 3435f76f5d | |||
| 138f6b4da0 | |||
| 34db348707 | |||
| 9fca82703b | |||
| 5b9c00fa7a | |||
| 8e044fcf3c | |||
| da0237d49c | |||
| a9e940b166 | |||
| 543be1111a | |||
| 09c86944ac | |||
| c3b9977b0c | |||
| 6c95b3acc3 | |||
| 6a29821a7b | |||
| d693499397 | |||
| 213149881c | |||
| 92faa0fe09 | |||
| 1b56cb7a8c | |||
| 0a654d130a | |||
| 77075b2650 | |||
| 1896b5fab0 | |||
| b531948d4d | |||
| dbe2da2927 | |||
| bee97b4fe8 | |||
| c47ecc21e6 | |||
| 854affeaae | |||
| 22f35893d7 | |||
| 18248fdcd7 | |||
| 6365464a1b | |||
| f5a13de4b5 | |||
| 9e1459973c | |||
| 3884b35829 | |||
| a824d9a124 | |||
| addc61e2a9 | |||
| cb8c37c23a | |||
| 18874ddbf2 | |||
| c24961171f | |||
| db79fbf9e0 | |||
| 939e6d553d | |||
| b6ec65741a | |||
| 1a25a566c8 | |||
| ba61724a08 | |||
| e5874bf936 | |||
| 6288d4e4bb | |||
| eeeeecacc5 | |||
| 9ccd63be3c | |||
| 0d3f789bdc | |||
| 364371d952 | |||
| eddc1cadde | |||
| a2db298fcd | |||
| 739600de89 | |||
| 94231cb3b1 | |||
| cbac432bb6 | |||
| 5d8e43175e | |||
| 59b255b85d | |||
| 7203a4ab07 | |||
| 6adff46fd1 | |||
| f539cf9b7b | |||
| 3b4ce5b33e | |||
| 3703b148e9 | |||
| 66acc50c49 | |||
| 672e987c70 | |||
| c7c4471d4d | |||
| e9db3305c5 | |||
| ba3fa75006 | |||
| d464491172 | |||
| b77f023548 | |||
| 5dd354a86b | |||
| 61cbd6e7bd | |||
| 1273ec6e99 | |||
| ca8bbd397b | |||
| 13d0a6d190 | |||
| 919ff09351 | |||
| 5bcf5e737b | |||
| 89daacba36 | |||
| 7bece884da | |||
| 829bf6ca38 | |||
| 1f38e07b05 | |||
| 43f6ab8f6a | |||
| f37b88d78b | |||
| 755a2e83d8 | |||
| 1521d9445c | |||
| bce3580b22 | |||
| 4ea590e708 | |||
| bf241345bf | |||
| 570812de88 | |||
| a283e98e98 | |||
| 1482e9989a | |||
| cd6675652b | |||
| 2af32ee476 | |||
| 25ed3a009a | |||
| 52ee731e3f | |||
| 4b3cf36d95 | |||
| db5cacfe8f | |||
| 471248eba8 | |||
| d77ce672b3 | |||
| 3f2001e2d1 | |||
| af16f581dd | |||
| d0f79c9207 | |||
| 228014bc8f | |||
| 97bba4edb7 | |||
| 6f9529ada2 | |||
| 3db3cc78eb | |||
| b6228f7747 | |||
| 2423b25dea | |||
| 7b424d1649 | |||
| f579ed49e7 | |||
| 4b694120ff | |||
| a03b2516e3 | |||
| 2a5d1ecbd9 | |||
| b12060f133 | |||
| 5c8a15262e | |||
| eff5f21d04 | |||
| 4daac778a0 | |||
| fef5480322 | |||
| 6e948020ef | |||
| 1eb936a003 | |||
| 9d0fdfc0f8 | |||
| 3c349f4195 | |||
| 877abc9577 | |||
| 7462e2aeef | |||
| 0b0a217abc | |||
| 626003c061 | |||
| cac739c52b | |||
| 15e41c628a | |||
| 7bb49f86d5 | |||
| d56b4293d7 | |||
| db2acbf52e | |||
| 23ef6c3ca0 | |||
| c3ecc08767 | |||
| 6c6fb64ab1 | |||
| 11a957b08a | |||
| a4ebf3c651 | |||
| 16195f4cb4 | |||
| 3fe8edf88a | |||
| 9f820436fc | |||
| 98039f36ca | |||
| d081695725 | |||
| b3ea965c46 | |||
| cd6f10a534 | |||
| 953ae2e0f9 | |||
| 48eaa6d1ad | |||
| 4bd2e5566a | |||
| 655a4eef56 | |||
| 8832a2199e | |||
| 855fed2a47 | |||
| 509121a2ab | |||
| ac12d8cfe6 | |||
| 2018e98e7c | |||
| 0ba25c1cac | |||
| a5a0c26e8f | |||
| 81a45e4387 | |||
| cafd6f4073 | |||
| 054fc0a44a | |||
| 87e1de7f16 | |||
| 7bd7da427d | |||
| 0b57ffa684 | |||
| af89bb7707 | |||
| 690f0547cd | |||
| e98de0ae84 | |||
| e3b403c162 | |||
| e96d5fca99 | |||
| d2b62bd351 | |||
| 9c1a453ff7 | |||
| b6f026e5b7 | |||
| f805bbcd4a | |||
| 1611b5d3b5 | |||
| a8dfceeb09 | |||
| 147cb2bad7 | |||
| cde7da64ad | |||
| a5ed2f5784 | |||
| b17de4a2ac | |||
| e45ebd524b | |||
| 508c3b570a | |||
| f841c9ec7f | |||
| a073682615 | |||
| 68c4d94ccc | |||
| 2d6e8de164 | |||
| 163e8273c5 | |||
| 9b4e9073a2 | |||
| 9fd8fa02af | |||
| c6dea41c80 | |||
| 75b2206b70 | |||
| 8676b5340e | |||
| 3b569068d4 | |||
| 250df54c29 | |||
| db026e990d | |||
| 5a9da59acc | |||
| 8aa4edabd4 | |||
| 2c09abc373 | |||
| 326bd32183 | |||
| 95e64c530a | |||
| de8924b84d | |||
| 82127a81ba | |||
| 6f2af2f395 | |||
| 1780509509 | |||
| 0e069b5594 | |||
| 04704d4526 | |||
| a1a6756b6c | |||
| 3a53b5e531 | |||
| 6b6d4db571 | |||
| fbcd12a5b9 | |||
| 0815d64f3c | |||
| 377c287eec | |||
| 9ebab375a9 | |||
| da71e04e83 | |||
| e6c3eefbcb | |||
| c6b017d5fe | |||
| ffc51c10a3 | |||
| 37610439a6 | |||
| 43c2dbcfa2 | |||
| a302bbd65f | |||
| 9dec586217 | |||
| 933987eab1 | |||
| 3072e8eccd | |||
| c9ecc5979c | |||
| e4263b5f47 | |||
| a75950d3a6 | |||
| 8e4c7410b9 | |||
| b832851842 | |||
| 541a944c0c | |||
| 7dcaf19925 | |||
| f73badd5fc | |||
| da1db91368 | |||
| 63a3433838 | |||
| 0aaf45d20d | |||
| b2c49d978a | |||
| aa31ffb0e8 | |||
| b642c1d40f | |||
| 3798f9da95 | |||
| f7c231de00 | |||
| 9ebf620ed8 | |||
| ed26a10a98 | |||
| 7413dc4e6e | |||
| d0e411ac12 | |||
| 352792b76f | |||
| 85e4985311 | |||
| 99f213e461 | |||
| 073a3bbd2f | |||
| f72691cecb | |||
| 11e6ecdf48 | |||
| ebeb5ea04b | |||
| 42683db961 | |||
| a83b8efacb | |||
| 8c1216f24d | |||
| bdb0ca5bb1 | |||
| 9b5c2f8fc8 | |||
| ded1b36cfb | |||
| 63f85a223d | |||
| db18064511 | |||
| 326e9bb97c | |||
| 2ec530d881 | |||
| dde29136fa | |||
| cba52086c2 | |||
| 0a25259cf4 | |||
| b00cc9536f | |||
| d31c495a54 | |||
| 862777a9c7 | |||
| 7363952dae | |||
| db0a0dd19c | |||
| 75136d665b | |||
| 2b5ed007b4 | |||
| 03456dd990 | |||
| b4ed42456e | |||
| 6b030894ef | |||
| 56a76f51b7 | |||
| 766c1f8176 | |||
| 4ef2855e49 | |||
| ad67064e17 | |||
| 4af72ba3ef | |||
| f734708cf3 | |||
| b69222d24f | |||
| edba01722c | |||
| c62eda84bb | |||
| c6fa6838db | |||
| 6584fa0e72 | |||
| 80359de181 | |||
| 6ce9fc4c48 | |||
| 211dd26ca3 | |||
| a31710e2d9 | |||
| b7edf26cc9 | |||
| ff402f14ca | |||
| 3582521e4e | |||
| 492e052d5b | |||
| 86378c16b7 | |||
| a1ba9efd89 | |||
| 4ebd868d20 | |||
| b390d5bc90 | |||
| 3accaa1850 | |||
| 2c9f176912 | |||
| ab9ff70f77 | |||
| b6a2ab2921 | |||
| 6e6b5c31c7 | |||
| 5083910c95 | |||
| d6457be563 | |||
| 1d9aa0834c | |||
| be4543b62e | |||
| fdfa9cbd37 | |||
| d7b6dd375a | |||
| 0a1e2b7813 | |||
| d02482a591 | |||
| 5af0a314a6 | |||
| 3ad905cd59 | |||
| 843d03ac20 | |||
| 9a2e2af37a | |||
| d9b7b6c966 | |||
| e7efaa9d1e | |||
| 93ed6fae1e | |||
| cb91e66646 | |||
| d01b98f9c3 | |||
| 8ea55fd99e | |||
| 008cd2ffc5 | |||
| 3ec7c18ace | |||
| 2376c952d2 | |||
| 3312c2addf | |||
| 8016ec78f1 | |||
| 741da016fd | |||
| 6aeee46c7c | |||
| c35ae83511 | |||
| 950b91441b | |||
| cb38aa55a4 | |||
| 4c0d1023a0 | |||
| a0bd1da1ca | |||
| d06d8fe910 | |||
| 4096922e61 | |||
| 1f5a4a7fb7 | |||
| 9bace6aa99 | |||
| 094b55f349 | |||
| 63f4d1067e | |||
| 94128b05ca | |||
| fee9fc9852 | |||
| f9b3f56a04 | |||
| 76c6fca2a5 | |||
| 6883916de1 | |||
| 25202ccb35 | |||
| b26efd07fd | |||
| 899613c689 | |||
| b66c69d925 | |||
| 4585ee59d6 | |||
| 3fbfc2ea09 | |||
| c9a499e38b | |||
| 37618b0bd5 | |||
| d448779c8d | |||
| 96db3dc1bd | |||
| 564b3e2de9 | |||
| e695b9bdac | |||
| 8cb3fe192d | |||
| b7a05c2c24 | |||
| cb1ac100da | |||
| 6a185a2361 | |||
| ba05b59f4d | |||
| cdb09a5ca1 | |||
| 424edb89a7 | |||
| 3efbf21a14 | |||
| 85856ccc28 | |||
| 2c3f682b18 | |||
| 9b97bff159 | |||
| da1124a065 | |||
| 30d5cfbb7c | |||
| ea64303410 | |||
| 176bdbc811 | |||
| 476be36a03 | |||
| 14da4fb2d1 | |||
| 64163a675f | |||
| 999250c160 | |||
| 32f3c75241 | |||
| ff172c7f72 | |||
| d75cce01d7 | |||
| 789e4183ec | |||
| d553ddc9c5 | |||
| 83b4794c13 | |||
| 0d697c488d | |||
| dcc1a98b3b | |||
| 28b557f18f | |||
| 02547cb470 | |||
| 084e641855 | |||
| ff01b741fc | |||
| d3cdbff3d9 | |||
| b75ee1da2d | |||
| 4c96d7255d | |||
| 42e57a89fd | |||
| fc35e40688 | |||
| 2ae23e5915 | |||
| b094d4632f | |||
| 063764dc82 | |||
| 798a831227 | |||
| 67704725b2 | |||
| 3a15541170 | |||
| 63e182e214 | |||
| 8b33abb973 | |||
| 8e0aa200a6 | |||
| 4335a8500b | |||
| ae30a865c7 | |||
| 0f9fb4e8fb | |||
| 1a6bff9d49 | |||
| 9fbad1f405 | |||
| eec698fd0a | |||
| 776c2819de | |||
| 27edecb94e | |||
| f3f0e87b3c | |||
| d58c9f7c79 | |||
| 028a89348e | |||
| 492c073349 | |||
| 8b04e5c80b | |||
| 7f82edf4f9 | |||
| 3a7b0e4762 | |||
| f7f9849d14 | |||
| 82d80a7537 | |||
| b0d35b6ff5 | |||
| eb20011f07 | |||
| 610f66de38 | |||
| ff086b7114 | |||
| 57c56c0d11 | |||
| ca2a0f79d1 | |||
| a065b32856 | |||
| 5279a65284 | |||
| 94b8c992da | |||
| acaa0ea442 | |||
| 0c6899264d | |||
| b61652084d | |||
| d4bdc1651f | |||
| 6e1c7ee715 | |||
| c619b97aa4 | |||
| 8a6609f2c2 | |||
| f5fe35d36b | |||
| 56b365cbe7 | |||
| 4dcb732148 | |||
| 2521af3a55 | |||
| 8cdd6aaa21 | |||
| 83c4b6ec3d | |||
| 36a8aff783 | |||
| 060046a6a6 | |||
| 8f2612bda2 | |||
| cdb8261be9 | |||
| 89978ddbe8 | |||
| 5536428125 | |||
| 2e53786aa0 | |||
| 215fcd3a76 | |||
| 00148863ad | |||
| e571ae2caf |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -15,8 +15,11 @@ native
|
||||
# VSCode
|
||||
#//////////////////////////
|
||||
.vscode/
|
||||
|
||||
.codebuddy/
|
||||
#//////////////////////////
|
||||
# WebStorm
|
||||
#//////////////////////////
|
||||
.idea/
|
||||
.idea/
|
||||
extensions/
|
||||
extensions/oops-plugin-framework
|
||||
|
||||
|
||||
503
.qoder/repowiki/zh/content/地图系统/地图模型.md
Normal file
503
.qoder/repowiki/zh/content/地图系统/地图模型.md
Normal file
@@ -0,0 +1,503 @@
|
||||
# 地图模型
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [map.json](file://assets/resources/config/map/map.json)
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [数据结构分析](#数据结构分析)
|
||||
7. [ECS初始化流程](#ecs初始化流程)
|
||||
8. [地图跳转逻辑](#地图跳转逻辑)
|
||||
9. [数据驱动设计](#数据驱动设计)
|
||||
10. [最佳实践](#最佳实践)
|
||||
11. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
MapModelComp组件是Cocos游戏项目中地图系统的核心数据层组件,采用ECS(Entity-Component-System)架构模式设计。该组件负责管理地图资源路径、关卡配置及地图跳转逻辑,为整个地图系统提供数据支撑和状态管理功能。
|
||||
|
||||
地图系统基于两个关键的JSON配置文件:
|
||||
- `map.json`:存储地图基本信息(ID、名称、可跳转关卡)
|
||||
- `map_delivery.json`:存储地图连接点、目标地图和出生点信息
|
||||
|
||||
## 项目结构
|
||||
|
||||
地图系统的文件组织遵循清晰的分层架构:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "地图系统架构"
|
||||
A[MapModelComp.ts<br/>数据模型组件] --> B[GameMap.ts<br/>游戏地图实体]
|
||||
B --> C[MapViewComp.ts<br/>视图组件]
|
||||
C --> D[MapViewScene.ts<br/>场景逻辑]
|
||||
E[map.json<br/>地图配置] --> A
|
||||
F[map_delivery.json<br/>连接点配置] --> A
|
||||
G[SingletonModuleComp.ts<br/>单例模块] --> B
|
||||
H[LoadingViewComp.ts<br/>加载界面] --> B
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
|
||||
**章节来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### MapModelComp - 地图模型组件
|
||||
|
||||
MapModelComp是地图系统的核心数据组件,继承自ECS框架的ecs.Comp基类,负责维护地图的基本状态和资源配置。
|
||||
|
||||
#### 主要属性
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 描述 |
|
||||
|--------|------|--------|------|
|
||||
| id | number | 1 | 初始地图编号,标识当前激活的地图 |
|
||||
| resPrefab | string | "game/map/map_rpg" | 地图显示预制体资源路径 |
|
||||
|
||||
#### 设计特点
|
||||
|
||||
1. **数据驱动**:所有地图配置通过外部JSON文件管理
|
||||
2. **资源管理**:集中管理地图相关的资源路径
|
||||
3. **状态控制**:维护当前地图的状态信息
|
||||
4. **扩展性**:预留了资源获取方法的注释,支持动态资源加载
|
||||
|
||||
**章节来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L9-L43)
|
||||
|
||||
### GameMap - 游戏地图实体
|
||||
|
||||
GameMap继承自ecs.Entity,是地图系统的主实体,负责地图的整体生命周期管理和资源加载。
|
||||
|
||||
#### 核心功能
|
||||
|
||||
1. **组件初始化**:自动添加MapModelComp组件
|
||||
2. **资源加载**:异步加载地图显示资源
|
||||
3. **场景管理**:协调地图视图和场景逻辑
|
||||
|
||||
**章节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L14-L36)
|
||||
|
||||
## 架构概览
|
||||
|
||||
地图系统采用经典的ECS架构模式,实现了数据与行为的分离:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MapModelComp {
|
||||
+number id
|
||||
+string resPrefab
|
||||
+reset() void
|
||||
}
|
||||
class GameMap {
|
||||
+MapModelComp MapModel
|
||||
+MapViewComp MapView
|
||||
+init() void
|
||||
+load() void
|
||||
}
|
||||
class MapViewComp {
|
||||
+MapViewScene scene
|
||||
+Timer game_timer
|
||||
+onLoad() void
|
||||
+start() void
|
||||
+load_data() void
|
||||
+update(dt) void
|
||||
}
|
||||
class MapViewScene {
|
||||
+Camera camera
|
||||
+Node layer
|
||||
+MapLayer mapLayer
|
||||
+EntityLayer entityLayer
|
||||
+SkillLayer SkillLayer
|
||||
+Vec2 ratio
|
||||
+init() void
|
||||
+update(dt) void
|
||||
}
|
||||
class SingletonModuleComp {
|
||||
+GameMap map
|
||||
+number fight_hero
|
||||
+any heros
|
||||
+updateFihgtHero(id) void
|
||||
+addHero(uuid) void
|
||||
}
|
||||
GameMap --> MapModelComp : "包含"
|
||||
GameMap --> MapViewComp : "包含"
|
||||
MapViewComp --> MapViewScene : "使用"
|
||||
SingletonModuleComp --> GameMap : "管理"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L9-L43)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L14-L36)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L14-L45)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L17-L77)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### MapModelComp组件深度分析
|
||||
|
||||
#### 组件注册与继承
|
||||
|
||||
MapModelComp通过`@ecs.register('MapModel')`装饰器注册到ECS系统中,继承自ecs.Comp基类,具备以下特性:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant ECS as "ECS系统"
|
||||
participant Comp as "MapModelComp"
|
||||
participant Entity as "GameMap实体"
|
||||
ECS->>Comp : 注册组件
|
||||
Entity->>Comp : 创建实例
|
||||
Comp->>Comp : 初始化默认属性
|
||||
Entity->>Comp : 添加到实体
|
||||
Comp->>ECS : 准备就绪
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L8-L9)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L20-L22)
|
||||
|
||||
#### 资源管理策略
|
||||
|
||||
组件提供了灵活的资源管理机制:
|
||||
|
||||
1. **预制体资源**:`resPrefab`属性指向地图显示预制体
|
||||
2. **注释方法**:预留了多种资源获取方法(迷你地图、瓦片、数据资源)
|
||||
3. **默认配置**:提供合理的默认值,确保系统正常运行
|
||||
|
||||
#### 生命周期管理
|
||||
|
||||
reset()方法为空实现,为未来的扩展预留空间。
|
||||
|
||||
**章节来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L9-L43)
|
||||
|
||||
### GameMap实体分析
|
||||
|
||||
#### 实体生命周期
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[GameMap创建] --> B[init方法调用]
|
||||
B --> C[添加MapModelComp组件]
|
||||
C --> D[load方法调用]
|
||||
D --> E[异步加载资源]
|
||||
E --> F[实例化预制体]
|
||||
F --> G[添加MapView组件]
|
||||
G --> H[地图加载完成]
|
||||
E --> I[错误处理]
|
||||
I --> J[控制台输出错误]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L20-L36)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L36-L42)
|
||||
|
||||
#### 资源加载机制
|
||||
|
||||
load()方法实现了异步资源加载,包括:
|
||||
1. **资源验证**:检查加载结果
|
||||
2. **实例化**:创建地图实例
|
||||
3. **层级设置**:设置父节点关系
|
||||
4. **组件添加**:添加地图视图组件
|
||||
|
||||
**章节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L24-L36)
|
||||
|
||||
### 地图视图系统
|
||||
|
||||
#### 组件层次结构
|
||||
|
||||
MapViewComp和MapViewScene构成了完整的地图视图系统:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[MapViewComp] --> B[MapViewScene]
|
||||
B --> C[Camera]
|
||||
B --> D[MapLayer]
|
||||
B --> E[EntityLayer]
|
||||
B --> F[SkillLayer]
|
||||
D --> G[背景图片]
|
||||
E --> H[游戏实体]
|
||||
F --> I[技能效果]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L14-L45)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L17-L77)
|
||||
|
||||
**章节来源**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L14-L45)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L17-L77)
|
||||
|
||||
## 数据结构分析
|
||||
|
||||
### map.json - 地图基本信息配置
|
||||
|
||||
map.json文件定义了地图的基本信息和关联关系:
|
||||
|
||||
#### 配置结构
|
||||
|
||||
| 字段 | 类型 | 描述 | 示例值 |
|
||||
|------|------|------|--------|
|
||||
| id | number | 地图唯一标识符 | 1, 2, 3... |
|
||||
| name | string | 地图资源名称 | "img_map3", "img_map15" |
|
||||
| delivery | string | 可跳转的连接点列表 | "1,2", "3,4" |
|
||||
|
||||
#### 数据示例分析
|
||||
|
||||
根据现有配置:
|
||||
- 地图1(ID:1)关联连接点1和2
|
||||
- 地图2(ID:2)关联连接点3和4
|
||||
|
||||
这种设计允许:
|
||||
1. **多路径跳转**:一个地图可以有多个出口
|
||||
2. **动态配置**:通过修改JSON文件即可调整地图关系
|
||||
3. **解耦设计**:地图逻辑与配置分离
|
||||
|
||||
**章节来源**
|
||||
- [map.json](file://assets/resources/config/map/map.json#L1-L12)
|
||||
|
||||
### map_delivery.json - 地图连接点配置
|
||||
|
||||
map_delivery.json定义了具体的跳转连接点信息:
|
||||
|
||||
#### 完整配置结构
|
||||
|
||||
| 字段 | 类型 | 描述 | 示例值 |
|
||||
|------|------|------|--------|
|
||||
| id | number | 连接点唯一标识 | 1, 2, 3... |
|
||||
| mapId | number | 当前地图ID | 1, 2 |
|
||||
| pos | string | 连接点坐标 | "19,267" |
|
||||
| toMapId | number | 目标地图ID | 2, 5, 3, 1 |
|
||||
| start | string | 出生点坐标 | "66,237" |
|
||||
|
||||
#### 数据流分析
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[用户点击连接点] --> B[读取map_delivery.json]
|
||||
B --> C[获取目标地图ID]
|
||||
C --> D[获取出生点坐标]
|
||||
D --> E[切换到目标地图]
|
||||
E --> F[设置玩家位置]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json#L1-L30)
|
||||
|
||||
**章节来源**
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json#L1-L30)
|
||||
|
||||
## ECS初始化流程
|
||||
|
||||
### 系统启动序列
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as "应用程序"
|
||||
participant SM as "SingletonModule"
|
||||
participant LM as "LoadingView"
|
||||
participant GM as "GameMap"
|
||||
participant MM as "MapModel"
|
||||
App->>SM : 初始化单例模块
|
||||
SM->>GM : 创建GameMap实体
|
||||
GM->>MM : 添加MapModel组件
|
||||
MM->>MM : 初始化默认状态
|
||||
SM->>LM : 开始加载界面
|
||||
LM->>GM : 调用load()方法
|
||||
GM->>GM : 异步加载资源
|
||||
GM->>SM : 设置smc.map引用
|
||||
SM->>App : 启动游戏主界面
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L36-L42)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L25-L26)
|
||||
|
||||
### 组件注册机制
|
||||
|
||||
ECS框架通过装饰器模式实现组件注册:
|
||||
|
||||
1. **MapModelComp注册**:`@ecs.register('MapModel')`
|
||||
2. **GameMap注册**:`@ecs.register('GameMap')`
|
||||
3. **MapViewComp注册**:`@ecs.register('MapView', false)`
|
||||
|
||||
这种设计确保了:
|
||||
- **自动发现**:ECS系统自动识别和管理组件
|
||||
- **类型安全**:编译时类型检查
|
||||
- **性能优化**:避免运行时反射开销
|
||||
|
||||
**章节来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L8-L9)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L14-L15)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L36-L42)
|
||||
|
||||
## 地图跳转逻辑
|
||||
|
||||
### 跳转流程设计
|
||||
|
||||
地图跳转是一个复杂的多阶段过程:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[检测到跳转请求] --> B[验证连接点有效性]
|
||||
B --> C{连接点存在?}
|
||||
C --> |否| D[显示错误信息]
|
||||
C --> |是| E[读取连接点配置]
|
||||
E --> F[获取目标地图ID]
|
||||
F --> G[获取出生点坐标]
|
||||
G --> H[清理当前地图资源]
|
||||
H --> I[加载目标地图]
|
||||
I --> J[设置玩家位置]
|
||||
J --> K[更新地图状态]
|
||||
K --> L[触发相关事件]
|
||||
```
|
||||
|
||||
### 多路径跳转实现
|
||||
|
||||
通过map.json中的delivery字段实现多路径跳转:
|
||||
|
||||
1. **配置解析**:将"1,2"字符串解析为数组
|
||||
2. **连接点匹配**:根据用户选择确定具体跳转路径
|
||||
3. **动态路由**:支持运行时修改跳转关系
|
||||
|
||||
### 地图解锁条件
|
||||
|
||||
虽然当前实现中没有显式的解锁条件,但可以通过以下方式扩展:
|
||||
|
||||
1. **成就系统**:完成特定任务后解锁新地图
|
||||
2. **等级要求**:达到一定等级才能访问高级地图
|
||||
3. **前置条件**:需要完成特定关卡才能解锁
|
||||
|
||||
**章节来源**
|
||||
- [map.json](file://assets/resources/config/map/map.json#L2-L11)
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json#L1-L30)
|
||||
|
||||
## 数据驱动设计
|
||||
|
||||
### 配置文件的作用
|
||||
|
||||
数据驱动设计的核心优势:
|
||||
|
||||
1. **灵活性**:无需修改代码即可调整地图配置
|
||||
2. **可维护性**:配置与逻辑分离,便于维护
|
||||
3. **可扩展性**:支持动态添加新地图和连接点
|
||||
4. **版本控制**:配置文件易于版本管理和协作
|
||||
|
||||
### 动态配置加载
|
||||
|
||||
系统支持运行时加载配置:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[JSON配置文件] --> B[oops.res.load]
|
||||
B --> C[解析JSON数据]
|
||||
C --> D[构建地图配置对象]
|
||||
D --> E[应用到地图系统]
|
||||
```
|
||||
|
||||
### 配置验证机制
|
||||
|
||||
为了确保配置的正确性,系统应该包含:
|
||||
|
||||
1. **格式验证**:检查JSON语法正确性
|
||||
2. **完整性检查**:验证必需字段的存在
|
||||
3. **一致性验证**:确保地图ID和连接点ID的一致性
|
||||
4. **边界检查**:验证坐标值的有效范围
|
||||
|
||||
**章节来源**
|
||||
- [map.json](file://assets/resources/config/map/map.json#L1-L12)
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json#L1-L30)
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 地图配置最佳实践
|
||||
|
||||
#### 新地图添加流程
|
||||
|
||||
1. **创建地图资源**:准备地图图像和相关资源
|
||||
2. **更新map.json**:添加新的地图条目
|
||||
3. **配置连接点**:在map_delivery.json中添加对应的连接点
|
||||
4. **测试验证**:确保跳转逻辑正确
|
||||
|
||||
#### 配置示例
|
||||
|
||||
```json
|
||||
{
|
||||
"3": {
|
||||
"id": 3,
|
||||
"name": "img_map_new",
|
||||
"delivery": "5,6"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"5": {
|
||||
"id": 5,
|
||||
"mapId": 3,
|
||||
"pos": "30,40",
|
||||
"toMapId": 1,
|
||||
"start": "15,25"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 性能优化建议
|
||||
|
||||
1. **资源预加载**:提前加载常用地图资源
|
||||
2. **延迟加载**:对于不常用的地图采用按需加载
|
||||
3. **内存管理**:及时释放不再使用的地图资源
|
||||
4. **缓存策略**:缓存频繁访问的地图配置
|
||||
|
||||
### 错误处理策略
|
||||
|
||||
1. **配置缺失**:提供默认配置或友好的错误提示
|
||||
2. **资源加载失败**:实现资源降级方案
|
||||
3. **跳转失败**:提供重试机制或备用路径
|
||||
4. **数据损坏**:实现配置文件的备份和恢复
|
||||
|
||||
## 总结
|
||||
|
||||
MapModelComp组件作为地图系统的核心数据层,成功地实现了以下目标:
|
||||
|
||||
### 技术亮点
|
||||
|
||||
1. **ECS架构**:采用现代的游戏开发模式,实现了良好的解耦
|
||||
2. **数据驱动**:通过JSON配置文件实现了灵活的地图管理
|
||||
3. **资源管理**:提供了完整的资源生命周期管理
|
||||
4. **扩展性**:预留了丰富的扩展点和优化空间
|
||||
|
||||
### 设计优势
|
||||
|
||||
1. **模块化**:各组件职责明确,便于维护和扩展
|
||||
2. **可配置性**:通过配置文件即可调整地图逻辑
|
||||
3. **性能优化**:支持异步加载和资源管理
|
||||
4. **错误处理**:内置了基本的错误处理机制
|
||||
|
||||
### 应用价值
|
||||
|
||||
该设计为游戏开发提供了:
|
||||
- **快速迭代**:通过配置即可实现地图逻辑变更
|
||||
- **团队协作**:策划人员可以直接编辑配置文件
|
||||
- **跨平台支持**:基于Cocos引擎,支持多平台部署
|
||||
- **未来扩展**:为后续的功能扩展奠定了良好基础
|
||||
|
||||
通过深入理解MapModelComp的设计理念和实现细节,开发者可以更好地利用这一组件,构建更加复杂和有趣的游戏世界。
|
||||
408
.qoder/repowiki/zh/content/地图系统/地图系统.md
Normal file
408
.qoder/repowiki/zh/content/地图系统/地图系统.md
Normal file
@@ -0,0 +1,408 @@
|
||||
# 地图系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [map.json](file://assets/resources/config/map/map.json)
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概述](#架构概述)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
本文档详尽描述了基于Cocos引擎的《英雄》游戏项目中地图系统的整体架构与运行机制。系统涵盖关卡设计、怪物生成、战斗区域管理及视图渲染等核心功能。通过分析`GameMap.ts`中的地图主控制器职责,结合`RogueConfig.ts`解释随机关卡生成逻辑,深入剖析`Mon.ts`中怪物实体的设计模式及其与英雄的交互方式。同时,阐述`MapModelComp.ts`与`MapViewComp.ts`如何实现数据与表现层的分离,并结合`map.json`和`map_delivery.json`配置文件说明地图数据结构与关卡参数定义。最后,提供实例说明如何添加新关卡、配置怪物波次及实现战斗区域判定。
|
||||
|
||||
## 项目结构
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "Assets"
|
||||
subgraph "resources"
|
||||
subgraph "config"
|
||||
subgraph "map"
|
||||
map_json["map.json"]
|
||||
map_delivery_json["map_delivery.json"]
|
||||
end
|
||||
end
|
||||
end
|
||||
subgraph "script"
|
||||
subgraph "game"
|
||||
subgraph "map"
|
||||
GameMap_ts["GameMap.ts"]
|
||||
RogueConfig_ts["RogueConfig.ts"]
|
||||
MissionMonComp_ts["MissionMonComp.ts"]
|
||||
subgraph "model"
|
||||
MapModelComp_ts["MapModelComp.ts"]
|
||||
end
|
||||
subgraph "view"
|
||||
MapViewComp_ts["MapViewComp.ts"]
|
||||
MapViewScene_ts["MapViewScene.ts"]
|
||||
subgraph "layer"
|
||||
MapLayer_ts["MapLayer.ts"]
|
||||
EntityLayer_ts["EntityLayer.ts"]
|
||||
SkillLayer_ts["SkillLayer.ts"]
|
||||
end
|
||||
end
|
||||
end
|
||||
subgraph "hero"
|
||||
Mon_ts["Mon.ts"]
|
||||
MonModelComp_ts["MonModelComp.ts"]
|
||||
end
|
||||
subgraph "common"
|
||||
subgraph "config"
|
||||
heroSet_ts["heroSet.ts"]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [map.json](file://assets/resources/config/map/map.json)
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts)
|
||||
|
||||
**本节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [map.json](file://assets/resources/config/map/map.json)
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json)
|
||||
|
||||
## 核心组件
|
||||
|
||||
地图系统的核心由多个组件构成,实现了数据与逻辑的分离。`GameMap`作为地图主控制器,负责协调地图模型与视图。`MapModelComp`封装了地图的静态数据,如初始地图ID和资源路径。`MapViewComp`则负责地图的显示逻辑,通过`MapViewScene`管理地图层、实体层和技能层。`RogueConfig.ts`定义了随机关卡的生成规则,包括怪物类型、数量和强度的动态调整。`Mon.ts`实现了怪物实体的加载与初始化,支持根据关卡进度调整属性强度。
|
||||
|
||||
**本节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L310)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108)
|
||||
|
||||
## 架构概述
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class GameMap {
|
||||
+MapModel : MapModelComp
|
||||
+MapView : MapViewComp
|
||||
+init() : void
|
||||
+load() : void
|
||||
}
|
||||
class MapModelComp {
|
||||
+id : number
|
||||
+resPrefab : string
|
||||
+reset() : void
|
||||
}
|
||||
class MapViewComp {
|
||||
+scene : MapViewScene
|
||||
+game_timer : Timer
|
||||
+onLoad() : void
|
||||
+start() : void
|
||||
+reset() : void
|
||||
+update(dt : number) : void
|
||||
}
|
||||
class MapViewScene {
|
||||
+camera : Camera
|
||||
+layer : Node
|
||||
+mapLayer : MapLayer
|
||||
+floorLayer : Node
|
||||
+entityLayer : EntityLayer
|
||||
+SkillLayer : SkillLayer
|
||||
+isFollowPlayer : boolean
|
||||
+ratio : Vec2
|
||||
+onLoad() : void
|
||||
+start() : void
|
||||
+reset() : void
|
||||
+init() : void
|
||||
+update(dt : number) : void
|
||||
}
|
||||
class MapLayer {
|
||||
+bgImg : Sprite
|
||||
+init() : void
|
||||
+clear() : void
|
||||
+bgImage : Sprite
|
||||
+width : number
|
||||
+height : number
|
||||
}
|
||||
class EntityLayer {
|
||||
+timer : Timer
|
||||
+update(dt : number) : void
|
||||
+start() : void
|
||||
+clear() : void
|
||||
}
|
||||
class SkillLayer {
|
||||
+timer : Timer
|
||||
+light : Prefab
|
||||
+onLoad() : void
|
||||
+doSkill() : void
|
||||
+update(dt : number) : void
|
||||
+start() : void
|
||||
+clear() : void
|
||||
}
|
||||
GameMap --> MapModelComp : "包含"
|
||||
GameMap --> MapViewComp : "包含"
|
||||
MapViewComp --> MapViewScene : "引用"
|
||||
MapViewScene --> MapLayer : "引用"
|
||||
MapViewScene --> EntityLayer : "引用"
|
||||
MapViewScene --> SkillLayer : "引用"
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L46)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L47)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 地图主控制器分析
|
||||
|
||||
`GameMap`类是地图系统的主控制器,使用ECS(实体-组件-系统)架构模式。它继承自`ecs.Entity`,并注册为`GameMap`实体。该类包含两个核心组件:`MapModel`(数据模型)和`MapView`(视图组件)。`init`方法在实体初始化时被调用,用于添加`MapModelComp`组件。`load`方法负责加载地图的显示资源,通过资源管理器异步加载地图预制件,并将其挂载到游戏根节点下,最后将地图视图组件添加到当前实体。
|
||||
|
||||
#### 对象导向组件
|
||||
```mermaid
|
||||
classDiagram
|
||||
class GameMap {
|
||||
+MapModel : MapModelComp
|
||||
+MapView : MapViewComp
|
||||
+init() : void
|
||||
+load() : void
|
||||
}
|
||||
class MapModelComp {
|
||||
+id : number
|
||||
+resPrefab : string
|
||||
+reset() : void
|
||||
}
|
||||
GameMap --> MapModelComp : "包含"
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42)
|
||||
|
||||
**本节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42)
|
||||
|
||||
### 随机关卡生成逻辑分析
|
||||
|
||||
`RogueConfig.ts`文件定义了随机关卡的生成规则。系统通过`getStageType`函数根据关卡号和等级决定关卡类型(普通、精英、Boss、事件)。`generateStageConfig`函数根据关卡类型生成怪物类型数组,`calculateMonsterCount`函数根据关卡进度动态调整怪物数量,`calculateMonsterStrengthMultiplier`函数计算怪物强度倍率。`getStageMonsterConfigs`函数综合以上逻辑,生成包含怪物UUID、类型和强度倍率的完整配置。
|
||||
|
||||
#### API/服务组件
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Game as "游戏逻辑"
|
||||
participant RogueConfig as "RogueConfig"
|
||||
participant MissionMonComp as "MissionMonComp"
|
||||
Game->>RogueConfig : getStageType(stageNumber, level)
|
||||
RogueConfig-->>Game : 返回关卡类型
|
||||
Game->>RogueConfig : generateStageConfig(stageNumber, level)
|
||||
RogueConfig-->>Game : 返回怪物类型数组
|
||||
Game->>RogueConfig : calculateMonsterCount(...)
|
||||
RogueConfig-->>Game : 返回实际数量
|
||||
Game->>RogueConfig : calculateMonsterStrengthMultiplier(...)
|
||||
RogueConfig-->>Game : 返回强度倍率
|
||||
Game->>RogueConfig : getStageMonsterConfigs(...)
|
||||
RogueConfig-->>Game : 返回完整怪物配置
|
||||
Game->>MissionMonComp : do_mon_wave()
|
||||
MissionMonComp->>MissionMonComp : generateMonstersFromStageConfig()
|
||||
MissionMonComp->>MissionMonComp : addToStageSpawnQueue()
|
||||
loop 每个怪物
|
||||
MissionMonComp->>MissionMonComp : spawnNextMonster()
|
||||
MissionMonComp->>Monster : load()
|
||||
end
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L310)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L239)
|
||||
|
||||
**本节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L310)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L239)
|
||||
|
||||
### 怪物实体设计模式分析
|
||||
|
||||
`Mon.ts`文件定义了`Monster`类,代表游戏中的怪物实体。该类同样基于ECS架构,包含`HeroModel`(模型组件)、`HeroView`(视图组件)和`BattleMove`(战斗移动组件)。`load`方法负责加载怪物的预制件并初始化其位置和属性。`hero_init`方法根据怪物UUID从`HeroInfo`配置中获取基础属性,并根据强度倍率进行调整。怪物的技能、属性和状态均在此方法中初始化。
|
||||
|
||||
#### 复杂逻辑组件
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([怪物加载]) --> Load["load(pos, scale, uuid, is_boss)"]
|
||||
Load --> GetPrefab["获取预制件路径"]
|
||||
GetPrefab --> Instantiate["实例化预制件"]
|
||||
Instantiate --> SetParent["设置父节点为entityLayer"]
|
||||
SetParent --> Init["调用hero_init初始化"]
|
||||
Init --> GetHeroInfo["从HeroInfo获取基础属性"]
|
||||
GetHeroInfo --> AdjustAttrs["根据strengthMultiplier调整属性"]
|
||||
AdjustAttrs --> InitSkills["初始化技能数组"]
|
||||
InitSkills --> AddComponent["将HeroViewComp添加到实体"]
|
||||
AddComponent --> SetMove["设置BattleMove参数"]
|
||||
SetMove --> Dispatch["派发monster_load事件"]
|
||||
Dispatch --> End([怪物加载完成])
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L151)
|
||||
|
||||
**本节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L151)
|
||||
|
||||
### 数据与表现层分离分析
|
||||
|
||||
地图系统严格遵循MVC(模型-视图-控制器)设计模式,实现了数据与表现的分离。`MapModelComp`作为模型层,仅负责存储地图的静态数据,如地图ID和资源路径。`MapViewComp`作为视图层,负责地图的显示和用户交互。`MapViewScene`作为视图的具体实现,管理地图的各个显示层(背景层、实体层、技能层)。这种分离使得数据逻辑与显示逻辑解耦,提高了代码的可维护性和可测试性。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MapModelComp {
|
||||
+id : number
|
||||
+resPrefab : string
|
||||
}
|
||||
class MapViewComp {
|
||||
+scene : MapViewScene
|
||||
}
|
||||
class MapViewScene {
|
||||
+mapLayer : MapLayer
|
||||
+entityLayer : EntityLayer
|
||||
+SkillLayer : SkillLayer
|
||||
}
|
||||
MapModelComp --> MapViewComp : "数据驱动"
|
||||
MapViewComp --> MapViewScene : "控制"
|
||||
MapViewScene --> MapLayer : "显示"
|
||||
MapViewScene --> EntityLayer : "显示"
|
||||
MapViewScene --> SkillLayer : "显示"
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76)
|
||||
|
||||
**本节来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76)
|
||||
|
||||
### 地图数据结构与关卡参数分析
|
||||
|
||||
地图数据由两个JSON文件定义:`map.json`和`map_delivery.json`。`map.json`定义了地图的基本信息,包括地图ID、名称和转场点。`map_delivery.json`定义了地图转场的具体参数,包括转场点ID、所在地图ID、触发位置、目标地图ID和目标地图的起始位置。这种设计支持非线性关卡流程,玩家可以通过不同的转场点进入不同的地图。
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
MAP {
|
||||
string id PK
|
||||
string name
|
||||
string delivery
|
||||
}
|
||||
MAP_DELIVERY {
|
||||
string id PK
|
||||
string mapId FK
|
||||
string pos
|
||||
string toMapId
|
||||
string start
|
||||
}
|
||||
MAP ||--o{ MAP_DELIVERY : "包含"
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [map.json](file://assets/resources/config/map/map.json#L1-L11)
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json#L1-L29)
|
||||
|
||||
**本节来源**
|
||||
- [map.json](file://assets/resources/config/map/map.json#L1-L11)
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json#L1-L29)
|
||||
|
||||
## 依赖分析
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
GameMap_ts --> MapModelComp_ts
|
||||
GameMap_ts --> MapViewComp_ts
|
||||
MapViewComp_ts --> MapViewScene_ts
|
||||
MapViewScene_ts --> MapLayer_ts
|
||||
MapViewScene_ts --> EntityLayer_ts
|
||||
MapViewScene_ts --> SkillLayer_ts
|
||||
MissionMonComp_ts --> RogueConfig_ts
|
||||
MissionMonComp_ts --> Mon_ts
|
||||
Mon_ts --> heroSet_ts
|
||||
RogueConfig_ts --> heroSet_ts
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L46)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L47)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L239)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L310)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L151)
|
||||
|
||||
**本节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L46)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L47)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L239)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L310)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L151)
|
||||
|
||||
## 性能考虑
|
||||
地图系统在性能方面进行了合理的设计。视图层的更新通过`update`方法每帧执行,但关键的实体排序逻辑被注释,表明开发者意识到性能问题并考虑优化。怪物生成采用队列机制,通过`spawnInterval`控制生成频率,避免一次性生成过多怪物导致性能骤降。地图资源采用异步加载,防止主线程阻塞。建议进一步优化实体层的深度排序,考虑使用空间分区或仅在必要时排序。
|
||||
|
||||
## 故障排除指南
|
||||
- **地图无法加载**:检查`MapModelComp`中的`resPrefab`路径是否正确,确保预制件存在于资源目录中。
|
||||
- **怪物未生成**:确认`MissionMonComp`是否监听了`FightReady`事件,检查`monsterQueue`是否正确填充。
|
||||
- **属性未按倍率调整**:确保`Mon.ts`中的`hero_init`方法正确接收并应用`strengthMultiplier`参数。
|
||||
- **转场无效**:验证`map_delivery.json`中的`pos`和`start`坐标格式是否正确,确保触发位置与玩家位置匹配。
|
||||
|
||||
**本节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L239)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108)
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json#L1-L29)
|
||||
|
||||
## 结论
|
||||
本文档全面分析了Cocos游戏项目中的地图系统架构。系统采用ECS和MVC设计模式,实现了良好的代码分离和可扩展性。随机关卡生成逻辑灵活,支持动态调整怪物数量和强度。数据与表现层分离清晰,便于维护和迭代。通过合理使用配置文件,实现了关卡数据的外部化管理。整体架构设计合理,为游戏的长期发展奠定了坚实基础。
|
||||
383
.qoder/repowiki/zh/content/地图系统/地图视图/地图图层管理/光照效果实现.md
Normal file
383
.qoder/repowiki/zh/content/地图系统/地图视图/地图图层管理/光照效果实现.md
Normal file
@@ -0,0 +1,383 @@
|
||||
# 光照效果实现
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [light.ts](file://assets/script/game/map/view/map/layer/light.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [FlashSprite.ts](file://assets/script/game/map/FlashSprite.ts)
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts)
|
||||
- [map.json](file://assets/resources/config/map/map.json)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [项目概述](#项目概述)
|
||||
2. [光照效果架构](#光照效果架构)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [遮罩层实现方案](#遮罩层实现方案)
|
||||
5. [后处理效果实现](#后处理效果实现)
|
||||
6. [视野范围控制机制](#视野范围控制机制)
|
||||
7. [地图分块加载联动](#地图分块加载联动)
|
||||
8. [性能优化与适配](#性能优化与适配)
|
||||
9. [高级视觉效果扩展](#高级视觉效果扩展)
|
||||
10. [最佳实践建议](#最佳实践建议)
|
||||
|
||||
## 项目概述
|
||||
|
||||
本项目是一个基于Cocos Creator的游戏,采用ECS架构设计,实现了肉鸽游戏风格的迷雾探索玩法。光照效果作为核心视觉系统的重要组成部分,负责控制玩家视野范围,营造神秘感和探索氛围。
|
||||
|
||||
### 技术栈特点
|
||||
- **引擎版本**: Cocos Creator
|
||||
- **架构模式**: ECS(Entity-Component-System)
|
||||
- **渲染技术**: 支持多种光照实现方案
|
||||
- **性能考量**: 针对移动端优化的设计
|
||||
|
||||
## 光照效果架构
|
||||
|
||||
光照效果系统采用分层架构设计,包含以下核心层次:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "光照效果系统架构"
|
||||
A[光照控制器] --> B[遮罩层管理器]
|
||||
A --> C[后处理效果处理器]
|
||||
B --> D[灰度图遮罩]
|
||||
B --> E[透明度渐变遮罩]
|
||||
C --> F[Shader处理]
|
||||
C --> G[SpriteMask处理]
|
||||
H[地图分块系统] --> A
|
||||
I[玩家位置系统] --> A
|
||||
J[相机跟随系统] --> A
|
||||
end
|
||||
subgraph "渲染管线"
|
||||
K[主摄像机] --> L[光照遮罩层]
|
||||
L --> M[游戏场景层]
|
||||
M --> N[UI层]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [light.ts](file://assets/script/game/map/view/map/layer/light.ts#L1-L18)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### 基础光照组件
|
||||
|
||||
当前项目中的基础光照组件位于[`light.ts`](file://assets/script/game/map/view/map/layer/light.ts#L1-L18),虽然目前处于空壳状态,但为未来的功能扩展预留了接口。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class LightComponent {
|
||||
+start() void
|
||||
+onLoad() void
|
||||
+update(deltaTime) void
|
||||
+createFogMask() Mask
|
||||
+updateVisibility(playerPos) void
|
||||
+applyShaderEffect() void
|
||||
}
|
||||
class MapViewScene {
|
||||
+camera Camera
|
||||
+layer Node
|
||||
+mapLayer MapLayer
|
||||
+entityLayer EntityLayer
|
||||
+isFollowPlayer boolean
|
||||
+ratio Vec2
|
||||
+init() void
|
||||
+update(dt) void
|
||||
}
|
||||
class MapLayer {
|
||||
+bgImg Sprite
|
||||
+init() void
|
||||
+clear() void
|
||||
+bgImage Sprite
|
||||
+width number
|
||||
+height number
|
||||
}
|
||||
LightComponent --> MapViewScene : "控制"
|
||||
MapViewScene --> MapLayer : "管理"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [light.ts](file://assets/script/game/map/view/map/layer/light.ts#L4-L18)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L15-L45)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L15-L46)
|
||||
|
||||
**章节来源**
|
||||
- [light.ts](file://assets/script/game/map/view/map/layer/light.ts#L1-L18)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L47)
|
||||
|
||||
### 地图视图管理系统
|
||||
|
||||
地图视图系统负责整体场景的渲染管理和光照效果的协调工作:
|
||||
|
||||
- **摄像机控制**: 实现玩家跟随和视野限制
|
||||
- **层级管理**: 确保光照效果正确叠加在游戏场景之上
|
||||
- **渲染优化**: 通过分层渲染减少不必要的绘制调用
|
||||
|
||||
**章节来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L15-L77)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
|
||||
## 遮罩层实现方案
|
||||
|
||||
### 方案一:灰度图遮罩层
|
||||
|
||||
灰度图遮罩是最经典的迷雾效果实现方式,通过调整纹理的灰度值来控制可见性。
|
||||
|
||||
#### 实现原理
|
||||
1. **纹理准备**: 使用黑白灰度图定义可见区域
|
||||
2. **Alpha混合**: 通过Shader实现灰度值到透明度的映射
|
||||
3. **动态更新**: 根据玩家位置实时更新遮罩纹理
|
||||
|
||||
#### 技术优势
|
||||
- **性能优异**: GPU原生支持,计算开销小
|
||||
- **视觉效果好**: 自然的渐变过渡
|
||||
- **易于调试**: 可直接编辑遮罩纹理
|
||||
|
||||
### 方案二:透明度渐变遮罩
|
||||
|
||||
基于透明度渐变的遮罩实现,适合需要复杂视觉效果的场景。
|
||||
|
||||
#### 实现特点
|
||||
- **渐变控制**: 支持多种渐变模式(圆形、矩形、不规则形状)
|
||||
- **多光源支持**: 可同时处理多个光源的遮罩效果
|
||||
- **边缘平滑**: 提供高质量的边缘处理
|
||||
|
||||
**章节来源**
|
||||
- [FlashSprite.ts](file://assets/script/game/map/FlashSprite.ts#L1-L28)
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L49)
|
||||
|
||||
## 后处理效果实现
|
||||
|
||||
### Shader-Based光照效果
|
||||
|
||||
基于Shader的后处理效果提供了最灵活的光照控制能力:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家位置
|
||||
participant System as 光照系统
|
||||
participant Shader as Shader处理器
|
||||
participant Render as 渲染管线
|
||||
Player->>System : 位置更新
|
||||
System->>System : 计算视野范围
|
||||
System->>Shader : 传递参数
|
||||
Shader->>Shader : 执行光照计算
|
||||
Shader->>Render : 输出处理结果
|
||||
Render->>Player : 显示最终画面
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L198-L235)
|
||||
|
||||
#### Shader实现要点
|
||||
1. **顶点着色器**: 处理几何变换和光照坐标计算
|
||||
2. **片段着色器**: 实现复杂的光照算法和遮罩效果
|
||||
3. **纹理采样**: 优化纹理访问模式,减少带宽消耗
|
||||
|
||||
### SpriteMask实现方案
|
||||
|
||||
SpriteMask是一种轻量级的遮罩实现方式:
|
||||
|
||||
#### 优势特点
|
||||
- **简单易用**: 不需要编写Shader代码
|
||||
- **兼容性强**: 支持所有平台和设备
|
||||
- **调试方便**: 可直接在编辑器中预览效果
|
||||
|
||||
#### 适用场景
|
||||
- 移动设备优化
|
||||
- 快速原型开发
|
||||
- 简单的遮罩需求
|
||||
|
||||
**章节来源**
|
||||
- [FlashSprite.ts](file://assets/script/game/map/FlashSprite.ts#L15-L28)
|
||||
|
||||
## 视野范围控制机制
|
||||
|
||||
### 动态视野算法
|
||||
|
||||
视野范围控制是光照效果的核心功能,其实现涉及多个方面的协调:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[玩家位置检测] --> B{视野类型判断}
|
||||
B --> |静态视野| C[固定半径遮罩]
|
||||
B --> |动态视野| D[渐进式展开]
|
||||
B --> |追踪视野| E[跟随玩家移动]
|
||||
C --> F[遮罩纹理更新]
|
||||
D --> F
|
||||
E --> F
|
||||
F --> G[性能优化检查]
|
||||
G --> H{性能阈值}
|
||||
H --> |正常| I[应用最终效果]
|
||||
H --> |过载| J[降级处理]
|
||||
I --> K[渲染输出]
|
||||
J --> L[简化效果]
|
||||
L --> K
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L198-L262)
|
||||
|
||||
### 视野参数配置
|
||||
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
|---------|------|--------|------|
|
||||
| 视野半径 | number | 300 | 玩家周围可见范围半径 |
|
||||
| 渐变强度 | number | 0.8 | 遮罩边缘的模糊程度 |
|
||||
| 更新频率 | number | 0.1s | 视野更新的时间间隔 |
|
||||
| 最大遮罩数量 | number | 4 | 同时存在的遮罩层数 |
|
||||
|
||||
**章节来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L198-L262)
|
||||
|
||||
## 地图分块加载联动
|
||||
|
||||
### 分块加载机制
|
||||
|
||||
地图分块加载与光照效果的联动确保了游戏性能和视觉体验的平衡:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "地图分块系统"
|
||||
A[当前区块] --> B[已加载区域]
|
||||
C[相邻区块] --> D[预加载区域]
|
||||
E[远处区块] --> F[未加载区域]
|
||||
end
|
||||
subgraph "光照效果系统"
|
||||
G[视野中心] --> H[光照遮罩]
|
||||
H --> I[动态更新]
|
||||
I --> J[性能优化]
|
||||
end
|
||||
B --> H
|
||||
D --> H
|
||||
F -.-> H
|
||||
subgraph "联动逻辑"
|
||||
K[区块加载] --> L[光照初始化]
|
||||
M[区块卸载] --> N[光照清理]
|
||||
O[玩家移动] --> P[区块切换]
|
||||
P --> Q[光照重定位]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
|
||||
### 动态更新策略
|
||||
|
||||
1. **渐进式加载**: 当玩家接近新区域时逐步加载光照数据
|
||||
2. **内存管理**: 及时释放远离玩家区域的光照资源
|
||||
3. **同步机制**: 确保光照效果与地图加载状态保持一致
|
||||
|
||||
**章节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L20-L36)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L15-L45)
|
||||
|
||||
## 性能优化与适配
|
||||
|
||||
### 性能对比分析
|
||||
|
||||
| 实现方案 | CPU开销 | GPU开销 | 内存占用 | 兼容性 | 推荐场景 |
|
||||
|---------|---------|---------|----------|--------|----------|
|
||||
| Shader遮罩 | 低 | 中等 | 中等 | 高 | PC端、高端设备 |
|
||||
| SpriteMask | 中等 | 低 | 低 | 极高 | 移动端、低端设备 |
|
||||
| 后处理效果 | 中等 | 高 | 高 | 中等 | 主流设备 |
|
||||
|
||||
### 适配策略
|
||||
|
||||
#### 移动端优化
|
||||
- **降低分辨率**: 减少光照纹理的分辨率
|
||||
- **简化算法**: 使用更简单的遮罩算法
|
||||
- **帧率控制**: 动态调整光照更新频率
|
||||
|
||||
#### 高端设备优化
|
||||
- **增强效果**: 使用高质量的Shader和纹理
|
||||
- **多光源**: 支持复杂的多光源叠加效果
|
||||
- **实时阴影**: 实现动态阴影投射
|
||||
|
||||
**章节来源**
|
||||
- [FlashSprite.ts](file://assets/script/game/map/FlashSprite.ts#L1-L28)
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L49)
|
||||
|
||||
## 高级视觉效果扩展
|
||||
|
||||
### 多光源叠加系统
|
||||
|
||||
扩展光照系统以支持多个光源的同时作用:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MultiLightSystem {
|
||||
+lights LightSource[]
|
||||
+addLight(source) void
|
||||
+removeLight(id) void
|
||||
+updateLights() void
|
||||
+combineEffects() Texture
|
||||
}
|
||||
class LightSource {
|
||||
+position Vec2
|
||||
+radius number
|
||||
+color Color
|
||||
+intensity number
|
||||
+shape Shape
|
||||
+calculateEffect() Effect
|
||||
}
|
||||
class ShadowCaster {
|
||||
+castShadow(light) Texture
|
||||
+calculateDepthMap() Texture
|
||||
+applySoftShadows() Texture
|
||||
}
|
||||
MultiLightSystem --> LightSource : "管理"
|
||||
LightSource --> ShadowCaster : "产生"
|
||||
ShadowCaster --> MultiLightSystem : "贡献"
|
||||
```
|
||||
|
||||
### 动态阴影实现
|
||||
|
||||
动态阴影系统能够根据光源位置和物体高度产生真实的阴影效果:
|
||||
|
||||
#### 实现步骤
|
||||
1. **深度缓冲**: 创建专门的深度纹理存储场景深度信息
|
||||
2. **阴影映射**: 将光源视角下的深度信息投影到屏幕空间
|
||||
3. **软阴影**: 应用阴影过滤算法产生柔和的边缘效果
|
||||
|
||||
### 区域高亮效果
|
||||
|
||||
为重要区域(如宝箱、传送点)添加特殊的高亮效果:
|
||||
|
||||
#### 效果类型
|
||||
- **脉冲高亮**: 周期性闪烁的高亮效果
|
||||
- **追踪高亮**: 跟随目标移动的持续高亮
|
||||
- **交互高亮**: 响应玩家操作的即时高亮
|
||||
|
||||
**章节来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L198-L262)
|
||||
|
||||
## 最佳实践建议
|
||||
|
||||
### 开发规范
|
||||
|
||||
1. **组件分离**: 将光照效果与业务逻辑完全分离
|
||||
2. **参数化设计**: 提供丰富的配置参数以便调整
|
||||
3. **性能监控**: 实现运行时性能指标收集
|
||||
|
||||
### 测试策略
|
||||
|
||||
1. **多设备测试**: 在不同硬件配置下验证效果
|
||||
2. **性能基准**: 建立性能基线用于回归测试
|
||||
3. **用户体验测试**: 确保光照效果不会影响游戏体验
|
||||
|
||||
### 维护建议
|
||||
|
||||
1. **文档更新**: 及时更新光照系统的使用文档
|
||||
2. **版本兼容**: 保持与引擎版本的兼容性
|
||||
3. **社区反馈**: 积极响应开发者社区的需求
|
||||
|
||||
通过以上架构设计和实现方案,本光照效果系统能够满足肉鸽游戏的迷雾探索需求,同时具备良好的扩展性和性能表现。开发者可以根据具体项目需求选择合适的实现方案,并在此基础上进行功能扩展和优化。
|
||||
272
.qoder/repowiki/zh/content/地图系统/地图视图/地图图层管理/地图图层管理.md
Normal file
272
.qoder/repowiki/zh/content/地图系统/地图视图/地图图层管理/地图图层管理.md
Normal file
@@ -0,0 +1,272 @@
|
||||
# 地图图层管理
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts)
|
||||
- [light.ts](file://assets/script/game/map/view/map/layer/light.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概述](#架构概述)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
本文档系统阐述了Cocos游戏项目中地图图层管理系统的实现机制。重点分析MapLayer作为背景图层的基础实现,EntityLayer如何承载动态实体并实现Z轴层级控制,SkillLayer在技能特效渲染中的作用,以及light.ts实现光照效果的潜在扩展方式。同时详细解析各图层继承Component的结构设计,展示图层间协作模式与节点组织策略,并提供新增自定义图层、优化图层渲染顺序与内存管理的最佳实践。
|
||||
|
||||
## 项目结构
|
||||
地图图层管理系统位于`assets/script/game/map/`目录下,采用MVC架构模式组织代码。系统分为模型层(model)、视图层(view)和控制器层,其中图层相关实现集中在view目录下的map/layer子目录中。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "地图系统"
|
||||
Model[模型层\nMapModelComp]
|
||||
View[视图层\nMapViewComp/MapViewScene]
|
||||
Layers[图层组件\nMapLayer/EntityLayer/SkillLayer]
|
||||
end
|
||||
Model --> View
|
||||
View --> Layers
|
||||
Layers --> CC[CC引擎组件\nSprite/Node/Camera]
|
||||
```
|
||||
|
||||
**图层来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L10)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L10)
|
||||
|
||||
**章节来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L80)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L50)
|
||||
|
||||
## 核心组件
|
||||
地图图层管理系统由四个核心图层组件构成:MapLayer负责背景渲染,EntityLayer管理动态实体,SkillLayer处理技能特效,light.ts提供光照效果扩展。这些组件均继承自CC引擎的Component类,通过节点树结构组织,形成分层渲染体系。
|
||||
|
||||
**章节来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L47)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
|
||||
|
||||
## 架构概述
|
||||
地图图层系统采用分层架构设计,通过MapViewScene统一管理各图层组件的生命周期和交互逻辑。系统实现了数据与视图的分离,通过ECS架构模式管理游戏实体状态。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Component {
|
||||
<<abstract>>
|
||||
}
|
||||
class MapLayer {
|
||||
-bgImg : Sprite
|
||||
+init() : void
|
||||
+clear() : void
|
||||
+bgImage : Sprite
|
||||
+width : number
|
||||
+height : number
|
||||
}
|
||||
class EntityLayer {
|
||||
-timer : Timer
|
||||
+update(dt : number)
|
||||
+clear() : void
|
||||
}
|
||||
class SkillLayer {
|
||||
-timer : Timer
|
||||
-light : Prefab
|
||||
+doSkill() : void
|
||||
+clear() : void
|
||||
}
|
||||
class light {
|
||||
+start() : void
|
||||
+onLoad() : void
|
||||
+update(deltaTime : number) : void
|
||||
}
|
||||
class MapViewScene {
|
||||
-camera : Camera
|
||||
-mapLayer : MapLayer
|
||||
-entityLayer : EntityLayer
|
||||
-SkillLayer : SkillLayer
|
||||
+init() : void
|
||||
+reset() : void
|
||||
}
|
||||
Component <|-- MapLayer
|
||||
Component <|-- EntityLayer
|
||||
Component <|-- SkillLayer
|
||||
Component <|-- light
|
||||
MapViewScene --> MapLayer
|
||||
MapViewScene --> EntityLayer
|
||||
MapViewScene --> SkillLayer
|
||||
```
|
||||
|
||||
**图层来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L47)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L48)
|
||||
- [light.ts](file://assets/script/game/map/view/map/layer/light.ts#L1-L20)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### MapLayer分析
|
||||
MapLayer组件作为地图的背景图层,负责初始化纹理、适配尺寸和管理精灵帧。通过Sprite组件实现背景图像的渲染,利用UITransform组件控制图层尺寸。
|
||||
|
||||
#### 类图
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MapLayer {
|
||||
-bgImg : Sprite
|
||||
+init() : void
|
||||
+clear() : void
|
||||
+bgImage : Sprite
|
||||
+width : number
|
||||
+height : number
|
||||
}
|
||||
class Sprite {
|
||||
-spriteFrame : SpriteFrame
|
||||
-texture : Texture2D
|
||||
}
|
||||
class UITransform {
|
||||
-width : number
|
||||
-height : number
|
||||
}
|
||||
MapLayer --> Sprite : "包含"
|
||||
MapLayer --> UITransform : "使用"
|
||||
```
|
||||
|
||||
**图层来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L15-L47)
|
||||
|
||||
**章节来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L47)
|
||||
|
||||
### EntityLayer分析
|
||||
EntityLayer组件承载英雄与怪物等动态实体,通过子节点排序实现Z轴层级控制。采用定时器优化渲染更新频率,避免每帧都进行排序操作以提升性能。
|
||||
|
||||
#### 序列图
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant EntityLayer as EntityLayer
|
||||
participant Timer as Timer
|
||||
participant Node as Node.children
|
||||
participant Sort as zIndexSort
|
||||
EntityLayer->>Timer : update(dt)
|
||||
Timer-->>EntityLayer : 是否达到0.2秒间隔?
|
||||
alt 达到间隔
|
||||
EntityLayer->>Node : children.sort()
|
||||
Node->>Sort : 执行Z轴排序
|
||||
Sort-->>Node : 返回排序结果
|
||||
Node-->>EntityLayer : 完成排序
|
||||
end
|
||||
EntityLayer->>EntityLayer : 继续下一帧更新
|
||||
```
|
||||
|
||||
**图层来源**
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
|
||||
- [Timer.ts](file://assets/script/game/common/config/BoxSet.ts#L1-L10)
|
||||
|
||||
**章节来源**
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
|
||||
|
||||
### SkillLayer分析
|
||||
SkillLayer组件专门处理技能特效的渲染,通过预制体(Prefab)管理技能相关的视觉效果。组件设计支持事件驱动的技能触发机制,为技能系统的扩展提供了基础。
|
||||
|
||||
#### 流程图
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A([组件加载]) --> B{是否监听到\n"do_use_skill"事件?}
|
||||
B --> |是| C[执行doSkill方法]
|
||||
B --> |否| D[等待下一帧]
|
||||
C --> E[实例化技能特效预制体]
|
||||
E --> F[添加到场景节点树]
|
||||
F --> G[播放技能动画]
|
||||
G --> H[技能效果完成]
|
||||
H --> I[清理特效节点]
|
||||
I --> D
|
||||
D --> J{组件是否销毁?}
|
||||
J --> |是| K([组件卸载])
|
||||
J --> |否| B
|
||||
```
|
||||
|
||||
**图层来源**
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L48)
|
||||
- [Prefab](file://assets/script/game/common/config/BoxSet.ts#L1-L10)
|
||||
|
||||
**章节来源**
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L48)
|
||||
|
||||
### 光照系统分析
|
||||
light.ts文件定义了基础的光照组件,为地图系统提供了光照效果的扩展能力。虽然当前实现较为简单,但已具备完整的组件生命周期管理。
|
||||
|
||||
#### 状态图
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 初始化
|
||||
初始化 --> 加载中 : onLoad()
|
||||
加载中 --> 运行中 : start()
|
||||
运行中 --> 加载中 : 重新加载
|
||||
运行中 --> 更新中 : update()
|
||||
更新中 --> 运行中 : 完成更新
|
||||
运行中 --> 销毁 : 组件移除
|
||||
销毁 --> [*]
|
||||
```
|
||||
|
||||
**图层来源**
|
||||
- [light.ts](file://assets/script/game/map/view/map/layer/light.ts#L1-L20)
|
||||
|
||||
**章节来源**
|
||||
- [light.ts](file://assets/script/game/map/view/map/layer/light.ts#L1-L20)
|
||||
|
||||
## 依赖分析
|
||||
地图图层系统依赖于Oops插件框架提供的核心功能,包括资源管理、消息系统和ECS架构。各图层组件通过MapViewScene进行协调管理,形成清晰的依赖关系。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[MapLayer] --> B[CC引擎]
|
||||
C[EntityLayer] --> B
|
||||
D[SkillLayer] --> B
|
||||
E[light] --> B
|
||||
F[MapViewScene] --> A
|
||||
F --> C
|
||||
F --> D
|
||||
F --> E
|
||||
G[Oops框架] --> F
|
||||
G --> C
|
||||
G --> D
|
||||
B --> H[Sprite]
|
||||
B --> I[Node]
|
||||
B --> J[Camera]
|
||||
```
|
||||
|
||||
**图层来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
|
||||
**章节来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
|
||||
## 性能考虑
|
||||
地图图层系统在设计时充分考虑了性能优化。EntityLayer和SkillLayer均采用定时器控制更新频率,避免不必要的每帧计算。MapLayer通过直接操作UITransform组件实现高效的尺寸适配。
|
||||
|
||||
系统建议的性能优化策略包括:
|
||||
1. 对于静态背景,使用MapLayer一次性初始化
|
||||
2. 动态实体的Z轴排序采用0.2秒间隔更新,平衡视觉效果与性能
|
||||
3. 技能特效使用对象池模式管理预制体实例,减少GC压力
|
||||
4. 光照效果可根据需要动态启用或禁用
|
||||
|
||||
## 故障排除指南
|
||||
当遇到地图图层相关问题时,可参考以下排查步骤:
|
||||
|
||||
**章节来源**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
|
||||
## 结论
|
||||
地图图层管理系统通过分层设计实现了关注点分离,各图层职责明确,便于维护和扩展。系统充分利用了CC引擎的节点组件体系,结合Oops框架的ECS架构,构建了一个高效、可扩展的地图渲染解决方案。未来可进一步优化Z轴排序算法,引入更复杂的光照模型,并完善技能特效的资源管理机制。
|
||||
615
.qoder/repowiki/zh/content/地图系统/地图视图/地图图层管理/地图基础图层.md
Normal file
615
.qoder/repowiki/zh/content/地图系统/地图视图/地图图层管理/地图基础图层.md
Normal file
@@ -0,0 +1,615 @@
|
||||
# 地图基础图层
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts)
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts)
|
||||
- [map.json](file://assets/resources/config/map/map.json)
|
||||
- [map_delivery.json](file://assets/resources/config/map/map_delivery.json)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能优化策略](#性能优化策略)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
MapLayer类是Cocos Creator游戏引擎中地图系统的核心组件,作为地图背景图层的基础实现。该类继承自cc.Component,提供了地图纹理资源的动态加载、精灵帧初始化、尺寸适配以及节点锚点校准等关键功能。通过与MapViewComp的紧密协作,MapLayer确保了在不同分辨率设备下的正确渲染和高效的性能表现。
|
||||
|
||||
本文档将深入解析MapLayer的实现机制,包括其生命周期管理、纹理资源处理流程、尺寸适配策略以及在地图系统中的注册与更新机制。同时,我们将探讨如何扩展MapLayer以支持多段滚动背景和动态材质更新,并提供实用的性能优化建议。
|
||||
|
||||
## 项目结构
|
||||
|
||||
地图系统的文件组织采用了模块化的架构设计,主要分为视图层(view)和模型层(model)两个核心部分:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "地图系统架构"
|
||||
GameMap[GameMap 游戏地图实体]
|
||||
MapModel[MapModelComp 地图模型组件]
|
||||
MapView[MapViewComp 地图视图组件]
|
||||
subgraph "视图层组件"
|
||||
MapViewScene[MapViewScene 地图场景逻辑]
|
||||
MapLayer[MapLayer 地图背景层]
|
||||
EntityLayer[EntityLayer 实体层]
|
||||
SkillLayer[SkillLayer 技能层]
|
||||
end
|
||||
subgraph "配置文件"
|
||||
MapConfig[map.json 地图配置]
|
||||
DeliveryConfig[map_delivery.json 传送点配置]
|
||||
end
|
||||
end
|
||||
GameMap --> MapModel
|
||||
GameMap --> MapView
|
||||
MapView --> MapViewScene
|
||||
MapViewScene --> MapLayer
|
||||
MapViewScene --> EntityLayer
|
||||
MapViewScene --> SkillLayer
|
||||
MapModel --> MapConfig
|
||||
MapModel --> DeliveryConfig
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76)
|
||||
|
||||
**章节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### MapLayer类设计
|
||||
|
||||
MapLayer作为地图背景图层的核心实现,具有以下关键特性:
|
||||
|
||||
| 属性/方法 | 类型 | 描述 | 默认值 |
|
||||
|-----------|------|------|--------|
|
||||
| bgImg | Sprite | 背景图像精灵组件 | null |
|
||||
| width | number | 图层宽度属性 | 动态计算 |
|
||||
| height | number | 图层高度属性 | 动态计算 |
|
||||
| init() | void | 初始化方法 | - |
|
||||
| clear() | void | 清理方法 | - |
|
||||
| bgImage | Sprite | 背景图像访问器 | - |
|
||||
|
||||
### 组件继承体系
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Component {
|
||||
+onLoad() void
|
||||
+start() void
|
||||
+update(dt : number) void
|
||||
+destroy() void
|
||||
}
|
||||
class MapLayer {
|
||||
-bgImg : Sprite
|
||||
+init() void
|
||||
+clear() void
|
||||
+bgImage : Sprite
|
||||
+width : number
|
||||
+height : number
|
||||
}
|
||||
class MapViewScene {
|
||||
+camera : Camera
|
||||
+layer : Node
|
||||
+mapLayer : MapLayer
|
||||
+floorLayer : Node
|
||||
+entityLayer : EntityLayer
|
||||
+SkillLayer : SkillLayer
|
||||
+isFollowPlayer : boolean
|
||||
+ratio : Vec2
|
||||
+onLoad() void
|
||||
+start() void
|
||||
+reset() void
|
||||
+init() void
|
||||
+update(dt : number) void
|
||||
}
|
||||
class EntityLayer {
|
||||
-timer : Timer
|
||||
+update(dt : number) void
|
||||
+clear() void
|
||||
}
|
||||
class SkillLayer {
|
||||
-timer : Timer
|
||||
+light : Prefab
|
||||
+onLoad() void
|
||||
+doSkill() void
|
||||
+update(dt : number) void
|
||||
+clear() void
|
||||
}
|
||||
Component <|-- MapLayer
|
||||
Component <|-- EntityLayer
|
||||
Component <|-- SkillLayer
|
||||
MapViewScene --> MapLayer : "包含"
|
||||
MapViewScene --> EntityLayer : "包含"
|
||||
MapViewScene --> SkillLayer : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L46)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L47)
|
||||
|
||||
**章节来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L46)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76)
|
||||
|
||||
## 架构概览
|
||||
|
||||
地图系统采用ECS(Entity-Component-System)架构模式,通过组件化设计实现了高度的灵活性和可扩展性:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant GM as GameMap
|
||||
participant MM as MapModel
|
||||
participant MVC as MapViewComp
|
||||
participant MVS as MapViewScene
|
||||
participant ML as MapLayer
|
||||
participant BG as Background Sprite
|
||||
GM->>MM : 创建地图模型
|
||||
GM->>MVC : 加载地图视图
|
||||
MVC->>MVS : 初始化场景逻辑
|
||||
MVS->>ML : 注册地图层
|
||||
ML->>BG : 初始化背景精灵
|
||||
BG->>ML : 设置纹理资源
|
||||
ML->>MVS : 完成初始化
|
||||
MVS->>MVC : 场景就绪
|
||||
MVC->>GM : 视图组件激活
|
||||
Note over GM,BG : 地图初始化完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L25-L35)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L25-L35)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L50-L60)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L20-L25)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### MapLayer生命周期管理
|
||||
|
||||
MapLayer的生命周期管理遵循Cocos Creator的标准组件生命周期,通过init()方法进行初始化配置:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([组件加载]) --> OnInit["调用init()方法"]
|
||||
OnInit --> GetTransform["获取UITransform组件"]
|
||||
GetTransform --> CalcSize["计算宽度和高度"]
|
||||
CalcSize --> SetSize["设置节点尺寸"]
|
||||
SetSize --> Ready([初始化完成])
|
||||
Ready --> UpdateLoop{"游戏循环"}
|
||||
UpdateLoop --> UpdateLoop
|
||||
Ready --> ClearCall["调用clear()方法"]
|
||||
ClearCall --> ResetSprite["重置精灵帧"]
|
||||
ResetSprite --> Cleanup([清理完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L20-L30)
|
||||
|
||||
#### 初始化流程详解
|
||||
|
||||
MapLayer的init()方法负责设置图层的基本属性,主要包括:
|
||||
|
||||
1. **尺寸适配**:通过UITransform组件动态调整节点尺寸
|
||||
2. **锚点校准**:确保在不同分辨率下的正确对齐
|
||||
3. **纹理绑定**:建立与背景精灵的关联关系
|
||||
|
||||
#### 清理机制
|
||||
|
||||
clear()方法提供了优雅的资源清理机制:
|
||||
- 释放当前绑定的精灵帧资源
|
||||
- 防止内存泄漏
|
||||
- 支持动态切换地图内容
|
||||
|
||||
**章节来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L20-L35)
|
||||
|
||||
### 纹理资源动态加载
|
||||
|
||||
地图系统通过MapModelComp管理资源配置,支持动态加载不同地图的纹理资源:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph "资源配置"
|
||||
Config[map.json<br/>地图配置文件]
|
||||
Delivery[map_delivery.json<br/>传送点配置]
|
||||
end
|
||||
subgraph "资源加载"
|
||||
Model[MapModelComp<br/>模型组件]
|
||||
Loader[Oops资源管理器<br/>oops.res.load]
|
||||
Prefab[地图预制件<br/>resPrefab]
|
||||
end
|
||||
subgraph "实例化"
|
||||
Instantiate[实例化地图节点]
|
||||
AddToScene[添加到场景]
|
||||
RegisterLayers[注册图层组件]
|
||||
end
|
||||
Config --> Model
|
||||
Delivery --> Model
|
||||
Model --> Loader
|
||||
Loader --> Prefab
|
||||
Prefab --> Instantiate
|
||||
Instantiate --> AddToScene
|
||||
AddToScene --> RegisterLayers
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L15-L20)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L25-L35)
|
||||
- [map.json](file://assets/resources/config/map/map.json#L1-L11)
|
||||
|
||||
#### 资源加载策略
|
||||
|
||||
| 资源类型 | 加载方式 | 缓存策略 | 释放时机 |
|
||||
|----------|----------|----------|----------|
|
||||
| 地图预制件 | 异步加载 | 自动缓存 | 场景切换时 |
|
||||
| 纹理资源 | 按需加载 | 批量管理 | 地图销毁时 |
|
||||
| 配置文件 | 同步加载 | 内存常驻 | 应用退出时 |
|
||||
|
||||
**章节来源**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L15-L20)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L25-L35)
|
||||
|
||||
### 尺寸适配与节点锚点校准
|
||||
|
||||
MapLayer通过UITransform组件实现智能的尺寸适配:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph "尺寸计算"
|
||||
GetSprite["获取背景精灵"]
|
||||
GetTransform["读取UITransform"]
|
||||
CalcWidth["计算宽度"]
|
||||
CalcHeight["计算高度"]
|
||||
end
|
||||
subgraph "锚点校准"
|
||||
SetAnchor["设置锚点"]
|
||||
AdjustPosition["调整位置"]
|
||||
ValidateBounds["验证边界"]
|
||||
end
|
||||
subgraph "渲染优化"
|
||||
BatchRender["批处理渲染"]
|
||||
ReduceDrawCalls["减少绘制调用"]
|
||||
OptimizeMemory["优化内存使用"]
|
||||
end
|
||||
GetSprite --> GetTransform
|
||||
GetTransform --> CalcWidth
|
||||
GetTransform --> CalcHeight
|
||||
CalcWidth --> SetAnchor
|
||||
CalcHeight --> SetAnchor
|
||||
SetAnchor --> AdjustPosition
|
||||
AdjustPosition --> ValidateBounds
|
||||
ValidateBounds --> BatchRender
|
||||
BatchRender --> ReduceDrawCalls
|
||||
ReduceDrawCalls --> OptimizeMemory
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L30-L45)
|
||||
|
||||
#### 适配算法实现
|
||||
|
||||
MapLayer采用以下策略确保在不同设备上的正确显示:
|
||||
|
||||
1. **动态尺寸计算**:基于背景精灵的实际纹理尺寸
|
||||
2. **锚点智能定位**:自动调整节点锚点以适应不同的显示需求
|
||||
3. **边界验证**:确保渲染边界不会超出屏幕范围
|
||||
|
||||
**章节来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L30-L45)
|
||||
|
||||
### MapViewComp中的注册与更新策略
|
||||
|
||||
MapViewComp作为地图系统的协调中心,负责管理所有子图层的生命周期:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MVC as MapViewComp
|
||||
participant MVS as MapViewScene
|
||||
participant ML as MapLayer
|
||||
participant EL as EntityLayer
|
||||
participant SL as SkillLayer
|
||||
MVC->>MVS : 创建场景实例
|
||||
MVS->>ML : 注册地图层
|
||||
MVS->>EL : 注册实体层
|
||||
MVS->>SL : 注册技能层
|
||||
loop 游戏循环
|
||||
MVS->>ML : 更新背景
|
||||
MVS->>EL : 更新实体
|
||||
MVS->>SL : 更新技能
|
||||
ML->>ML : 处理纹理动画
|
||||
EL->>EL : 处理深度排序
|
||||
SL->>SL : 处理特效渲染
|
||||
end
|
||||
Note over MVC,SL : 地图系统运行中
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L25-L35)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L25-L45)
|
||||
|
||||
#### 图层初始化顺序
|
||||
|
||||
地图系统按照以下优先级顺序初始化各图层:
|
||||
|
||||
1. **背景层(MapLayer)**:最先初始化,确保基础渲染环境
|
||||
2. **实体层(EntityLayer)**:紧随其后,处理游戏对象渲染
|
||||
3. **技能层(SkillLayer)**:最后初始化,处理特效和技能动画
|
||||
|
||||
#### 渲染层级基础设定
|
||||
|
||||
| 图层类型 | 渲染层级 | Z-Index范围 | 主要职责 |
|
||||
|----------|----------|-------------|----------|
|
||||
| 背景层 | 最底层 | 0-10 | 地图背景渲染 |
|
||||
| 地面层 | 中间层 | 11-50 | 地面装饰物 |
|
||||
| 实体层 | 中间层 | 51-100 | 游戏实体对象 |
|
||||
| 技能层 | 最顶层 | 101+ | 技能特效动画 |
|
||||
|
||||
**章节来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L25-L45)
|
||||
|
||||
### 扩展MapLayer支持多段滚动背景
|
||||
|
||||
为了支持更复杂的游戏场景,可以扩展MapLayer以实现多段滚动背景:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MapLayer {
|
||||
+bgImg : Sprite
|
||||
+scrollSpeed : number
|
||||
+repeatMode : RepeatMode
|
||||
+init() void
|
||||
+update(dt : number) void
|
||||
+setScrollSpeed(speed : number) void
|
||||
+enableParallax(parallax : boolean) void
|
||||
}
|
||||
class MultiScrollLayer {
|
||||
-layers : MapLayer[]
|
||||
-parallaxFactor : number
|
||||
+addBackground(layer : MapLayer) void
|
||||
+removeBackground(layer : MapLayer) void
|
||||
+update(dt : number) void
|
||||
+setParallaxFactor(factor : number) void
|
||||
}
|
||||
class ParallaxEffect {
|
||||
+depth : number
|
||||
+speedMultiplier : number
|
||||
+offset : Vec2
|
||||
+applyEffect(sprite : Sprite) void
|
||||
}
|
||||
MapLayer <|-- MultiScrollLayer
|
||||
MultiScrollLayer --> ParallaxEffect : "使用"
|
||||
MultiScrollLayer --> MapLayer : "管理多个"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L46)
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L49)
|
||||
|
||||
#### 动态材质更新机制
|
||||
|
||||
通过MoveUV组件可以实现动态UV动画效果:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始UV动画]) --> GetSprite["获取Sprite组件"]
|
||||
GetSprite --> InitRect["初始化矩形区域"]
|
||||
InitRect --> SetPackable["禁用打包优化"]
|
||||
SetPackable --> UpdateLoop{"更新循环"}
|
||||
UpdateLoop --> CheckWrapMode{"检查包装模式"}
|
||||
CheckWrapMode --> |变更| UpdateWrapMode["更新纹理包装模式"]
|
||||
CheckWrapMode --> |未变| CalculateOffset["计算偏移量"]
|
||||
UpdateWrapMode --> CalculateOffset
|
||||
CalculateOffset --> ApplyOffset["应用UV偏移"]
|
||||
ApplyOffset --> MarkDirty["标记渲染数据更新"]
|
||||
MarkDirty --> UpdateLoop
|
||||
UpdateLoop --> Stop([停止动画])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L25-L49)
|
||||
|
||||
**章节来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L49)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
地图系统的依赖关系体现了清晰的分层架构:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "外部依赖"
|
||||
Cocos[Cocos Creator Engine]
|
||||
Oops[Oops Plugin Framework]
|
||||
ECS[ECS Framework]
|
||||
end
|
||||
subgraph "核心组件"
|
||||
MapLayer[MapLayer]
|
||||
MapViewComp[MapViewComp]
|
||||
MapViewScene[MapViewScene]
|
||||
MapModel[MapModelComp]
|
||||
end
|
||||
subgraph "辅助组件"
|
||||
EntityLayer[EntityLayer]
|
||||
SkillLayer[SkillLayer]
|
||||
MoveUV[MoveUV]
|
||||
end
|
||||
subgraph "配置系统"
|
||||
MapConfig[地图配置]
|
||||
DeliveryConfig[传送点配置]
|
||||
end
|
||||
Cocos --> MapLayer
|
||||
Cocos --> MapViewComp
|
||||
Cocos --> MapViewScene
|
||||
Cocos --> MapModel
|
||||
Cocos --> EntityLayer
|
||||
Cocos --> SkillLayer
|
||||
Cocos --> MoveUV
|
||||
Oops --> MapLayer
|
||||
Oops --> MapViewComp
|
||||
Oops --> MapViewScene
|
||||
Oops --> MapModel
|
||||
ECS --> MapLayer
|
||||
ECS --> MapViewComp
|
||||
ECS --> MapViewScene
|
||||
ECS --> MapModel
|
||||
MapConfig --> MapModel
|
||||
DeliveryConfig --> MapModel
|
||||
MapViewScene --> MapLayer
|
||||
MapViewScene --> EntityLayer
|
||||
MapViewScene --> SkillLayer
|
||||
MapLayer --> MoveUV
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L10)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L10)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L10)
|
||||
|
||||
### 组件耦合度分析
|
||||
|
||||
| 组件对 | 耦合类型 | 耦合强度 | 优化建议 |
|
||||
|--------|----------|----------|----------|
|
||||
| MapLayer ↔ MoveUV | 功能耦合 | 中等 | 提取通用接口 |
|
||||
| MapViewScene ↔ MapLayer | 依赖耦合 | 高 | 使用事件解耦 |
|
||||
| GameMap ↔ MapModel | 实体耦合 | 低 | 添加中间管理层 |
|
||||
|
||||
**章节来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L10)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L10)
|
||||
|
||||
## 性能优化策略
|
||||
|
||||
### 图集合并优化
|
||||
|
||||
通过合理组织纹理资源,可以显著提升渲染性能:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph "原始资源"
|
||||
T1[纹理1]
|
||||
T2[纹理2]
|
||||
T3[纹理3]
|
||||
T4[纹理4]
|
||||
end
|
||||
subgraph "图集合并"
|
||||
Atlas[纹理图集]
|
||||
Pack[打包算法]
|
||||
end
|
||||
subgraph "优化效果"
|
||||
Batch[批处理渲染]
|
||||
DrawCalls[减少绘制调用]
|
||||
Memory[优化内存使用]
|
||||
end
|
||||
T1 --> Pack
|
||||
T2 --> Pack
|
||||
T3 --> Pack
|
||||
T4 --> Pack
|
||||
Pack --> Atlas
|
||||
Atlas --> Batch
|
||||
Batch --> DrawCalls
|
||||
DrawCalls --> Memory
|
||||
```
|
||||
|
||||
#### 性能优化建议
|
||||
|
||||
1. **纹理打包策略**
|
||||
- 将频繁一起使用的纹理合并到同一图集中
|
||||
- 使用合理的图集大小(建议1024x1024或2048x2048)
|
||||
- 避免过度填充导致的内存浪费
|
||||
|
||||
2. **绘制批次优化**
|
||||
- 相同材质的精灵自动合并到同一绘制批次
|
||||
- 减少状态切换开销
|
||||
- 优化渲染顺序以提高缓存命中率
|
||||
|
||||
3. **内存管理**
|
||||
- 及时释放不再使用的纹理资源
|
||||
- 使用对象池管理临时对象
|
||||
- 监控内存使用情况,避免内存泄漏
|
||||
|
||||
### 动态加载优化
|
||||
|
||||
对于大型地图场景,建议采用分块加载策略:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([地图加载开始]) --> LoadCore["加载核心图层"]
|
||||
LoadCore --> LoadVisible["加载可见区域"]
|
||||
LoadVisible --> PreloadNearby["预加载邻近区域"]
|
||||
PreloadNearby --> Monitor["监控玩家位置"]
|
||||
Monitor --> PlayerMoved{"玩家移动?"}
|
||||
PlayerMoved --> |是| UnloadOld["卸载远离区域"]
|
||||
PlayerMoved --> |否| Monitor
|
||||
UnloadOld --> LoadNew["加载新区域"]
|
||||
LoadNew --> PreloadNearby
|
||||
Monitor --> End([加载完成])
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [MapLayer.ts](file://assets/script/game/view/map/layer/MapLayer.ts#L1-L46)
|
||||
- [MoveUV.ts](file://assets/script/game/view/MoveUV.ts#L1-L49)
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
| 问题类型 | 症状描述 | 可能原因 | 解决方案 |
|
||||
|----------|----------|----------|----------|
|
||||
| 纹理加载失败 | 背景显示为空白 | 资源路径错误 | 检查resPrefab配置 |
|
||||
| 尺寸适配异常 | 图层显示变形 | 锚点设置不当 | 验证UITransform配置 |
|
||||
| 性能下降 | 帧率降低 | 绘制批次过多 | 优化纹理打包策略 |
|
||||
| 内存泄漏 | 内存持续增长 | 资源未正确释放 | 检查clear()方法调用 |
|
||||
|
||||
### 调试技巧
|
||||
|
||||
1. **资源监控**
|
||||
- 使用Cocos Creator的Profiler监控渲染性能
|
||||
- 检查纹理内存使用情况
|
||||
- 监控绘制调用次数
|
||||
|
||||
2. **日志记录**
|
||||
- 在关键方法添加调试日志
|
||||
- 记录资源加载状态
|
||||
- 跟踪组件生命周期
|
||||
|
||||
3. **可视化调试**
|
||||
- 显示图层边界框
|
||||
- 标记关键节点位置
|
||||
- 可视化渲染顺序
|
||||
|
||||
**章节来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L25-L35)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L45-L60)
|
||||
|
||||
## 结论
|
||||
|
||||
MapLayer作为地图系统的核心组件,通过精心设计的架构实现了高效的地图渲染功能。其继承自cc.Component的生命周期管理确保了组件的正确初始化和清理,而动态纹理加载和精灵帧初始化流程则保证了资源的灵活使用。
|
||||
|
||||
通过与MapViewComp的紧密协作,MapLayer不仅实现了基本的地图背景渲染,还为扩展功能如多段滚动背景和动态材质更新奠定了坚实基础。合理的性能优化策略,包括图集合并和绘制批次减少,使得地图系统能够在各种设备上保持良好的性能表现。
|
||||
|
||||
未来的发展方向包括:
|
||||
- 进一步优化多段滚动背景的实现
|
||||
- 增强动态材质更新的功能
|
||||
- 实现更智能的资源加载策略
|
||||
- 提供更丰富的视觉效果支持
|
||||
|
||||
这些改进将使地图系统更加灵活和强大,为游戏开发提供更好的技术支持。
|
||||
170
.qoder/repowiki/zh/content/地图系统/地图视图/地图图层管理/实体图层管理.md
Normal file
170
.qoder/repowiki/zh/content/地图系统/地图视图/地图图层管理/实体图层管理.md
Normal file
@@ -0,0 +1,170 @@
|
||||
# 实体图层管理
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [timer.md](file://doc/core/common/timer.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [实体图层结构](#实体图层结构)
|
||||
3. [Z轴层级管理机制](#z轴层级管理机制)
|
||||
4. [定时器更新策略](#定时器更新策略)
|
||||
5. [ECS系统数据同步](#ecs系统数据同步)
|
||||
6. [性能优化方案](#性能优化方案)
|
||||
7. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
本文档深入解析EntityLayer作为动态实体容器的实现机制,重点阐述其如何承载英雄、怪物及其他可移动单位的可视化节点。文档将详细说明其通过addChild与zIndex控制子节点渲染顺序的Z轴层级管理机制,分析其内置的定时器更新策略,以及与ECS系统中BattleMoveComp的数据同步设计模式。同时,提供处理大量实体时的性能优化方案。
|
||||
|
||||
## 实体图层结构
|
||||
|
||||
EntityLayer作为游戏场景中的物体层,负责管理所有动态实体的可视化节点。该图层通过Cocos Creator的节点系统实现,作为场景中的一个特殊容器节点,专门用于承载英雄、怪物等可移动单位。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "场景层级结构"
|
||||
MapViewScene[地图场景]
|
||||
EntityLayer[实体图层]
|
||||
SkillLayer[技能图层]
|
||||
MapLayer[地图图层]
|
||||
end
|
||||
MapViewScene --> EntityLayer
|
||||
MapViewScene --> SkillLayer
|
||||
MapViewScene --> MapLayer
|
||||
EntityLayer --> HeroNode[英雄节点]
|
||||
EntityLayer --> MonsterNode[怪物节点]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L20)
|
||||
|
||||
**Section sources**
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L20)
|
||||
|
||||
## Z轴层级管理机制
|
||||
|
||||
EntityLayer通过精确的Z轴层级管理机制确保战斗单位在地形与特效间的正确叠加。该机制不直接依赖节点的z坐标,而是通过控制节点在父节点中的兄弟索引(sibling index)来实现渲染顺序的控制。
|
||||
|
||||
核心实现位于BattleMoveSystem中,通过updateRenderOrder方法动态调整所有单位的渲染层级:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始更新渲染层级]) --> FindUnits["查找所有HeroViewComp实体"]
|
||||
FindUnits --> FilterByFac["按阵营分组"]
|
||||
FilterByFac --> SortByX["按x坐标排序<br/>x坐标越小越靠后"]
|
||||
SortByX --> SetSiblingIndex["设置兄弟索引<br/>index越大层级越高"]
|
||||
SetSiblingIndex --> End([完成渲染层级更新])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L233-L262)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L50)
|
||||
|
||||
**Section sources**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L233-L262)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L50)
|
||||
|
||||
## 定时器更新策略
|
||||
|
||||
EntityLayer采用智能的定时器更新策略,通过固定帧间隔批量刷新实体位置以降低渲染开销。该策略避免了每帧都进行深度排序可能带来的性能问题。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class EntityLayer {
|
||||
-timer : Timer
|
||||
+update(dt : number)
|
||||
+clear()
|
||||
}
|
||||
class Timer {
|
||||
+interval : number
|
||||
+update(dt : number) : boolean
|
||||
}
|
||||
EntityLayer --> Timer : "使用"
|
||||
```
|
||||
|
||||
EntityLayer中定义了一个间隔为0.2秒的Timer实例,理论上应该周期性地执行节点排序。然而,当前实现中相关代码被注释,表明开发者意识到每帧排序的性能开销问题,为未来优化预留了接口。
|
||||
|
||||
**Diagram sources**
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38)
|
||||
- [timer.md](file://doc/core/common/timer.md#L79-L91)
|
||||
|
||||
**Section sources**
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38)
|
||||
- [timer.md](file://doc/core/common/timer.md#L79-L91)
|
||||
|
||||
## ECS系统数据同步
|
||||
|
||||
系统采用实体-组件-系统(ECS)架构实现视图与逻辑的完全解耦。BattleMoveComp作为数据组件承载移动状态,而EntityLayer作为视图容器负责可视化呈现。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant BattleMoveSystem as BattleMoveSystem
|
||||
participant BattleMoveComp as BattleMoveComp
|
||||
participant HeroViewComp as HeroViewComp
|
||||
participant EntityLayer as EntityLayer
|
||||
BattleMoveSystem->>BattleMoveComp : 读取移动状态
|
||||
BattleMoveSystem->>HeroViewComp : 获取节点引用
|
||||
BattleMoveSystem->>HeroViewComp : 更新位置
|
||||
BattleMoveSystem->>BattleMoveSystem : updateRenderOrder()
|
||||
BattleMoveSystem->>HeroViewComp : setSiblingIndex()
|
||||
HeroViewComp->>EntityLayer : 节点层级更新
|
||||
```
|
||||
|
||||
当英雄或怪物实体被加载时,通过addChild方法将其节点添加到EntityLayer中,实现视图与逻辑的绑定:
|
||||
|
||||
**Section sources**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L45-L55)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L48-L58)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L34)
|
||||
|
||||
## 性能优化方案
|
||||
|
||||
### 对象池复用
|
||||
系统通过ECS框架内置的对象池机制实现组件和实体的高效复用。当实体被销毁时,其组件会被放入缓存池中,下次创建时优先从池中获取,避免频繁的内存分配与垃圾回收。
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
ENTITY["实体"] {
|
||||
string name PK
|
||||
boolean active
|
||||
}
|
||||
COMPONENT["组件"] {
|
||||
string type PK
|
||||
boolean pooled
|
||||
}
|
||||
ENTITY_POOL["实体池"] {
|
||||
int capacity
|
||||
int count
|
||||
}
|
||||
COMPONENT_POOL["组件池"] {
|
||||
int capacity
|
||||
int count
|
||||
}
|
||||
ENTITY ||--o{ COMPONENT : "包含"
|
||||
ENTITY_POOL }o--|| ENTITY : "存储"
|
||||
COMPONENT_POOL }o--|| COMPONENT : "存储"
|
||||
```
|
||||
|
||||
### 可见性裁剪
|
||||
虽然当前代码未显式实现可见性裁剪,但在BattleMoveSystem中通过阵营分组过滤和距离检测,间接实现了部分裁剪功能。系统只对同阵营的单位进行渲染层级计算,减少了不必要的处理。
|
||||
|
||||
### 批量更新策略
|
||||
通过0.2秒的定时器间隔,系统可以批量处理多个实体的位置更新和层级排序,而不是每帧都执行,有效降低了CPU开销。
|
||||
|
||||
**Section sources**
|
||||
- [ecs.md](file://ecs.md#L29-L87)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L34)
|
||||
|
||||
## 结论
|
||||
EntityLayer作为动态实体容器,通过精心设计的Z轴层级管理机制和定时器更新策略,有效平衡了视觉效果与性能开销。其与ECS系统的深度集成实现了视图与逻辑的完美解耦,为游戏的可维护性和扩展性奠定了坚实基础。未来的优化方向包括启用定时排序、实现完整的可见性裁剪以及进一步优化对象池策略。
|
||||
368
.qoder/repowiki/zh/content/地图系统/地图视图/地图图层管理/技能特效图层.md
Normal file
368
.qoder/repowiki/zh/content/地图系统/地图视图/地图图层管理/技能特效图层.md
Normal file
@@ -0,0 +1,368 @@
|
||||
# 技能特效图层
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/layer/SkillLayer.ts)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
SkillLayer是《英雄传说》项目中负责技能释放特效渲染的核心独立渲染层级。它作为技能动画与地图背景之间的隔离屏障,确保技能特效能够在正确的视觉层级中呈现,同时保持与施法者位置和朝向的精确同步。该系统采用ECS架构设计,支持多种特效类型(粒子系统、Spine动画)的集成,并提供了完整的生命周期管理机制。
|
||||
|
||||
## 项目结构
|
||||
|
||||
SkillLayer系统在项目中的组织结构体现了清晰的职责分离和模块化设计:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "地图视图层"
|
||||
MapView[MapViewScene]
|
||||
MapLayer[MapLayer]
|
||||
EntityLayer[EntityLayer]
|
||||
SkillLayer[SkillLayer]
|
||||
end
|
||||
subgraph "技能系统"
|
||||
SkillEnt[SkillEnt]
|
||||
SkillViewCom[SkillViewCom]
|
||||
AtkConCom[AtkConCom]
|
||||
SkillConComp[SkillConComp]
|
||||
end
|
||||
subgraph "配置系统"
|
||||
SkillSet[SkillSet]
|
||||
HeroAttrs[HeroAttrs]
|
||||
end
|
||||
MapView --> MapLayer
|
||||
MapView --> EntityLayer
|
||||
MapView --> SkillLayer
|
||||
SkillEnt --> SkillViewCom
|
||||
SkillViewCom --> AtkConCom
|
||||
SkillConComp --> SkillEnt
|
||||
SkillSet --> SkillViewCom
|
||||
SkillSet --> AtkConCom
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/layer/SkillLayer.ts#L1-L48)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
|
||||
**章节来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/layer/SkillLayer.ts#L1-L48)
|
||||
|
||||
## 核心组件
|
||||
|
||||
SkillLayer系统由以下核心组件构成:
|
||||
|
||||
### SkillLayer - 独立渲染层级
|
||||
作为技能特效的专用渲染容器,SkillLayer实现了以下关键功能:
|
||||
- **层级隔离**:确保技能特效不会干扰地图背景和其他UI元素
|
||||
- **深度排序**:支持基于Z轴位置的自动排序机制
|
||||
- **生命周期管理**:提供完整的创建、播放和销毁流程
|
||||
|
||||
### SkillViewCom - 视图层控制器
|
||||
负责技能特效的视觉表现和行为控制:
|
||||
- **位置同步**:与施法者位置保持实时同步
|
||||
- **动画播放**:协调各种特效动画的播放时机
|
||||
- **生命周期控制**:管理技能特效的完整生命周期
|
||||
|
||||
### AtkConCom - 攻击逻辑组件
|
||||
处理技能的物理效果和碰撞检测:
|
||||
- **伤害计算**:基于技能配置进行精确的伤害计算
|
||||
- **碰撞检测**:实现高效的2D碰撞检测机制
|
||||
- **效果触发**:支持多种技能效果类型的触发
|
||||
|
||||
**章节来源**
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/layer/SkillLayer.ts#L18-L48)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L10-L156)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L14-L236)
|
||||
|
||||
## 架构概览
|
||||
|
||||
SkillLayer系统采用了分层架构设计,实现了视图层与业务逻辑的完全分离:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 施法者
|
||||
participant SkillCon as 技能控制器
|
||||
participant SkillEnt as 技能实体
|
||||
participant SkillLayer as 技能图层
|
||||
participant AtkCon as 攻击组件
|
||||
participant Effect as 特效系统
|
||||
Player->>SkillCon : 发起技能请求
|
||||
SkillCon->>SkillEnt : 创建技能实体
|
||||
SkillEnt->>SkillLayer : 加载特效预制体
|
||||
SkillLayer->>Effect : 实例化特效节点
|
||||
Effect->>AtkCon : 初始化攻击组件
|
||||
AtkCon->>Effect : 播放特效动画
|
||||
Effect->>AtkCon : 触发碰撞检测
|
||||
AtkCon->>Effect : 销毁特效节点
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L50-L90)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L77)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/layer/SkillLayer.ts#L25-L35)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### SkillLayer节点组织结构
|
||||
|
||||
SkillLayer作为独立的渲染层级,其节点组织结构体现了高效的空间管理和渲染优化:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SkillLayer {
|
||||
-timer : Timer
|
||||
-light : Prefab
|
||||
+onLoad() : void
|
||||
+doSkill() : void
|
||||
+update(dt : number) : void
|
||||
+clear() : void
|
||||
}
|
||||
class EntityLayer {
|
||||
-timer : Timer
|
||||
+update(dt : number) : void
|
||||
+clear() : void
|
||||
}
|
||||
class MapViewScene {
|
||||
+camera : Camera
|
||||
+layer : Node
|
||||
+mapLayer : MapLayer
|
||||
+entityLayer : EntityLayer
|
||||
+SkillLayer : SkillLayer
|
||||
+isFollowPlayer : boolean
|
||||
}
|
||||
MapViewScene --> SkillLayer
|
||||
MapViewScene --> EntityLayer
|
||||
SkillLayer --|> Component
|
||||
EntityLayer --|> Component
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/layer/SkillLayer.ts#L18-L48)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L18-L37)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L15-L35)
|
||||
|
||||
SkillLayer的节点管理遵循以下原则:
|
||||
- **惰性加载**:仅在需要时创建特效节点
|
||||
- **批量清理**:定期清理无效的特效节点
|
||||
- **深度排序**:基于节点的Z轴位置进行自动排序
|
||||
|
||||
**章节来源**
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/layer/SkillLayer.ts#L1-L48)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L37)
|
||||
|
||||
### 技能生命周期管理
|
||||
|
||||
SkillLayer系统实现了完整的技能生命周期管理,确保特效的正确创建、播放和销毁:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([技能释放请求]) --> LoadPrefab[加载特效预制体]
|
||||
LoadPrefab --> InstantiateNode[实例化特效节点]
|
||||
InstantiateNode --> InitComponents[初始化组件]
|
||||
InitComponents --> SyncPosition[同步位置信息]
|
||||
SyncPosition --> PlayAnimation[播放特效动画]
|
||||
PlayAnimation --> CollisionCheck{碰撞检测}
|
||||
CollisionCheck --> |命中目标| ApplyDamage[应用伤害效果]
|
||||
CollisionCheck --> |未命中| ContinuePlay[继续播放]
|
||||
ApplyDamage --> CheckDuration{检查持续时间}
|
||||
ContinuePlay --> CheckDuration
|
||||
CheckDuration --> |达到上限| DestroyNode[销毁节点]
|
||||
CheckDuration --> |未达到| CollisionCheck
|
||||
DestroyNode --> CleanupResources[清理资源]
|
||||
CleanupResources --> End([生命周期结束])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L77)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L147-L186)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L50-L80)
|
||||
|
||||
**章节来源**
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L147-L186)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L50-L80)
|
||||
|
||||
### SkillViewCom与AtkConCom协作机制
|
||||
|
||||
SkillViewCom和AtkConCom通过紧密的协作确保技能特效与施法者位置的精确同步:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant SV as SkillViewCom
|
||||
participant AC as AtkConCom
|
||||
participant Hero as 施法者
|
||||
participant Target as 目标对象
|
||||
Hero->>SV : 更新施法者位置
|
||||
SV->>SV : 同步节点位置
|
||||
SV->>AC : 传递位置信息
|
||||
AC->>AC : 计算目标轨迹
|
||||
AC->>AC : 播放特效动画
|
||||
AC->>Target : 触发碰撞检测
|
||||
Target->>AC : 反馈碰撞结果
|
||||
AC->>AC : 应用伤害效果
|
||||
AC->>SV : 请求销毁节点
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L120-L156)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L120-L147)
|
||||
|
||||
这种协作机制的优势包括:
|
||||
- **实时同步**:确保特效始终跟随施法者移动
|
||||
- **精确控制**:支持复杂的运动轨迹计算
|
||||
- **高效通信**:通过组件间的消息传递实现解耦
|
||||
|
||||
**章节来源**
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L120-L156)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L120-L147)
|
||||
|
||||
### 粒子系统与Spine动画集成
|
||||
|
||||
SkillLayer系统支持多种特效类型的无缝集成:
|
||||
|
||||
| 特效类型 | 实现方式 | 性能特点 | 使用场景 |
|
||||
|---------|---------|---------|---------|
|
||||
| 粒子系统 | Cocos Particle System | 高性能,适合大规模效果 | 火焰、爆炸、魔法阵 |
|
||||
| Spine动画 | Spine Runtime | 中等性能,适合复杂骨骼动画 | 英雄技能、特殊效果 |
|
||||
| 2D精灵 | Sprite Animation | 低性能,适合简单动画 | 基础攻击特效 |
|
||||
| 着色器效果 | Shader Effects | 高性能,适合全局效果 | 光晕、扭曲、渐变 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L80-L147)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L58-L96)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
SkillLayer系统的依赖关系体现了清晰的分层架构:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "表现层"
|
||||
SkillLayer[SkillLayer]
|
||||
EntityLayer[EntityLayer]
|
||||
MapLayer[MapLayer]
|
||||
end
|
||||
subgraph "业务逻辑层"
|
||||
SkillEnt[SkillEnt]
|
||||
SkillViewCom[SkillViewCom]
|
||||
AtkConCom[AtkConCom]
|
||||
SkillConComp[SkillConComp]
|
||||
end
|
||||
subgraph "配置层"
|
||||
SkillSet[SkillSet]
|
||||
HeroAttrs[HeroAttrs]
|
||||
end
|
||||
subgraph "框架层"
|
||||
ECS[ECS框架]
|
||||
Oops[Oops框架]
|
||||
Cocos[Cocos引擎]
|
||||
end
|
||||
SkillLayer --> EntityLayer
|
||||
SkillLayer --> MapLayer
|
||||
SkillEnt --> SkillViewCom
|
||||
SkillViewCom --> AtkConCom
|
||||
SkillConComp --> SkillEnt
|
||||
SkillSet --> SkillViewCom
|
||||
SkillSet --> AtkConCom
|
||||
ECS --> SkillEnt
|
||||
ECS --> SkillViewCom
|
||||
ECS --> AtkConCom
|
||||
Oops --> SkillEnt
|
||||
Cocos --> SkillLayer
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/layer/SkillLayer.ts#L1-L15)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L10)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L1-L10)
|
||||
|
||||
**章节来源**
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/layer/SkillLayer.ts#L1-L15)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L10)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L1-L10)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
SkillLayer系统在设计时充分考虑了性能优化,特别是在高频技能释放场景下的内存管理:
|
||||
|
||||
### 内存波动管理策略
|
||||
|
||||
1. **资源预加载机制**
|
||||
- 在技能释放前预先加载特效资源
|
||||
- 使用对象池技术复用特效节点
|
||||
- 实现智能的资源卸载策略
|
||||
|
||||
2. **对象池管理**
|
||||
- 动态创建和回收特效节点
|
||||
- 避免频繁的垃圾回收操作
|
||||
- 优化内存分配和释放频率
|
||||
|
||||
3. **渲染优化**
|
||||
- 减少不必要的渲染调用
|
||||
- 实现高效的深度排序算法
|
||||
- 使用视锥剔除减少不可见对象的渲染
|
||||
|
||||
### 最佳实践建议
|
||||
|
||||
| 优化策略 | 实现方法 | 性能收益 | 适用场景 |
|
||||
|---------|---------|---------|---------|
|
||||
| 对象池复用 | 预先创建特效对象池 | 减少50%的内存分配 | 高频技能释放 |
|
||||
| 异步加载 | 技能释放前异步加载资源 | 提升首帧性能 | 大型特效资源 |
|
||||
| 分帧处理 | 将特效创建分散到多帧 | 避免卡顿 | 大量并发技能 |
|
||||
| 资源压缩 | 使用压缩格式存储特效资源 | 减少内存占用30% | 所有场景 |
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
1. **特效不显示或显示异常**
|
||||
- 检查SkillLayer是否正确添加到场景中
|
||||
- 验证特效预制体的加载路径是否正确
|
||||
- 确认特效节点的渲染层级设置
|
||||
|
||||
2. **技能特效与施法者不同步**
|
||||
- 检查SkillViewCom的位置同步逻辑
|
||||
- 验证AtkConCom的更新频率设置
|
||||
- 确认节点的父级变换矩阵
|
||||
|
||||
3. **内存泄漏问题**
|
||||
- 检查特效节点的销毁逻辑
|
||||
- 验证事件监听器的正确移除
|
||||
- 确认对象池的正确使用
|
||||
|
||||
**章节来源**
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L211-L235)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L140-L156)
|
||||
|
||||
## 结论
|
||||
|
||||
SkillLayer作为技能特效渲染的核心组件,成功实现了以下目标:
|
||||
|
||||
1. **架构优势**:采用ECS架构设计,实现了高度的模块化和可扩展性
|
||||
2. **性能优化**:通过对象池、异步加载等技术有效管理内存波动
|
||||
3. **功能完整性**:支持多种特效类型和复杂的技能效果
|
||||
4. **维护便利性**:清晰的职责分离使得系统易于维护和扩展
|
||||
|
||||
该系统为游戏提供了流畅的技能特效体验,同时为未来的功能扩展奠定了坚实的基础。通过合理的架构设计和性能优化策略,SkillLayer能够应对各种复杂的技能释放场景,确保游戏的高质量运行。
|
||||
269
.qoder/repowiki/zh/content/地图系统/地图视图/地图视图.md
Normal file
269
.qoder/repowiki/zh/content/地图系统/地图视图/地图视图.md
Normal file
@@ -0,0 +1,269 @@
|
||||
# 地图视图
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts)
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [map.json](file://assets/resources/config/map/map.json)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概述](#架构概述)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
本文档深入解析 `MapViewComp` 作为地图表现层的核心作用,涵盖地图预制体加载、地图图层管理(背景、实体、技能等)以及 UV 动画效果的实现。结合 `MapView.ts` 和 `MapViewScene.ts` 阐述地图场景的构建流程与节点组织结构。分析 `MapLayer.ts` 和 `EntityLayer.ts` 如何实现分层渲染与实体挂载。阐述 `MoveUV.ts` 实现的动态纹理偏移技术用于模拟地图流动效果。最后提供自定义地图视觉风格、添加新图层及优化渲染性能的实践指南。
|
||||
|
||||
## 项目结构
|
||||
项目结构清晰地将地图相关逻辑分离到 `assets/script/game/map/` 目录下,采用 MVC 模式组织代码。`model` 目录存放地图数据模型,`view` 目录存放视图组件和图层管理,`view/map/layer` 子目录进一步细化了不同图层的实现。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "地图系统"
|
||||
subgraph "模型层"
|
||||
MapModelComp[MapModelComp.ts]
|
||||
end
|
||||
subgraph "视图层"
|
||||
MapViewComp[MapViewComp.ts]
|
||||
MapViewScene[MapViewScene.ts]
|
||||
MoveUV[MoveUV.ts]
|
||||
subgraph "图层组件"
|
||||
MapLayer[MapLayer.ts]
|
||||
EntityLayer[EntityLayer.ts]
|
||||
SkillLayer[SkillLayer.ts]
|
||||
end
|
||||
end
|
||||
subgraph "控制层"
|
||||
GameMap[GameMap.ts]
|
||||
end
|
||||
end
|
||||
MapViewComp --> MapViewScene
|
||||
MapViewScene --> MapLayer
|
||||
MapViewScene --> EntityLayer
|
||||
MapViewScene --> SkillLayer
|
||||
MapViewComp --> MoveUV
|
||||
GameMap --> MapModelComp
|
||||
GameMap --> MapViewComp
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts)
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
|
||||
**Section sources**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts)
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
|
||||
## 核心组件
|
||||
`MapViewComp` 是地图表现层的核心组件,负责协调地图场景的初始化和生命周期管理。它通过 `MapViewScene` 组件访问各个地图图层,并在 `start` 方法中建立引用关系。`MapModelComp` 定义了地图的基本属性,如初始地图编号和地图显示预制体路径。`GameMap` 类作为 ECS 实体,整合了模型和视图组件,提供地图加载的入口方法。
|
||||
|
||||
**Section sources**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
|
||||
## 架构概述
|
||||
地图系统采用基于 ECS(Entity-Component-System)架构的设计模式,将地图数据(Model)、视图(View)和控制逻辑(Controller)分离。`GameMap` 实体持有 `MapModelComp` 和 `MapViewComp` 组件,实现了数据与表现的解耦。地图场景由 `MapViewScene` 组件管理,它通过属性装饰器关联了多个图层组件,包括 `MapLayer`(背景层)、`EntityLayer`(实体层)和 `SkillLayer`(技能层),形成了清晰的层次化结构。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class GameMap {
|
||||
+MapModel : MapModelComp
|
||||
+MapView : MapViewComp
|
||||
+load() : void
|
||||
}
|
||||
class MapModelComp {
|
||||
+id : number
|
||||
+resPrefab : string
|
||||
+reset() : void
|
||||
}
|
||||
class MapViewComp {
|
||||
+scene : MapViewScene
|
||||
+start() : void
|
||||
+update(dt : number) : void
|
||||
}
|
||||
class MapViewScene {
|
||||
+camera : Camera
|
||||
+mapLayer : MapLayer
|
||||
+entityLayer : EntityLayer
|
||||
+SkillLayer : SkillLayer
|
||||
+isFollowPlayer : boolean
|
||||
+ratio : Vec2
|
||||
+init() : void
|
||||
+update(dt : number) : void
|
||||
}
|
||||
class MapLayer {
|
||||
+bgImg : Sprite
|
||||
+init() : void
|
||||
+clear() : void
|
||||
+bgImage : Sprite
|
||||
+width : number
|
||||
+height : number
|
||||
}
|
||||
class EntityLayer {
|
||||
+timer : Timer
|
||||
+update(dt : number) : void
|
||||
+clear() : void
|
||||
}
|
||||
class SkillLayer {
|
||||
+light : Prefab
|
||||
+doSkill() : void
|
||||
+clear() : void
|
||||
}
|
||||
GameMap --> MapModelComp : "包含"
|
||||
GameMap --> MapViewComp : "包含"
|
||||
MapViewComp --> MapViewScene : "引用"
|
||||
MapViewScene --> MapLayer : "引用"
|
||||
MapViewScene --> EntityLayer : "引用"
|
||||
MapViewScene --> SkillLayer : "引用"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L47)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L48)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### MapViewComp 分析
|
||||
`MapViewComp` 组件作为地图视图的主控制器,负责地图场景的初始化和事件监听。在 `onLoad` 方法中,它可以监听全局事件,如角色添加或技能使用。`start` 方法中,它通过 `getComponent` 获取 `MapViewScene` 的引用,建立与地图场景的连接。该组件还包含一个 `Timer` 实例,可用于周期性任务的调度。
|
||||
|
||||
**Section sources**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
|
||||
### MapViewScene 分析
|
||||
`MapViewScene` 组件是地图场景的核心逻辑容器,它通过 Cocos Creator 的属性系统(`@property`)将场景中的各个节点和组件关联起来。这包括摄像机(`camera`)、背景层(`mapLayer`)、实体层(`entityLayer`)和技能层(`SkillLayer`)。`isFollowPlayer` 属性控制摄像机是否跟随玩家移动。`reset` 方法用于清理各个图层的状态,确保地图切换时的干净环境。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant LoadingView as LoadingViewComp
|
||||
participant GameMap as GameMap
|
||||
participant MapView as MapViewComp
|
||||
participant MapViewScene as MapViewScene
|
||||
LoadingView->>GameMap : map.load()
|
||||
GameMap->>Oops : oops.res.load(resPrefab)
|
||||
Oops-->>GameMap : Prefab
|
||||
GameMap->>GameMap : instantiate(res)
|
||||
GameMap->>GameMap : add(map.getChildByName("map").getComponent(MapViewComp))
|
||||
MapView->>MapView : start()
|
||||
MapView->>MapView : getComponent(MapViewScene)
|
||||
MapViewScene->>MapViewScene : 初始化各图层引用
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L1-L90)
|
||||
|
||||
### MapLayer 分析
|
||||
`MapLayer` 组件负责管理地图的背景图像。它通过 `@property(Sprite)` 装饰器引用一个 Sprite 组件(`bgImg`),用于显示地图背景。`init` 方法根据背景图的尺寸设置自身的宽高,`clear` 方法则用于清除当前的背景图片。`width` 和 `height` 属性通过访问 `bgImg` 的 `UITransform` 组件来获取实际尺寸。
|
||||
|
||||
**Section sources**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L47)
|
||||
|
||||
### EntityLayer 分析
|
||||
`EntityLayer` 组件管理地图上的所有游戏实体,如角色、怪物等。其 `update` 方法中包含一个定时器(`timer`),可用于定期执行深度排序等操作,以确保实体的正确渲染顺序。`clear` 方法遍历并清理所有子节点,为地图切换做准备。注释中提到深度排序可能成为性能瓶颈,建议在必要时优化为非每帧执行。
|
||||
|
||||
**Section sources**
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
|
||||
|
||||
### MoveUV 分析
|
||||
`MoveUV` 组件实现了动态纹理偏移效果,用于模拟水流、云层移动等视觉效果。它通过 `moveSpeedX` 和 `moveSpeedY` 属性控制纹理在 X 和 Y 方向上的移动速度。在 `update` 方法中,它获取 `Sprite` 组件的 `spriteFrame`,修改其 `rect` 的 `x` 和 `y` 值,从而实现 UV 坐标的偏移。`wrapMode` 属性确保纹理在边缘处重复,形成无缝滚动效果。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([MoveUV.update]) --> GetSprite["获取Sprite组件"]
|
||||
GetSprite --> CheckWrapMode{"WrapMode变化?"}
|
||||
CheckWrapMode --> |是| UpdateWrap["更新纹理WrapMode"]
|
||||
CheckWrapMode --> |否| UpdateRect["更新Rect坐标"]
|
||||
UpdateWrap --> UpdateRect
|
||||
UpdateRect --> ApplyRect["设置spriteFrame.rect"]
|
||||
ApplyRect --> MarkUpdate["标记渲染数据更新"]
|
||||
MarkUpdate --> End([结束])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L50)
|
||||
|
||||
## 依赖分析
|
||||
地图系统依赖于 Cocos Creator 引擎的核心模块(如 `cc`),以及项目中的 `oops-plugin-framework` 框架。`MapViewComp` 和 `MapViewScene` 依赖于 `oops` 对象进行资源加载和消息通信。`EntityLayer` 和 `SkillLayer` 依赖于框架中的 `Timer` 类。各图层组件之间通过 `MapViewScene` 进行协调,没有直接的相互依赖,保证了模块的独立性。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
MapViewComp --> oops[Oops Framework]
|
||||
MapViewScene --> oops
|
||||
EntityLayer --> Timer[Timer Class]
|
||||
SkillLayer --> Timer
|
||||
SkillLayer --> oops
|
||||
MapViewComp --> MapViewScene
|
||||
MapViewScene --> MapLayer
|
||||
MapViewScene --> EntityLayer
|
||||
MapViewScene --> SkillLayer
|
||||
GameMap --> MapModelComp
|
||||
GameMap --> MapViewComp
|
||||
GameMap --> oops
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L48)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
|
||||
**Section sources**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L48)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
|
||||
## 性能考虑
|
||||
- **深度排序**: `EntityLayer` 和 `SkillLayer` 中的每帧深度排序可能成为性能瓶颈,尤其是在实体数量众多时。建议根据实际需求,将排序频率降低(如每0.2秒一次)或采用空间分区等更高效的排序算法。
|
||||
- **纹理重复**: `MoveUV` 组件通过修改 `spriteFrame.rect` 来实现动画,这是一种轻量级的方法,避免了创建额外的动画帧,对性能友好。
|
||||
- **资源加载**: `GameMap.load()` 方法异步加载地图预制体,避免了主线程阻塞,保证了游戏的流畅性。
|
||||
- **节点清理**: `MapViewScene.reset()` 方法显式清理各图层的子节点,防止内存泄漏。
|
||||
|
||||
## 故障排除指南
|
||||
- **地图未显示**: 检查 `MapModelComp.resPrefab` 路径是否正确,确认预制体资源已正确导入。
|
||||
- **UV动画无效**: 确保应用 `MoveUV` 组件的精灵(Sprite)的纹理(Texture)Wrap Mode 设置为 `REPEAT`,否则偏移效果将不可见。
|
||||
- **实体层排序异常**: 如果发现实体渲染顺序错误,检查 `EntityLayer.update()` 中的排序逻辑是否被正确执行,或尝试调整 `Timer` 的间隔。
|
||||
- **摄像机不跟随**: 确认 `MapViewScene.isFollowPlayer` 属性已启用,并检查摄像机跟随的逻辑是否在其他地方被实现(当前代码中未找到具体实现)。
|
||||
|
||||
**Section sources**
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L50)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
|
||||
## 结论
|
||||
本项目中的地图视图系统设计清晰,采用 MVC 和 ECS 模式实现了良好的代码组织和可维护性。`MapViewComp` 和 `MapViewScene` 协同工作,构建了地图场景的骨架。通过 `MapLayer`、`EntityLayer` 和 `SkillLayer` 等组件实现了分层渲染,便于管理和优化。`MoveUV` 组件提供了一种简单有效的动态纹理动画方案。开发者可以基于此架构轻松扩展新功能,如添加新的图层类型或实现更复杂的地图特效。
|
||||
495
.qoder/repowiki/zh/content/地图系统/地图视图/地图视图控制.md
Normal file
495
.qoder/repowiki/zh/content/地图系统/地图视图/地图视图控制.md
Normal file
@@ -0,0 +1,495 @@
|
||||
# 地图视图控制
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [MapView.ts](file://assets/script/game/map/MapView.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [move.ts](file://assets/script/game/map/move.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
地图视图控制系统是Cocos Creator游戏引擎中负责地图渲染和用户交互的核心模块。该系统采用ECS(Entity-Component-System)架构模式,通过MapViewComp作为主要控制器,协调MapViewScene场景管理和各个视图层的渲染工作。系统实现了完整的地图生命周期管理,包括初始化、资源加载、事件监听、定时器管理等功能。
|
||||
|
||||
## 项目结构
|
||||
|
||||
地图视图控制系统的文件组织遵循清晰的层次结构:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "地图视图控制架构"
|
||||
GameMap["GameMap<br/>游戏地图实体"]
|
||||
MapViewComp["MapViewComp<br/>地图视图组件"]
|
||||
MapViewScene["MapViewScene<br/>地图场景逻辑"]
|
||||
subgraph "视图层"
|
||||
MapLayer["MapLayer<br/>地图背景层"]
|
||||
EntityLayer["EntityLayer<br/>实体层"]
|
||||
SkillLayer["SkillLayer<br/>技能特效层"]
|
||||
end
|
||||
subgraph "模型组件"
|
||||
MapModelComp["MapModelComp<br/>地图模型组件"]
|
||||
end
|
||||
subgraph "事件系统"
|
||||
GameEvent["GameEvent<br/>游戏事件定义"]
|
||||
end
|
||||
end
|
||||
GameMap --> MapViewComp
|
||||
MapViewComp --> MapViewScene
|
||||
MapViewScene --> MapLayer
|
||||
MapViewScene --> EntityLayer
|
||||
MapViewScene --> SkillLayer
|
||||
MapViewComp --> MapModelComp
|
||||
GameEvent --> MapViewComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
|
||||
**章节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### GameMap - 游戏地图实体
|
||||
|
||||
GameMap是地图系统的根实体,继承自ecs.Entity,负责管理地图的完整生命周期。它通过ECS框架注册为游戏实体,包含MapModelComp和MapViewComp两个核心组件。
|
||||
|
||||
### MapViewComp - 地图视图控制器
|
||||
|
||||
MapViewComp作为地图表现层的主要控制器,承担以下职责:
|
||||
- 初始化地图场景环境
|
||||
- 管理资源加载流程
|
||||
- 处理生命周期事件
|
||||
- 协调与其他组件的交互
|
||||
|
||||
### MapViewScene - 场景逻辑管理器
|
||||
|
||||
MapViewScene负责具体的场景逻辑实现,包括:
|
||||
- 摄像机跟随逻辑
|
||||
- 层级结构管理
|
||||
- 场景状态控制
|
||||
- 更新循环处理
|
||||
|
||||
**章节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L15-L36)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L12-L45)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L15-L77)
|
||||
|
||||
## 架构概览
|
||||
|
||||
地图视图控制系统采用分层架构设计,确保了良好的模块化和可维护性:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant GM as GameMap
|
||||
participant MC as MapViewComp
|
||||
participant MS as MapViewScene
|
||||
participant ML as MapLayer
|
||||
participant EL as EntityLayer
|
||||
participant SL as SkillLayer
|
||||
GM->>MC : 创建地图实体
|
||||
MC->>MS : 获取场景组件
|
||||
MS->>ML : 初始化地图层
|
||||
MS->>EL : 初始化实体层
|
||||
MS->>SL : 初始化技能层
|
||||
MC->>MC : 启动事件监听
|
||||
MC->>MC : 启动定时器
|
||||
loop 游戏更新循环
|
||||
MC->>MS : 更新场景状态
|
||||
MS->>ML : 更新地图渲染
|
||||
MS->>EL : 更新实体渲染
|
||||
MS->>SL : 更新技能渲染
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L25-L36)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L28-L32)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L42-L77)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### MapViewComp - 地图视图控制器详解
|
||||
|
||||
MapViewComp是地图系统的核心控制器,实现了完整的生命周期管理和事件处理机制。
|
||||
|
||||
#### 生命周期管理
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([组件启动]) --> OnLoad["onLoad()<br/>监听全局事件"]
|
||||
OnLoad --> Start["start()<br/>获取场景实例"]
|
||||
Start --> InitScene["初始化场景<br/>scene = getComponent(MapViewScene)"]
|
||||
InitScene --> LoadData["load_data()<br/>加载数据"]
|
||||
LoadData --> UpdateLoop["update()<br/>主更新循环"]
|
||||
UpdateLoop --> Reset["reset()<br/>清理资源"]
|
||||
Reset --> End([组件销毁])
|
||||
UpdateLoop --> TimerCheck{"定时器检查"}
|
||||
TimerCheck --> |触发| TimerAction["执行定时任务"]
|
||||
TimerAction --> UpdateLoop
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L18-L45)
|
||||
|
||||
#### 事件监听与定时器管理
|
||||
|
||||
MapViewComp内部集成了Timer类来管理游戏定时器,提供了灵活的时间控制机制:
|
||||
|
||||
- **game_timer**: 主要游戏定时器,间隔为1秒
|
||||
- **EntityLayer.timer**: 实体层级定时器,间隔为0.2秒
|
||||
- **SkillLayer.timer**: 技能特效定时器,间隔为0.2秒
|
||||
|
||||
#### 资源加载机制
|
||||
|
||||
系统通过GameMap实体的load方法实现地图资源的异步加载:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant GM as GameMap
|
||||
participant OOPS as Oops资源系统
|
||||
participant Prefab as 地图预制件
|
||||
participant MC as MapViewComp
|
||||
GM->>OOPS : 加载地图资源
|
||||
OOPS->>Prefab : 获取地图预制件
|
||||
Prefab->>GM : 返回实例化对象
|
||||
GM->>MC : 添加地图视图组件
|
||||
MC->>MC : 初始化组件状态
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L25-L36)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L28-L32)
|
||||
|
||||
**章节来源**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L12-L45)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L25-L36)
|
||||
|
||||
### MapViewScene - 场景逻辑管理器
|
||||
|
||||
MapViewScene负责具体的场景逻辑实现,是地图渲染的核心调度器。
|
||||
|
||||
#### 场景节点结构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MapViewScene {
|
||||
+Camera camera
|
||||
+Node layer
|
||||
+MapLayer mapLayer
|
||||
+Node floorLayer
|
||||
+EntityLayer entityLayer
|
||||
+SkillLayer SkillLayer
|
||||
+boolean isFollowPlayer
|
||||
+Vec2 ratio
|
||||
+onLoad() void
|
||||
+start() void
|
||||
+init() void
|
||||
+update(dt) void
|
||||
+reset() void
|
||||
+clear() void
|
||||
}
|
||||
class MapLayer {
|
||||
+Sprite bgImg
|
||||
+init() void
|
||||
+clear() void
|
||||
+width() number
|
||||
+height() number
|
||||
}
|
||||
class EntityLayer {
|
||||
+Timer timer
|
||||
+update(dt) void
|
||||
+clear() void
|
||||
}
|
||||
class SkillLayer {
|
||||
+Prefab light
|
||||
+Timer timer
|
||||
+onLoad() void
|
||||
+doSkill() void
|
||||
+update(dt) void
|
||||
+clear() void
|
||||
}
|
||||
MapViewScene --> MapLayer : "管理"
|
||||
MapViewScene --> EntityLayer : "管理"
|
||||
MapViewScene --> SkillLayer : "管理"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L15-L77)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L15-L47)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L18-L39)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L18-L48)
|
||||
|
||||
#### 摄像机跟随逻辑
|
||||
|
||||
MapViewScene实现了摄像机跟随玩家的功能,通过isFollowPlayer属性控制:
|
||||
|
||||
- **启用跟随**: 当isFollowPlayer为true时,摄像机会根据玩家位置自动调整
|
||||
- **比例转换**: 使用ratio属性在2D坐标和3D坐标之间进行转换
|
||||
- **平滑移动**: 通过update方法实现摄像机的平滑跟随效果
|
||||
|
||||
#### 层级管理
|
||||
|
||||
系统采用分层渲染架构,每一层都有特定的职责:
|
||||
|
||||
1. **floorLayer**: 地面层,负责地形和背景元素
|
||||
2. **entityLayer**: 实体层,负责游戏角色和物体
|
||||
3. **SkillLayer**: 技能特效层,负责技能动画和特效
|
||||
4. **mapLayer**: 地图背景层,负责静态地图纹理
|
||||
|
||||
**章节来源**
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L15-L77)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L15-L47)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L18-L39)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L18-L48)
|
||||
|
||||
### 视图层组件详解
|
||||
|
||||
#### MapLayer - 地图背景层
|
||||
|
||||
MapLayer专门负责地图背景的渲染和管理:
|
||||
|
||||
- **背景图片管理**: 通过bgImg属性管理地图背景精灵
|
||||
- **尺寸控制**: 提供width和height属性控制地图尺寸
|
||||
- **清理功能**: clear方法用于清除背景图片
|
||||
|
||||
#### EntityLayer - 实体层
|
||||
|
||||
EntityLayer负责游戏实体的渲染和管理:
|
||||
|
||||
- **深度排序**: 通过zIndexSort方法对实体进行深度排序
|
||||
- **定时更新**: 使用Timer进行定期的实体状态更新
|
||||
- **性能优化**: 可配置的更新频率以平衡性能和效果
|
||||
|
||||
#### SkillLayer - 技能特效层
|
||||
|
||||
SkillLayer专门处理技能特效和动画:
|
||||
|
||||
- **特效预制件**: 通过light属性管理技能特效预制件
|
||||
- **事件响应**: 响应技能使用事件播放特效
|
||||
- **清理机制**: 提供clear方法清理所有特效对象
|
||||
|
||||
**章节来源**
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L15-L47)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L18-L39)
|
||||
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L18-L48)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
地图视图控制系统的依赖关系体现了清晰的分层架构:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "外部依赖"
|
||||
Cocos["Cocos Creator Engine"]
|
||||
Oops["Oops Framework"]
|
||||
ECS["ECS Framework"]
|
||||
end
|
||||
subgraph "核心组件"
|
||||
GameMap["GameMap"]
|
||||
MapViewComp["MapViewComp"]
|
||||
MapViewScene["MapViewScene"]
|
||||
end
|
||||
subgraph "视图层"
|
||||
MapLayer["MapLayer"]
|
||||
EntityLayer["EntityLayer"]
|
||||
SkillLayer["SkillLayer"]
|
||||
end
|
||||
subgraph "模型组件"
|
||||
MapModelComp["MapModelComp"]
|
||||
end
|
||||
subgraph "工具类"
|
||||
Timer["Timer"]
|
||||
GameEvent["GameEvent"]
|
||||
end
|
||||
Cocos --> GameMap
|
||||
Oops --> GameMap
|
||||
ECS --> GameMap
|
||||
GameMap --> MapViewComp
|
||||
MapViewComp --> MapViewScene
|
||||
MapViewScene --> MapLayer
|
||||
MapViewScene --> EntityLayer
|
||||
MapViewScene --> SkillLayer
|
||||
GameMap --> MapModelComp
|
||||
MapViewComp --> Timer
|
||||
MapViewComp --> GameEvent
|
||||
EntityLayer --> Timer
|
||||
SkillLayer --> Timer
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L10)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L11)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L10)
|
||||
|
||||
### 组件间通信
|
||||
|
||||
系统通过多种方式实现组件间的通信:
|
||||
|
||||
1. **事件系统**: 使用oops.message进行全局事件通信
|
||||
2. **组件引用**: 通过getComponent方法直接访问其他组件
|
||||
3. **实体管理**: 通过ecs.Entity管理组件关系
|
||||
4. **配置共享**: 通过SingletonModuleComp共享配置数据
|
||||
|
||||
**章节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 内存管理
|
||||
|
||||
系统在多个层面实现了内存优化:
|
||||
|
||||
1. **组件复用**: 通过ECS框架实现组件的高效复用
|
||||
2. **延迟加载**: 地图资源采用异步加载策略
|
||||
3. **及时清理**: 在reset方法中清理不再需要的对象引用
|
||||
4. **定时器管理**: 合理配置定时器间隔避免过度计算
|
||||
|
||||
### 渲染优化
|
||||
|
||||
- **分层渲染**: 通过不同层级减少不必要的渲染计算
|
||||
- **批量操作**: 使用removeAllChildren等批量方法提高效率
|
||||
- **条件更新**: update方法中仅在必要时执行更新逻辑
|
||||
|
||||
### 事件处理优化
|
||||
|
||||
- **事件去重**: 避免重复监听相同事件
|
||||
- **及时解绑**: 在组件销毁时及时移除事件监听器
|
||||
- **弱引用**: 使用弱引用避免循环引用导致的内存泄漏
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 资源未释放问题
|
||||
|
||||
**问题描述**: 地图切换或重新加载时出现内存泄漏
|
||||
|
||||
**解决方案**:
|
||||
1. 在reset方法中添加资源清理逻辑
|
||||
2. 确保所有事件监听器都被正确移除
|
||||
3. 使用Timer的stop方法停止定时器
|
||||
|
||||
```typescript
|
||||
// 示例清理代码
|
||||
reset(): void {
|
||||
// 清理事件监听
|
||||
oops.message.offAll(this);
|
||||
|
||||
// 清理定时器
|
||||
this.game_timer.stop();
|
||||
|
||||
// 清理场景资源
|
||||
if (this.scene) {
|
||||
this.scene.reset();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 事件重复监听问题
|
||||
|
||||
**问题描述**: 地图多次加载导致事件监听器重复绑定
|
||||
|
||||
**解决方案**:
|
||||
1. 在onLoad方法中添加事件监听前的检查
|
||||
2. 使用唯一标识符管理事件监听器
|
||||
3. 在组件销毁时确保所有监听器被移除
|
||||
|
||||
```typescript
|
||||
// 示例事件监听解决方案
|
||||
async onLoad(){
|
||||
// 检查是否已存在监听器
|
||||
if (!this.eventListeners) {
|
||||
this.eventListeners = new Set();
|
||||
this.setupEventListeners();
|
||||
}
|
||||
}
|
||||
|
||||
setupEventListeners(): void {
|
||||
const events = [
|
||||
GameEvent.MAP_MOVE_END_LEFT,
|
||||
GameEvent.MAP_MOVE_END_RIGHT
|
||||
];
|
||||
|
||||
events.forEach(event => {
|
||||
oops.message.on(event, this.handleEvent, this);
|
||||
this.eventListeners.add(event);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### 定时器管理问题
|
||||
|
||||
**问题描述**: 定时器未正确停止导致持续运行
|
||||
|
||||
**解决方案**:
|
||||
1. 在组件销毁时停止所有定时器
|
||||
2. 使用try-catch块保护定时器操作
|
||||
3. 提供定时器状态检查方法
|
||||
|
||||
```typescript
|
||||
// 示例定时器管理
|
||||
class MapViewComp extends CCComp {
|
||||
private timers: Timer[] = [];
|
||||
|
||||
createTimer(interval: number): Timer {
|
||||
const timer = new Timer(interval);
|
||||
this.timers.push(timer);
|
||||
return timer;
|
||||
}
|
||||
|
||||
onDestroy(): void {
|
||||
// 停止所有定时器
|
||||
this.timers.forEach(timer => timer.stop());
|
||||
this.timers = [];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 调试技巧
|
||||
|
||||
1. **日志记录**: 在关键方法中添加调试日志
|
||||
2. **状态检查**: 定期检查组件状态的一致性
|
||||
3. **性能监控**: 使用Cocos Creator的性能分析工具
|
||||
4. **单元测试**: 为关键功能编写单元测试
|
||||
|
||||
**章节来源**
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L25-L30)
|
||||
- [move.ts](file://assets/script/game/map/move.ts#L18-L25)
|
||||
|
||||
## 结论
|
||||
|
||||
地图视图控制系统展现了现代游戏开发中优秀的架构设计原则。通过ECS模式的应用,系统实现了高度的模块化和可扩展性。MapViewComp作为核心控制器,有效协调了场景逻辑、视图渲染和用户交互之间的关系。
|
||||
|
||||
系统的主要优势包括:
|
||||
|
||||
1. **清晰的分层架构**: 从实体到组件再到视图层的清晰分离
|
||||
2. **灵活的生命周期管理**: 完整的组件生命周期支持
|
||||
3. **高效的资源管理**: 异步加载和及时清理机制
|
||||
4. **强大的事件系统**: 基于消息传递的松耦合通信
|
||||
5. **完善的错误处理**: 全面的资源清理和异常处理机制
|
||||
|
||||
对于开发者而言,理解和掌握这套系统的设计理念和实现细节,有助于构建更加稳定和高性能的游戏应用。同时,系统提供的故障排除指南和最佳实践,为后续的维护和扩展奠定了坚实的基础。
|
||||
300
.qoder/repowiki/zh/content/地图系统/地图视图/地图视觉特效.md
Normal file
300
.qoder/repowiki/zh/content/地图系统/地图视图/地图视觉特效.md
Normal file
@@ -0,0 +1,300 @@
|
||||
# 地图视觉特效
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts)
|
||||
- [light.ts](file://assets/script/game/map/view/map/layer/light.ts)
|
||||
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
MoveUV组件是Cocos Creator游戏引擎中用于实现动态纹理滚动效果的核心组件。它通过动态修改SpriteFrame的rect偏移量,实现了流畅的纹理动画效果,广泛应用于模拟水流、移动地面、动态背景等视觉特效。该组件提供了灵活的速度控制和纹理包装模式设置,支持多种动画效果的实现。
|
||||
|
||||
## 项目结构
|
||||
|
||||
MoveUV组件位于地图视图模块中,与其他地图相关组件协同工作,形成完整的地图渲染系统。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "地图视图模块"
|
||||
MoveUV["MoveUV组件<br/>纹理滚动控制器"]
|
||||
MapLayer["MapLayer<br/>地图背景层"]
|
||||
EntityLayer["EntityLayer<br/>实体对象层"]
|
||||
Light["light<br/>光照效果"]
|
||||
end
|
||||
subgraph "地图模型"
|
||||
GameMap["GameMap<br/>游戏地图实体"]
|
||||
MapModel["MapModelComp<br/>地图模型组件"]
|
||||
end
|
||||
subgraph "渲染系统"
|
||||
Sprite["Sprite组件<br/>精灵渲染器"]
|
||||
SpriteFrame["SpriteFrame<br/>精灵帧"]
|
||||
Texture2D["Texture2D<br/>纹理资源"]
|
||||
end
|
||||
GameMap --> MapModel
|
||||
GameMap --> MoveUV
|
||||
MoveUV --> Sprite
|
||||
Sprite --> SpriteFrame
|
||||
SpriteFrame --> Texture2D
|
||||
MapLayer --> Sprite
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L50)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L47)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35)
|
||||
|
||||
**章节来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L50)
|
||||
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L47)
|
||||
|
||||
## 核心组件
|
||||
|
||||
MoveUV组件是一个专门负责纹理滚动动画的脚本组件,具有以下核心特性:
|
||||
|
||||
### 主要功能特性
|
||||
- **动态UV坐标控制**:通过修改SpriteFrame的rect属性实现纹理偏移
|
||||
- **双轴速度控制**:独立控制X轴和Y轴的滚动速度
|
||||
- **多种包装模式**:支持REPEAT、MIRRORED_REPEAT、CLAMP_TO_EDGE等纹理包装方式
|
||||
- **高效渲染优化**:仅在必要时标记渲染数据更新,避免不必要的重绘
|
||||
|
||||
### 核心属性配置
|
||||
- `moveSpeedX`:X轴方向的滚动速度,正值向右,负值向左
|
||||
- `moveSpeedY`:Y轴方向的滚动速度,正值向上,负值向下
|
||||
- `wrapMode`:纹理包装模式,决定纹理超出边界时的行为
|
||||
|
||||
**章节来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L8-L15)
|
||||
|
||||
## 架构概览
|
||||
|
||||
MoveUV组件采用组件化设计,与Cocos Creator的渲染管线紧密集成,形成了高效的纹理动画系统。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Scene as "场景初始化"
|
||||
participant MoveUV as "MoveUV组件"
|
||||
participant Sprite as "Sprite组件"
|
||||
participant Render as "渲染系统"
|
||||
Scene->>MoveUV : onLoad()
|
||||
MoveUV->>Sprite : 获取Sprite组件
|
||||
Sprite-->>MoveUV : 返回Sprite实例
|
||||
MoveUV->>MoveUV : 初始化_rect变量
|
||||
MoveUV->>Sprite : 设置packable=false
|
||||
loop 每帧更新
|
||||
Scene->>MoveUV : update(dt)
|
||||
MoveUV->>MoveUV : 检查wrapMode变化
|
||||
MoveUV->>Sprite : 更新_rect坐标
|
||||
MoveUV->>Sprite : markForUpdateRenderData()
|
||||
Sprite->>Render : 触发渲染更新
|
||||
Render-->>Scene : 显示更新后的纹理
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L25-L49)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### MoveUV组件核心实现
|
||||
|
||||
MoveUV组件通过精确控制SpriteFrame的rect属性来实现纹理滚动效果,其核心算法如下:
|
||||
|
||||
#### 初始化阶段(onLoad)
|
||||
|
||||
组件在加载时执行以下初始化操作:
|
||||
|
||||
1. **组件获取验证**:确保当前节点包含有效的Sprite组件
|
||||
2. **初始状态设置**:复制原始SpriteFrame的rect作为起始坐标
|
||||
3. **性能优化配置**:禁用spriteFrame的packable属性以提高渲染效率
|
||||
|
||||
#### 动画更新机制(update)
|
||||
|
||||
每帧更新过程包含以下关键步骤:
|
||||
|
||||
1. **包装模式检查**:比较当前wrapMode与上次记录值,如有变化则更新纹理设置
|
||||
2. **UV坐标计算**:基于移动速度和时间增量计算新的坐标位置
|
||||
3. **渲染数据标记**:通知渲染系统更新纹理数据
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([update函数开始]) --> CheckWrapMode["检查wrapMode变化"]
|
||||
CheckWrapMode --> WrapChanged{"包装模式改变?"}
|
||||
WrapChanged --> |是| UpdateWrapMode["更新纹理包装模式"]
|
||||
WrapChanged --> |否| SkipWrap["跳过包装模式更新"]
|
||||
UpdateWrapMode --> CalcNewPos["计算新UV坐标<br/>x += moveSpeedX * dt<br/>y += moveSpeedY * dt"]
|
||||
SkipWrap --> CalcNewPos
|
||||
CalcNewPos --> UpdateRect["更新SpriteFrame.rect"]
|
||||
UpdateRect --> MarkRender["markForUpdateRenderData()"]
|
||||
MarkRender --> End([update函数结束])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L35-L49)
|
||||
|
||||
**章节来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L25-L49)
|
||||
|
||||
### 纹理包装模式详解
|
||||
|
||||
MoveUV组件支持三种主要的纹理包装模式,每种模式对应不同的视觉效果:
|
||||
|
||||
| 包装模式 | 值 | 视觉效果 | 应用场景 |
|
||||
|---------|---|---------|---------|
|
||||
| REPEAT | 1001 | 纹理重复平铺 | 流水、地面移动、背景循环 |
|
||||
| MIRRORED_REPEAT | 1002 | 镜像重复平铺 | 对称动画、特殊效果 |
|
||||
| CLAMP_TO_EDGE | 1000 | 边缘拉伸 | 单次动画、边缘处理 |
|
||||
|
||||
#### REPEAT模式的工作原理
|
||||
|
||||
当wrapMode设置为REPEAT时,纹理会在超出边界时自动重复平铺。MoveUV组件通过不断修改rect的x和y坐标,创造出无限循环的滚动效果:
|
||||
|
||||
- **水平滚动**:通过增加rect.x值实现从左到右的滚动
|
||||
- **垂直滚动**:通过增加rect.y值实现从下到上的滚动
|
||||
- **循环无缝**:由于REPEAT模式的存在,当纹理到达边界时会自动重新开始
|
||||
|
||||
**章节来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L13-L15)
|
||||
|
||||
### 性能优化策略
|
||||
|
||||
MoveUV组件采用了多项性能优化措施:
|
||||
|
||||
#### 渲染数据更新优化
|
||||
- **条件性标记**:仅在必要时调用`markForUpdateRenderData()`,避免频繁的渲染更新
|
||||
- **包装模式缓存**:通过`_currentWrapMode`变量避免重复设置相同的包装模式
|
||||
- **最小化操作**:每次更新只修改必要的rect坐标,减少计算开销
|
||||
|
||||
#### 内存管理优化
|
||||
- **packable禁用**:设置spriteFrame.packable为false,防止不必要的内存分配
|
||||
- **局部变量复用**:使用预定义的_rect变量,避免频繁的对象创建
|
||||
|
||||
**章节来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L30-L32)
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L47-L49)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
MoveUV组件与多个系统和组件存在密切的依赖关系:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "外部依赖"
|
||||
CC["Cocos Creator引擎"]
|
||||
Texture2D["Texture2D类"]
|
||||
Sprite["Sprite组件"]
|
||||
Rect["rect工具函数"]
|
||||
end
|
||||
subgraph "内部组件"
|
||||
MoveUV["MoveUV组件"]
|
||||
MapLayer["MapLayer地图层"]
|
||||
EntityLayer["EntityLayer实体层"]
|
||||
end
|
||||
CC --> Texture2D
|
||||
CC --> Sprite
|
||||
CC --> Rect
|
||||
MoveUV --> Texture2D
|
||||
MoveUV --> Sprite
|
||||
MoveUV --> Rect
|
||||
MapLayer --> MoveUV
|
||||
EntityLayer --> MoveUV
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L7)
|
||||
|
||||
### 关键依赖说明
|
||||
|
||||
1. **Cocos Creator引擎**:MoveUV组件依赖于引擎提供的核心功能
|
||||
2. **Texture2D类**:用于设置纹理的包装模式
|
||||
3. **Sprite组件**:作为MoveUV的目标渲染对象
|
||||
4. **rect工具**:提供矩形区域的创建和操作功能
|
||||
|
||||
**章节来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L7)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 渲染性能优化
|
||||
|
||||
MoveUV组件的设计充分考虑了渲染性能,采用了以下优化策略:
|
||||
|
||||
#### 减少渲染调用
|
||||
- **批量更新**:通过`markForUpdateRenderData()`统一标记渲染更新
|
||||
- **条件检查**:只有在包装模式发生变化时才更新纹理设置
|
||||
- **最小化操作**:每次更新只修改必要的rect坐标
|
||||
|
||||
#### 内存使用优化
|
||||
- **对象复用**:使用预定义的rect对象避免频繁创建
|
||||
- **资源管理**:正确设置spriteFrame的packable属性
|
||||
|
||||
### 性能监控建议
|
||||
|
||||
为了确保最佳性能,建议开发者注意以下几点:
|
||||
|
||||
1. **避免频繁切换包装模式**:包装模式的切换会触发额外的GPU操作
|
||||
2. **合理设置移动速度**:过高的速度可能导致视觉效果不自然
|
||||
3. **监控渲染调用频率**:确保不会出现过度的渲染更新
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 1. 纹理滚动不生效
|
||||
**可能原因**:
|
||||
- Sprite组件未正确添加到节点
|
||||
- MoveUV组件未正确挂载
|
||||
- 纹理资源未正确设置
|
||||
|
||||
**解决方案**:
|
||||
- 检查节点是否包含Sprite组件
|
||||
- 验证MoveUV组件已正确挂载
|
||||
- 确认纹理资源已正确加载
|
||||
|
||||
#### 2. 包装模式设置无效
|
||||
**可能原因**:
|
||||
- wrapMode属性值设置错误
|
||||
- 纹理格式不支持特定包装模式
|
||||
|
||||
**解决方案**:
|
||||
- 使用正确的枚举值(REPEAT、MIRRORED_REPEAT、CLAMP_TO_EDGE)
|
||||
- 检查纹理格式兼容性
|
||||
|
||||
#### 3. 性能问题
|
||||
**可能原因**:
|
||||
- 频繁的渲染数据更新
|
||||
- 不当的移动速度设置
|
||||
|
||||
**解决方案**:
|
||||
- 优化移动速度设置
|
||||
- 减少不必要的组件更新
|
||||
|
||||
**章节来源**
|
||||
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L26-L32)
|
||||
|
||||
## 结论
|
||||
|
||||
MoveUV组件是一个设计精良的地图视觉特效组件,通过巧妙地利用Cocos Creator的SpriteFrame系统,实现了高效且灵活的纹理滚动效果。其核心优势包括:
|
||||
|
||||
1. **简洁的API设计**:通过简单的属性配置即可实现复杂的动画效果
|
||||
2. **优秀的性能表现**:采用多种优化策略,确保流畅的运行性能
|
||||
3. **灵活的效果控制**:支持多种包装模式和速度配置
|
||||
4. **良好的集成性**:与Cocos Creator生态系统完美融合
|
||||
|
||||
该组件为游戏开发中的动态背景、流水效果、移动地面等视觉需求提供了标准化的解决方案,是地图视觉特效开发的重要工具。开发者可以基于MoveUV组件快速实现各种创意性的纹理动画效果,同时保持良好的性能表现。
|
||||
490
.qoder/repowiki/zh/content/地图系统/怪物系统/属性系统.md
Normal file
490
.qoder/repowiki/zh/content/地图系统/怪物系统/属性系统.md
Normal file
@@ -0,0 +1,490 @@
|
||||
# 属性系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
英雄属性系统是游戏战斗机制的核心组成部分,负责管理角色的基础属性、动态计算和战斗中的属性变化。该系统通过strengthMultiplier强度倍率实现了基于配置数据的动态属性缩放机制,支持HP、AP、DEF、SPEED等基础属性的精确计算,并提供了完整的buff/debuff管理系统。
|
||||
|
||||
系统采用模块化设计,将属性定义、计算逻辑、配置管理和运行时控制分离,确保了良好的可维护性和扩展性。通过HeroAttrs.ts中的getAttrs与getNeAttrs函数,系统建立了完整的属性容器构建逻辑,支持英雄和怪物的统一属性管理。
|
||||
|
||||
## 项目结构
|
||||
|
||||
属性系统的核心文件分布在以下目录结构中:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
A[HeroAttrs.ts] --> B[属性枚举定义]
|
||||
A --> C[属性类型配置]
|
||||
A --> D[职业成长配置]
|
||||
E[heroSet.ts] --> F[英雄配置数据]
|
||||
E --> G[怪物配置数据]
|
||||
end
|
||||
subgraph "实体层"
|
||||
H[Hero.ts] --> I[英雄实体]
|
||||
J[Mon.ts] --> K[怪物实体]
|
||||
end
|
||||
subgraph "视图层"
|
||||
L[HeroViewComp.ts] --> M[属性计算引擎]
|
||||
L --> N[Buff系统]
|
||||
L --> O[负面状态管理]
|
||||
end
|
||||
A --> L
|
||||
E --> H
|
||||
E --> J
|
||||
H --> L
|
||||
J --> L
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L546)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L152)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L780)
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L100)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L50)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 属性枚举系统
|
||||
|
||||
属性系统定义了完整的属性分类体系,涵盖基础生存、攻击、防御、特殊效果等多个维度:
|
||||
|
||||
| 属性类别 | 属性名称 | 类型 | 描述 |
|
||||
|---------|---------|------|------|
|
||||
| 基础生存 | HP_MAX | 数值型 | 最大生命值 |
|
||||
| 基础生存 | MP_MAX | 数值型 | 最大魔法值 |
|
||||
| 攻击属性 | AP | 数值型 | 攻击力 |
|
||||
| 攻击属性 | MAP | 数值型 | 魔法攻击力 |
|
||||
| 防御属性 | DEF | 数值型 | 物理防御 |
|
||||
| 防御属性 | MDEF | 数值型 | 魔法防御 |
|
||||
| 特殊效果 | SPEED | 百分比型 | 移动速度加成 |
|
||||
| 特殊效果 | CRITICAL | 百分比型 | 暴击率 |
|
||||
|
||||
### Buff类型系统
|
||||
|
||||
系统支持两种类型的Buff效果:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class BType {
|
||||
+VALUE : 0
|
||||
+RATIO : 1
|
||||
}
|
||||
class BuffInstance {
|
||||
+number value
|
||||
+BType BType
|
||||
+number remainTime
|
||||
}
|
||||
class HeroViewComp {
|
||||
+Record~number, Array~ BUFFS
|
||||
+Record~number, Array~ BUFFS_TEMP
|
||||
+recalculateSingleAttr(attrIndex)
|
||||
+addBuff(buffConf)
|
||||
+clearBuffs(attrIndex, isBuff)
|
||||
}
|
||||
HeroViewComp --> BuffInstance
|
||||
BuffInstance --> BType
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L5-L15)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L95-L110)
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L20-L100)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L72-L120)
|
||||
|
||||
## 架构概览
|
||||
|
||||
属性系统采用分层架构设计,实现了清晰的职责分离:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[配置层] --> B[计算层]
|
||||
B --> C[运行时层]
|
||||
C --> D[渲染层]
|
||||
A1[属性枚举] --> A
|
||||
A2[职业配置] --> A
|
||||
A3[Buff配置] --> A
|
||||
B1[属性计算] --> B
|
||||
B2[强度倍率] --> B
|
||||
B3[成长曲线] --> B
|
||||
C1[属性容器] --> C
|
||||
C2[Buff系统] --> C
|
||||
C3[负面状态] --> C
|
||||
D1[视觉效果] --> D
|
||||
D2[伤害显示] --> D
|
||||
D3[状态提示] --> D
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L546)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L780)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### hero_init方法中的强度倍率计算
|
||||
|
||||
hero_init方法是属性系统的核心入口,负责根据strengthMultiplier强度倍率进行动态属性计算:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 客户端
|
||||
participant Mon as Monster
|
||||
participant Hero as Hero
|
||||
participant Calc as 属性计算器
|
||||
participant View as HeroViewComp
|
||||
Client->>Mon : hero_init(strengthMultiplier)
|
||||
Mon->>Calc : 计算基础属性
|
||||
Calc->>Calc : baseHp = hero.hp * strengthMultiplier
|
||||
Calc->>Calc : baseAp = hero.ap * strengthMultiplier
|
||||
Calc->>Calc : baseDef = hero.def * strengthMultiplier
|
||||
Mon->>View : 初始化属性容器
|
||||
View->>View : getAttrs()
|
||||
View->>View : getNeAttrs()
|
||||
View->>View : 设置基础属性
|
||||
View->>View : initAttrs()
|
||||
View-->>Client : 属性初始化完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L61-L108)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L65-L100)
|
||||
|
||||
#### 强度倍率的应用机制
|
||||
|
||||
强度倍率通过以下方式影响属性计算:
|
||||
|
||||
1. **基础属性缩放**:`baseHp = hero.hp * strengthMultiplier`
|
||||
2. **攻击力调整**:`baseAp = hero.ap * strengthMultiplier`
|
||||
3. **防御力计算**:`baseDef = hero.def * strengthMultiplier`
|
||||
|
||||
这种设计允许系统根据关卡进度、难度系数等因素动态调整怪物强度,而无需修改英雄配置数据。
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L61-L108)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L65-L100)
|
||||
|
||||
### hv.Attrs与hv.NeAttrs属性系统
|
||||
|
||||
#### 属性容器初始化流程
|
||||
|
||||
属性容器的初始化遵循严格的步骤序列:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始初始化] --> B[清空现有Buff]
|
||||
B --> C[获取英雄配置]
|
||||
C --> D[重置基础属性]
|
||||
D --> E[初始化其他属性]
|
||||
E --> F[加载初始Buff]
|
||||
F --> G[属性计算引擎就绪]
|
||||
D1[Attrs.HP_MAX = base_hp] --> D
|
||||
D2[Attrs.MP_MAX = base_mp] --> D
|
||||
D3[Attrs.DEF = base_def] --> D
|
||||
D4[Attrs.AP = base_ap] --> D
|
||||
D5[Attrs.MAP = base_map] --> D
|
||||
D6[Attrs.SPEED = base_speed] --> D
|
||||
D7[Attrs.DIS = base_dis] --> D
|
||||
E1[设置其他属性为0] --> E
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L120-L180)
|
||||
|
||||
#### 属性容器构建逻辑
|
||||
|
||||
getAttrs和getNeAttrs函数负责构建属性容器:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Attrs {
|
||||
<<enumeration>>
|
||||
HP_MAX : 0
|
||||
MP_MAX : 1
|
||||
AP : 10
|
||||
DEF : 20
|
||||
SPEED : 63
|
||||
+getAttrs() : object
|
||||
}
|
||||
class NeAttrs {
|
||||
<<enumeration>>
|
||||
IN_FROST : 0
|
||||
IN_STUN : 1
|
||||
IN_BURN : 2
|
||||
IN_POISON : 3
|
||||
+getNeAttrs() : object
|
||||
}
|
||||
class HeroViewComp {
|
||||
+any Attrs
|
||||
+any NeAttrs
|
||||
+initAttrs()
|
||||
+recalculateSingleAttr(attrIndex)
|
||||
}
|
||||
HeroViewComp --> Attrs
|
||||
HeroViewComp --> NeAttrs
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L16-L30)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L72-L120)
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L16-L30)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L120-L180)
|
||||
|
||||
### 怪物数据共享机制
|
||||
|
||||
怪物通过heroSet.ts中的英雄配置数据实现数据共享:
|
||||
|
||||
#### 怪物配置复用
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[HeroInfo配置] --> B[英雄数据]
|
||||
A --> C[怪物数据]
|
||||
B1[uuid: 5001] --> B
|
||||
B2[name: 刘邦] --> B
|
||||
B3[type: warrior] --> B
|
||||
B4[hp: 125] --> B
|
||||
B5[ap: 15] --> B
|
||||
C1[uuid: 5201] --> C
|
||||
C2[name: 兽人战士] --> C
|
||||
C3[type: warrior] --> C
|
||||
C4[hp: 25] --> C
|
||||
C5[ap: 5] --> C
|
||||
B -.->|复用| C
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L70-L152)
|
||||
|
||||
#### 怪物强度动态调整
|
||||
|
||||
系统通过RogueConfig.ts提供怪物强度的动态调整机制:
|
||||
|
||||
| 参数 | 默认值 | 说明 |
|
||||
|------|--------|------|
|
||||
| stageMultiplier | 1 + (stageNumber - 1) * 0.1 | 关卡倍率,每关增加10% |
|
||||
| levelMultiplier | 1 + (level - 1) * 0.05 | 等级倍率,每级增加5% |
|
||||
| totalMultiplier | stageMultiplier * levelMultiplier | 总强度倍率 |
|
||||
|
||||
**章节来源**
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L70-L152)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L180-L205)
|
||||
|
||||
### 属性计算引擎
|
||||
|
||||
#### 属性计算公式
|
||||
|
||||
系统采用双重计算模式,根据属性类型选择不同的计算公式:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[属性计算开始] --> B{属性类型判断}
|
||||
B --> |数值型| C[数值型计算]
|
||||
B --> |百分比型| D[百分比型计算]
|
||||
C --> C1[基础值 + 数值Buff]
|
||||
C1 --> C2[× (1 + 百分比Buff/100)]
|
||||
C2 --> C3[Math.floor结果)
|
||||
D --> D1[基础值 + 数值Buff]
|
||||
D1 --> D2[+ 百分比Buff]
|
||||
D2 --> D3[直接结果]
|
||||
C3 --> E[属性值规范化]
|
||||
D3 --> E
|
||||
E --> F[属性计算完成]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L250-L320)
|
||||
|
||||
#### Buff系统管理
|
||||
|
||||
Buff系统支持持久型和临时型两种Buff类型:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class BuffSystem {
|
||||
+Record~number, Array~ BUFFS
|
||||
+Record~number, Array~ BUFFS_TEMP
|
||||
+addBuff(buffConf)
|
||||
+removeBuff(attrIndex, value, isPermanent)
|
||||
+updateTemporaryBuffsDebuffs(dt)
|
||||
+recalculateSingleAttr(attrIndex)
|
||||
}
|
||||
class BuffConf {
|
||||
+number buff
|
||||
+BType BType
|
||||
+number value
|
||||
+number time
|
||||
+number chance
|
||||
}
|
||||
class BuffInstance {
|
||||
+number value
|
||||
+BType BType
|
||||
+number remainTime
|
||||
}
|
||||
BuffSystem --> BuffConf
|
||||
BuffSystem --> BuffInstance
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L180-L250)
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L180-L350)
|
||||
|
||||
### 职业成长曲线系统
|
||||
|
||||
#### 职业属性增长配置
|
||||
|
||||
系统为每种职业定义了独特的属性成长曲线:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "战士职业成长"
|
||||
A1[力量→生命值: 3.0]
|
||||
A2[力量→攻击力: 1.5]
|
||||
A3[力量→防御力: 0.8]
|
||||
A4[敏捷→暴击率: 0.3]
|
||||
A5[精神→吸血: 0.4]
|
||||
end
|
||||
subgraph "刺客职业成长"
|
||||
B1[力量→生命值: 1.8]
|
||||
B2[力量→攻击力: 1.3]
|
||||
B3[力量→防御力: 0.3]
|
||||
B4[敏捷→暴击率: 1.0]
|
||||
B5[幸运→暴击率: 1.5]
|
||||
end
|
||||
subgraph "法师职业成长"
|
||||
C1[智力→魔法值: 2.0]
|
||||
C2[智力→魔法攻击: 1.8]
|
||||
C3[智力→魔法防御: 0.8]
|
||||
C4[智力→作用范围: 0.3]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L266-L439)
|
||||
|
||||
#### 成长系数计算
|
||||
|
||||
系统提供了多种快捷方法来计算属性增长:
|
||||
|
||||
| 方法名 | 输入参数 | 输出 | 用途 |
|
||||
|--------|----------|------|------|
|
||||
| addStrength | heroType, strengthPoints | 属性增长映射 | 计算力量属性增长 |
|
||||
| addIntelligence | heroType, intelligencePoints | 属性增长映射 | 计算智力属性增长 |
|
||||
| addAgility | heroType, agilityPoints | 属性增长映射 | 计算敏捷属性增长 |
|
||||
| calculateTotalAttributeGains | heroType, baseAttrs | 总属性增长 | 计算多属性总增长 |
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L435-L544)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
属性系统的依赖关系呈现清晰的层次结构:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[HeroAttrs.ts] --> B[HeroViewComp.ts]
|
||||
C[heroSet.ts] --> D[Hero.ts]
|
||||
C --> E[Mon.ts]
|
||||
B --> D
|
||||
B --> E
|
||||
F[RogueConfig.ts] --> E
|
||||
G[Mission.ts] --> F
|
||||
A --> H[属性枚举]
|
||||
A --> I[属性类型]
|
||||
A --> J[职业配置]
|
||||
K[GameEvent.ts] --> B
|
||||
L[SkillSet.ts] --> B
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L10)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L20)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L15)
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L10)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L10)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 属性计算优化策略
|
||||
|
||||
1. **延迟计算**:只在必要时重新计算属性值
|
||||
2. **批量更新**:合并多个属性变更操作
|
||||
3. **缓存机制**:避免重复计算相同属性
|
||||
4. **增量更新**:只更新受影响的属性
|
||||
|
||||
### 内存管理
|
||||
|
||||
- 使用对象池管理Buff实例
|
||||
- 及时清理过期的临时Buff
|
||||
- 避免属性容器的频繁重建
|
||||
|
||||
### 计算复杂度
|
||||
|
||||
属性计算的时间复杂度为O(n),其中n为活跃Buff的数量。系统通过以下方式优化性能:
|
||||
|
||||
- 使用索引快速定位属性
|
||||
- 批量处理相似类型的Buff
|
||||
- 延迟执行非关键属性计算
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 属性计算异常
|
||||
|
||||
**问题**:属性值超出预期范围
|
||||
**原因**:Buff叠加过多或计算公式错误
|
||||
**解决方案**:检查Buff配置,验证属性值规范化逻辑
|
||||
|
||||
#### 性能问题
|
||||
|
||||
**问题**:属性更新导致帧率下降
|
||||
**原因**:频繁的属性重新计算
|
||||
**解决方案**:实施属性变更批处理,减少不必要的重新计算
|
||||
|
||||
#### 数据同步问题
|
||||
|
||||
**问题**:客户端与服务器属性不一致
|
||||
**原因**:配置数据版本不匹配
|
||||
**解决方案**:实施配置版本控制,确保数据一致性
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L315-L354)
|
||||
|
||||
## 结论
|
||||
|
||||
英雄属性系统通过strengthMultiplier强度倍率实现了灵活的动态属性计算机制,支持HP、AP、DEF、SPEED等基础属性的精确缩放。系统采用模块化设计,将属性定义、计算逻辑、配置管理和运行时控制分离,确保了良好的可维护性和扩展性。
|
||||
|
||||
通过HeroAttrs.ts中的getAttrs与getNeAttrs函数,系统建立了完整的属性容器构建逻辑,支持英雄和怪物的统一属性管理。职业成长曲线系统为不同职业提供了特色化的属性发展路径,增强了游戏的策略深度。
|
||||
|
||||
怪物通过heroSet.ts中的英雄配置数据实现数据共享,配合RogueConfig.ts中的强度倍率计算,实现了自定义属性成长曲线和难度系数调整功能。系统提供了丰富的配置选项和性能优化建议,为游戏开发提供了强大的属性管理基础设施。
|
||||
735
.qoder/repowiki/zh/content/地图系统/怪物系统/怪物实体/怪物实体.md
Normal file
735
.qoder/repowiki/zh/content/地图系统/怪物系统/怪物实体/怪物实体.md
Normal file
@@ -0,0 +1,735 @@
|
||||
# 怪物实体ECS架构实现深度解析
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [项目结构分析](#项目结构分析)
|
||||
3. [Monster类核心架构](#monster类核心架构)
|
||||
4. [ECS注册机制详解](#ecs注册机制详解)
|
||||
5. [load方法完整流程分析](#load方法完整流程分析)
|
||||
6. [BattleMoveComp组件集成](#battlemovemovecomp组件集成)
|
||||
7. [MonModelComp模型数据管理](#monmodelcomp模型数据管理)
|
||||
8. [系统架构与依赖关系](#系统架构与依赖关系)
|
||||
9. [开发示例与最佳实践](#开发示例与最佳实践)
|
||||
10. [常见错误与调试方法](#常见错误与调试方法)
|
||||
11. [总结](#总结)
|
||||
|
||||
## 概述
|
||||
|
||||
本文档深入解析Cocos Creator游戏项目中Monster类的ECS(Entity-Component-System)架构实现。Monster类作为游戏中的怪物实体,采用了现代游戏开发中流行的组件化架构模式,通过继承ecs.Entity并注册为`Monster`类型,实现了高度可扩展和可维护的游戏实体系统。
|
||||
|
||||
该架构的核心优势在于:
|
||||
- **组件化设计**:将怪物的不同功能分解为独立的组件
|
||||
- **类型安全**:利用TypeScript的类型系统确保组件正确使用
|
||||
- **性能优化**:通过组件缓存池和批量处理提升性能
|
||||
- **易于扩展**:支持动态添加和移除组件
|
||||
|
||||
## 项目结构分析
|
||||
|
||||
项目的ECS架构采用分层设计,主要包含以下层次:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "实体层"
|
||||
Monster[Monster实体]
|
||||
Hero[Hero实体]
|
||||
end
|
||||
subgraph "组件层"
|
||||
BattleMove[BattleMoveComp<br/>战斗移动组件]
|
||||
MonModel[MonModelComp<br/>怪物模型组件]
|
||||
HeroView[HeroViewComp<br/>英雄视图组件]
|
||||
Tal[TalComp<br/>天赋组件]
|
||||
end
|
||||
subgraph "系统层"
|
||||
BattleMoveSys[BattleMoveSystem<br/>移动系统]
|
||||
PositionSys[EcsPositionSystem<br/>位置系统]
|
||||
end
|
||||
subgraph "管理层"
|
||||
MissionMon[MissionMonComp<br/>任务怪物管理]
|
||||
RogueConfig[RogueConfig<br/>肉鸽配置]
|
||||
end
|
||||
Monster --> BattleMove
|
||||
Monster --> MonModel
|
||||
Monster --> Tal
|
||||
Monster --> HeroView
|
||||
BattleMoveSys --> BattleMove
|
||||
BattleMoveSys --> HeroView
|
||||
MissionMon --> Monster
|
||||
MissionMon --> RogueConfig
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L111)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L272)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
|
||||
## Monster类核心架构
|
||||
|
||||
Monster类作为ECS架构中的核心实体,展现了现代游戏开发的最佳实践:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Monster {
|
||||
+MonModelComp HeroModel
|
||||
+HeroViewComp HeroView
|
||||
+BattleMoveComp BattleMove
|
||||
+init() void
|
||||
+destroy() void
|
||||
+load(pos, scale, uuid, is_boss, is_call, strengthMultiplier) void
|
||||
+hero_init(uuid, node, scale, box_group, is_boss, is_call, strengthMultiplier) void
|
||||
}
|
||||
class ecs_Entity {
|
||||
<<abstract>>
|
||||
+add(component) void
|
||||
+remove(component) void
|
||||
+get(component) Comp
|
||||
+has(component) boolean
|
||||
+destroy() void
|
||||
}
|
||||
class BattleMoveComp {
|
||||
+number direction
|
||||
+number targetX
|
||||
+boolean moving
|
||||
+reset() void
|
||||
}
|
||||
class MonModelComp {
|
||||
+reset() void
|
||||
}
|
||||
class HeroViewComp {
|
||||
+number scale
|
||||
+FacSet fac
|
||||
+HType type
|
||||
+boolean is_boss
|
||||
+number hero_uuid
|
||||
+string hero_name
|
||||
+number base_hp
|
||||
+number base_mp
|
||||
+number base_ap
|
||||
+number base_def
|
||||
+number hp
|
||||
+number mp
|
||||
+number ap
|
||||
+number def
|
||||
+Attrs attrs
|
||||
+Skills skills
|
||||
}
|
||||
Monster --|> ecs_Entity
|
||||
Monster --> BattleMoveComp
|
||||
Monster --> MonModelComp
|
||||
Monster --> HeroViewComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L18-L35)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L1-L16)
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts#L1-L20)
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L111)
|
||||
|
||||
## ECS注册机制详解
|
||||
|
||||
Monster类通过装饰器`@ecs.register('Monster')`完成ECS系统的注册,这是整个架构的基础:
|
||||
|
||||
### 注册机制特点
|
||||
|
||||
1. **类型标识**:通过字符串标识符'Monster'唯一标识实体类型
|
||||
2. **自动发现**:ECS系统能够自动发现和管理注册的实体类型
|
||||
3. **类型安全**:编译时确保实体类型的一致性
|
||||
|
||||
### 组件注册与关联
|
||||
|
||||
Monster实体在初始化时通过`init()`方法注册所需的组件:
|
||||
|
||||
```typescript
|
||||
protected init() {
|
||||
this.addComponents<ecs.Comp>(
|
||||
BattleMoveComp,
|
||||
MonModelComp,
|
||||
TalComp,
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
这种设计的优势:
|
||||
- **明确依赖**:清楚展示实体所需的所有组件
|
||||
- **生命周期管理**:组件的创建和销毁与实体同步
|
||||
- **性能优化**:避免重复创建相同类型的组件
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L25-L35)
|
||||
|
||||
## load方法完整流程分析
|
||||
|
||||
`load`方法是Monster实体的核心初始化方法,实现了从预制体加载到组件绑定的完整流程:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始load方法]) --> SetScale["设置scale=-1<br/>怪物朝向左侧"]
|
||||
SetScale --> GetScene["获取场景引用<br/>scene = smc.map.MapView.scene"]
|
||||
GetScene --> BuildPath["构建预制体路径<br/>path = 'game/heros/' + HeroInfo[uuid].path"]
|
||||
BuildPath --> LoadPrefab["加载预制体<br/>prefab = oops.res.get(path, Prefab)"]
|
||||
LoadPrefab --> Instantiate["实例化预制体<br/>node = instantiate(prefab)"]
|
||||
Instantiate --> SetParent["设置父节点<br/>node.parent = scene.entityLayer!.node!"]
|
||||
SetParent --> DisableCollider["禁用碰撞体<br/>collider.enabled = false"]
|
||||
DisableCollider --> EnableCollider["延迟启用碰撞体<br/>延迟一帧启用"]
|
||||
EnableCollider --> SetPosition["设置初始位置<br/>node.setPosition(pos)"]
|
||||
SetPosition --> CallInit["调用hero_init方法<br/>初始化怪物属性"]
|
||||
CallInit --> DispatchEvent["分发monster_load事件<br/>通知其他模块"]
|
||||
DispatchEvent --> InitMove["初始化移动参数<br/>设置向左移动"]
|
||||
InitMove --> UpdateCounter["更新怪物计数<br/>smc.vmdata.mission_data.mon_num++"]
|
||||
UpdateCounter --> End([完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L37-L65)
|
||||
|
||||
### 关键步骤详解
|
||||
|
||||
#### 1. 预制体动态加载
|
||||
```typescript
|
||||
var path = "game/heros/" + HeroInfo[uuid].path;
|
||||
var prefab: Prefab = oops.res.get(path, Prefab)!;
|
||||
var node = instantiate(prefab);
|
||||
```
|
||||
|
||||
这个过程展示了:
|
||||
- **配置驱动**:通过HeroInfo配置表动态确定预制体路径
|
||||
- **资源管理**:使用oops.res进行资源加载和缓存
|
||||
- **类型安全**:明确指定Prefab类型确保类型安全
|
||||
|
||||
#### 2. 碰撞体延迟启用机制
|
||||
```typescript
|
||||
const collider = node.getComponent(BoxCollider2D);
|
||||
if (collider) collider.enabled = false;
|
||||
```
|
||||
|
||||
这种设计考虑了:
|
||||
- **性能优化**:避免不必要的物理计算
|
||||
- **稳定性**:确保碰撞体在正确时机启用
|
||||
- **兼容性**:适应不同预制体的碰撞体配置
|
||||
|
||||
#### 3. 事件通知机制
|
||||
```typescript
|
||||
oops.message.dispatchEvent("monster_load", this);
|
||||
```
|
||||
|
||||
事件系统的作用:
|
||||
- **解耦**:减少组件间的直接依赖
|
||||
- **扩展性**:支持多个监听器响应同一事件
|
||||
- **异步处理**:允许异步执行相关逻辑
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L37-L65)
|
||||
|
||||
## BattleMoveComp组件集成
|
||||
|
||||
BattleMoveComp是Monster实体的核心移动组件,负责控制怪物的移动行为:
|
||||
|
||||
### 组件结构分析
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class BattleMoveComp {
|
||||
+number direction
|
||||
+number targetX
|
||||
+boolean moving
|
||||
+reset() void
|
||||
}
|
||||
class BattleMoveSystem {
|
||||
+filter() IMatcher
|
||||
+update(entity) void
|
||||
+checkEnemiesInFace(entity) boolean
|
||||
+updateRenderOrder(entity) void
|
||||
+validatePosition(newX, move) boolean
|
||||
}
|
||||
BattleMoveSystem --> BattleMoveComp : "管理"
|
||||
BattleMoveSystem --> HeroViewComp : "协作"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L1-L16)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L272)
|
||||
|
||||
### 移动逻辑实现
|
||||
|
||||
BattleMoveSystem通过复杂的AI逻辑控制怪物移动:
|
||||
|
||||
#### 1. 基础移动控制
|
||||
```typescript
|
||||
const delta = (view.Attrs[Attrs.SPEED]/3) * this.dt * move.direction;
|
||||
const newX = view.node.position.x + delta;
|
||||
```
|
||||
|
||||
#### 2. 边界检测与停止
|
||||
```typescript
|
||||
if (this.validatePosition(newX, move)) {
|
||||
view.status_change("move");
|
||||
view.node.setPosition(newX, view.node.position.y, 0);
|
||||
} else {
|
||||
view.status_change("idle");
|
||||
move.moving = false;
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 敌人检测与反应
|
||||
```typescript
|
||||
const shouldStop = this.checkEnemiesInFace(e);
|
||||
if (shouldStop) {
|
||||
view.status_change("idle");
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
### 驱动怪物向左移动的逻辑
|
||||
|
||||
在Monster的load方法中,通过以下代码设置移动参数:
|
||||
|
||||
```typescript
|
||||
const move = this.get(BattleMoveComp);
|
||||
move.direction = -1; // 向左移动
|
||||
move.targetX = -800; // 左边界
|
||||
```
|
||||
|
||||
这种设计体现了:
|
||||
- **组件化控制**:移动逻辑完全封装在BattleMoveComp中
|
||||
- **灵活性**:可以在运行时动态修改移动参数
|
||||
- **可测试性**:便于单独测试移动逻辑
|
||||
|
||||
**章节来源**
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L1-L16)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L15-L272)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L55-L60)
|
||||
|
||||
## MonModelComp模型数据管理
|
||||
|
||||
MonModelComp虽然看似简单,但在ECS架构中扮演着重要的数据管理角色:
|
||||
|
||||
### 组件设计特点
|
||||
|
||||
```typescript
|
||||
@ecs.register('MonModel')
|
||||
export class MonModelComp extends ecs.Comp {
|
||||
reset() {
|
||||
// 目前为空实现
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 数据存储与管理策略
|
||||
|
||||
尽管MonModelComp目前没有复杂的数据存储,但它遵循了ECS架构的最佳实践:
|
||||
|
||||
1. **职责单一**:专注于怪物模型相关的数据管理
|
||||
2. **可扩展性**:预留了未来扩展的空间
|
||||
3. **一致性**:与其他组件保持相同的接口风格
|
||||
|
||||
### 属性重置机制
|
||||
|
||||
```typescript
|
||||
reset() {
|
||||
// 目前为空实现
|
||||
}
|
||||
```
|
||||
|
||||
这种设计考虑了:
|
||||
- **性能优化**:避免不必要的重置操作
|
||||
- **灵活性**:允许子类根据需要重写重置逻辑
|
||||
- **一致性**:保持与ecs.Comp基类的接口一致
|
||||
|
||||
**章节来源**
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts#L1-L20)
|
||||
|
||||
## 系统架构与依赖关系
|
||||
|
||||
Monster实体的完整生命周期涉及多个系统和组件的协作:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "输入层"
|
||||
Config[配置数据<br/>HeroInfo, MonSet]
|
||||
Resources[资源文件<br/>预制体, 图集]
|
||||
end
|
||||
subgraph "管理层"
|
||||
MissionMon[MissionMonComp<br/>任务管理器]
|
||||
RogueConfig[RogueConfig<br/>肉鸽配置]
|
||||
end
|
||||
subgraph "实体层"
|
||||
Monster[Monster实体]
|
||||
end
|
||||
subgraph "组件层"
|
||||
BattleMove[BattleMoveComp<br/>移动控制]
|
||||
MonModel[MonModelComp<br/>模型数据]
|
||||
HeroView[HeroViewComp<br/>视图管理]
|
||||
Tal[TalComp<br/>天赋系统]
|
||||
end
|
||||
subgraph "系统层"
|
||||
BattleMoveSys[BattleMoveSystem<br/>移动系统]
|
||||
PositionSys[EcsPositionSystem<br/>位置系统]
|
||||
end
|
||||
Config --> MissionMon
|
||||
Resources --> Monster
|
||||
RogueConfig --> MissionMon
|
||||
MissionMon --> Monster
|
||||
Monster --> BattleMove
|
||||
Monster --> MonModel
|
||||
Monster --> HeroView
|
||||
Monster --> Tal
|
||||
BattleMove --> BattleMoveSys
|
||||
HeroView --> BattleMoveSys
|
||||
BattleMoveSys --> PositionSys
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L111)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L272)
|
||||
|
||||
### 关键依赖关系
|
||||
|
||||
1. **配置依赖**:Monster依赖HeroInfo配置表获取怪物数据
|
||||
2. **资源依赖**:依赖预制体资源进行实例化
|
||||
3. **系统依赖**:依赖BattleMoveSystem进行移动逻辑处理
|
||||
4. **事件依赖**:通过消息系统与其他模块通信
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L152)
|
||||
|
||||
## 开发示例与最佳实践
|
||||
|
||||
### 新增怪物实体类型示例
|
||||
|
||||
以下是新增一种新型态怪物的完整实现:
|
||||
|
||||
#### 1. 创建新的怪物类型配置
|
||||
|
||||
```typescript
|
||||
// 在heroSet.ts中添加新的怪物配置
|
||||
export const HeroInfo: Record<number, heroInfo> = {
|
||||
// ...
|
||||
5204: {uuid: 5204, name: "冰霜巨人", path: "mo2", fac: FacSet.MON, kind: 1,
|
||||
type: HType.warrior, lv: 1, hp: 50, mp: 120, ap: 8, map: 15, def: 10, mdef: 0,
|
||||
ap: 8, dis: 120, speed: 80, skills: [6006], buff: [], tal: [], info: "冰霜系怪物"},
|
||||
};
|
||||
```
|
||||
|
||||
#### 2. 创建专门的怪物实体类
|
||||
|
||||
```typescript
|
||||
@ecs.register('IceGiant')
|
||||
export class IceGiant extends ecs.Entity {
|
||||
IceModel!: MonModelComp;
|
||||
IceView!: HeroViewComp;
|
||||
IceMove!: BattleMoveComp;
|
||||
IceEffect!: IceEffectComp; // 新增冰霜效果组件
|
||||
|
||||
protected init() {
|
||||
this.addComponents<ecs.Comp>(
|
||||
BattleMoveComp,
|
||||
MonModelComp,
|
||||
IceEffectComp, // 添加新组件
|
||||
TalComp,
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 实现特定的加载逻辑
|
||||
|
||||
```typescript
|
||||
loadIceGiant(pos: Vec3, scale: number = 1, strengthMultiplier: number = 1.0) {
|
||||
// 调用通用加载逻辑
|
||||
this.load(pos, scale, 5204, false, false, strengthMultiplier);
|
||||
|
||||
// 特定于冰霜巨人的初始化
|
||||
const effect = this.get(IceEffectComp);
|
||||
effect.freezeDuration = 2.0; // 冻结持续时间
|
||||
effect.freezeChance = 0.3; // 冻结概率
|
||||
}
|
||||
```
|
||||
|
||||
### 配置预制体路径的最佳实践
|
||||
|
||||
1. **命名规范**:使用统一的命名约定
|
||||
```typescript
|
||||
// 推荐:mo1, mo2, mo3 表示不同的怪物类型
|
||||
// 不推荐:monster1, enemy1, badguy
|
||||
```
|
||||
|
||||
2. **资源组织**:按类型分类存放预制体
|
||||
```
|
||||
assets/resources/game/heros/
|
||||
├── mo1/ # 普通怪物
|
||||
├── mo2/ # 冰霜怪物
|
||||
├── mo3/ # 火焰怪物
|
||||
└── boss/ # Boss怪物
|
||||
```
|
||||
|
||||
3. **版本管理**:为不同版本的预制体建立目录结构
|
||||
```
|
||||
assets/resources/game/heros/v1.0/mo1/
|
||||
assets/resources/game/heros/v1.1/mo1/
|
||||
```
|
||||
|
||||
### 初始化参数配置指南
|
||||
|
||||
#### 基础属性配置
|
||||
|
||||
```typescript
|
||||
interface MonsterConfig {
|
||||
uuid: number;
|
||||
position: number; // 在MonSet中的位置索引
|
||||
type: MonsterType; // 怪物类型
|
||||
level: number; // 等级(1-5)
|
||||
strengthMultiplier: number; // 强度倍率
|
||||
isBoss?: boolean; // 是否为Boss
|
||||
isCall?: boolean; // 是否为召唤怪
|
||||
}
|
||||
```
|
||||
|
||||
#### 强度倍率计算
|
||||
|
||||
```typescript
|
||||
function calculateMonsterStrengthMultiplier(stageNumber: number, level: number): number {
|
||||
const stageMultiplier = 1 + (stageNumber - 1) * 0.1; // 每关增加10%
|
||||
const levelMultiplier = 1 + (level - 1) * 0.05; // 每级增加5%
|
||||
return stageMultiplier * levelMultiplier;
|
||||
}
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L130-L152)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L175-L190)
|
||||
|
||||
## 常见错误与调试方法
|
||||
|
||||
### 常见集成错误
|
||||
|
||||
#### 1. 组件注册错误
|
||||
|
||||
**错误表现**:
|
||||
```typescript
|
||||
// 错误:忘记注册组件
|
||||
export class Monster extends ecs.Entity {
|
||||
// 缺少组件声明
|
||||
// HeroModel!: MonModelComp;
|
||||
// HeroView!: HeroViewComp;
|
||||
// BattleMove!: BattleMoveComp;
|
||||
}
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 正确:在类中声明组件
|
||||
export class Monster extends ecs.Entity {
|
||||
HeroModel!: MonModelComp;
|
||||
HeroView!: HeroViewComp;
|
||||
BattleMove!: BattleMoveComp;
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 预制体加载失败
|
||||
|
||||
**错误表现**:
|
||||
```typescript
|
||||
// 错误:路径拼写错误
|
||||
var path = "game/heros/" + HeroInfo[uuid].path; // 可能导致加载失败
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 正确:添加错误处理和日志
|
||||
try {
|
||||
var path = "game/heros/" + HeroInfo[uuid].path;
|
||||
var prefab: Prefab = oops.res.get(path, Prefab);
|
||||
if (!prefab) {
|
||||
console.error(`预制体加载失败: ${path}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`加载预制体时出错:`, error);
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 组件初始化顺序问题
|
||||
|
||||
**错误表现**:
|
||||
```typescript
|
||||
// 错误:在组件未注册前就尝试获取
|
||||
load() {
|
||||
const move = this.get(BattleMoveComp); // 可能在init之前调用
|
||||
move.direction = -1;
|
||||
}
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 正确:确保在init之后调用
|
||||
protected init() {
|
||||
this.addComponents<ecs.Comp>(
|
||||
BattleMoveComp,
|
||||
MonModelComp,
|
||||
TalComp,
|
||||
);
|
||||
}
|
||||
|
||||
load() {
|
||||
// load方法会在init之后调用
|
||||
const move = this.get(BattleMoveComp);
|
||||
move.direction = -1;
|
||||
}
|
||||
```
|
||||
|
||||
### 调试方法
|
||||
|
||||
#### 1. 组件状态监控
|
||||
|
||||
```typescript
|
||||
// 在Monster类中添加调试方法
|
||||
debugPrintState() {
|
||||
console.log(`Monster状态:`, {
|
||||
hasBattleMove: this.has(BattleMoveComp),
|
||||
hasHeroView: this.has(HeroViewComp),
|
||||
hasMonModel: this.has(MonModelComp),
|
||||
battleMoveDirection: this.BattleMove?.direction,
|
||||
heroName: this.HeroView?.hero_name,
|
||||
hp: this.HeroView?.hp,
|
||||
mp: this.HeroView?.mp
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 生命周期跟踪
|
||||
|
||||
```typescript
|
||||
// 添加生命周期钩子
|
||||
protected init() {
|
||||
console.log('Monster init');
|
||||
super.init();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
console.log('Monster destroy');
|
||||
super.destroy();
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 系统状态检查
|
||||
|
||||
```typescript
|
||||
// 在BattleMoveSystem中添加调试信息
|
||||
update(e: ecs.Entity) {
|
||||
const move = e.get(BattleMoveComp);
|
||||
const view = e.get(HeroViewComp);
|
||||
|
||||
console.log(`[${view.hero_name}] 位置: ${view.node.position.x.toFixed(1)}, 方向: ${move.direction}, 移动: ${move.moving}`);
|
||||
|
||||
// 原有逻辑...
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. 性能监控
|
||||
|
||||
```typescript
|
||||
// 监控组件创建和销毁
|
||||
static createCount = 0;
|
||||
static destroyCount = 0;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
Monster.createCount++;
|
||||
console.log(`Monster创建总数: ${Monster.createCount}`);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
Monster.destroyCount++;
|
||||
console.log(`Monster销毁总数: ${Monster.destroyCount}`);
|
||||
super.destroy();
|
||||
}
|
||||
```
|
||||
|
||||
### 性能优化建议
|
||||
|
||||
#### 1. 组件缓存池优化
|
||||
|
||||
```typescript
|
||||
// 利用ECS系统的组件缓存池
|
||||
const move = ecs.getComponent(BattleMoveComp);
|
||||
try {
|
||||
move.direction = -1;
|
||||
move.targetX = -800;
|
||||
} finally {
|
||||
ecs.releaseComponent(move);
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 批量处理优化
|
||||
|
||||
```typescript
|
||||
// 批量创建怪物
|
||||
function batchCreateMonsters(configs: MonsterConfig[]) {
|
||||
configs.forEach(config => {
|
||||
const monster = ecs.getEntity<Monster>(Monster);
|
||||
monster.load(
|
||||
v3(MonSet[config.position].pos),
|
||||
-1, // scale
|
||||
config.uuid,
|
||||
config.type === MonsterType.BOSS,
|
||||
false,
|
||||
config.strengthMultiplier
|
||||
);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 内存泄漏预防
|
||||
|
||||
```typescript
|
||||
// 确保正确清理事件监听器
|
||||
destroy() {
|
||||
oops.message.removeEventListener("monster_load", this.onMonsterLoad);
|
||||
super.destroy();
|
||||
}
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L30-L35)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L15-L50)
|
||||
|
||||
## 总结
|
||||
|
||||
Monster类的ECS架构实现展现了现代游戏开发中组件化设计的最佳实践。通过深入分析,我们可以看到:
|
||||
|
||||
### 架构优势
|
||||
|
||||
1. **高度模块化**:每个组件负责单一职责,便于维护和扩展
|
||||
2. **类型安全**:利用TypeScript确保组件使用的正确性
|
||||
3. **性能优化**:通过组件缓存池和批量处理提升性能
|
||||
4. **易于测试**:组件间松耦合,便于单元测试
|
||||
|
||||
### 设计亮点
|
||||
|
||||
1. **灵活的预制体加载机制**:支持动态配置和资源管理
|
||||
2. **智能的移动控制系统**:结合AI逻辑实现复杂的怪物行为
|
||||
3. **完善的事件通知机制**:支持模块间解耦通信
|
||||
4. **可扩展的配置系统**:支持多种怪物类型和强度配置
|
||||
|
||||
### 最佳实践总结
|
||||
|
||||
1. **严格遵循ECS原则**:组件职责单一,实体轻量化
|
||||
2. **合理使用装饰器**:通过`@ecs.register`简化组件注册
|
||||
3. **注重错误处理**:添加适当的异常处理和日志记录
|
||||
4. **性能优先**:充分利用组件缓存池和批量处理
|
||||
5. **文档完善**:为复杂逻辑添加详细的注释和文档
|
||||
|
||||
这套ECS架构不仅适用于怪物实体,也为游戏中的其他实体类型提供了可复用的设计模式。通过遵循这些设计原则和最佳实践,开发者可以构建出高性能、可维护的游戏系统。
|
||||
580
.qoder/repowiki/zh/content/地图系统/怪物系统/怪物实体/怪物实体初始化流程.md
Normal file
580
.qoder/repowiki/zh/content/地图系统/怪物系统/怪物实体/怪物实体初始化流程.md
Normal file
@@ -0,0 +1,580 @@
|
||||
# 怪物实体初始化流程
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/entityLayer.ts)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [项目结构分析](#项目结构分析)
|
||||
3. [核心组件架构](#核心组件架构)
|
||||
4. [Monster类load方法详解](#monster类load方法详解)
|
||||
5. [hero_init方法深度解析](#hero_init方法深度解析)
|
||||
6. [资源加载与预制体管理](#资源加载与预制体管理)
|
||||
7. [场景节点挂载机制](#场景节点挂载机制)
|
||||
8. [消息事件系统](#消息事件系统)
|
||||
9. [异常处理与调试策略](#异常处理与调试策略)
|
||||
10. [实际应用示例](#实际应用示例)
|
||||
11. [总结](#总结)
|
||||
|
||||
## 概述
|
||||
|
||||
Monster类是游戏中的核心怪物实体管理器,负责怪物的完整生命周期管理,包括预制体加载、属性初始化、技能配置、碰撞体控制等关键功能。本文档将深入解析Monster类中load方法的完整初始化流程,重点阐述其动态加载机制、属性调整逻辑以及与其他系统的集成方式。
|
||||
|
||||
## 项目结构分析
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "怪物系统架构"
|
||||
A[Monster类] --> B[load方法]
|
||||
A --> C[hero_init方法]
|
||||
B --> D[预制体加载]
|
||||
B --> E[节点挂载]
|
||||
B --> F[碰撞体控制]
|
||||
C --> G[属性初始化]
|
||||
C --> H[技能配置]
|
||||
C --> I[Buff系统]
|
||||
end
|
||||
subgraph "配置系统"
|
||||
J[HeroInfo配置] --> K[基础属性]
|
||||
J --> L[技能列表]
|
||||
M[SkillSet配置] --> N[技能数据]
|
||||
O[BoxSet配置] --> P[碰撞组]
|
||||
end
|
||||
subgraph "场景系统"
|
||||
Q[EntityLayer] --> R[节点管理]
|
||||
S[MapView] --> T[场景容器]
|
||||
end
|
||||
A --> J
|
||||
A --> M
|
||||
B --> Q
|
||||
B --> S
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L14-L110)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L70-L151)
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L110)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L151)
|
||||
|
||||
## 核心组件架构
|
||||
|
||||
Monster类采用ECS(Entity-Component-System)架构模式,继承自ecs.Entity基类,包含以下核心组件:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Monster {
|
||||
+HeroModel! MonModelComp
|
||||
+HeroView! HeroViewComp
|
||||
+BattleMove! BattleMoveComp
|
||||
+init() void
|
||||
+destroy() void
|
||||
+load(pos, scale, uuid, is_boss, is_call, strengthMultiplier) void
|
||||
+hero_init(uuid, node, scale, box_group, is_boss, is_call, strengthMultiplier) void
|
||||
}
|
||||
class MonModelComp {
|
||||
+reset() void
|
||||
}
|
||||
class HeroViewComp {
|
||||
+scale number
|
||||
+fac FacSet
|
||||
+type HType
|
||||
+is_boss boolean
|
||||
+box_group BoxSet
|
||||
+hero_uuid number
|
||||
+hero_name string
|
||||
+base_hp number
|
||||
+base_mp number
|
||||
+base_ap number
|
||||
+base_def number
|
||||
+skills Skill[]
|
||||
+Attrs Attrs
|
||||
+initAttrs() void
|
||||
}
|
||||
class BattleMoveComp {
|
||||
+direction number
|
||||
+targetX number
|
||||
}
|
||||
Monster --> MonModelComp : "包含"
|
||||
Monster --> HeroViewComp : "包含"
|
||||
Monster --> BattleMoveComp : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L14-L35)
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts#L10-L18)
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L14-L35)
|
||||
|
||||
## Monster类load方法详解
|
||||
|
||||
load方法是Monster类的核心初始化入口,负责完整的怪物实体创建流程:
|
||||
|
||||
### 方法签名与参数说明
|
||||
|
||||
| 参数名 | 类型 | 默认值 | 说明 |
|
||||
|--------|------|--------|------|
|
||||
| pos | Vec3 | Vec3.ZERO | 怪物初始位置坐标 |
|
||||
| scale | number | 1 | 怪物缩放比例 |
|
||||
| uuid | number | 1001 | 怪物唯一标识符 |
|
||||
| is_boss | boolean | false | 是否为Boss怪物 |
|
||||
| is_call | boolean | false | 是否为召唤怪物 |
|
||||
| strengthMultiplier | number | 1.0 | 强度倍率 |
|
||||
|
||||
### 完整初始化流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始load方法] --> B[设置缩放参数]
|
||||
B --> C[确定碰撞组]
|
||||
C --> D[获取场景引用]
|
||||
D --> E[构建资源路径]
|
||||
E --> F[加载预制体]
|
||||
F --> G{预制体加载成功?}
|
||||
G --> |否| H[抛出异常]
|
||||
G --> |是| I[创建节点实例]
|
||||
I --> J[设置父节点]
|
||||
J --> K[禁用碰撞体]
|
||||
K --> L[设置初始位置]
|
||||
L --> M[调用hero_init]
|
||||
M --> N[派发monster_load事件]
|
||||
N --> O[初始化移动参数]
|
||||
O --> P[更新怪物计数]
|
||||
P --> Q[结束]
|
||||
H --> R[错误处理]
|
||||
R --> Q
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L36-L60)
|
||||
|
||||
### 关键实现细节
|
||||
|
||||
#### 1. 动态资源路径构建
|
||||
```typescript
|
||||
// 资源路径格式:game/heros/{hero.path}
|
||||
var path = "game/heros/" + HeroInfo[uuid].path;
|
||||
```
|
||||
|
||||
#### 2. 碰撞体延迟启用机制
|
||||
```typescript
|
||||
// 先禁用碰撞体,延迟一帧启用
|
||||
const collider = node.getComponent(BoxCollider2D);
|
||||
if (collider) collider.enabled = false;
|
||||
```
|
||||
|
||||
#### 3. 缩放与方向控制
|
||||
```typescript
|
||||
// Boss怪物特殊处理
|
||||
let scale = -1; // 默认向左朝向
|
||||
if (is_boss) scale = 1; // Boss面向右侧
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L36-L60)
|
||||
|
||||
## hero_init方法深度解析
|
||||
|
||||
hero_init方法负责怪物的基础属性初始化和技能配置,是怪物能力系统的核心:
|
||||
|
||||
### 属性初始化流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MI as Monster Instance
|
||||
participant HV as HeroViewComp
|
||||
participant HI as HeroInfo
|
||||
participant SS as SkillSet
|
||||
participant AS as Attrs System
|
||||
MI->>HV : 获取HeroView组件
|
||||
MI->>HI : 查询怪物配置
|
||||
MI->>HV : 设置基础属性
|
||||
MI->>MI : 计算强度倍率属性
|
||||
MI->>SS : 遍历技能列表
|
||||
SS-->>MI : 返回技能配置
|
||||
MI->>HV : 添加技能到技能列表
|
||||
MI->>AS : 初始化属性系统
|
||||
MI->>HV : 调用initAttrs()
|
||||
MI->>MI : 添加到实体组件
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L61-L108)
|
||||
|
||||
### 强度倍率动态调整机制
|
||||
|
||||
hero_init方法的核心特性是根据strengthMultiplier参数动态调整怪物属性:
|
||||
|
||||
#### 基础属性计算公式
|
||||
```typescript
|
||||
// 根据强度倍率调整基础属性
|
||||
const baseHp = Math.floor(hero.hp * strengthMultiplier);
|
||||
const baseAp = Math.floor(hero.ap * strengthMultiplier);
|
||||
const baseDef = Math.floor(hero.def * strengthMultiplier);
|
||||
```
|
||||
|
||||
#### 属性倍率影响范围
|
||||
| 属性类型 | 基础值 | 强度倍率影响 | 说明 |
|
||||
|----------|--------|--------------|------|
|
||||
| HP | hero.hp | × strengthMultiplier | 生命值线性增长 |
|
||||
| AP | hero.ap | × strengthMultiplier | 物理攻击力线性增长 |
|
||||
| DEF | hero.def | × strengthMultiplier | 物理防御力线性增长 |
|
||||
| MP | hero.mp | 不受影响 | 魔法值保持不变 |
|
||||
|
||||
### 技能系统初始化
|
||||
|
||||
#### 技能配置转换
|
||||
```typescript
|
||||
// 将HeroInfo中的技能ID转换为完整的技能配置
|
||||
for (let i = 0; i < hero.skills.length; i++) {
|
||||
let skill = {
|
||||
uuid: SkillSet[hero.skills[i]].uuid,
|
||||
cd_max: SkillSet[hero.skills[i]].cd,
|
||||
cost: SkillSet[hero.skills[i]].cost,
|
||||
cd: 0
|
||||
}
|
||||
hv.skills.push(skill);
|
||||
}
|
||||
```
|
||||
|
||||
#### 技能冷却系统
|
||||
每个技能初始化时:
|
||||
- `cd_max`: 技能最大冷却时间
|
||||
- `cost`: 技能消耗值
|
||||
- `cd`: 当前冷却计时器(初始为0)
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L61-L108)
|
||||
|
||||
## 资源加载与预制体管理
|
||||
|
||||
### 资源加载机制
|
||||
|
||||
游戏采用Oops Framework的资源管理系统,通过oops.res.get方法加载预制体:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[资源请求] --> B[oops.res.get]
|
||||
B --> C{资源是否存在?}
|
||||
C --> |是| D[返回预制体]
|
||||
C --> |否| E[抛出错误]
|
||||
D --> F[实例化预制体]
|
||||
F --> G[返回节点实例]
|
||||
E --> H[异常处理]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L40-L42)
|
||||
|
||||
### 常见资源路径错误
|
||||
|
||||
#### 错误类型与解决方案
|
||||
|
||||
| 错误类型 | 症状 | 解决方案 |
|
||||
|----------|------|----------|
|
||||
| 路径不存在 | 预制体加载失败 | 检查HeroInfo配置中的path字段 |
|
||||
| 文件损坏 | 实例化时报错 | 重新导入预制体资源 |
|
||||
| 资源未打包 | 运行时找不到资源 | 确保资源已正确打包到构建中 |
|
||||
|
||||
### UUID越界检查
|
||||
|
||||
```typescript
|
||||
// UUID有效性验证
|
||||
let hero = HeroInfo[uuid];
|
||||
if (!hero) {
|
||||
console.error(`[Monster] 无效的怪物UUID: ${uuid}`);
|
||||
throw new Error(`怪物配置不存在: ${uuid}`);
|
||||
}
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L40-L42)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L70-L151)
|
||||
|
||||
## 场景节点挂载机制
|
||||
|
||||
### EntityLayer节点管理
|
||||
|
||||
EntityLayer作为场景中的物体层,负责管理所有动态物体的渲染顺序和生命周期:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A[Scene] --> B[EntityLayer]
|
||||
B --> C[怪物节点]
|
||||
B --> D[技能特效]
|
||||
B --> E[UI元素]
|
||||
C --> F[Monster实例]
|
||||
F --> G[HeroViewComp]
|
||||
F --> H[MonModelComp]
|
||||
F --> I[BattleMoveComp]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L18-L38)
|
||||
|
||||
### 挂载流程详解
|
||||
|
||||
#### 1. 场景引用获取
|
||||
```typescript
|
||||
var scene = smc.map.MapView.scene;
|
||||
```
|
||||
|
||||
#### 2. 父节点设置
|
||||
```typescript
|
||||
node.parent = scene.entityLayer!.node!;
|
||||
```
|
||||
|
||||
#### 3. 深度排序机制
|
||||
EntityLayer实现了定时器驱动的深度排序:
|
||||
```typescript
|
||||
private timer: Timer = new Timer(0.2);
|
||||
update(dt: number) {
|
||||
this.timer.update(dt);
|
||||
// 深度排序逻辑
|
||||
}
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L18-L38)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L44-L45)
|
||||
|
||||
## 消息事件系统
|
||||
|
||||
### monster_load事件派发
|
||||
|
||||
游戏通过oops.message系统实现松耦合的消息通信:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant M as Monster
|
||||
participant EM as Event Manager
|
||||
participant MC as MissionMonComp
|
||||
participant SM as Scene Manager
|
||||
M->>EM : dispatchEvent("monster_load", monster)
|
||||
EM->>MC : 通知怪物加载完成
|
||||
MC->>SM : 更新场景状态
|
||||
SM->>M : 可能的后续处理
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L56-L57)
|
||||
|
||||
### 事件监听与处理
|
||||
|
||||
#### MissionMonComp中的事件处理
|
||||
```typescript
|
||||
onLoad() {
|
||||
this.on(GameEvent.FightReady, this.fight_ready, this);
|
||||
this.on(GameEvent.NewWave, this.fight_ready, this);
|
||||
}
|
||||
```
|
||||
|
||||
#### 事件处理流程
|
||||
1. **FightReady事件**: 准备战斗阶段
|
||||
2. **NewWave事件**: 新一波怪物生成
|
||||
3. **monster_load事件**: 怪物实体加载完成
|
||||
|
||||
### 事件系统优势
|
||||
|
||||
| 优势 | 说明 | 应用场景 |
|
||||
|------|------|----------|
|
||||
| 松耦合 | 组件间无需直接依赖 | 怪物生成与场景管理 |
|
||||
| 可扩展 | 易于添加新的事件处理器 | 新增功能模块 |
|
||||
| 异步处理 | 支持异步事件流 | 怪物AI行为 |
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L56-L57)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L34-L40)
|
||||
|
||||
## 异常处理与调试策略
|
||||
|
||||
### 常见异常类型
|
||||
|
||||
#### 1. 资源加载异常
|
||||
```typescript
|
||||
try {
|
||||
var prefab: Prefab = oops.res.get(path, Prefab)!;
|
||||
var node = instantiate(prefab);
|
||||
} catch (error) {
|
||||
console.error(`[Monster] 预制体加载失败: ${path}`, error);
|
||||
// 回退到默认预制体或显示错误界面
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. UUID越界异常
|
||||
```typescript
|
||||
if (!HeroInfo[uuid]) {
|
||||
console.error(`[Monster] 未知的怪物UUID: ${uuid}`);
|
||||
// 使用默认怪物配置
|
||||
uuid = 5201; // 兽人战士作为默认值
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 节点层级缺失异常
|
||||
```typescript
|
||||
if (!scene.entityLayer || !scene.entityLayer.node) {
|
||||
console.error('[Monster] 场景实体层不存在');
|
||||
// 创建默认场景结构
|
||||
}
|
||||
```
|
||||
|
||||
### 调试策略
|
||||
|
||||
#### 1. 日志记录系统
|
||||
```typescript
|
||||
// 详细日志级别
|
||||
console.log("[Mon] mission_data.mon_num:", smc.vmdata.mission_data.mon_num);
|
||||
console.log("[Monster] 加载怪物:", uuid, "类型:", HeroInfo[uuid].type);
|
||||
```
|
||||
|
||||
#### 2. 断点调试技巧
|
||||
```typescript
|
||||
// 在关键位置设置断点
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
debugger;
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 性能监控
|
||||
```typescript
|
||||
// 性能计时器
|
||||
const startTime = performance.now();
|
||||
// ... 执行加载操作
|
||||
const endTime = performance.now();
|
||||
console.log(`[Monster] 加载耗时: ${endTime - startTime}ms`);
|
||||
```
|
||||
|
||||
### 异常恢复机制
|
||||
|
||||
#### 资源回退策略
|
||||
```typescript
|
||||
// 1. 尝试加载指定资源
|
||||
// 2. 如果失败,尝试加载备用资源
|
||||
// 3. 如果仍然失败,使用默认资源
|
||||
```
|
||||
|
||||
#### 配置验证
|
||||
```typescript
|
||||
// 验证HeroInfo配置完整性
|
||||
function validateHeroConfig(hero: heroInfo): boolean {
|
||||
return hero &&
|
||||
hero.hp > 0 &&
|
||||
hero.ap > 0 &&
|
||||
hero.def > 0 &&
|
||||
hero.skills.length > 0;
|
||||
}
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L36-L60)
|
||||
|
||||
## 实际应用示例
|
||||
|
||||
### 生成普通怪物
|
||||
|
||||
```typescript
|
||||
// 创建普通怪物实例
|
||||
let monster = ecs.getEntity<Monster>(Monster);
|
||||
let pos: Vec3 = v3(240, 100, 0);
|
||||
let scale = -1;
|
||||
|
||||
monster.load(
|
||||
pos, // 初始位置
|
||||
scale, // 缩放比例
|
||||
5201, // 兽人战士UUID
|
||||
false, // 非Boss
|
||||
false, // 非召唤
|
||||
1.0 // 强度倍率
|
||||
);
|
||||
```
|
||||
|
||||
### 生成Boss怪物
|
||||
|
||||
```typescript
|
||||
// 创建Boss怪物实例
|
||||
let boss = ecs.getEntity<Monster>(Monster);
|
||||
let bossPos: Vec3 = v3(400, 100, 0);
|
||||
|
||||
boss.load(
|
||||
bossPos, // Boss专用位置
|
||||
1, // 正向缩放
|
||||
5201, // 使用相同基础配置
|
||||
true, // Boss标志
|
||||
false, // 非召唤
|
||||
2.0 // 双倍强度
|
||||
);
|
||||
```
|
||||
|
||||
### MissionMonComp中的批量生成
|
||||
|
||||
```typescript
|
||||
// 在MissionMonComp中批量生成怪物
|
||||
private addMonster(
|
||||
uuid: number = 1001,
|
||||
i: number = 0,
|
||||
is_boss: boolean = false,
|
||||
is_call: boolean = false,
|
||||
lv: number = 1,
|
||||
strengthMultiplier: number = 1.0
|
||||
) {
|
||||
let mon = ecs.getEntity<Monster>(Monster);
|
||||
let scale = -1;
|
||||
let pos: Vec3 = v3(MonSet[i].pos);
|
||||
|
||||
mon.load(pos, scale, uuid, is_boss, is_call, strengthMultiplier);
|
||||
}
|
||||
```
|
||||
|
||||
### 强度倍率的实际效果
|
||||
|
||||
#### 基础属性对比表
|
||||
|
||||
| 属性类型 | 基础值(1.0倍) | 1.5倍 | 2.0倍 | 2.5倍 |
|
||||
|----------|---------------|-------|-------|-------|
|
||||
| HP | 25 | 37 | 50 | 62 |
|
||||
| AP | 5 | 7 | 10 | 12 |
|
||||
| DEF | 5 | 7 | 10 | 12 |
|
||||
| MP | 100 | 100 | 100 | 100 |
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L215-L239)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L120-L151)
|
||||
|
||||
## 总结
|
||||
|
||||
Monster类的load方法和hero_init方法构成了游戏怪物系统的核心基础设施,通过以下关键技术实现了灵活而强大的怪物生成机制:
|
||||
|
||||
### 核心技术特点
|
||||
|
||||
1. **动态资源加载**: 基于UUID的预制体动态加载,支持运行时配置
|
||||
2. **属性倍率系统**: 通过strengthMultiplier参数实现怪物强度的灵活调整
|
||||
3. **ECS架构模式**: 清晰的组件分离,便于维护和扩展
|
||||
4. **事件驱动通信**: 松耦合的消息系统,支持复杂的业务逻辑
|
||||
5. **异常处理机制**: 完善的错误处理和恢复策略
|
||||
|
||||
### 性能优化要点
|
||||
|
||||
- **预制体缓存**: 利用Oops Framework的资源管理系统
|
||||
- **延迟初始化**: 碰撞体的延迟启用减少初始化开销
|
||||
- **批量操作**: MissionMonComp中的批量怪物生成
|
||||
- **内存管理**: 及时清理不再使用的怪物实体
|
||||
|
||||
### 扩展建议
|
||||
|
||||
1. **配置系统增强**: 支持更多的怪物类型和属性变体
|
||||
2. **AI行为系统**: 集成更复杂的怪物AI逻辑
|
||||
3. **视觉效果**: 添加更多的怪物特效和动画
|
||||
4. **平衡性调整**: 提供更精细的难度调节机制
|
||||
|
||||
通过深入理解这些机制,开发者可以更好地维护和扩展游戏的怪物系统,为玩家提供更加丰富和有趣的游戏体验。
|
||||
270
.qoder/repowiki/zh/content/地图系统/怪物系统/怪物实体/怪物实体组件系统.md
Normal file
270
.qoder/repowiki/zh/content/地图系统/怪物系统/怪物实体/怪物实体组件系统.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# 怪物实体组件系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概述](#架构概述)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
本文档详细说明了Cocos游戏项目中Monster实体的ECS(实体-组件-系统)机制,重点分析了在init方法中注册BattleMoveComp和MonModelComp组件的实现。文档深入解析了BattleMoveComp如何驱动怪物向左移动至目标X坐标(-800)的逻辑,结合BoxSet.MONSTER碰撞分组常量说明其在物理系统中的角色定义。同时阐述了MonModelComp作为数据容器的职责,包括属性重置机制与扩展字段设计原则,并提供开发示例和典型问题排查方法。
|
||||
|
||||
## 项目结构
|
||||
本项目采用基于功能模块的文件组织方式,核心游戏逻辑位于`assets/script/game`目录下,分为多个子模块如`hero`、`common`、`map`等。ECS相关组件和系统被组织在`common/ecs/position`路径下,体现了清晰的架构分层。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Assets"
|
||||
subgraph "Script"
|
||||
subgraph "Game"
|
||||
Hero[hero模块]
|
||||
Common[common模块]
|
||||
Map[map模块]
|
||||
Initialize[initialize模块]
|
||||
end
|
||||
Main[Main.ts]
|
||||
end
|
||||
Resources[resources]
|
||||
end
|
||||
Hero --> |包含| Monster[Monster实体]
|
||||
Common --> |包含| ECS[ECS系统]
|
||||
Common --> |包含| Config[配置文件]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts)
|
||||
|
||||
**Section sources**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
|
||||
## 核心组件
|
||||
Monster实体通过ECS架构实现了行为与数据的分离,其核心由BattleMoveComp(移动行为)和MonModelComp(数据模型)两个组件构成。这种设计模式使得组件可以独立开发、测试和复用,同时通过系统(System)统一管理组件间的交互逻辑。
|
||||
|
||||
**Section sources**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts)
|
||||
|
||||
## 架构概述
|
||||
游戏采用ECS(Entity-Component-System)架构模式,将游戏对象分解为实体(Entity)、组件(Component)和系统(System)三个核心概念。实体作为容器,持有多个组件;组件作为纯数据结构,存储特定功能的数据;系统则负责处理具有特定组件组合的实体,实现游戏逻辑。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Entity {
|
||||
+addComponent(comp)
|
||||
+removeComponent(comp)
|
||||
+getComponent(type)
|
||||
}
|
||||
class Component {
|
||||
<<abstract>>
|
||||
+reset()
|
||||
}
|
||||
class System {
|
||||
<<abstract>>
|
||||
+filter()
|
||||
+update(entity)
|
||||
}
|
||||
class Monster {
|
||||
-BattleMoveComp
|
||||
-MonModelComp
|
||||
-TalComp
|
||||
}
|
||||
class BattleMoveComp {
|
||||
+direction : number
|
||||
+targetX : number
|
||||
+moving : boolean
|
||||
}
|
||||
class MonModelComp {
|
||||
<<data container>>
|
||||
}
|
||||
class BattleMoveSystem {
|
||||
+filter()
|
||||
+update(entity)
|
||||
}
|
||||
Entity <|-- Monster
|
||||
Component <|-- BattleMoveComp
|
||||
Component <|-- MonModelComp
|
||||
System <|-- BattleMoveSystem
|
||||
Monster --> BattleMoveComp
|
||||
Monster --> MonModelComp
|
||||
BattleMoveSystem ..> BattleMoveComp : processes
|
||||
BattleMoveSystem ..> HeroViewComp : interacts with
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### Monster实体初始化机制
|
||||
Monster实体在初始化时通过`addComponents`方法注册了BattleMoveComp、MonModelComp和TalComp三个组件。这一过程遵循ECS框架的组件注册规范,确保实体具备必要的数据和行为能力。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant M as Monster
|
||||
participant ECS as ECS框架
|
||||
participant BMS as BattleMoveSystem
|
||||
M->>ECS : init()
|
||||
M->>ECS : addComponents(BattleMoveComp, MonModelComp, TalComp)
|
||||
ECS->>M : 返回组件实例引用
|
||||
M->>M : 设置HeroModel、HeroView、BattleMove成员变量
|
||||
M->>BMS : 系统检测到新实体
|
||||
BMS->>BMS : 将实体加入处理队列
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
|
||||
**Section sources**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L15-L30)
|
||||
|
||||
### BattleMoveComp移动逻辑解析
|
||||
BattleMoveComp组件负责管理怪物的移动行为,其核心属性包括`direction`(移动方向)、`targetX`(目标X坐标)和`moving`(移动状态)。在Monster的`load`方法中,这些属性被初始化为向左移动至-800坐标。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始移动]) --> CheckState["检查游戏状态<br/>(play && !pause)"]
|
||||
CheckState --> |否| End([停止移动])
|
||||
CheckState --> |是| CheckStop["检查停止条件<br/>(is_stop, is_dead, isStun等)"]
|
||||
CheckStop --> |是| SetIdle["设置idle状态"] --> End
|
||||
CheckStop --> |否| CalculateDelta["计算位移增量<br/>delta = (SPEED/3) * dt * direction"]
|
||||
CalculateDelta --> CalculateNewX["计算新X坐标<br/>newX = currentX + delta"]
|
||||
CalculateNewX --> ValidatePos["验证位置有效性"]
|
||||
ValidatePos --> |有效| UpdatePos["更新节点位置"] --> SetMove["设置move状态"] --> End
|
||||
ValidatePos --> |无效| StopMoving["设置moving=false"] --> SetIdle --> End
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L1-L15)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L50-L270)
|
||||
|
||||
**Section sources**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L80-L90)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
|
||||
### BoxSet.MONSTER碰撞分组角色
|
||||
BoxSet.MONSTER常量定义了怪物实体在物理系统中的碰撞分组标识,值为2。该常量不仅用于物理碰撞检测,还作为阵营标识参与游戏逻辑判断,如敌我识别、技能作用范围等。
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
BOXSET ||--o{ MONSTER : "包含"
|
||||
BOXSET ||--o{ HERO : "包含"
|
||||
BOXSET ||--o{ SKILL : "包含"
|
||||
BOXSET {
|
||||
int MONSTER
|
||||
int HERO
|
||||
int SKILL_TAG
|
||||
int ATK_RANGE
|
||||
}
|
||||
MONSTER {
|
||||
string name
|
||||
int group = 2
|
||||
}
|
||||
HERO {
|
||||
string name
|
||||
int group = 4
|
||||
}
|
||||
SKILL {
|
||||
string name
|
||||
int tag = 8
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L5-L15)
|
||||
|
||||
**Section sources**
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L75-L80)
|
||||
|
||||
### MonModelComp数据容器职责
|
||||
MonModelComp作为纯粹的数据容器组件,遵循ECS框架的组件设计原则。其主要职责是存储怪物的持久化数据,通过reset方法实现组件回收时的状态重置,保证组件在对象池中的可重用性。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MonModelComp {
|
||||
<<data container>>
|
||||
+reset()
|
||||
}
|
||||
note right of MonModelComp
|
||||
作为数据容器,不包含业务逻辑
|
||||
所有数据操作由系统或其他组件完成
|
||||
reset方法确保组件回收时状态清零
|
||||
end note
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts#L1-L20)
|
||||
|
||||
**Section sources**
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts)
|
||||
|
||||
## 依赖分析
|
||||
Monster实体的组件系统存在明确的依赖关系,BattleMoveComp依赖于HeroViewComp的存在,因为移动逻辑需要操作视图节点的位置和状态。这种依赖关系通过BattleMoveSystem的filter方法声明,确保只有同时拥有这两个组件的实体才会被系统处理。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[BattleMoveSystem] --> B[BattleMoveComp]
|
||||
A --> C[HeroViewComp]
|
||||
D[Monster] --> B
|
||||
D --> E[MonModelComp]
|
||||
D --> F[TalComp]
|
||||
D --> C
|
||||
style A fill:#f9f,stroke:#333
|
||||
style B fill:#bbf,stroke:#333
|
||||
style C fill:#bbf,stroke:#333
|
||||
style D fill:#9f9,stroke:#333
|
||||
style E fill:#f96,stroke:#333
|
||||
style F fill:#f96,stroke:#333
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L10-L15)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
|
||||
**Section sources**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
|
||||
## 性能考虑
|
||||
ECS架构通过组件对象池机制有效减少了运行时的内存分配和垃圾回收压力。BattleMoveComp和MonModelComp的reset方法确保了组件在销毁时能够正确重置状态,使其可以安全地返回对象池供后续复用,从而提升整体性能表现。
|
||||
|
||||
## 故障排除指南
|
||||
### 组件注册遗漏
|
||||
当Monster实体缺少必要组件时,可能导致移动功能失效或数据丢失。检查`init`方法中的`addComponents`调用,确保所有必需组件都被正确注册。
|
||||
|
||||
**Section sources**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L15-L30)
|
||||
|
||||
### 依赖顺序错误
|
||||
BattleMoveSystem要求实体同时拥有BattleMoveComp和HeroViewComp才能正常工作。如果组件添加顺序不当或遗漏HeroViewComp,系统将无法处理该实体。确保在调用`hero_init`方法前已完成所有必要组件的注册。
|
||||
|
||||
**Section sources**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L100-L120)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L10-L15)
|
||||
|
||||
## 结论
|
||||
Monster实体的ECS实现展示了良好的架构设计,通过组件化分离了数据与行为,提高了代码的可维护性和可扩展性。BattleMoveComp的移动逻辑与BoxSet.MONSTER的碰撞分组协同工作,确保了怪物在游戏世界中的正确行为。开发者在扩展功能时应遵循相同的组件设计原则,确保系统的稳定性和一致性。
|
||||
427
.qoder/repowiki/zh/content/地图系统/怪物系统/怪物系统.md
Normal file
427
.qoder/repowiki/zh/content/地图系统/怪物系统/怪物系统.md
Normal file
@@ -0,0 +1,427 @@
|
||||
# 怪物系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
Mon.ts文件定义了游戏中的怪物系统,采用ECS(Entity-Component-System)架构模式,通过继承Entity类并注册为`Monster`类型来实现怪物实体的管理和控制。该系统提供了完整的怪物生命周期管理,包括预制体动态加载、属性初始化、难度自适应调整以及移动行为控制等功能。
|
||||
|
||||
## 项目结构
|
||||
|
||||
怪物系统的文件组织结构体现了清晰的模块化设计:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "怪物系统模块"
|
||||
Mon[Mon.ts<br/>怪物实体类]
|
||||
MonModel[MonModelComp.ts<br/>怪物模型组件]
|
||||
BattleMove[BattleMoveComp.ts<br/>移动组件]
|
||||
end
|
||||
subgraph "配置系统"
|
||||
HeroSet[heroSet.ts<br/>英雄配置]
|
||||
HeroAttrs[HeroAttrs.ts<br/>属性配置]
|
||||
end
|
||||
subgraph "ECS系统"
|
||||
BattleMoveSys[BattleMoveSystem.ts<br/>移动系统]
|
||||
end
|
||||
Mon --> MonModel
|
||||
Mon --> BattleMove
|
||||
Mon --> HeroSet
|
||||
Mon --> HeroAttrs
|
||||
BattleMoveSys --> BattleMove
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L109)
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts#L1-L20)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L1-L16)
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L109)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L152)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### Monster实体类
|
||||
|
||||
Monster类是怪物系统的核心实体类,继承自ECS框架的Entity基类,并注册为`Monster`类型。该类实现了怪物的完整生命周期管理:
|
||||
|
||||
- **组件管理**:自动添加BattleMoveComp和MonModelComp组件
|
||||
- **生命周期控制**:提供init和destroy方法管理实体状态
|
||||
- **预制体加载**:通过load方法动态加载怪物预制体
|
||||
- **属性初始化**:通过hero_init方法设置怪物基础属性
|
||||
|
||||
### BattleMoveComp移动组件
|
||||
|
||||
BattleMoveComp负责控制怪物的移动行为,包含以下关键属性:
|
||||
|
||||
- **direction**:移动方向(1向右,-1向左)
|
||||
- **targetX**:目标X坐标
|
||||
- **moving**:移动状态标识
|
||||
|
||||
### 属性系统
|
||||
|
||||
怪物系统采用统一的属性管理机制,支持:
|
||||
|
||||
- **基础属性**:HP、MP、AP、DEF等核心战斗属性
|
||||
- **百分比属性**:暴击率、闪避率等百分比型属性
|
||||
- **特殊属性**:吸血、燃烧概率等特殊效果属性
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L17-L40)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L3-L15)
|
||||
|
||||
## 架构概览
|
||||
|
||||
怪物系统采用ECS架构模式,实现了高度解耦的设计:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Monster {
|
||||
+MonModelComp HeroModel
|
||||
+HeroViewComp HeroView
|
||||
+BattleMoveComp BattleMove
|
||||
+init() void
|
||||
+destroy() void
|
||||
+load(pos, scale, uuid, is_boss, is_call, strengthMultiplier) void
|
||||
+hero_init(uuid, node, scale, box_group, is_boss, is_call, strengthMultiplier) void
|
||||
}
|
||||
class BattleMoveComp {
|
||||
+number direction
|
||||
+number targetX
|
||||
+boolean moving
|
||||
+reset() void
|
||||
}
|
||||
class MonModelComp {
|
||||
+reset() void
|
||||
}
|
||||
class HeroViewComp {
|
||||
+number scale
|
||||
+FacSet fac
|
||||
+HType type
|
||||
+boolean is_boss
|
||||
+number box_group
|
||||
+number hero_uuid
|
||||
+string hero_name
|
||||
+number base_hp
|
||||
+number base_mp
|
||||
+number base_ap
|
||||
+number base_def
|
||||
+number hp
|
||||
+number mp
|
||||
+object Attrs
|
||||
+object skills
|
||||
+initAttrs() void
|
||||
}
|
||||
Monster --> BattleMoveComp : "包含"
|
||||
Monster --> MonModelComp : "包含"
|
||||
Monster --> HeroViewComp : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L17-L40)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L3-L15)
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts#L10-L19)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### load方法:预制体动态加载流程
|
||||
|
||||
load方法实现了怪物的完整初始化流程:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "调用方"
|
||||
participant Monster as "Monster实体"
|
||||
participant Resources as "资源系统"
|
||||
participant Scene as "场景节点"
|
||||
participant BattleMove as "BattleMove组件"
|
||||
Client->>Monster : load(pos, scale, uuid, ...)
|
||||
Monster->>Resources : 获取预制体路径
|
||||
Resources-->>Monster : 返回Prefab资源
|
||||
Monster->>Scene : 实例化预制体
|
||||
Scene-->>Monster : 返回Node节点
|
||||
Monster->>Monster : 设置位置和缩放
|
||||
Monster->>Monster : hero_init初始化属性
|
||||
Monster->>BattleMove : 设置移动参数
|
||||
BattleMove->>BattleMove : direction = -1
|
||||
BattleMove->>BattleMove : targetX = -800
|
||||
Monster->>Client : dispatchEvent("monster_load")
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L35-L58)
|
||||
|
||||
#### 关键步骤解析:
|
||||
|
||||
1. **预制体路径构建**:根据uuid从HeroInfo配置中获取对应的预制体路径
|
||||
2. **实例化处理**:使用oops.res.get获取预制体并实例化
|
||||
3. **场景集成**:将实例化的节点添加到场景的entityLayer中
|
||||
4. **碰撞体管理**:先禁用碰撞体,延迟一帧再启用以避免初始化问题
|
||||
5. **位置设置**:根据传入的pos参数设置怪物初始位置
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L35-L58)
|
||||
|
||||
### hero_init方法:难度自适应属性系统
|
||||
|
||||
hero_init方法实现了基于strengthMultiplier的难度自适应属性调整:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始初始化]) --> GetHeroInfo["获取英雄配置信息"]
|
||||
GetHeroInfo --> SetBasicProps["设置基础属性"]
|
||||
SetBasicProps --> CalcStrength["计算强度倍率"]
|
||||
CalcStrength --> AdjustHP["调整HP = hero.hp × strengthMultiplier"]
|
||||
AdjustHP --> AdjustAP["调整AP = hero.ap × strengthMultiplier"]
|
||||
AdjustAP --> AdjustDEF["调整DEF = hero.def × strengthMultiplier"]
|
||||
AdjustDEF --> LoadSkills["加载技能配置"]
|
||||
LoadSkills --> InitAttrs["初始化属性系统"]
|
||||
InitAttrs --> Complete([初始化完成])
|
||||
style Start fill:#e1f5fe
|
||||
style Complete fill:#e8f5e8
|
||||
style CalcStrength fill:#fff3e0
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L60-L91)
|
||||
|
||||
#### 属性调整机制:
|
||||
|
||||
1. **基础属性计算**:
|
||||
- HP = hero.hp × strengthMultiplier(向下取整)
|
||||
- AP = hero.ap × strengthMultiplier(向下取整)
|
||||
- DEF = hero.def × strengthMultiplier(向下取整)
|
||||
|
||||
2. **技能系统集成**:
|
||||
- 遍历hero.skills数组
|
||||
- 从SkillSet配置中获取技能详细信息
|
||||
- 创建技能对象并添加到hv.skills数组
|
||||
|
||||
3. **属性系统初始化**:
|
||||
- 调用getAttrs()获取默认属性值
|
||||
- 调用getNeAttrs()获取负面状态属性
|
||||
- 设置各项属性的基础值和当前值
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L60-L91)
|
||||
|
||||
### BattleMoveComp组件:移动行为控制
|
||||
|
||||
BattleMoveComp组件驱动怪物向左移动的行为:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Idle : 初始状态
|
||||
Idle --> Moving : 开始移动
|
||||
Moving --> Idle : 到达目标
|
||||
Moving --> Stopped : 遇到障碍
|
||||
Stopped --> Moving : 清除障碍
|
||||
Idle --> [*] : 销毁实体
|
||||
note right of Moving : direction = -1<br/>targetX = -800
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L3-L15)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L10-L271)
|
||||
|
||||
#### 移动参数配置:
|
||||
|
||||
- **direction = -1**:设置向左移动的方向
|
||||
- **targetX = -800**:设定左边界为目标位置
|
||||
- **moving = true**:启用移动状态
|
||||
|
||||
**章节来源**
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L3-L15)
|
||||
|
||||
### 数据复用机制:HeroAttrs与heroSet配置
|
||||
|
||||
怪物系统通过HeroAttrs.ts和heroSet.ts实现英雄配置的数据复用:
|
||||
|
||||
#### HeroAttrs.ts属性系统
|
||||
|
||||
HeroAttrs.ts定义了完整的属性枚举和类型系统:
|
||||
|
||||
| 属性类别 | 属性名称 | 类型 | 描述 |
|
||||
|---------|---------|------|------|
|
||||
| 基础生存属性 | HP_MAX | VALUE | 最大生命值 |
|
||||
| 基础生存属性 | MP_MAX | VALUE | 最大魔法值 |
|
||||
| 攻击属性 | AP | VALUE | 攻击力 |
|
||||
| 攻击属性 | MAP | VALUE | 魔法攻击力 |
|
||||
| 防御属性 | DEF | VALUE | 物理防御 |
|
||||
| 特殊效果属性 | CRITICAL | RATIO | 暴击率 |
|
||||
| 增益效果属性 | SPEED | RATIO | 移动速度加成 |
|
||||
|
||||
#### heroSet.ts配置系统
|
||||
|
||||
heroSet.ts提供了怪物配置的集中管理:
|
||||
|
||||
- **HeroInfo配置表**:存储所有怪物的基础属性数据
|
||||
- **MonSet位置配置**:定义怪物在战场上的初始位置
|
||||
- **职业类型枚举**:支持warrior、remote、mage、support、assassin五种职业
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L25-L105)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L60-L152)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
怪物系统的依赖关系体现了清晰的分层架构:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "外部依赖"
|
||||
ECS[ECS框架]
|
||||
CC[Cocos Creator]
|
||||
Oops[Oops插件框架]
|
||||
end
|
||||
subgraph "核心模块"
|
||||
Monster[Monster实体]
|
||||
BattleMove[BattleMove组件]
|
||||
HeroView[HeroView组件]
|
||||
end
|
||||
subgraph "配置模块"
|
||||
HeroInfo[HeroInfo配置]
|
||||
HeroAttrs[属性配置]
|
||||
SkillSet[技能配置]
|
||||
end
|
||||
subgraph "系统模块"
|
||||
BattleMoveSys[BattleMoveSystem]
|
||||
SingletonModule[单例模块]
|
||||
end
|
||||
Monster --> ECS
|
||||
Monster --> CC
|
||||
Monster --> Oops
|
||||
Monster --> BattleMove
|
||||
Monster --> HeroView
|
||||
Monster --> HeroInfo
|
||||
Monster --> HeroAttrs
|
||||
Monster --> SkillSet
|
||||
BattleMoveSys --> BattleMove
|
||||
BattleMoveSys --> HeroView
|
||||
SingletonModule --> Monster
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L15)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L10)
|
||||
|
||||
### 关键依赖说明:
|
||||
|
||||
1. **ECS框架依赖**:Monster类继承自ecs.Entity,BattleMoveComp继承自ecs.Comp
|
||||
2. **Cocos Creator依赖**:使用Node、Prefab、Vec3等Cocos类型
|
||||
3. **配置依赖**:依赖HeroInfo、HeroAttrs、SkillSet等配置模块
|
||||
4. **系统依赖**:依赖BattleMoveSystem进行移动逻辑处理
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L15)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L10)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 内存管理优化
|
||||
|
||||
1. **组件化设计**:通过组件分离职责,避免单个类过于庞大
|
||||
2. **生命周期管理**:destroy方法确保正确清理组件引用
|
||||
3. **资源池化**:预制体实例化采用资源管理系统
|
||||
|
||||
### 性能优化策略
|
||||
|
||||
1. **批量更新**:BattleMoveSystem采用批量处理方式
|
||||
2. **条件检查**:在更新前进行状态检查,避免不必要的计算
|
||||
3. **边界检测**:使用validatePosition方法限制移动范围
|
||||
|
||||
### 扩展性设计
|
||||
|
||||
1. **配置驱动**:通过配置文件控制怪物属性和行为
|
||||
2. **组件扩展**:支持添加新的组件类型
|
||||
3. **系统扩展**:BattleMoveSystem可添加新的移动逻辑
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 1. 怪物无法正常移动
|
||||
|
||||
**问题现象**:怪物加载后静止不动
|
||||
|
||||
**排查步骤**:
|
||||
- 检查BattleMoveComp的moving属性是否为true
|
||||
- 验证targetX设置是否合理
|
||||
- 确认BattleMoveSystem是否正常运行
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 确保移动组件正确初始化
|
||||
const move = this.get(BattleMoveComp);
|
||||
move.moving = true;
|
||||
move.targetX = -800; // 设置合理的边界值
|
||||
```
|
||||
|
||||
#### 2. 属性计算错误
|
||||
|
||||
**问题现象**:怪物属性显示异常
|
||||
|
||||
**排查步骤**:
|
||||
- 检查strengthMultiplier参数是否正确传递
|
||||
- 验证HeroInfo配置中的基础属性值
|
||||
- 确认属性计算逻辑
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 确保属性计算正确
|
||||
const baseHp = Math.floor(hero.hp * strengthMultiplier);
|
||||
const baseAp = Math.floor(hero.ap * strengthMultiplier);
|
||||
const baseDef = Math.floor(hero.def * strengthMultiplier);
|
||||
```
|
||||
|
||||
#### 3. 预制体加载失败
|
||||
|
||||
**问题现象**:怪物无法显示模型
|
||||
|
||||
**排查步骤**:
|
||||
- 检查HeroInfo中的path配置是否正确
|
||||
- 验证资源路径是否存在
|
||||
- 确认资源是否已正确打包
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 确保资源路径正确
|
||||
var path = "game/heros/" + HeroInfo[uuid].path;
|
||||
var prefab: Prefab = oops.res.get(path, Prefab)!;
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L35-L58)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L10-L50)
|
||||
|
||||
## 结论
|
||||
|
||||
Mon.ts文件实现了一个功能完整、架构清晰的怪物系统。通过ECS架构模式,系统实现了高度的模块化和可扩展性。主要特点包括:
|
||||
|
||||
1. **ECS架构优势**:通过组件化设计实现了职责分离和代码复用
|
||||
2. **难度自适应**:基于strengthMultiplier的属性调整机制提供了灵活的难度控制
|
||||
3. **数据复用**:通过HeroAttrs和heroSet配置系统实现了数据的集中管理
|
||||
4. **性能优化**:采用组件化和批量处理策略确保良好的运行性能
|
||||
5. **扩展性强**:支持添加新怪物类型、配置技能组合和实现召唤单位等扩展需求
|
||||
|
||||
该系统为游戏开发提供了坚实的基础,能够满足不同类型怪物的开发需求,同时保持了良好的维护性和扩展性。
|
||||
498
.qoder/repowiki/zh/content/地图系统/怪物系统/技能机制.md
Normal file
498
.qoder/repowiki/zh/content/地图系统/怪物系统/技能机制.md
Normal file
@@ -0,0 +1,498 @@
|
||||
# 技能机制
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [核心组件架构](#核心组件架构)
|
||||
3. [技能初始化机制](#技能初始化机制)
|
||||
4. [技能控制系统](#技能控制系统)
|
||||
5. [技能数据结构](#技能数据结构)
|
||||
6. [技能释放流程](#技能释放流程)
|
||||
7. [技能类型与效果](#技能类型与效果)
|
||||
8. [开发指引](#开发指引)
|
||||
9. [常见问题与解决方案](#常见问题与解决方案)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 概述
|
||||
|
||||
本游戏采用基于ECS(Entity-Component-System)架构的技能系统,通过多个核心组件协同工作,实现了复杂的技能机制。技能系统支持主动技能、被动技能、技能组合以及自定义技能行为,为战斗提供了丰富的策略深度。
|
||||
|
||||
## 核心组件架构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Monster {
|
||||
+MonModelComp HeroModel
|
||||
+HeroViewComp HeroView
|
||||
+BattleMoveComp BattleMove
|
||||
+hero_init(uuid, node, scale, box_group, is_boss, is_call, strength_multiplier)
|
||||
+load(pos, scale, uuid, is_boss, is_call, strengthMultiplier)
|
||||
}
|
||||
class SkillConComp {
|
||||
+HeroView HeroView
|
||||
+HeroEntity HeroEntity
|
||||
+TALCOMP TALCOMP
|
||||
+skill_cd number
|
||||
+update(dt)
|
||||
+castSkill(config)
|
||||
+doSkill(config, is_wfuny, dmg)
|
||||
+selectTargets(t_num)
|
||||
}
|
||||
class SkillEnt {
|
||||
+load(startPos, parent, uuid, targetPos, caster, dmg)
|
||||
+destroy()
|
||||
}
|
||||
class HeroViewComp {
|
||||
+skills any[]
|
||||
+mp number
|
||||
+hp number
|
||||
+Attrs any[]
|
||||
+playSkillEffect(skill_id)
|
||||
+do_atked(remainingDamage, CAttrs, s_uuid)
|
||||
}
|
||||
class SkillSet {
|
||||
+uuid number
|
||||
+name string
|
||||
+SType SType
|
||||
+TGroup TGroup
|
||||
+ap number
|
||||
+cd number
|
||||
+cost number
|
||||
}
|
||||
Monster --> SkillConComp : "包含"
|
||||
SkillConComp --> HeroViewComp : "控制"
|
||||
SkillConComp --> SkillEnt : "创建"
|
||||
SkillEnt --> SkillViewCom : "加载"
|
||||
HeroViewComp --> SkillSet : "使用配置"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L111)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L780)
|
||||
|
||||
## 技能初始化机制
|
||||
|
||||
### hero_init方法详解
|
||||
|
||||
`hero_init`方法是技能初始化的核心入口,负责根据英雄配置动态创建技能实例并设置各项参数。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["开始 hero_init"] --> B["获取英雄配置"]
|
||||
B --> C["初始化基础属性"]
|
||||
C --> D["遍历技能数组"]
|
||||
D --> E["创建技能对象"]
|
||||
E --> F["设置UUID、CD、消耗值"]
|
||||
F --> G["添加到技能列表"]
|
||||
G --> H["初始化属性系统"]
|
||||
H --> I["结束"]
|
||||
E --> E1["uuid: SkillSet[hero.skills[i]].uuid"]
|
||||
E --> E2["cd_max: SkillSet[hero.skills[i]].cd"]
|
||||
E --> E3["cost: SkillSet[hero.skills[i]].cost"]
|
||||
E --> E4["cd: 0"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L65-L85)
|
||||
|
||||
#### 技能初始化步骤
|
||||
|
||||
1. **英雄配置获取**:从`HeroInfo`中获取英雄基础数据
|
||||
2. **属性基础值设置**:根据强度倍率调整基础属性值
|
||||
3. **技能数组遍历**:逐个处理英雄配置中的技能UUID
|
||||
4. **技能对象创建**:为每个技能创建包含UUID、冷却时间、消耗值的对象
|
||||
5. **技能列表填充**:将创建的技能对象添加到`HeroView.skills`数组
|
||||
6. **属性系统初始化**:调用`initAttrs()`初始化完整属性系统
|
||||
|
||||
**节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L65-L85)
|
||||
|
||||
### 技能配置数据结构
|
||||
|
||||
技能配置通过`SkillSet`常量定义,支持多种技能类型和效果:
|
||||
|
||||
| 属性 | 类型 | 描述 | 示例值 |
|
||||
|------|------|------|--------|
|
||||
| uuid | number | 技能唯一标识符 | 6001, 6005 |
|
||||
| name | string | 技能显示名称 | "挥击", "火球术" |
|
||||
| SType | SType | 技能效果类型 | SType.damage, SType.heal |
|
||||
| TGroup | TGroup | 目标群体类型 | TGroup.Enemy, TGroup.Self |
|
||||
| ap | number | 攻击力百分比 | 100, 300 |
|
||||
| cd | number | 冷却时间(秒) | 1, 5 |
|
||||
| cost | number | 技能消耗值 | 0, 20 |
|
||||
| hit_num | number | 攻击目标数量 | 1, 3 |
|
||||
|
||||
**节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L80-L147)
|
||||
|
||||
## 技能控制系统
|
||||
|
||||
### SkillConComp组件功能
|
||||
|
||||
`SkillConComp`是技能系统的核心控制器,负责技能触发、冷却管理和释放流程。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as "玩家输入"
|
||||
participant SkillCon as "SkillConComp"
|
||||
participant HeroView as "HeroViewComp"
|
||||
participant SkillEnt as "SkillEnt"
|
||||
participant SkillView as "SkillViewCom"
|
||||
Player->>SkillCon : 技能触发请求
|
||||
SkillCon->>SkillCon : 检查冷却时间
|
||||
SkillCon->>SkillCon : 检查MP消耗
|
||||
SkillCon->>SkillCon : castSkill()
|
||||
SkillCon->>SkillCon : doSkill()
|
||||
SkillCon->>SkillCon : selectTargets()
|
||||
SkillCon->>SkillEnt : 创建技能实体
|
||||
SkillEnt->>SkillView : 加载技能视图
|
||||
SkillView->>SkillView : 执行技能动画
|
||||
SkillView->>SkillView : 处理碰撞检测
|
||||
SkillView->>HeroView : 造成伤害/效果
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L40-L110)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L70)
|
||||
|
||||
#### 技能触发机制
|
||||
|
||||
技能触发遵循以下优先级和条件:
|
||||
|
||||
1. **状态检查**:确保角色未处于眩晕或冰冻状态
|
||||
2. **冷却检查**:技能CD时间超过最大值
|
||||
3. **资源检查**:MP值足够支付技能消耗
|
||||
4. **类型匹配**:技能类型为伤害类且角色处于攻击状态
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L38-L48)
|
||||
|
||||
### 冷却管理系统
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["update(dt)"] --> B{"游戏状态检查"}
|
||||
B --> |暂停/未开始| C["跳过更新"]
|
||||
B --> |正常| D["遍历技能列表"]
|
||||
D --> E["累积CD时间"]
|
||||
E --> F{"CD > CD_MAX AND MP >= COST?"}
|
||||
F --> |是| G["触发技能"]
|
||||
F --> |否| H["继续等待"]
|
||||
G --> I["重置CD = 0"]
|
||||
I --> J["扣除MP"]
|
||||
J --> K["播放技能效果"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L38-L48)
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L38-L48)
|
||||
|
||||
## 技能数据结构
|
||||
|
||||
### SkillSet配置系统
|
||||
|
||||
`SkillSet`提供了完整的技能数据结构定义,支持技能的完整生命周期管理。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SkillConfig {
|
||||
+uuid : number
|
||||
+name : string
|
||||
+sp_name : string
|
||||
+path : string
|
||||
+TGroup : TGroup
|
||||
+SType : SType
|
||||
+act : string
|
||||
+DTType : DTType
|
||||
+DType : DType
|
||||
+ap : number
|
||||
+cd : number
|
||||
+t_num : number
|
||||
+hit_num : number
|
||||
+hit : number
|
||||
+hitcd : number
|
||||
+speed : number
|
||||
+cost : number
|
||||
+with : number
|
||||
+buffs : BuffConf[]
|
||||
+neAttrs : NeAttrsConf[]
|
||||
+info : string
|
||||
}
|
||||
class BuffConf {
|
||||
+buff : Attrs
|
||||
+BType : BType
|
||||
+value : number
|
||||
+time : number
|
||||
+chance : number
|
||||
}
|
||||
class NeAttrsConf {
|
||||
+neAttrs : NeAttrs
|
||||
+value : number
|
||||
+time : number
|
||||
}
|
||||
SkillConfig --> BuffConf : "包含"
|
||||
SkillConfig --> NeAttrsConf : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L95-L147)
|
||||
|
||||
### 技能类型枚举
|
||||
|
||||
| SType值 | 类型名称 | 效果描述 | 使用场景 |
|
||||
|---------|----------|----------|----------|
|
||||
| 0 | damage | 造成伤害 | 主要攻击技能 |
|
||||
| 1 | heal | 治疗效果 | 辅助/回复技能 |
|
||||
| 2 | shield | 护盾效果 | 防御型技能 |
|
||||
| 3 | atk_speed | 攻击速度提升 | 增益技能 |
|
||||
| 4 | power_up | 力量提升 | 战斗强化技能 |
|
||||
| 5 | ap_up | 攻击力提升 | 输出增强技能 |
|
||||
| 10 | zhaohuan | 召唤技能 | 召唤物技能 |
|
||||
| 11 | buff | 通用增益 | 多功能增益技能 |
|
||||
|
||||
**节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L35-L50)
|
||||
|
||||
## 技能释放流程
|
||||
|
||||
### 技能实体创建流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant SkillCon as "SkillConComp"
|
||||
participant ECS as "ECS系统"
|
||||
participant SkillEnt as "SkillEnt"
|
||||
participant SkillView as "SkillViewCom"
|
||||
participant AtkCon as "AtkConCom"
|
||||
SkillCon->>ECS : 获取SkillEnt实体
|
||||
ECS-->>SkillCon : 返回SkillEnt实例
|
||||
SkillCon->>SkillEnt : load(startPos, parent, uuid, targetPos, caster, dmg)
|
||||
SkillEnt->>SkillEnt : 验证技能配置
|
||||
SkillEnt->>SkillEnt : 加载技能预制体
|
||||
SkillEnt->>SkillEnt : 设置节点属性
|
||||
SkillEnt->>SkillView : 添加SkillViewCom组件
|
||||
SkillView->>SkillView : 初始化技能参数
|
||||
SkillView->>SkillView : 创建AtkConCom实例
|
||||
SkillView->>AtkCon : 配置攻击组件
|
||||
AtkCon->>AtkCon : 执行具体技能逻辑
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L70)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L60-L120)
|
||||
|
||||
### 目标选择算法
|
||||
|
||||
技能系统实现了智能的目标选择机制,支持多种目标选择策略:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["开始目标选择"] --> B{"是否有目标实体?"}
|
||||
B --> |否| C["返回默认位置"]
|
||||
B --> |是| D["获取所有目标实体"]
|
||||
D --> E["第一个目标:最前排"]
|
||||
E --> F["后续目标:随机选择"]
|
||||
F --> G["返回目标坐标数组"]
|
||||
E --> E1["计算最前排位置"]
|
||||
E1 --> E2["选择最近的实体"]
|
||||
F --> F1["随机选择实体"]
|
||||
F1 --> F2["重复选择可重复"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L115-L150)
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L115-L150)
|
||||
|
||||
## 技能类型与效果
|
||||
|
||||
### 伤害计算机制
|
||||
|
||||
技能造成的伤害通过多层计算确定:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["基础攻击力"] --> B["应用技能AP比例"]
|
||||
B --> C["计算最终伤害"]
|
||||
C --> D{"是否暴击?"}
|
||||
D --> |是| E["应用暴击伤害倍率"]
|
||||
D --> |否| F["普通伤害"]
|
||||
E --> G["应用穿透效果"]
|
||||
F --> G
|
||||
G --> H["应用护盾吸收"]
|
||||
H --> I["最终伤害值"]
|
||||
G --> G1["计算穿透衰减"]
|
||||
G1 --> G2["应用穿透属性"]
|
||||
H --> H1["检查护盾值"]
|
||||
H1 --> H2["计算吸收量"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L650-L680)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L130-L160)
|
||||
|
||||
### Buff系统集成
|
||||
|
||||
技能系统与Buff系统紧密集成,支持技能触发Buff效果:
|
||||
|
||||
| Buff类型 | BType | 效果 | 应用时机 |
|
||||
|----------|-------|------|----------|
|
||||
| 数值型 | VALUE | 直接数值加成 | 属性计算时 |
|
||||
| 百分比型 | RATIO | 百分比加成 | 属性计算时 |
|
||||
| 持久型 | - | 永久生效 | 持续应用 |
|
||||
| 临时型 | - | 按时间衰减 | 定时更新 |
|
||||
|
||||
**节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L150-L200)
|
||||
|
||||
## 开发指引
|
||||
|
||||
### 为怪物配置主动技能
|
||||
|
||||
1. **编辑heroSet.ts**:在`HeroInfo`中添加怪物配置
|
||||
2. **配置技能数组**:在`skills`字段中指定技能UUID
|
||||
3. **调整属性值**:根据怪物定位设置HP、MP、AP等属性
|
||||
4. **测试平衡性**:验证技能冷却和消耗的合理性
|
||||
|
||||
### 实现技能组合
|
||||
|
||||
```typescript
|
||||
// 示例:配置多重技能组合
|
||||
const monsterConfig = {
|
||||
uuid: 5201,
|
||||
name: "兽人战士",
|
||||
skills: [6001, 6005, 6006], // 多个技能
|
||||
// 其他属性...
|
||||
};
|
||||
|
||||
// 在技能触发时添加组合效果
|
||||
SkillConComp.prototype.comboSkills = function() {
|
||||
// 实现技能组合逻辑
|
||||
// 如:连续使用技能获得额外效果
|
||||
};
|
||||
```
|
||||
|
||||
### 自定义技能行为
|
||||
|
||||
1. **扩展SkillSet**:在`SkillSet`中添加新技能配置
|
||||
2. **实现特殊效果**:在`AtkConCom`中添加自定义逻辑
|
||||
3. **注册事件监听**:监听技能触发相关事件
|
||||
4. **测试兼容性**:确保新技能与现有系统兼容
|
||||
|
||||
**节来源**
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L120-L152)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L80-L147)
|
||||
|
||||
## 常见问题与解决方案
|
||||
|
||||
### 技能同步问题
|
||||
|
||||
#### 问题描述
|
||||
多人游戏中技能释放不同步,导致战斗结果不一致。
|
||||
|
||||
#### 解决方案
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["技能释放请求"] --> B["客户端验证"]
|
||||
B --> C["发送服务器确认"]
|
||||
C --> D["服务器验证"]
|
||||
D --> E{"验证通过?"}
|
||||
E --> |是| F["广播技能效果"]
|
||||
E --> |否| G["拒绝请求"]
|
||||
F --> H["客户端同步显示"]
|
||||
G --> I["显示错误提示"]
|
||||
D --> D1["检查冷却时间"]
|
||||
D --> D2["检查资源充足"]
|
||||
D --> D3["检查状态允许"]
|
||||
```
|
||||
|
||||
#### 实现要点
|
||||
|
||||
1. **服务器端验证**:所有技能释放必须经过服务器验证
|
||||
2. **延迟补偿**:处理网络延迟导致的技能时间差
|
||||
3. **状态同步**:确保客户端和服务器状态一致
|
||||
4. **错误处理**:优雅处理同步失败的情况
|
||||
|
||||
### 性能优化建议
|
||||
|
||||
#### 技能实体管理
|
||||
|
||||
```typescript
|
||||
// 优化技能实体创建和销毁
|
||||
class SkillEntityManager {
|
||||
private pool: SkillEnt[] = [];
|
||||
|
||||
createSkill(config: SkillConfig): SkillEnt {
|
||||
let skill = this.pool.pop();
|
||||
if (!skill) {
|
||||
skill = ecs.getEntity<SkillEnt>(SkillEnt);
|
||||
}
|
||||
skill.load(...);
|
||||
return skill;
|
||||
}
|
||||
|
||||
recycleSkill(skill: SkillEnt): void {
|
||||
skill.reset();
|
||||
this.pool.push(skill);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 冷却时间优化
|
||||
|
||||
1. **批量更新**:每帧批量处理所有技能的CD更新
|
||||
2. **优先级调度**:优先处理重要技能的冷却检查
|
||||
3. **内存池**:复用技能对象减少GC压力
|
||||
|
||||
### 调试工具
|
||||
|
||||
#### 技能日志系统
|
||||
|
||||
```typescript
|
||||
class SkillDebugger {
|
||||
static logSkillExecution(skillId: number, params: any): void {
|
||||
console.log(`[Skill] 执行技能 ${skillId}`, {
|
||||
timestamp: Date.now(),
|
||||
params,
|
||||
performance: performance.now()
|
||||
});
|
||||
}
|
||||
|
||||
static logCooldownUpdate(skillId: number, currentCD: number, maxCD: number): void {
|
||||
console.log(`[Skill] 技能${skillId}冷却: ${currentCD}/${maxCD}`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L40-L60)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L30)
|
||||
|
||||
## 总结
|
||||
|
||||
本技能系统通过ECS架构实现了高度模块化和可扩展的设计,主要特点包括:
|
||||
|
||||
1. **模块化架构**:各组件职责明确,便于维护和扩展
|
||||
2. **灵活配置**:通过SkillSet实现技能的完全配置化
|
||||
3. **性能优化**:采用对象池和批量处理提高性能
|
||||
4. **扩展性强**:支持自定义技能类型和效果
|
||||
5. **网络友好**:内置同步机制确保多人游戏一致性
|
||||
|
||||
该系统为游戏战斗提供了坚实的技术基础,支持复杂技能组合和策略玩法,是构建高质量战斗体验的重要组成部分。
|
||||
503
.qoder/repowiki/zh/content/地图系统/肉鸽关卡配置/关卡生成规则.md
Normal file
503
.qoder/repowiki/zh/content/地图系统/肉鸽关卡配置/关卡生成规则.md
Normal file
@@ -0,0 +1,503 @@
|
||||
# 关卡生成规则
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构概览](#项目结构概览)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [关卡类型判定逻辑](#关卡类型判定逻辑)
|
||||
5. [怪物配置规则](#怪物配置规则)
|
||||
6. [动态数量计算机制](#动态数量计算机制)
|
||||
7. [强度倍率计算](#强度倍率计算)
|
||||
8. [事件系统集成](#事件系统集成)
|
||||
9. [GameMap集成调用](#gamemap集成调用)
|
||||
10. [配置修改指南](#配置修改指南)
|
||||
11. [性能优化考虑](#性能优化考虑)
|
||||
12. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
RogueConfig.ts是肉鸽模式的核心配置脚本,实现了动态关卡生成系统。该系统通过复杂的关卡类型判定逻辑、智能的怪物配置规则和渐进式的难度曲线,为玩家提供持续挑战的游戏体验。系统支持普通、精英、Boss和事件四种关卡类型,并具备完善的随机事件机制。
|
||||
|
||||
## 项目结构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "关卡生成系统"
|
||||
RC[RogueConfig.ts<br/>核心配置脚本]
|
||||
MC[MissionMonComp.ts<br/>怪物管理组件]
|
||||
GM[GameMap.ts<br/>游戏地图]
|
||||
end
|
||||
subgraph "配置数据"
|
||||
SCR[StageConfigRules<br/>关卡配置规则]
|
||||
EC[EventConfig<br/>事件配置]
|
||||
EML[EliteMonsterList<br/>精英怪物列表]
|
||||
BML[BossMonsterList<br/>Boss怪物列表]
|
||||
end
|
||||
subgraph "运行时组件"
|
||||
ST[getStageType<br/>关卡类型判定]
|
||||
CMC[calculateMonsterCount<br/>数量计算]
|
||||
CMSM[calculateMonsterStrengthMultiplier<br/>强度计算]
|
||||
GSC[generateStageConfig<br/>关卡配置生成]
|
||||
end
|
||||
RC --> SCR
|
||||
RC --> EC
|
||||
RC --> EML
|
||||
RC --> BML
|
||||
RC --> ST
|
||||
RC --> CM
|
||||
RC --> CMSM
|
||||
RC --> GSC
|
||||
MC --> RC
|
||||
GM --> MC
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L311)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### 关卡类型枚举系统
|
||||
|
||||
系统定义了四个主要的关卡类型,每种类型都有其独特的特征和配置规则:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class StageType {
|
||||
<<enumeration>>
|
||||
+NORMAL : "normal"
|
||||
+ELITE : "elite"
|
||||
+BOSS : "boss"
|
||||
+EVENT : "event"
|
||||
}
|
||||
class MonsterType {
|
||||
<<enumeration>>
|
||||
+NORMAL : "normal"
|
||||
+ELITE : "elite"
|
||||
+BOSS : "boss"
|
||||
}
|
||||
class EventType {
|
||||
<<enumeration>>
|
||||
+TREASURE : "treasure"
|
||||
+TRAP : "trap"
|
||||
+BUFF : "buff"
|
||||
+DEBUFF : "debuff"
|
||||
}
|
||||
class StageConfigRules {
|
||||
+NORMAL : Config
|
||||
+ELITE : Config
|
||||
+BOSS : Config
|
||||
+EVENT : Config
|
||||
}
|
||||
StageType --> StageConfigRules : "使用"
|
||||
MonsterType --> StageConfigRules : "配置"
|
||||
EventType --> EventConfig : "触发"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L25-L52)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L25-L52)
|
||||
|
||||
### 怪物配置表结构
|
||||
|
||||
系统维护了专门的怪物配置表,用于管理不同类型的怪物:
|
||||
|
||||
| 怪物类型 | 配置表 | 描述 |
|
||||
|---------|--------|------|
|
||||
| 普通怪物 | getMonList() | 基础怪物配置,通过HeroInfo过滤得到 |
|
||||
| 精英怪物 | EliteMonsterList | 特殊精英怪物列表,包含5201、5202、5203等 |
|
||||
| Boss怪物 | BossMonsterList | Boss怪物配置,目前包含5201、5202等 |
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L17-L32)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L32-L38)
|
||||
|
||||
## 关卡类型判定逻辑
|
||||
|
||||
### getStageType函数详解
|
||||
|
||||
getStageType函数是关卡类型判定的核心逻辑,采用分层决策树结构:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始关卡类型判定]) --> CheckEvent{"检查是否为5的倍数关卡且等级为3"}
|
||||
CheckEvent --> |是| ReturnEvent[返回EVENT类型]
|
||||
CheckEvent --> |否| CheckTen{"检查是否为10的倍数关卡"}
|
||||
CheckTen --> |是| CheckLevelTen{"检查等级"}
|
||||
CheckLevelTen --> |等级5| ReturnBoss[返回BOSS类型]
|
||||
CheckLevelTen --> |等级4| ReturnElite[返回ELITE类型]
|
||||
CheckLevelTen --> |其他| ReturnNormal[返回NORMAL类型]
|
||||
CheckTen --> |否| CheckLevel{"检查等级"}
|
||||
CheckLevel --> |等级5| ReturnElite2[返回ELITE类型]
|
||||
CheckLevel --> |其他| ReturnNormal2[返回NORMAL类型]
|
||||
ReturnEvent --> End([结束])
|
||||
ReturnBoss --> End
|
||||
ReturnElite --> End
|
||||
ReturnNormal --> End
|
||||
ReturnElite2 --> End
|
||||
ReturnNormal2 --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L129-L168)
|
||||
|
||||
### 特殊关卡规则详解
|
||||
|
||||
#### 事件关卡规则
|
||||
- **触发条件**:关卡号为5的倍数(5、10、15...)且玩家等级为3
|
||||
- **特点**:包含少量普通怪物,提供随机事件机会
|
||||
- **概率分布**:30%宝箱、25%陷阱、25%增益、20%减益
|
||||
|
||||
#### Boss关卡规则
|
||||
- **触发条件**:关卡号为10的倍数(10、20、30...)
|
||||
- **等级要求**:仅在特定等级触发
|
||||
- 第5级:Boss关卡
|
||||
- 第4级:精英关卡
|
||||
- 其他等级:普通关卡
|
||||
|
||||
#### 精英关卡规则
|
||||
- **触发条件**:玩家等级达到5级
|
||||
- **特点**:混合精英和普通怪物,提供更高挑战
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L129-L168)
|
||||
|
||||
## 怪物配置规则
|
||||
|
||||
### StageConfigRules配置体系
|
||||
|
||||
StageConfigRules提供了四类关卡的详细配置规则:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "普通关卡"
|
||||
NC[3个普通怪物<br/>基础数量: 3<br/>最小数量: 2<br/>最大数量: 6]
|
||||
end
|
||||
subgraph "精英关卡"
|
||||
EC1[2个精英怪物<br/>基础数量: 2<br/>最小数量: 1<br/>最大数量: 4]
|
||||
EC2[3个普通怪物<br/>基础数量: 3<br/>最小数量: 2<br/>最大数量: 5]
|
||||
end
|
||||
subgraph "Boss关卡"
|
||||
BC1[1个Boss怪物<br/>基础数量: 1<br/>最小数量: 1<br/>最大数量: 1]
|
||||
BC2[2个精英怪物<br/>基础数量: 2<br/>最小数量: 1<br/>最大数量: 3]
|
||||
BC3[2个普通怪物<br/>基础数量: 2<br/>最小数量: 1<br/>最大数量: 4]
|
||||
end
|
||||
subgraph "事件关卡"
|
||||
VC[2个普通怪物<br/>基础数量: 2<br/>最小数量: 1<br/>最大数量: 4]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L54-L95)
|
||||
|
||||
### 怪物数量扩展机制
|
||||
|
||||
系统实现了智能的数量扩展算法,确保游戏体验的平衡性:
|
||||
|
||||
#### 扩展公式
|
||||
```
|
||||
实际数量 = 基础数量 + floor(关卡号 / 5)
|
||||
```
|
||||
|
||||
#### 数量范围控制
|
||||
- 使用`Math.max(minCount, Math.min(maxCount, count))`确保数量在合理范围内
|
||||
- 每5关递增1个怪物,避免突变式难度提升
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L54-L95)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L150-L168)
|
||||
|
||||
## 动态数量计算机制
|
||||
|
||||
### calculateMonsterCount函数实现
|
||||
|
||||
calculateMonsterCount函数负责根据关卡进度动态调整怪物数量:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Caller as 调用方
|
||||
participant CMC as calculateMonsterCount
|
||||
participant Formula as 数量计算公式
|
||||
Caller->>CMC : calculateMonsterCount(stageNumber, baseCount, minCount, maxCount)
|
||||
CMC->>Formula : increment = Math.floor(stageNumber / 5)
|
||||
Formula-->>CMC : 返回增量值
|
||||
CMC->>CMC : count = baseCount + increment
|
||||
CMC->>CMC : count = Math.max(minCount, Math.min(maxCount, count))
|
||||
CMC-->>Caller : 返回实际怪物数量
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L150-L168)
|
||||
|
||||
### 数量增长曲线分析
|
||||
|
||||
| 关卡范围 | 基础数量 | 增量 | 最终数量范围 |
|
||||
|---------|----------|------|-------------|
|
||||
| 1-4 | 3 | 0 | 3-6 |
|
||||
| 5-9 | 3 | 1 | 4-6 |
|
||||
| 10-14 | 3 | 2 | 5-6 |
|
||||
| 15+ | 3 | 3+ | 6 |
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L150-L168)
|
||||
|
||||
## 强度倍率计算
|
||||
|
||||
### calculateMonsterStrengthMultiplier函数
|
||||
|
||||
系统实现了双维度的强度倍率计算,综合考虑关卡进度和玩家等级:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始强度计算]) --> CalcStage["计算关卡倍率<br/>stageMultiplier = 1 + (stageNumber - 1) * 0.1"]
|
||||
CalcStage --> CalcLevel["计算等级倍率<br/>levelMultiplier = 1 + (level - 1) * 0.05"]
|
||||
CalcLevel --> Multiply["计算总倍率<br/>strengthMultiplier = stageMultiplier * levelMultiplier"]
|
||||
Multiply --> Return[返回强度倍率]
|
||||
Return --> End([结束])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L170-L178)
|
||||
|
||||
### 强度增长特性
|
||||
|
||||
#### 关卡维度
|
||||
- 每关增加10%的强度
|
||||
- 关卡1: 1.0x
|
||||
- 关卡5: 1.4x
|
||||
- 关卡10: 1.9x
|
||||
- 关卡20: 2.9x
|
||||
|
||||
#### 等级维度
|
||||
- 每级增加5%的强度
|
||||
- 等级1: 1.0x
|
||||
- 等级3: 1.1x
|
||||
- 等级5: 1.2x
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L170-L178)
|
||||
|
||||
## 事件系统集成
|
||||
|
||||
### 随机事件配置
|
||||
|
||||
EventConfig提供了完整的随机事件系统:
|
||||
|
||||
| 事件类型 | 触发概率 | 效果描述 |
|
||||
|---------|----------|----------|
|
||||
| TREASURE | 30% | 获得额外奖励(+50金币) |
|
||||
| TRAP | 25% | 受到一定伤害 |
|
||||
| BUFF | 25% | 获得临时增益效果 |
|
||||
| DEBUFF | 20% | 受到临时减益效果 |
|
||||
|
||||
### 事件触发机制
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MC as MissionMonComp
|
||||
participant RC as RogueConfig
|
||||
participant EC as EventConfig
|
||||
MC->>RC : getStageType(stageNumber, level)
|
||||
RC-->>MC : 返回关卡类型
|
||||
MC->>MC : 检查是否为EVENT类型
|
||||
alt 是事件关卡
|
||||
MC->>RC : getRandomEvent()
|
||||
RC->>EC : 遍历事件配置
|
||||
EC-->>RC : 返回事件类型
|
||||
RC-->>MC : 返回EventType
|
||||
MC->>MC : processRandomEvent()
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L97-L127)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L293-L310)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L97-L127)
|
||||
|
||||
## GameMap集成调用
|
||||
|
||||
### MissionMonComp集成流程
|
||||
|
||||
MissionMonComp作为GameMap的核心组件,负责关卡生成的执行:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant GM as GameMap
|
||||
participant MC as MissionMonComp
|
||||
participant RC as RogueConfig
|
||||
GM->>MC : do_mon_wave()
|
||||
MC->>MC : 重置召唤状态
|
||||
MC->>RC : getStageType(currentStage, level)
|
||||
RC-->>MC : 返回关卡类型
|
||||
MC->>MC : 检查是否为事件关卡
|
||||
alt 是事件关卡
|
||||
MC->>RC : getRandomEvent()
|
||||
RC-->>MC : 返回事件类型
|
||||
end
|
||||
MC->>RC : getStageMonsterConfigs(currentStage, level)
|
||||
RC-->>MC : 返回怪物配置数组
|
||||
MC->>MC : generateMonstersFromStageConfig()
|
||||
MC->>MC : addToStageSpawnQueue()
|
||||
MC->>MC : spawnNextMonster()
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L95-L115)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L147-L169)
|
||||
|
||||
### 怪物生成队列管理
|
||||
|
||||
系统采用了队列化的怪物生成机制:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "怪物生成流程"
|
||||
A[生成怪物配置] --> B[添加到队列]
|
||||
B --> C[定时器检查]
|
||||
C --> D{是否暂停?}
|
||||
D --> |是| E[暂停计时]
|
||||
D --> |否| F[正常生成]
|
||||
F --> G[召唤计数+1]
|
||||
G --> H{达到5只?}
|
||||
H --> |是| I[进入暂停状态]
|
||||
H --> |否| J[继续生成]
|
||||
I --> K[暂停5秒]
|
||||
K --> L[恢复生成]
|
||||
E --> M[等待恢复]
|
||||
L --> J
|
||||
M --> N[暂停结束]
|
||||
N --> J
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L69-L105)
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L95-L115)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L147-L169)
|
||||
|
||||
## 配置修改指南
|
||||
|
||||
### 修改难度曲线
|
||||
|
||||
#### 调整怪物数量
|
||||
1. **修改基础数量**:直接修改StageConfigRules中各关卡的`count`值
|
||||
2. **调整数量范围**:修改`minCount`和`maxCount`限制
|
||||
3. **改变增长速率**:修改calculateMonsterCount函数中的增量公式
|
||||
|
||||
#### 调整强度倍率
|
||||
1. **修改关卡倍率**:调整calculateMonsterStrengthMultiplier函数中的`0.1`系数
|
||||
2. **修改等级倍率**:调整`0.05`系数
|
||||
3. **添加新维度**:可扩展新的强度计算因子
|
||||
|
||||
### 新增特殊关卡类型
|
||||
|
||||
#### 步骤1:定义关卡类型
|
||||
```typescript
|
||||
export enum StageType {
|
||||
// 现有类型...
|
||||
SPECIAL = "special" // 新增特殊关卡类型
|
||||
}
|
||||
```
|
||||
|
||||
#### 步骤2:添加配置规则
|
||||
```typescript
|
||||
export const StageConfigRules = {
|
||||
// 现有规则...
|
||||
[StageType.SPECIAL]: {
|
||||
description: "特殊关卡",
|
||||
monsters: [
|
||||
{ type: MonsterType.BOSS, count: 1, minCount: 1, maxCount: 1 },
|
||||
{ type: MonsterType.ELITE, count: 3, minCount: 2, maxCount: 4 }
|
||||
]
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
#### 步骤3:更新判定逻辑
|
||||
```typescript
|
||||
export function getStageType(stageNumber: number, level: number = 1): StageType {
|
||||
// 现有逻辑...
|
||||
|
||||
// 新增特殊关卡规则
|
||||
if (/* 特殊条件 */) {
|
||||
return StageType.SPECIAL;
|
||||
}
|
||||
|
||||
return /* 默认返回 */;
|
||||
}
|
||||
```
|
||||
|
||||
### 调整关卡频率
|
||||
|
||||
#### 修改事件关卡频率
|
||||
```typescript
|
||||
// 修改getStageType函数中的事件触发条件
|
||||
if (stageNumber % 5 === 0 && level === 3) {
|
||||
return StageType.EVENT;
|
||||
}
|
||||
```
|
||||
|
||||
#### 修改Boss关卡频率
|
||||
```typescript
|
||||
// 修改Boss关卡触发条件
|
||||
if (stageNumber % 10 === 0) {
|
||||
// Boss逻辑...
|
||||
}
|
||||
```
|
||||
|
||||
## 性能优化考虑
|
||||
|
||||
### 内存管理优化
|
||||
|
||||
1. **怪物配置缓存**:避免重复计算相同的关卡配置
|
||||
2. **事件概率预计算**:使用累积概率减少每次触发的计算开销
|
||||
3. **队列长度控制**:限制怪物生成队列的最大长度
|
||||
|
||||
### 计算性能优化
|
||||
|
||||
1. **早期退出机制**:在getStageType中使用早期返回
|
||||
2. **批量操作**:一次性生成所有怪物配置而非逐个生成
|
||||
3. **数值计算优化**:使用Math.floor替代更复杂的数学运算
|
||||
|
||||
### 内存使用监控
|
||||
|
||||
```typescript
|
||||
// 监控怪物队列大小
|
||||
console.log(`怪物队列大小: ${this.monsterQueue.length}`);
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
RogueConfig.ts实现了一个完整而灵活的肉鸽模式关卡生成系统。通过分层的关卡类型判定逻辑、智能的怪物配置规则和渐进式的难度曲线,为玩家提供了丰富的游戏体验。
|
||||
|
||||
### 主要特性
|
||||
|
||||
1. **动态关卡生成**:基于关卡号和玩家等级的智能判定
|
||||
2. **渐进式难度**:通过数量和强度倍率实现平滑的难度提升
|
||||
3. **随机事件系统**:增加游戏的不确定性和趣味性
|
||||
4. **模块化设计**:清晰的职责分离便于维护和扩展
|
||||
5. **性能优化**:合理的内存管理和计算优化
|
||||
|
||||
### 扩展建议
|
||||
|
||||
1. **新增关卡类型**:可根据游戏需求添加更多特殊关卡
|
||||
2. **动态配置加载**:支持运行时修改配置而不需重启
|
||||
3. **数据分析功能**:添加关卡统计数据收集和分析
|
||||
4. **多语言支持**:完善国际化支持
|
||||
|
||||
该系统为肉鸽游戏提供了坚实的技术基础,通过合理的配置和适当的扩展,可以满足各种游戏设计需求。
|
||||
435
.qoder/repowiki/zh/content/地图系统/肉鸽关卡配置/怪物配置体系.md
Normal file
435
.qoder/repowiki/zh/content/地图系统/肉鸽关卡配置/怪物配置体系.md
Normal file
@@ -0,0 +1,435 @@
|
||||
# 怪物配置体系
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 概述
|
||||
|
||||
RogueConfig.ts是肉鸽模式中的核心怪物配置管理系统,提供了完整的怪物类型定义、关卡配置规则、强度计算机制和随机事件系统。该系统通过分层的配置结构实现了怪物的差异化管理,支持普通怪物、精英怪物和Boss怪物三种类型,并能够根据关卡进度动态调整怪物数量和强度。
|
||||
|
||||
系统的主要功能包括:
|
||||
- **怪物类型管理**:通过MonsterType枚举定义三种怪物类型
|
||||
- **关卡配置系统**:支持普通关卡、精英关卡、Boss关卡和事件关卡
|
||||
- **强度计算引擎**:基于关卡号和等级计算怪物强度倍率
|
||||
- **随机事件系统**:提供宝箱、陷阱、增益和减益事件
|
||||
- **程序化关卡生成**:支持怪物数量随关卡递增的动态配置
|
||||
|
||||
## 项目结构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "怪物配置模块"
|
||||
RC[RogueConfig.ts<br/>核心配置管理]
|
||||
MC[MissionMonComp.ts<br/>怪物生成控制]
|
||||
end
|
||||
subgraph "数据源模块"
|
||||
HS[heroSet.ts<br/>英雄/怪物数据]
|
||||
Mon[Mon.ts<br/>怪物实体管理]
|
||||
end
|
||||
subgraph "配置系统"
|
||||
SC[StageConfigRules<br/>关卡配置规则]
|
||||
EM[EliteMonsterList<br/>精英怪物配置]
|
||||
BM[BossMonsterList<br/>Boss怪物配置]
|
||||
end
|
||||
RC --> SC
|
||||
RC --> EM
|
||||
RC --> BM
|
||||
MC --> RC
|
||||
MC --> Mon
|
||||
Mon --> HS
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L311)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L209)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L50)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L35)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 怪物类型枚举系统
|
||||
|
||||
系统定义了三个核心的怪物类型,通过枚举确保类型安全和可维护性:
|
||||
|
||||
| 怪物类型 | 描述 | 特征 |
|
||||
|---------|------|------|
|
||||
| NORMAL | 普通怪物 | 基础属性,随机选择 |
|
||||
| ELITE | 精英怪物 | 强化配置,固定列表 |
|
||||
| BOSS | Boss怪物 | 高强度,特殊配置 |
|
||||
|
||||
### 关卡类型系统
|
||||
|
||||
| 关卡类型 | 触发条件 | 怪物组成 |
|
||||
|---------|----------|----------|
|
||||
| NORMAL | 1-9关1-4级 | 普通怪物为主 |
|
||||
| ELITE | 1-9关5级/10关4级 | 精英+普通怪物 |
|
||||
| BOSS | 10关5级 | Boss+精英+普通怪物 |
|
||||
| EVENT | 每5关特殊事件 | 少量普通怪物 |
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L35-L55)
|
||||
|
||||
## 架构概览
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家
|
||||
participant MC as MissionMonComp
|
||||
participant RC as RogueConfig
|
||||
participant Mon as Monster
|
||||
participant HS as HeroSet
|
||||
Player->>MC : 开始关卡
|
||||
MC->>RC : getStageType(stage, level)
|
||||
RC-->>MC : 返回关卡类型
|
||||
MC->>RC : getStageMonsterConfigs(stage, level)
|
||||
RC->>RC : calculateMonsterStrengthMultiplier()
|
||||
RC->>RC : generateStageConfig()
|
||||
RC->>RC : getMonsterUUIDsByType()
|
||||
RC-->>MC : 返回怪物配置数组
|
||||
MC->>Mon : 创建怪物实例
|
||||
Mon->>HS : 加载怪物数据
|
||||
HS-->>Mon : 返回属性配置
|
||||
Mon-->>MC : 怪物实例完成
|
||||
MC-->>Player : 关卡准备就绪
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L102-L136)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L269-L310)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 怪物类型管理系统
|
||||
|
||||
#### MonsterType枚举定义
|
||||
|
||||
系统通过清晰的枚举定义区分不同类型的怪物:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MonsterType {
|
||||
<<enumeration>>
|
||||
+NORMAL : "normal"
|
||||
+ELITE : "elite"
|
||||
+BOSS : "boss"
|
||||
}
|
||||
class StageType {
|
||||
<<enumeration>>
|
||||
+NORMAL : "normal"
|
||||
+ELITE : "elite"
|
||||
+BOSS : "boss"
|
||||
+EVENT : "event"
|
||||
}
|
||||
class EventType {
|
||||
<<enumeration>>
|
||||
+TREASURE : "treasure"
|
||||
+TRAP : "trap"
|
||||
+BUFF : "buff"
|
||||
+DEBUFF : "debuff"
|
||||
}
|
||||
MonsterType --> StageType : "映射到"
|
||||
StageType --> EventType : "可能触发"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L35-L55)
|
||||
|
||||
#### 怪物UUID获取机制
|
||||
|
||||
getMonsterUUIDsByType函数实现了根据不同怪物类型获取对应配置表的功能:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始获取怪物UUID]) --> CheckType{检查怪物类型}
|
||||
CheckType --> |NORMAL| GetNormal[调用getMonList获取普通怪物]
|
||||
CheckType --> |ELITE| GetElite[使用EliteMonsterList配置表]
|
||||
CheckType --> |BOSS| GetBoss[使用BossMonsterList配置表]
|
||||
CheckType --> |其他| ReturnEmpty[返回空数组]
|
||||
GetNormal --> FilterMonsters[过滤怪物数据]
|
||||
FilterMonsters --> ReturnUUIDs[返回UUID数组]
|
||||
GetElite --> ReturnEliteUUIDs[返回精英怪物UUID]
|
||||
GetBoss --> ReturnBossUUIDs[返回Boss怪物UUID]
|
||||
ReturnEmpty --> End([结束])
|
||||
ReturnUUIDs --> End
|
||||
ReturnEliteUUIDs --> End
|
||||
ReturnBossUUIDs --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L225-L247)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L225-L247)
|
||||
|
||||
### 关卡配置系统
|
||||
|
||||
#### StageConfigRules配置表
|
||||
|
||||
系统通过StageConfigRules定义了四种关卡类型的怪物配置规则:
|
||||
|
||||
| 关卡类型 | 普通怪物 | 精英怪物 | Boss怪物 | 数量范围 |
|
||||
|---------|----------|----------|----------|----------|
|
||||
| NORMAL | 3-6只 | 0只 | 0只 | 基础3只递增 |
|
||||
| ELITE | 2-5只 | 1-4只 | 0只 | 混合配置 |
|
||||
| BOSS | 1-4只 | 1-3只 | 1只 | 高强度组合 |
|
||||
| EVENT | 1-4只 | 0只 | 0只 | 少量怪物 |
|
||||
|
||||
#### 强度计算引擎
|
||||
|
||||
calculateMonsterStrengthMultiplier函数实现了基于关卡进度的强度倍率计算:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始计算强度倍率]) --> CalcStage[计算关卡倍率<br/>stageMultiplier = 1 + (stage-1) * 0.1]
|
||||
CalcStage --> CalcLevel[计算等级倍率<br/>levelMultiplier = 1 + (level-1) * 0.05]
|
||||
CalcLevel --> Multiply[相乘得到最终倍率<br/>strengthMultiplier = stageMultiplier * levelMultiplier]
|
||||
Multiply --> Return[返回强度倍率]
|
||||
Return --> End([结束])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L175-L180)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L65-L132)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L175-L180)
|
||||
|
||||
### 怪物生成流程
|
||||
|
||||
#### getStageMonsterConfigs函数详解
|
||||
|
||||
该函数是怪物配置生成的核心,整合了关卡配置、强度计算和UUID选择:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Caller as 调用者
|
||||
participant Func as getStageMonsterConfigs
|
||||
participant Gen as generateStageConfig
|
||||
participant Calc as calculateMonsterStrengthMultiplier
|
||||
participant UUID as getMonsterUUIDsByType
|
||||
Caller->>Func : getStageMonsterConfigs(stage, level)
|
||||
Func->>Gen : 生成关卡配置
|
||||
Gen-->>Func : 返回怪物类型数组
|
||||
Func->>Calc : 计算强度倍率
|
||||
Calc-->>Func : 返回倍率值
|
||||
loop 遍历每个怪物类型
|
||||
Func->>UUID : 获取该类型UUID列表
|
||||
UUID-->>Func : 返回UUID数组
|
||||
Func->>Func : 随机选择UUID
|
||||
Func->>Func : 构建怪物配置对象
|
||||
end
|
||||
Func-->>Caller : 返回完整怪物配置数组
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L269-L310)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L269-L310)
|
||||
|
||||
### 怪物数据源关联性
|
||||
|
||||
#### Mon.ts与heroSet.ts的数据绑定
|
||||
|
||||
怪物实体通过Mon.ts加载来自heroSet.ts的配置数据:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Monster {
|
||||
+load(pos, scale, uuid, is_boss, strengthMultiplier)
|
||||
+hero_init(uuid, node, scale, box_group, is_boss, is_call, strengthMultiplier)
|
||||
-init()
|
||||
-destroy()
|
||||
}
|
||||
class HeroInfo {
|
||||
+uuid : number
|
||||
+name : string
|
||||
+path : string
|
||||
+fac : FacSet
|
||||
+type : HType
|
||||
+hp : number
|
||||
+mp : number
|
||||
+ap : number
|
||||
+def : number
|
||||
+skills : number[]
|
||||
}
|
||||
class MonModelComp {
|
||||
+base_hp : number
|
||||
+base_mp : number
|
||||
+base_ap : number
|
||||
+base_def : number
|
||||
+strengthMultiplier : number
|
||||
}
|
||||
Monster --> HeroInfo : "使用数据"
|
||||
Monster --> MonModelComp : "包含组件"
|
||||
MonModelComp --> HeroInfo : "应用属性"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L20-L110)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L80-L151)
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L20-L110)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L80-L151)
|
||||
|
||||
### 随机事件系统
|
||||
|
||||
#### EventConfig配置表
|
||||
|
||||
系统提供了完整的随机事件配置,支持四种事件类型:
|
||||
|
||||
| 事件类型 | 触发概率 | 效果描述 |
|
||||
|---------|----------|----------|
|
||||
| TREASURE | 30% | 获得额外奖励 |
|
||||
| TRAP | 25% | 受到一定伤害 |
|
||||
| BUFF | 25% | 获得临时增益效果 |
|
||||
| DEBUFF | 20% | 受到临时减益效果 |
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L134-L165)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "外部依赖"
|
||||
ECS[ECS框架]
|
||||
Oops[Oops插件框架]
|
||||
CC[Cocos Creator]
|
||||
end
|
||||
subgraph "内部模块"
|
||||
RC[RogueConfig]
|
||||
MC[MissionMonComp]
|
||||
Mon[Monster实体]
|
||||
HS[HeroSet]
|
||||
end
|
||||
subgraph "配置数据"
|
||||
HeroInfo[HeroInfo配置]
|
||||
SkillSet[SkillSet配置]
|
||||
HeroAttrs[HeroAttrs配置]
|
||||
end
|
||||
RC --> HS
|
||||
MC --> RC
|
||||
MC --> Mon
|
||||
Mon --> HS
|
||||
Mon --> HeroInfo
|
||||
Mon --> SkillSet
|
||||
Mon --> HeroAttrs
|
||||
RC -.-> ECS
|
||||
MC -.-> Oops
|
||||
Mon -.-> CC
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L10)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L15)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L10)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L15)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 怪物生成优化策略
|
||||
|
||||
1. **延迟加载**:怪物实体采用延迟初始化机制,避免一次性加载过多资源
|
||||
2. **随机选择优化**:使用Math.random()进行高效随机选择,避免复杂算法
|
||||
3. **配置缓存**:关卡配置结果被缓存在MissionMonComp中,减少重复计算
|
||||
4. **内存管理**:怪物实体销毁时正确释放组件和资源
|
||||
|
||||
### 强度计算优化
|
||||
|
||||
- 使用简单的数学运算替代复杂的属性计算
|
||||
- 强度倍率计算结果被缓存,避免重复计算
|
||||
- 关卡类型判断采用分支预测友好的条件语句
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 怪物配置不生效
|
||||
|
||||
**问题现象**:关卡中没有生成预期的怪物类型
|
||||
|
||||
**排查步骤**:
|
||||
1. 检查EliteMonsterList和BossMonsterList是否包含正确的UUID
|
||||
2. 验证getMonsterUUIDsByType函数的返回值
|
||||
3. 确认generateStageConfig生成的怪物类型数组
|
||||
|
||||
**解决方案**:
|
||||
- 在heroSet.ts中添加缺失的怪物UUID
|
||||
- 检查MonsterType枚举定义是否正确
|
||||
- 验证关卡配置规则中的怪物数量设置
|
||||
|
||||
#### 强度倍率异常
|
||||
|
||||
**问题现象**:怪物强度不符合预期的增长曲线
|
||||
|
||||
**排查步骤**:
|
||||
1. 检查calculateMonsterStrengthMultiplier函数的计算逻辑
|
||||
2. 验证关卡号和等级参数传递是否正确
|
||||
3. 确认基础属性值是否合理
|
||||
|
||||
**解决方案**:
|
||||
- 调整关卡倍率和等级倍率的计算公式
|
||||
- 检查HeroInfo中的基础属性配置
|
||||
- 验证强度倍率的应用逻辑
|
||||
|
||||
#### 随机事件不触发
|
||||
|
||||
**问题现象**:事件关卡中没有随机事件发生
|
||||
|
||||
**排查步骤**:
|
||||
1. 检查EventConfig的概率设置
|
||||
2. 验证getRandomEvent函数的随机性
|
||||
3. 确认事件处理逻辑是否正确
|
||||
|
||||
**解决方案**:
|
||||
- 调整事件概率分布,确保总和为1
|
||||
- 检查随机数生成器的实现
|
||||
- 验证事件处理函数的调用时机
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L175-L200)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L135-L169)
|
||||
|
||||
## 结论
|
||||
|
||||
RogueConfig.ts构建了一个完整而灵活的怪物配置体系,通过分层的设计实现了怪物类型的差异化管理和关卡的程序化生成。系统的三大核心特性——类型管理、强度计算和随机事件——为肉鸽模式提供了丰富的游戏体验。
|
||||
|
||||
### 主要优势
|
||||
|
||||
1. **类型安全**:通过枚举确保怪物类型的一致性
|
||||
2. **可扩展性**:配置表设计支持轻松添加新怪物类型
|
||||
3. **动态平衡**:强度计算机制保证游戏难度的渐进式提升
|
||||
4. **随机性**:事件系统增加了游戏的不确定性和趣味性
|
||||
|
||||
### 改进建议
|
||||
|
||||
1. **配置验证**:添加配置完整性检查机制
|
||||
2. **性能监控**:在大型关卡中监控怪物生成性能
|
||||
3. **平衡调整**:提供更精细的强度调节工具
|
||||
4. **可视化编辑**:开发关卡配置的可视化编辑器
|
||||
|
||||
该系统为肉鸽游戏提供了坚实的基础架构,支持开发者根据具体需求进行定制和扩展,是构建高质量肉鸽游戏的重要组件。
|
||||
592
.qoder/repowiki/zh/content/地图系统/肉鸽关卡配置/肉鸽关卡配置.md
Normal file
592
.qoder/repowiki/zh/content/地图系统/肉鸽关卡配置/肉鸽关卡配置.md
Normal file
@@ -0,0 +1,592 @@
|
||||
# 肉鸽关卡配置系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [系统概述](#系统概述)
|
||||
2. [核心架构](#核心架构)
|
||||
3. [关卡类型系统](#关卡类型系统)
|
||||
4. [怪物类型体系](#怪物类型体系)
|
||||
5. [关卡配置规则](#关卡配置规则)
|
||||
6. [随机事件系统](#随机事件系统)
|
||||
7. [动态难度计算](#动态难度计算)
|
||||
8. [关卡生成流程](#关卡生成流程)
|
||||
9. [实际调用机制](#实际调用机制)
|
||||
10. [扩展指南](#扩展指南)
|
||||
11. [性能优化建议](#性能优化建议)
|
||||
12. [总结](#总结)
|
||||
|
||||
## 系统概述
|
||||
|
||||
肉鸽关卡配置系统是一个高度程序化的关卡生成框架,专为Roguelike游戏设计。该系统通过智能算法动态生成具有递增难度的关卡,支持多种怪物类型、随机事件和平衡性调整。
|
||||
|
||||
### 主要特性
|
||||
|
||||
- **程序化关卡生成**:基于关卡号和等级自动计算关卡配置
|
||||
- **动态难度曲线**:怪物数量和强度随关卡递增而增强
|
||||
- **多样化关卡类型**:普通关卡、精英关卡、Boss关卡、事件关卡
|
||||
- **随机事件系统**:包含奖励、陷阱、增益、减益等多种事件
|
||||
- **灵活配置管理**:支持快速调整难度曲线和平衡性
|
||||
|
||||
## 核心架构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
A[RogueConfig.ts] --> B[StageType枚举]
|
||||
A --> C[MonsterType枚举]
|
||||
A --> D[EventType枚举]
|
||||
A --> E[StageConfigRules]
|
||||
A --> F[EventConfig]
|
||||
end
|
||||
subgraph "逻辑层"
|
||||
G[getStageType] --> H[calculateMonsterCount]
|
||||
G --> I[calculateMonsterStrengthMultiplier]
|
||||
H --> J[generateStageConfig]
|
||||
I --> J
|
||||
J --> K[getStageMonsterConfigs]
|
||||
end
|
||||
subgraph "应用层"
|
||||
L[MissionMonComp.ts] --> M[GameMap.ts]
|
||||
L --> N[Mon.ts]
|
||||
L --> O[MapModelComp.ts]
|
||||
end
|
||||
A --> G
|
||||
K --> L
|
||||
M --> O
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L311)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L50)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L40)
|
||||
|
||||
## 关卡类型系统
|
||||
|
||||
系统定义了四种主要的关卡类型,每种类型都有独特的配置特征和挑战性。
|
||||
|
||||
### StageType枚举结构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class StageType {
|
||||
<<enumeration>>
|
||||
+NORMAL : "normal"
|
||||
+ELITE : "elite"
|
||||
+BOSS : "boss"
|
||||
+EVENT : "event"
|
||||
}
|
||||
class StageConfigRules {
|
||||
+NORMAL : NormalConfig
|
||||
+ELITE : EliteConfig
|
||||
+BOSS : BossConfig
|
||||
+EVENT : EventConfig
|
||||
}
|
||||
class NormalConfig {
|
||||
+description : "普通关卡"
|
||||
+monsters : MonsterGroup[]
|
||||
}
|
||||
class EliteConfig {
|
||||
+description : "精英关卡"
|
||||
+monsters : MonsterGroup[]
|
||||
}
|
||||
class BossConfig {
|
||||
+description : "Boss关卡"
|
||||
+monsters : MonsterGroup[]
|
||||
}
|
||||
class EventConfig {
|
||||
+description : "事件关卡"
|
||||
+monsters : MonsterGroup[]
|
||||
}
|
||||
StageType --> StageConfigRules : "映射到"
|
||||
StageConfigRules --> NormalConfig : "包含"
|
||||
StageConfigRules --> EliteConfig : "包含"
|
||||
StageConfigRules --> BossConfig : "包含"
|
||||
StageConfigRules --> EventConfig : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L35-L86)
|
||||
|
||||
### 关卡类型特征对比
|
||||
|
||||
| 关卡类型 | 怪物组成 | 数量范围 | 特殊规则 |
|
||||
|---------|---------|---------|---------|
|
||||
| 普通关卡 | 普通怪物 | 2-6只 | 基础难度,适合新手 |
|
||||
| 精英关卡 | 精英+普通 | 3-9只 | 中等难度,包含精英怪物 |
|
||||
| Boss关卡 | Boss+精英+普通 | 4-8只 | 高难度,包含Boss |
|
||||
| 事件关卡 | 普通怪物 | 1-4只 | 包含随机事件 |
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L47-L86)
|
||||
|
||||
## 怪物类型体系
|
||||
|
||||
系统采用分层的怪物分类体系,支持不同强度和行为特征的怪物配置。
|
||||
|
||||
### MonsterType枚举设计
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MonsterType {
|
||||
<<enumeration>>
|
||||
+NORMAL : "normal"
|
||||
+ELITE : "elite"
|
||||
+BOSS : "boss"
|
||||
}
|
||||
class MonsterConfig {
|
||||
+uuid : number
|
||||
+type : MonsterType
|
||||
+stageNumber : number
|
||||
+level : number
|
||||
+strengthMultiplier : number
|
||||
}
|
||||
class MonsterPool {
|
||||
+getMonsterUUIDsByType() : number[]
|
||||
+EliteMonsterList : number[]
|
||||
+BossMonsterList : number[]
|
||||
+getMonList() : number[]
|
||||
}
|
||||
MonsterType --> MonsterConfig : "生成"
|
||||
MonsterPool --> MonsterType : "提供"
|
||||
MonsterPool --> MonsterConfig : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L28-L34)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L240-L260)
|
||||
|
||||
### 怪物池配置
|
||||
|
||||
系统维护三个独立的怪物池,每个池包含特定类型的怪物:
|
||||
|
||||
- **普通怪物池**:使用 `getMonList()` 方法获取所有可用的普通怪物
|
||||
- **精英怪物池**:固定配置的精英怪物列表
|
||||
- **Boss怪物池**:固定配置的Boss怪物列表
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L18-L34)
|
||||
- [heroSet.ts](file://assets/script/game/game/common/config/heroSet.ts#L35-L40)
|
||||
|
||||
## 关卡配置规则
|
||||
|
||||
系统通过预定义的配置规则实现关卡的程序化生成,确保游戏体验的连贯性和挑战性。
|
||||
|
||||
### 配置规则结构
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[关卡号] --> B{关卡类型判断}
|
||||
B --> |第5关且等级3| C[事件关卡]
|
||||
B --> |第10关| D{等级判断}
|
||||
B --> |其他| E{等级判断}
|
||||
D --> |等级5| F[Boss关卡]
|
||||
D --> |等级4| G[精英关卡]
|
||||
D --> |其他| H[普通关卡]
|
||||
E --> |等级5| I[精英关卡]
|
||||
E --> |其他| J[普通关卡]
|
||||
C --> K[生成怪物配置]
|
||||
F --> K
|
||||
G --> K
|
||||
H --> K
|
||||
I --> K
|
||||
J --> K
|
||||
K --> L[计算怪物数量]
|
||||
K --> M[计算强度倍率]
|
||||
L --> N[生成最终配置]
|
||||
M --> N
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L129-L168)
|
||||
|
||||
### 怪物数量计算算法
|
||||
|
||||
系统采用线性递增算法计算怪物数量:
|
||||
|
||||
```typescript
|
||||
// 计算公式:基础数量 + (关卡号 ÷ 5) 的整数部分
|
||||
const increment = Math.floor(stageNumber / 5);
|
||||
let count = baseCount + increment;
|
||||
|
||||
// 确保数量在最小值和最大值范围内
|
||||
count = Math.max(minCount, Math.min(maxCount, count));
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L150-L175)
|
||||
|
||||
## 随机事件系统
|
||||
|
||||
系统提供了丰富的随机事件机制,为游戏增添不确定性和策略深度。
|
||||
|
||||
### EventType枚举
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class EventType {
|
||||
<<enumeration>>
|
||||
+TREASURE : "treasure"
|
||||
+TRAP : "trap"
|
||||
+BUFF : "buff"
|
||||
+DEBUFF : "debuff"
|
||||
}
|
||||
class EventConfig {
|
||||
+TREASURE : TreasureConfig
|
||||
+TRAP : TrapConfig
|
||||
+BUFF : BuffConfig
|
||||
+DEBUFF : DebuffConfig
|
||||
}
|
||||
class EventProbability {
|
||||
+TREASURE : 0.3
|
||||
+TRAP : 0.25
|
||||
+BUFF : 0.25
|
||||
+DEBUFF : 0.2
|
||||
}
|
||||
EventType --> EventConfig : "配置"
|
||||
EventConfig --> EventProbability : "概率分布"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L50-L75)
|
||||
|
||||
### 事件触发机制
|
||||
|
||||
事件系统采用累积概率算法确保公平性:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家
|
||||
participant System as 事件系统
|
||||
participant RNG as 随机数生成器
|
||||
participant Effect as 效果处理器
|
||||
Player->>System : 进入事件关卡
|
||||
System->>RNG : 生成随机数(0-1)
|
||||
RNG-->>System : 返回随机值
|
||||
System->>System : 累积概率计算
|
||||
alt 随机数 ≤ 0.3
|
||||
System->>Effect : 触发宝藏事件
|
||||
Effect->>Player : 增加50金币
|
||||
else 随机数 ≤ 0.55
|
||||
System->>Effect : 触发陷阱事件
|
||||
Effect->>Player : 造成伤害
|
||||
else 随机数 ≤ 0.8
|
||||
System->>Effect : 触发增益事件
|
||||
Effect->>Player : 获得临时增益
|
||||
else 随机数 > 0.8
|
||||
System->>Effect : 触发减益事件
|
||||
Effect->>Player : 造成临时减益
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L295-L311)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L50-L75)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L295-L311)
|
||||
|
||||
## 动态难度计算
|
||||
|
||||
系统实现了复杂的难度计算机制,确保游戏体验的渐进式挑战。
|
||||
|
||||
### 强度倍率计算
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[关卡号] --> B[阶段倍率计算]
|
||||
C[等级] --> D[等级倍率计算]
|
||||
B --> E[基础倍率 = 1 + (关卡号-1) × 0.1]
|
||||
D --> F[等级倍率 = 1 + (等级-1) × 0.05]
|
||||
E --> G[总倍率 = 阶段倍率 × 等级倍率]
|
||||
F --> G
|
||||
G --> H[应用到怪物属性]
|
||||
H --> I[HP = 基础HP × 总倍率]
|
||||
H --> J[AP = 基础AP × 总倍率]
|
||||
H --> K[DEF = 基础DEF × 总倍率]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L177-L185)
|
||||
|
||||
### 难度曲线特征
|
||||
|
||||
| 关卡范围 | 等级要求 | 强度倍率 | 怪物数量 | 挑战特点 |
|
||||
|---------|---------|---------|---------|---------|
|
||||
| 1-9 | 1-4级 | 1.0-1.4 | 2-6只 | 渐进适应 |
|
||||
| 1-9 | 5级 | 1.4-1.8 | 3-6只 | 中等挑战 |
|
||||
| 10 | 1-3级 | 1.9-2.3 | 3-6只 | 高强度 |
|
||||
| 10 | 4级 | 2.4-2.8 | 3-6只 | 极限挑战 |
|
||||
| 10 | 5级 | 2.9-3.3 | 3-6只 | 终极考验 |
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L177-L185)
|
||||
|
||||
## 关卡生成流程
|
||||
|
||||
系统通过多层函数协作实现完整的关卡生成流程。
|
||||
|
||||
### 完整生成序列
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MC as MissionComp
|
||||
participant RM as MissionMonComp
|
||||
participant RC as RogueConfig
|
||||
participant MM as MapModel
|
||||
participant M as Monster
|
||||
MC->>RM : do_mon_wave()
|
||||
RM->>RC : getStageType(stageNumber, level)
|
||||
RC-->>RM : StageType
|
||||
RM->>RC : getStageMonsterConfigs(stageNumber, level)
|
||||
RC->>RC : generateStageConfig()
|
||||
RC->>RC : calculateMonsterCount()
|
||||
RC->>RC : calculateMonsterStrengthMultiplier()
|
||||
RC-->>RM : 怪物配置数组
|
||||
RM->>RM : generateMonstersFromStageConfig()
|
||||
loop 每个怪物配置
|
||||
RM->>RM : addToStageSpawnQueue()
|
||||
end
|
||||
loop 怪物生成队列
|
||||
RM->>M : addMonster()
|
||||
M->>MM : 加载怪物资源
|
||||
MM-->>M : 怪物实例
|
||||
M-->>RM : 怪物实体
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L102-L136)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L207-L247)
|
||||
|
||||
### 怪物生成队列管理
|
||||
|
||||
系统采用队列机制控制怪物生成节奏:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 等待生成
|
||||
等待生成 --> 准备生成 : 怪物队列非空
|
||||
准备生成 --> 生成中 : spawnTimer >= spawnInterval
|
||||
生成中 --> 暂停检查 : 生成5只后
|
||||
生成中 --> 准备生成 : 继续生成
|
||||
暂停检查 --> 暂停中 : 需要暂停
|
||||
暂停检查 --> 准备生成 : 继续生成
|
||||
暂停中 --> 暂停结束 : pauseInterval时间到
|
||||
暂停结束 --> 准备生成 : 重置计数器
|
||||
准备生成 --> [*] : 队列为空
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L45-L85)
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L102-L136)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L150-L180)
|
||||
|
||||
## 实际调用机制
|
||||
|
||||
系统在游戏运行时通过事件驱动的方式调用关卡配置功能。
|
||||
|
||||
### 调用时序图
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant GM as GameMap
|
||||
participant MC as MissionComp
|
||||
participant MMon as MissionMonComp
|
||||
participant RC as RogueConfig
|
||||
GM->>MC : 初始化游戏
|
||||
MC->>MC : data_init()
|
||||
MC->>MC : mission_start()
|
||||
MC->>MC : to_fight()
|
||||
MC->>MMon : fight_ready()
|
||||
MMon->>MMon : do_mon_wave()
|
||||
Note over MMon : 开始关卡生成流程
|
||||
MMon->>RC : getStageType(currentStage, level)
|
||||
MMon->>RC : getStageMonsterConfigs(currentStage, level)
|
||||
RC-->>MMon : 怪物配置数据
|
||||
MMon->>MMon : generateMonstersFromStageConfig()
|
||||
MMon->>MMon : addToStageSpawnQueue()
|
||||
loop 怪物生成循环
|
||||
MMon->>MMon : spawnNextMonster()
|
||||
MMon->>GM : addMonster()
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L25-L35)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L75-L95)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L40-L50)
|
||||
|
||||
### 数据流传递
|
||||
|
||||
关卡配置数据通过以下路径传递:
|
||||
|
||||
1. **配置层**:RogueConfig.ts 提供基础配置
|
||||
2. **逻辑层**:MissionMonComp.ts 处理游戏逻辑
|
||||
3. **渲染层**:Mon.ts 负责怪物渲染和行为
|
||||
4. **状态层**:smc.vmdata.mission_data 管理游戏状态
|
||||
|
||||
**章节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L25-L35)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L75-L95)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L40-L50)
|
||||
|
||||
## 扩展指南
|
||||
|
||||
### 添加新事件类型
|
||||
|
||||
要添加新的随机事件类型,请按照以下步骤操作:
|
||||
|
||||
1. **扩展EventType枚举**:
|
||||
```typescript
|
||||
export enum EventType {
|
||||
// 现有类型...
|
||||
NEW_EVENT = "new_event" // 新增事件类型
|
||||
}
|
||||
```
|
||||
|
||||
2. **更新EventConfig配置**:
|
||||
```typescript
|
||||
export const EventConfig = {
|
||||
// 现有配置...
|
||||
[EventType.NEW_EVENT]: {
|
||||
description: "新事件描述",
|
||||
probability: 0.15, // 新事件概率
|
||||
effect: "新事件效果"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. **在事件处理函数中添加逻辑**:
|
||||
```typescript
|
||||
private processRandomEvent() {
|
||||
switch (this.currentEvent) {
|
||||
// 现有事件处理...
|
||||
case EventType.NEW_EVENT:
|
||||
// 实现新事件逻辑
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 调整难度曲线
|
||||
|
||||
可以通过修改以下参数来调整难度曲线:
|
||||
|
||||
1. **基础倍率调整**:
|
||||
```typescript
|
||||
// 修改 StageConfigRules 中的怪物配置
|
||||
[StageType.NORMAL]: {
|
||||
monsters: [
|
||||
{ type: MonsterType.NORMAL, count: 3, minCount: 2, maxCount: 6 }
|
||||
// count: 基础数量
|
||||
// minCount/maxCount: 数量范围限制
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
2. **强度倍率系数**:
|
||||
```typescript
|
||||
// 修改 calculateMonsterStrengthMultiplier 函数
|
||||
const stageMultiplier = 1 + (stageNumber - 1) * 0.15; // 增加每关倍率
|
||||
const levelMultiplier = 1 + (level - 1) * 0.08; // 增加每级倍率
|
||||
```
|
||||
|
||||
### 平衡精英/Boss关卡
|
||||
|
||||
1. **调整精英怪物配置**:
|
||||
```typescript
|
||||
export const EliteMonsterList = [
|
||||
5201, // 兽人战士
|
||||
5202, // 兽人刺客
|
||||
5203, // 兽人护卫
|
||||
// 添加更多精英怪物
|
||||
5204, // 新精英怪物
|
||||
5205 // 更强精英怪物
|
||||
];
|
||||
```
|
||||
|
||||
2. **优化Boss关卡配置**:
|
||||
```typescript
|
||||
[StageType.BOSS]: {
|
||||
description: "Boss关卡",
|
||||
monsters: [
|
||||
{ type: MonsterType.BOSS, count: 1, minCount: 1, maxCount: 1 },
|
||||
{ type: MonsterType.ELITE, count: 3, minCount: 2, maxCount: 4 }, // 增加精英数量
|
||||
{ type: MonsterType.NORMAL, count: 4, minCount: 2, maxCount: 6 } // 增加普通怪物
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义怪物池
|
||||
|
||||
如果需要添加特定类型的怪物:
|
||||
|
||||
1. **扩展怪物池**:
|
||||
```typescript
|
||||
// 在 RogueConfig.ts 中
|
||||
export const CustomMonsterList = [
|
||||
5301, // 自定义怪物1
|
||||
5302, // 自定义怪物2
|
||||
5303 // 自定义怪物3
|
||||
];
|
||||
```
|
||||
|
||||
2. **在 getMonsterUUIDsByType 中添加分支**:
|
||||
```typescript
|
||||
case MonsterType.CUSTOM:
|
||||
return CustomMonsterList;
|
||||
```
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
### 怪物生成优化
|
||||
|
||||
1. **批量生成**:使用对象池减少频繁的实例化
|
||||
2. **延迟加载**:怪物资源按需加载
|
||||
3. **队列管理**:合理控制生成频率避免性能峰值
|
||||
|
||||
### 内存管理
|
||||
|
||||
1. **及时清理**:战斗结束后立即清理怪物实体
|
||||
2. **资源卸载**:不再需要的资源及时卸载
|
||||
3. **缓存策略**:合理缓存常用的配置数据
|
||||
|
||||
### 配置优化
|
||||
|
||||
1. **预计算**:将静态配置在启动时预计算
|
||||
2. **分层加载**:按关卡需求分层加载配置
|
||||
3. **压缩存储**:使用紧凑的数据结构存储配置
|
||||
|
||||
## 总结
|
||||
|
||||
肉鸽关卡配置系统是一个设计精良的程序化关卡生成框架,具有以下核心优势:
|
||||
|
||||
### 技术亮点
|
||||
|
||||
- **模块化设计**:清晰的职责分离和接口定义
|
||||
- **可扩展性**:易于添加新类型和调整配置
|
||||
- **性能优化**:合理的算法设计和资源管理
|
||||
- **用户体验**:平衡的难度曲线和多样化的游戏体验
|
||||
|
||||
### 应用价值
|
||||
|
||||
该系统不仅适用于Roguelike游戏,也可作为其他类型游戏关卡生成的基础框架。其程序化的设计理念和灵活的配置机制为游戏开发提供了强大的工具支持。
|
||||
|
||||
通过深入理解和合理运用这套系统,开发者可以创造出具有深度策略性和持续挑战性的游戏体验,为玩家提供持久的游戏乐趣。
|
||||
342
.qoder/repowiki/zh/content/地图系统/肉鸽关卡配置/随机事件系统.md
Normal file
342
.qoder/repowiki/zh/content/地图系统/肉鸽关卡配置/随机事件系统.md
Normal file
@@ -0,0 +1,342 @@
|
||||
# 随机事件系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 概述
|
||||
|
||||
随机事件系统是肉鸽模式(Roguelike)游戏的核心机制之一,它为玩家提供了不可预测的游戏体验。本文档详细分析了RogueConfig.ts中实现的随机事件机制,包括事件类型定义、概率配置、触发逻辑以及与游戏流程的集成方式。
|
||||
|
||||
该系统通过EventType枚举定义了四种基本事件类型:宝箱事件(Treasure)、陷阱事件(Trap)、增益事件(Buff)和减益事件(Debuff),并通过EventConfig配置对象实现了灵活的概率控制和效果描述。
|
||||
|
||||
## 项目结构
|
||||
|
||||
随机事件系统的核心文件位于游戏的地图模块中,主要包含以下关键组件:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "随机事件系统架构"
|
||||
RogueConfig["RogueConfig.ts<br/>核心配置与算法"]
|
||||
MissionMonComp["MissionMonComp.ts<br/>事件处理控制器"]
|
||||
GameEvent["GameEvent.ts<br/>事件通信系统"]
|
||||
HeroAttrs["HeroAttrs.ts<br/>属性系统"]
|
||||
end
|
||||
subgraph "UI反馈系统"
|
||||
GameUIConfig["GameUIConfig.ts<br/>界面配置"]
|
||||
MessageSystem["消息系统"]
|
||||
end
|
||||
RogueConfig --> MissionMonComp
|
||||
MissionMonComp --> GameEvent
|
||||
MissionMonComp --> HeroAttrs
|
||||
GameEvent --> MessageSystem
|
||||
MessageSystem --> GameUIConfig
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L311)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L50)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L30)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### EventType枚举定义
|
||||
|
||||
系统定义了四种基本的随机事件类型,每种类型都有明确的业务含义:
|
||||
|
||||
| 事件类型 | 描述 | 业务含义 |
|
||||
|---------|------|----------|
|
||||
| TREASURE | 宝箱事件 | 提供额外奖励,增加玩家收益 |
|
||||
| TRAP | 陷阱事件 | 造成伤害,增加游戏风险 |
|
||||
| BUFF | 增益事件 | 提供临时能力提升,改善玩家状态 |
|
||||
| DEBUFF | 减益事件 | 降低玩家能力,增加挑战难度 |
|
||||
|
||||
### EventConfig配置对象
|
||||
|
||||
每个事件类型都通过EventConfig对象进行详细配置,包含触发概率和效果描述:
|
||||
|
||||
| 配置项 | 宝箱事件 | 陷阱事件 | 增益事件 | 减益事件 |
|
||||
|--------|----------|----------|----------|----------|
|
||||
| 触发概率 | 30% | 25% | 25% | 20% |
|
||||
| 效果描述 | 获得额外奖励 | 受到一定伤害 | 获得临时增益效果 | 受到临时减益效果 |
|
||||
|
||||
### StageType事件关卡
|
||||
|
||||
事件关卡(StageType.EVENT)作为特殊的关卡类型,具有独特的触发条件和游戏流程融合方式。
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L40-L85)
|
||||
|
||||
## 架构概览
|
||||
|
||||
随机事件系统采用分层架构设计,确保了良好的模块化和可扩展性:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as "玩家"
|
||||
participant MissionComp as "MissionMonComp"
|
||||
participant RogueConfig as "RogueConfig"
|
||||
participant GameEvent as "GameEvent系统"
|
||||
participant UI as "UI反馈"
|
||||
Player->>MissionComp : 进入关卡
|
||||
MissionComp->>RogueConfig : getStageType()
|
||||
RogueConfig-->>MissionComp : 返回关卡类型
|
||||
MissionComp->>RogueConfig : getRandomEvent()
|
||||
RogueConfig-->>MissionComp : 返回事件类型
|
||||
MissionComp->>MissionComp : processRandomEvent()
|
||||
MissionComp->>GameEvent : 触发事件
|
||||
GameEvent->>UI : 显示事件效果
|
||||
Note over Player,UI : 随机事件处理流程
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L102-L136)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L280-L311)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### getRandomEvent函数实现
|
||||
|
||||
getRandomEvent函数是随机事件系统的核心算法,基于累积概率算法实现加权随机选择:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始随机事件选择]) --> InitRandom["生成随机数<br/>random = Math.random()"]
|
||||
InitRandom --> ResetCumulative["重置累积概率<br/>cumulativeProbability = 0"]
|
||||
ResetCumulative --> LoopEvents["遍历EventConfig中的事件类型"]
|
||||
LoopEvents --> AddProbability["累积概率<br/>cumulativeProbability += probability"]
|
||||
AddProbability --> CheckCondition{"random <= cumulativeProbability?"}
|
||||
CheckCondition --> |是| ReturnEvent["返回事件类型"]
|
||||
CheckCondition --> |否| NextEvent["检查下一个事件"]
|
||||
NextEvent --> LoopEvents
|
||||
ReturnEvent --> End([结束])
|
||||
style Start fill:#e1f5fe
|
||||
style End fill:#e8f5e8
|
||||
style ReturnEvent fill:#fff3e0
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L280-L311)
|
||||
|
||||
该算法的关键特性:
|
||||
- **累积概率计算**:通过逐步累加各事件的概率,实现加权随机选择
|
||||
- **边界条件处理**:确保所有事件都有被选中的机会
|
||||
- **性能优化**:O(n)时间复杂度,其中n为事件类型数量
|
||||
|
||||
### getStageType关卡类型判断
|
||||
|
||||
关卡类型判断逻辑实现了复杂的触发条件:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始关卡类型判断]) --> CheckStageNumber{"stageNumber % 5 == 0?"}
|
||||
CheckStageNumber --> |是| CheckLevel{"level == 3?"}
|
||||
CheckLevel --> |是| ReturnEvent["返回EVENT类型"]
|
||||
CheckLevel --> |否| ContinueCheck["继续检查"]
|
||||
CheckStageNumber --> |否| CheckTen{"stageNumber % 10 == 0?"}
|
||||
CheckTen --> |是| CheckTenLevel{"level == 5?"}
|
||||
CheckTenLevel --> |是| ReturnBoss["返回BOSS类型"]
|
||||
CheckTenLevel --> |否| CheckFour{"level == 4?"}
|
||||
CheckFour --> |是| ReturnElite["返回ELITE类型"]
|
||||
CheckFour --> |否| ReturnNormal["返回NORMAL类型"]
|
||||
CheckTen --> |否| CheckOneToNine{"1 <= stageNumber <= 9?"}
|
||||
CheckOneToNine --> |是| CheckFive{"level == 5?"}
|
||||
CheckFive --> |是| ReturnElite2["返回ELITE类型"]
|
||||
CheckFive --> |否| ReturnNormal2["返回NORMAL类型"]
|
||||
ContinueCheck --> CheckTen
|
||||
ReturnEvent --> End([结束])
|
||||
ReturnBoss --> End
|
||||
ReturnElite --> End
|
||||
ReturnNormal --> End
|
||||
ReturnElite2 --> End
|
||||
ReturnNormal2 --> End
|
||||
style Start fill:#e1f5fe
|
||||
style End fill:#e8f5e8
|
||||
style ReturnEvent fill:#fff3e0
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L140-L170)
|
||||
|
||||
### 事件处理流程
|
||||
|
||||
事件处理通过MissionMonComp组件实现,包含完整的生命周期管理:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MissionMonComp {
|
||||
-currentEvent : EventType | null
|
||||
-eventProcessed : boolean
|
||||
+do_mon_wave() : void
|
||||
+processRandomEvent() : void
|
||||
-generateMonstersFromStageConfig() : void
|
||||
-addToStageSpawnQueue() : void
|
||||
}
|
||||
class EventType {
|
||||
<<enumeration>>
|
||||
TREASURE
|
||||
TRAP
|
||||
BUFF
|
||||
DEBUFF
|
||||
}
|
||||
class RogueConfig {
|
||||
+getRandomEvent() : EventType | null
|
||||
+getStageType() : StageType
|
||||
+calculateMonsterCount() : number
|
||||
+calculateMonsterStrengthMultiplier() : number
|
||||
}
|
||||
MissionMonComp --> EventType : "使用"
|
||||
MissionMonComp --> RogueConfig : "调用"
|
||||
RogueConfig --> EventType : "返回"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L15-L35)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L40-L85)
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L102-L169)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L280-L311)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
随机事件系统的依赖关系体现了清晰的分层架构:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "外部依赖"
|
||||
ECS[ECS框架]
|
||||
OopsFramework[Oops Framework]
|
||||
GameEngine[Cocos Creator引擎]
|
||||
end
|
||||
subgraph "核心模块"
|
||||
RogueConfig[RogueConfig.ts]
|
||||
MissionMonComp[MissionMonComp.ts]
|
||||
GameEvent[GameEvent.ts]
|
||||
end
|
||||
subgraph "配置模块"
|
||||
HeroAttrs[HeroAttrs.ts]
|
||||
GameUIConfig[GameUIConfig.ts]
|
||||
end
|
||||
ECS --> MissionMonComp
|
||||
OopsFramework --> GameEvent
|
||||
GameEngine --> ECS
|
||||
RogueConfig --> MissionMonComp
|
||||
MissionMonComp --> GameEvent
|
||||
GameEvent --> GameUIConfig
|
||||
HeroAttrs --> MissionMonComp
|
||||
style RogueConfig fill:#e3f2fd
|
||||
style MissionMonComp fill:#f3e5f5
|
||||
style GameEvent fill:#e8f5e8
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L15)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L20)
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L20)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L20)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
随机事件系统在设计时充分考虑了性能优化:
|
||||
|
||||
### 算法复杂度分析
|
||||
- **getRandomEvent函数**:O(n)时间复杂度,其中n为事件类型数量
|
||||
- **getStageType函数**:O(1)时间复杂度,固定条件判断
|
||||
- **事件处理**:单次事件处理时间复杂度为O(1)
|
||||
|
||||
### 内存使用优化
|
||||
- 事件配置采用静态常量定义,避免运行时内存分配
|
||||
- 事件类型使用枚举,减少字符串比较开销
|
||||
- 事件状态管理简洁,避免不必要的状态保存
|
||||
|
||||
### 扩展性设计
|
||||
- 新增事件类型只需修改EventType枚举和EventConfig配置
|
||||
- 事件效果处理采用switch语句,便于添加新的处理逻辑
|
||||
- 关卡类型判断逻辑支持未来扩展新的触发条件
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 事件触发概率异常
|
||||
**问题描述**:事件触发概率不符合预期
|
||||
**可能原因**:
|
||||
- EventConfig中的概率设置错误
|
||||
- 累积概率计算逻辑异常
|
||||
|
||||
**解决方案**:
|
||||
1. 检查EventConfig中各事件的概率总和是否为1
|
||||
2. 验证getRandomEvent函数的累积概率计算逻辑
|
||||
3. 添加调试日志输出随机数和累积概率值
|
||||
|
||||
#### 事件关卡触发时机错误
|
||||
**问题描述**:事件关卡在非预期关卡触发
|
||||
**可能原因**:
|
||||
- getStageType函数的关卡判断逻辑错误
|
||||
- 关卡参数传递不正确
|
||||
|
||||
**解决方案**:
|
||||
1. 检查关卡号和等级参数的传递
|
||||
2. 验证getStageType函数中的模运算逻辑
|
||||
3. 添加关卡类型判断的日志输出
|
||||
|
||||
#### 事件效果未生效
|
||||
**问题描述**:事件发生但效果未体现
|
||||
**可能原因**:
|
||||
- 事件处理逻辑缺失
|
||||
- UI反馈未正确触发
|
||||
|
||||
**解决方案**:
|
||||
1. 检查MissionMonComp中的processRandomEvent函数
|
||||
2. 验证GameEvent系统的事件分发机制
|
||||
3. 确认UI层的消息接收和处理逻辑
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L120-L169)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L280-L311)
|
||||
|
||||
## 结论
|
||||
|
||||
随机事件系统通过精心设计的架构和算法,为肉鸽模式游戏提供了丰富且可控的随机体验。系统的主要优势包括:
|
||||
|
||||
### 设计优势
|
||||
- **模块化架构**:清晰的职责分离,便于维护和扩展
|
||||
- **灵活的概率控制**:支持动态调整事件触发概率
|
||||
- **完善的事件处理**:从触发到效果呈现的完整流程
|
||||
- **良好的性能表现**:高效的算法实现和内存使用
|
||||
|
||||
### 扩展建议
|
||||
1. **新增事件类型**:可以轻松添加复活、传送等新事件类型
|
||||
2. **概率动态调整**:可以根据游戏进程动态调整事件概率
|
||||
3. **事件效果增强**:支持更复杂的事件效果和组合效果
|
||||
4. **UI反馈完善**:集成更丰富的视觉和音效反馈
|
||||
|
||||
### 最佳实践
|
||||
- 保持事件概率的平衡性,避免过于极端的结果
|
||||
- 提供清晰的事件效果说明,帮助玩家理解游戏机制
|
||||
- 实现事件历史记录功能,增加游戏的策略深度
|
||||
- 建立完善的测试机制,确保事件系统的稳定性
|
||||
|
||||
该随机事件系统为肉鸽游戏提供了坚实的基础,通过合理的扩展和优化,可以进一步提升游戏的趣味性和挑战性。
|
||||
363
.qoder/repowiki/zh/content/奖励系统/奖励UI交互/MissionComp事件处理机制.md
Normal file
363
.qoder/repowiki/zh/content/奖励系统/奖励UI交互/MissionComp事件处理机制.md
Normal file
@@ -0,0 +1,363 @@
|
||||
# MissionComp事件处理机制
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构概览](#项目结构概览)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [事件处理流程](#事件处理流程)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
MissionComp.ts是游戏战斗系统的核心控制器,负责管理整个任务生命周期中的事件监听、处理和游戏状态管理。该组件通过事件驱动的方式协调各个子系统的运作,包括战斗准备、怪物生成、英雄死亡检测、战斗结束处理等功能。
|
||||
|
||||
## 项目结构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "游戏地图模块"
|
||||
MissionComp[MissionComp<br/>任务控制器]
|
||||
MissionMonComp[MissionMonComp<br/>怪物控制器]
|
||||
VictoryComp[VictoryComp<br/>胜利界面]
|
||||
end
|
||||
subgraph "英雄系统"
|
||||
HeroViewComp[HeroViewComp<br/>英雄视图组件]
|
||||
HeroConComp[HeroConComp<br/>英雄控制组件]
|
||||
end
|
||||
subgraph "技能系统"
|
||||
AtkConCom[AtkConCom<br/>攻击控制组件]
|
||||
SkillViewCom[SkillViewCom<br/>技能视图组件]
|
||||
end
|
||||
subgraph "事件系统"
|
||||
GameEvent[GameEvent<br/>事件枚举]
|
||||
MessageCenter[消息中心]
|
||||
end
|
||||
MissionComp --> GameEvent
|
||||
MissionComp --> MessageCenter
|
||||
MissionMonComp --> GameEvent
|
||||
HeroViewComp --> GameEvent
|
||||
AtkConCom --> GameEvent
|
||||
MessageCenter --> MissionComp
|
||||
MessageCenter --> MissionMonComp
|
||||
MessageCenter --> HeroViewComp
|
||||
MessageCenter --> VictoryComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L151)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
MissionComp作为游戏战斗系统的核心控制器,主要负责以下功能:
|
||||
|
||||
### 主要职责
|
||||
- **事件监听管理**:注册并处理各种游戏事件
|
||||
- **战斗状态控制**:管理战斗开始、进行、结束的状态转换
|
||||
- **资源清理**:战斗结束后清理游戏实体和组件
|
||||
- **数据初始化**:每局游戏开始时初始化相关数据
|
||||
|
||||
### 关键属性
|
||||
- `rewards`:掉落物品奖励数组
|
||||
- `game_data`:游戏统计数据(经验、金币、钻石)
|
||||
- `node`:Cocos节点引用
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L15-L30)
|
||||
|
||||
## 架构概览
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家
|
||||
participant MissionComp as MissionComp
|
||||
participant MissionMonComp as MissionMonComp
|
||||
participant HeroViewComp as HeroViewComp
|
||||
participant VictoryComp as VictoryComp
|
||||
participant ECS as ECS系统
|
||||
Player->>MissionComp : 启动任务
|
||||
MissionComp->>MissionComp : data_init()
|
||||
MissionComp->>MissionComp : mission_start()
|
||||
MissionComp->>MissionMonComp : GameEvent.FightReady
|
||||
MissionMonComp->>MissionMonComp : 刷怪
|
||||
MissionComp->>MissionComp : to_fight()
|
||||
MissionComp->>MissionComp : GameEvent.FightStart
|
||||
loop 战斗进行中
|
||||
HeroViewComp->>MissionComp : GameEvent.HeroDead
|
||||
MissionComp->>MissionComp : do_hero_dead()
|
||||
HeroViewComp->>MissionComp : GameEvent.MonDead
|
||||
MissionComp->>MissionComp : do_mon_dead()
|
||||
end
|
||||
MissionComp->>MissionComp : fight_end()
|
||||
MissionComp->>ECS : cleanComponents()
|
||||
MissionComp->>VictoryComp : 打开胜利界面
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L66-L151)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L34-L80)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### onLoad方法中的事件注册
|
||||
|
||||
MissionComp在onLoad方法中注册了多个关键事件监听器:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MissionComp {
|
||||
+onLoad() void
|
||||
+do_mon_dead(event, data) void
|
||||
+do_hero_dead(event, data) void
|
||||
+fight_end() void
|
||||
+mission_start() Promise~void~
|
||||
+data_init() void
|
||||
-cleanComponents() void
|
||||
}
|
||||
class GameEvent {
|
||||
<<enumeration>>
|
||||
MissionStart
|
||||
FightEnd
|
||||
HeroDead
|
||||
MonDead
|
||||
FightReady
|
||||
FightStart
|
||||
MissionEnd
|
||||
}
|
||||
MissionComp --> GameEvent : 监听事件
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L25-L32)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L10-L60)
|
||||
|
||||
#### 事件监听器详解
|
||||
|
||||
1. **MissionStart事件**:任务开始事件
|
||||
- 触发时机:任务初始化时
|
||||
- 处理逻辑:发送FightReady事件,激活节点,初始化数据
|
||||
|
||||
2. **MonDead事件**:怪物死亡事件
|
||||
- 触发时机:怪物被击败时
|
||||
- 处理逻辑:减少怪物计数
|
||||
|
||||
3. **HeroDead事件**:英雄死亡事件
|
||||
- 触发时机:英雄生命值归零时
|
||||
- 处理逻辑:减少英雄计数,判断游戏失败
|
||||
|
||||
4. **FightEnd事件**:战斗结束事件
|
||||
- 触发时机:战斗结束时
|
||||
- 处理逻辑:延迟清理游戏实体
|
||||
|
||||
5. **MissionEnd事件**:任务结束事件
|
||||
- 触发时机:任务完成或失败时
|
||||
- 处理逻辑:隐藏任务节点
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L25-L32)
|
||||
|
||||
### fight_end方法的延迟清理机制
|
||||
|
||||
fight_end方法实现了战斗结束后的延迟清理逻辑:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([战斗结束]) --> Delay["延迟0.5秒"]
|
||||
Delay --> StopGame["停止游戏播放<br/>smc.mission.play=false"]
|
||||
StopGame --> StopPause["停止暂停<br/>smc.mission.pause=false"]
|
||||
StopPause --> CleanComponents["调用cleanComponents()"]
|
||||
CleanComponents --> QueryHeroes["查询所有HeroViewComp组件"]
|
||||
QueryHeroes --> RemoveHero["移除HeroViewComp组件"]
|
||||
RemoveHero --> DestroyHero["销毁英雄实体"]
|
||||
DestroyHero --> QueryAtk["查询所有AtkConCom组件"]
|
||||
QueryAtk --> RemoveAtk["移除AtkConCom组件"]
|
||||
RemoveAtk --> DestroyAtk["销毁攻击实体"]
|
||||
DestroyAtk --> QuerySkill["查询所有SkillViewCom组件"]
|
||||
QuerySkill --> RemoveSkill["移除SkillViewCom组件"]
|
||||
RemoveSkill --> DestroySkill["销毁技能实体"]
|
||||
DestroySkill --> End([清理完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L108-L116)
|
||||
|
||||
#### cleanComponents方法实现细节
|
||||
|
||||
cleanComponents方法通过ECS查询系统清理不同类型的游戏实体:
|
||||
|
||||
- **英雄实体清理**:查询所有带有HeroViewComp组件的实体
|
||||
- **攻击实体清理**:查询所有带有AtkConCom组件的实体
|
||||
- **技能实体清理**:查询所有带有SkillViewCom组件的实体
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L125-L130)
|
||||
|
||||
### do_hero_dead方法的游戏失败判定
|
||||
|
||||
do_hero_dead方法实现了英雄死亡时的游戏失败判定逻辑:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
HeroDead[英雄死亡事件] --> ReduceCount["减少英雄计数<br/>smc.vmdata.mission_data.hero_num--"]
|
||||
ReduceCount --> CheckCount{"英雄计数 <= 0?"}
|
||||
CheckCount --> |否| Continue[继续战斗]
|
||||
CheckCount --> |是| DispatchEnd["分发FightEnd事件<br/>GameEvent.FightEnd"]
|
||||
DispatchEnd --> OpenVictory["打开胜利界面<br/>UIID.Victory"]
|
||||
OpenVictory --> SetParams["设置参数:<br/>victory=false<br/>rewards=this.rewards<br/>game_data=this.game_data"]
|
||||
SetParams --> End[游戏失败]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L54-L62)
|
||||
|
||||
当所有英雄都死亡时,系统会:
|
||||
1. 分发FightEnd事件,携带victory=false参数
|
||||
2. 打开Victory界面,显示失败状态
|
||||
3. 传递奖励数组和游戏统计数据
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L54-L62)
|
||||
|
||||
### data_init方法的数据初始化过程
|
||||
|
||||
data_init方法负责每局游戏开始时的初始化工作:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始初始化]) --> SetPlay["设置游戏状态<br/>smc.mission.play = true"]
|
||||
SetPlay --> SetFight["设置战斗状态<br/>smc.vmdata.mission_data.in_fight=false"]
|
||||
SetFight --> SetTime["设置战斗时间<br/>smc.vmdata.mission_data.fight_time=0"]
|
||||
SetTime --> SetLevel["设置关卡<br/>smc.vmdata.mission_data.level=0"]
|
||||
SetLevel --> InitRewards["初始化奖励数组<br/>this.rewards=[]"]
|
||||
InitRewards --> Log["记录初始化日志"]
|
||||
Log --> End([初始化完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L118-L124)
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L118-L124)
|
||||
|
||||
## 事件处理流程
|
||||
|
||||
### 完整的事件派发与监听流程
|
||||
|
||||
以下是游戏战斗系统中典型的事件处理流程:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant UI as 用户界面
|
||||
participant MissionComp as MissionComp
|
||||
participant MessageCenter as 消息中心
|
||||
participant MissionMonComp as MissionMonComp
|
||||
participant HeroViewComp as HeroViewComp
|
||||
participant ECS as ECS系统
|
||||
UI->>MissionComp : 点击开始战斗
|
||||
MissionComp->>MessageCenter : GameEvent.MissionStart
|
||||
MessageCenter->>MissionComp : 接收事件
|
||||
MissionComp->>MessageCenter : GameEvent.FightReady
|
||||
MessageCenter->>MissionMonComp : 接收事件
|
||||
MissionMonComp->>MissionMonComp : 刷怪逻辑
|
||||
MissionMonComp->>MessageCenter : GameEvent.FightStart
|
||||
MessageCenter->>MissionComp : 接收事件
|
||||
loop 战斗过程中
|
||||
HeroViewComp->>MessageCenter : GameEvent.MonDead
|
||||
MessageCenter->>MissionComp : 接收事件
|
||||
MissionComp->>MissionComp : do_mon_dead()
|
||||
HeroViewComp->>MessageCenter : GameEvent.HeroDead
|
||||
MessageCenter->>MissionComp : 接收事件
|
||||
MissionComp->>MissionComp : do_hero_dead()
|
||||
alt 英雄全部死亡
|
||||
MissionComp->>MessageCenter : GameEvent.FightEnd
|
||||
MissionComp->>UI : 打开胜利界面
|
||||
end
|
||||
end
|
||||
MissionComp->>MessageCenter : GameEvent.FightEnd
|
||||
MessageCenter->>MissionComp : 接收事件
|
||||
MissionComp->>MissionComp : fight_end()
|
||||
MissionComp->>ECS : cleanComponents()
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L66-L151)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L34-L80)
|
||||
|
||||
### 参数传递机制
|
||||
|
||||
事件系统采用参数化设计,支持不同类型的参数传递:
|
||||
|
||||
| 事件类型 | 参数结构 | 用途 |
|
||||
|---------|---------|------|
|
||||
| GameEvent.FightEnd | `{victory: boolean}` | 标识战斗结果 |
|
||||
| GameEvent.MissionStart | 无参数 | 启动新任务 |
|
||||
| GameEvent.MonDead | `data: {monsterId: number}` | 怪物死亡信息 |
|
||||
| GameEvent.HeroDead | `data: {heroId: number}` | 英雄死亡信息 |
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L54-L62)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L48-L52)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 事件监听器优化
|
||||
|
||||
1. **事件去重**:确保相同事件不会重复注册
|
||||
2. **内存管理**:及时清理不再使用的事件监听器
|
||||
3. **异步处理**:战斗结束清理采用延迟执行避免阻塞
|
||||
|
||||
### ECS组件清理策略
|
||||
|
||||
cleanComponents方法采用批量查询和清理策略:
|
||||
- 使用ECS查询系统高效定位目标组件
|
||||
- 批量移除和销毁相关实体
|
||||
- 避免逐个遍历导致的性能问题
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 1. 事件未正确触发
|
||||
**症状**:某些事件监听器没有响应
|
||||
**原因**:事件名称拼写错误或事件未正确注册
|
||||
**解决**:检查GameEvent枚举定义和事件监听器注册
|
||||
|
||||
#### 2. 战斗结束后残留实体
|
||||
**症状**:战斗结束后仍有未清理的游戏实体
|
||||
**原因**:cleanComponents方法未能匹配到所有组件
|
||||
**解决**:检查组件标签是否正确,确保所有实体都包含相应组件
|
||||
|
||||
#### 3. 英雄死亡判定错误
|
||||
**症状**:英雄死亡后游戏未正确判定失败
|
||||
**原因**:do_hero_dead方法逻辑错误或事件传递中断
|
||||
**解决**:验证英雄计数逻辑和事件分发机制
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L54-L62)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L125-L130)
|
||||
|
||||
## 结论
|
||||
|
||||
MissionComp.ts作为游戏战斗系统的核心控制器,通过精心设计的事件驱动架构实现了高效的战斗管理。其主要优势包括:
|
||||
|
||||
1. **模块化设计**:清晰的职责分离,便于维护和扩展
|
||||
2. **事件驱动**:松耦合的组件通信机制
|
||||
3. **资源管理**:完善的清理机制确保内存安全
|
||||
4. **状态控制**:精确的游戏状态管理
|
||||
|
||||
该设计模式为游戏开发提供了可复用的战斗系统框架,能够适应不同类型的战斗场景需求。通过合理的事件管理和组件清理,确保了游戏运行的稳定性和性能表现。
|
||||
380
.qoder/repowiki/zh/content/奖励系统/奖励UI交互/基地组件状态同步.md
Normal file
380
.qoder/repowiki/zh/content/奖励系统/奖励UI交互/基地组件状态同步.md
Normal file
@@ -0,0 +1,380 @@
|
||||
# 基地组件状态同步
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [CardController.ts](file://assets/script/game/map/CardController.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构概览](#项目结构概览)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [架构设计](#架构设计)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [事件驱动机制](#事件驱动机制)
|
||||
7. [微信小游戏适配](#微信小游戏适配)
|
||||
8. [组件间协作流程](#组件间协作流程)
|
||||
9. [性能考虑](#性能考虑)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
MissionHomeComp是游戏中的基地状态视图控制器,负责管理基地界面的状态切换和UI更新。该组件在MissionEnd事件触发时激活基地节点,并通过home_active方法完成界面状态的恢复。同时,它还提供了微信小游戏环境检测、按钮交互接口预留等功能,确保游戏能够在不同平台环境下正常运行。
|
||||
|
||||
## 项目结构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "游戏地图模块"
|
||||
MissionHomeComp["MissionHomeComp<br/>基地视图控制器"]
|
||||
MissionComp["MissionComp<br/>任务控制器"]
|
||||
CardController["CardController<br/>卡片控制器"]
|
||||
end
|
||||
subgraph "事件系统"
|
||||
GameEvent["GameEvent<br/>游戏事件定义"]
|
||||
EventDispatcher["事件分发器"]
|
||||
end
|
||||
subgraph "单例模块"
|
||||
SingletonModule["SingletonModuleComp<br/>全局状态管理"]
|
||||
end
|
||||
MissionHomeComp --> GameEvent
|
||||
MissionComp --> GameEvent
|
||||
MissionHomeComp --> SingletonModule
|
||||
MissionComp --> SingletonModule
|
||||
CardController --> MissionHomeComp
|
||||
EventDispatcher --> MissionHomeComp
|
||||
EventDispatcher --> MissionComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L1-L53)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L151)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### MissionHomeComp组件特性
|
||||
|
||||
MissionHomeComp继承自CCComp基类,采用ECS架构模式,具有以下核心特性:
|
||||
|
||||
- **事件监听机制**:通过on方法监听MissionEnd事件
|
||||
- **状态管理**:提供home_active方法管理基地界面状态
|
||||
- **环境适配**:包含isWxClient方法检测微信环境
|
||||
- **扩展接口**:预留btn_func方法用于按钮交互扩展
|
||||
|
||||
### MissionComp组件职责
|
||||
|
||||
MissionComp负责整个战斗流程的控制,包括:
|
||||
- 战斗开始、结束的生命周期管理
|
||||
- 英雄死亡、怪物死亡的事件处理
|
||||
- 奖励发放和数据初始化
|
||||
- 组件清理和资源回收
|
||||
|
||||
**章节来源**
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L11-L53)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L17-L151)
|
||||
|
||||
## 架构设计
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MissionHomeComp {
|
||||
+onLoad() void
|
||||
+start() void
|
||||
+mission_end() void
|
||||
+home_active() void
|
||||
+uodate_data() void
|
||||
+isWxClient() boolean
|
||||
+btn_func(e, data) void
|
||||
+reset() void
|
||||
}
|
||||
class MissionComp {
|
||||
+onLoad() void
|
||||
+update(dt) void
|
||||
+mission_start() void
|
||||
+mission_end() void
|
||||
+fight_end() void
|
||||
+do_mon_dead(event, data) void
|
||||
+do_hero_dead(event, data) void
|
||||
+cleanComponents() void
|
||||
+reset() void
|
||||
}
|
||||
class SingletonModuleComp {
|
||||
+mission object
|
||||
+vmdata object
|
||||
+isWxClient() boolean
|
||||
+updateGold(gold) boolean
|
||||
+addHero(hero_uuid) boolean
|
||||
}
|
||||
class GameEvent {
|
||||
<<enumeration>>
|
||||
MissionEnd
|
||||
FightEnd
|
||||
MissionStart
|
||||
HeroDead
|
||||
MonDead
|
||||
}
|
||||
MissionHomeComp --> GameEvent : 监听
|
||||
MissionComp --> GameEvent : 触发
|
||||
MissionHomeComp --> SingletonModuleComp : 使用
|
||||
MissionComp --> SingletonModuleComp : 使用
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L13-L53)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L17-L151)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L25-L195)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### MissionHomeComp核心方法解析
|
||||
|
||||
#### mission_end方法 - 事件响应入口
|
||||
|
||||
当MissionEnd事件触发时,mission_end方法被调用,这是基地状态恢复的关键入口点。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MissionComp as "MissionComp"
|
||||
participant GameEvent as "GameEvent"
|
||||
participant MissionHomeComp as "MissionHomeComp"
|
||||
participant UI as "UI界面"
|
||||
MissionComp->>GameEvent : 触发MissionEnd事件
|
||||
GameEvent->>MissionHomeComp : 分发事件到mission_end
|
||||
MissionHomeComp->>MissionHomeComp : 调用home_active()
|
||||
MissionHomeComp->>MissionHomeComp : 调用uodate_data()
|
||||
MissionHomeComp->>UI : 设置node.active=true
|
||||
UI-->>MissionHomeComp : 界面激活完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L26-L32)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L114-L120)
|
||||
|
||||
#### home_active方法 - 状态激活逻辑
|
||||
|
||||
home_active方法是基地界面激活的核心逻辑,包含两个关键步骤:
|
||||
|
||||
1. **数据更新**:调用uodate_data()方法(当前为空,但设计意图明确)
|
||||
2. **界面激活**:设置节点可见性
|
||||
|
||||
#### uodate_data方法 - 设计意图分析
|
||||
|
||||
虽然当前实现为空,但从命名和设计模式来看,uodate_data方法预期用于:
|
||||
- 同步基地生命值信息
|
||||
- 更新防御状态数据
|
||||
- 刷新基地资源显示
|
||||
- 更新英雄驻守状态
|
||||
|
||||
这种设计遵循了MVVM模式的思想,为未来的数据绑定和自动更新做好准备。
|
||||
|
||||
#### isWxClient方法 - 平台检测机制
|
||||
|
||||
```typescript
|
||||
isWxClient(){
|
||||
return typeof wx !== 'undefined' && typeof (wx as any).getSystemInfoSync === 'function';
|
||||
}
|
||||
```
|
||||
|
||||
该方法通过检查wx对象的存在性和特定方法来判断是否运行在微信环境中,为微信小游戏特性提供支持。
|
||||
|
||||
#### btn_func方法 - 交互接口预留
|
||||
|
||||
btn_func方法作为按钮交互的预留接口,为未来扩展按钮功能提供便利:
|
||||
- 参数e:事件名称或类型标识
|
||||
- 参数data:附加数据对象
|
||||
- 设计目的:支持按钮点击、触摸等交互事件
|
||||
|
||||
**章节来源**
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L26-L53)
|
||||
|
||||
### MissionComp战斗流程管理
|
||||
|
||||
#### 事件监听机制
|
||||
|
||||
MissionComp通过on方法注册多个事件监听器:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([游戏启动]) --> MissionStart["监听MissionStart事件"]
|
||||
MissionStart --> FightReady["监听FightReady事件"]
|
||||
FightReady --> FightStart["监听FightStart事件"]
|
||||
FightStart --> MonDead["监听MonDead事件"]
|
||||
MonDead --> HeroDead["监听HeroDead事件"]
|
||||
HeroDead --> FightEnd["监听FightEnd事件"]
|
||||
FightEnd --> MissionEnd["监听MissionEnd事件"]
|
||||
MissionEnd --> MissionEndLogic["执行mission_end逻辑"]
|
||||
MissionEndLogic --> CleanComponents["清理组件"]
|
||||
CleanComponents --> End([流程结束])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L28-L36)
|
||||
|
||||
#### 战斗状态管理
|
||||
|
||||
MissionComp维护复杂的战斗状态,包括:
|
||||
- `smc.mission.play`:战斗是否进行中
|
||||
- `smc.mission.pause`:战斗是否暂停
|
||||
- `smc.mission.in_fight`:是否处于战斗状态
|
||||
- `smc.vmdata.mission_data`:战斗数据统计
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L28-L151)
|
||||
|
||||
## 事件驱动机制
|
||||
|
||||
### 事件流分析
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as "玩家"
|
||||
participant MissionComp as "MissionComp"
|
||||
participant GameEvent as "GameEvent"
|
||||
participant MissionHomeComp as "MissionHomeComp"
|
||||
participant UI as "UI界面"
|
||||
Player->>MissionComp : 开始战斗
|
||||
MissionComp->>GameEvent : 触发MissionStart
|
||||
GameEvent->>MissionComp : 分发事件
|
||||
MissionComp->>MissionComp : mission_start()
|
||||
MissionComp->>UI : 显示战斗界面
|
||||
Note over MissionComp : 战斗进行中...
|
||||
Player->>MissionComp : 英雄死亡
|
||||
MissionComp->>GameEvent : 触发HeroDead
|
||||
GameEvent->>MissionComp : 分发事件
|
||||
MissionComp->>MissionComp : do_hero_dead()
|
||||
MissionComp->>GameEvent : 触发FightEnd
|
||||
GameEvent->>MissionComp : 分发事件
|
||||
MissionComp->>MissionComp : fight_end()
|
||||
MissionComp->>GameEvent : 触发MissionEnd
|
||||
GameEvent->>MissionHomeComp : 分发事件
|
||||
MissionHomeComp->>MissionHomeComp : mission_end()
|
||||
MissionHomeComp->>MissionHomeComp : home_active()
|
||||
MissionHomeComp->>UI : 激活基地界面
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L66-L120)
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L26-L32)
|
||||
|
||||
### GameEvent枚举定义
|
||||
|
||||
GameEvent枚举定义了游戏中的所有事件类型,其中MissionEnd事件是基地状态恢复的关键触发点。
|
||||
|
||||
**章节来源**
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
|
||||
## 微信小游戏适配
|
||||
|
||||
### 平台检测机制
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([应用启动]) --> CheckWx["检查wx对象存在性"]
|
||||
CheckWx --> HasWx{"wx对象存在?"}
|
||||
HasWx --> |否| WebPlatform["Web平台"]
|
||||
HasWx --> |是| CheckMethod["检查getSystemInfoSync方法"]
|
||||
CheckMethod --> HasMethod{"方法存在?"}
|
||||
HasMethod --> |否| OtherPlatform["其他平台"]
|
||||
HasMethod --> |是| WeChatPlatform["微信平台"]
|
||||
WebPlatform --> DisableFeatures["禁用微信特性"]
|
||||
OtherPlatform --> DisableFeatures
|
||||
WeChatPlatform --> EnableFeatures["启用微信特性"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L58-L62)
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L40-L42)
|
||||
|
||||
### 数据同步机制
|
||||
|
||||
isWxClient方法不仅用于环境检测,还为后续的数据同步功能提供基础。当检测到微信环境时,系统会启用云端数据同步功能。
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L58-L195)
|
||||
|
||||
## 组件间协作流程
|
||||
|
||||
### 基地状态恢复完整流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
BattleEnd([战斗结束]) --> MissionEndEvent["触发MissionEnd事件"]
|
||||
MissionEndEvent --> MissionHomeComp["MissionHomeComp接收事件"]
|
||||
MissionHomeComp --> MissionEndMethod["调用mission_end方法"]
|
||||
MissionEndMethod --> HomeActive["调用home_active方法"]
|
||||
HomeActive --> UpdateData["调用uodate_data方法"]
|
||||
UpdateData --> ActivateNode["设置node.active=true"]
|
||||
ActivateNode --> ShowUI["显示基地界面"]
|
||||
ShowUI --> CheckWx{"检查微信环境"}
|
||||
CheckWx --> |是| SyncData["同步云端数据"]
|
||||
CheckWx --> |否| Complete["流程完成"]
|
||||
SyncData --> Complete
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L26-L35)
|
||||
- [CardController.ts](file://assets/script/game/map/CardController.ts#L32-L35)
|
||||
|
||||
### CardController集成
|
||||
|
||||
CardController作为页面控制器,负责在战斗界面和基地界面之间切换:
|
||||
|
||||
```typescript
|
||||
page_init(){
|
||||
this.node.getChildByName("mission_home").active=true;
|
||||
this.node.getChildByName("mission").active=false;
|
||||
}
|
||||
```
|
||||
|
||||
这种设计实现了清晰的界面分离,确保用户能够直观地从战斗状态过渡到基地状态。
|
||||
|
||||
**章节来源**
|
||||
- [CardController.ts](file://assets/script/game/map/CardController.ts#L32-L35)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 内存管理策略
|
||||
|
||||
MissionHomeComp实现了reset方法来处理组件销毁和内存释放:
|
||||
|
||||
```typescript
|
||||
reset() {
|
||||
this.node.destroy();
|
||||
}
|
||||
```
|
||||
|
||||
这种方法确保了组件在不需要时能够及时释放资源,避免内存泄漏。
|
||||
|
||||
### 事件监听优化
|
||||
|
||||
通过精确的事件监听机制,避免了不必要的回调调用,提高了整体性能。
|
||||
|
||||
### 状态同步优化
|
||||
|
||||
uodate_data方法的预留设计允许未来实现增量更新,减少不必要的UI刷新操作。
|
||||
|
||||
## 总结
|
||||
|
||||
MissionHomeComp作为基地状态的视图控制器,在游戏架构中扮演着重要角色。它通过事件驱动机制实现了从战斗到基地状态的平滑过渡,同时为未来的功能扩展预留了充足的空间。
|
||||
|
||||
### 主要特点
|
||||
|
||||
1. **事件驱动架构**:通过MissionEnd事件触发基地状态恢复
|
||||
2. **状态管理清晰**:home_active方法封装了界面激活逻辑
|
||||
3. **平台适配完善**:isWxClient方法支持微信小游戏特性
|
||||
4. **扩展性强**:btn_func方法预留了按钮交互接口
|
||||
5. **性能优化**:合理的内存管理和事件监听机制
|
||||
|
||||
### 设计优势
|
||||
|
||||
- **模块化设计**:MissionHomeComp独立于具体业务逻辑
|
||||
- **可测试性**:清晰的方法边界便于单元测试
|
||||
- **可维护性**:预留的扩展接口降低了未来修改的成本
|
||||
- **跨平台兼容**:完善的平台检测机制确保多环境支持
|
||||
|
||||
这种设计模式体现了现代游戏开发中关注分离、可扩展性和平台兼容性的最佳实践,为构建高质量的游戏应用奠定了坚实基础。
|
||||
423
.qoder/repowiki/zh/content/奖励系统/奖励UI交互/奖励UI交互.md
Normal file
423
.qoder/repowiki/zh/content/奖励系统/奖励UI交互/奖励UI交互.md
Normal file
@@ -0,0 +1,423 @@
|
||||
# 奖励UI交互
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [系统概述](#系统概述)
|
||||
2. [核心组件架构](#核心组件架构)
|
||||
3. [事件驱动机制](#事件驱动机制)
|
||||
4. [奖励触发条件](#奖励触发条件)
|
||||
5. [UI界面展示](#ui界面展示)
|
||||
6. [数据绑定与状态管理](#数据绑定与状态管理)
|
||||
7. [界面过渡动画](#界面过渡动画)
|
||||
8. [用户交互反馈](#用户交互反馈)
|
||||
9. [系统集成流程](#系统集成流程)
|
||||
10. [故障排除指南](#故障排除指南)
|
||||
|
||||
## 系统概述
|
||||
|
||||
奖励系统UI交互是游戏战斗胜利后的重要组成部分,负责在玩家完成战斗后展示奖励选项、经验值、金币和钻石等资源。系统采用事件驱动架构,通过MissionComp作为核心控制器,协调各个子组件完成完整的奖励展示流程。
|
||||
|
||||
### 系统特点
|
||||
- **事件驱动**:基于GameEvent机制的松耦合设计
|
||||
- **数据驱动**:使用MVVM模式实现数据绑定
|
||||
- **状态管理**:通过SingletonModuleComp统一管理游戏状态
|
||||
- **动画流畅**:支持平滑的界面过渡效果
|
||||
|
||||
## 核心组件架构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MissionComp {
|
||||
+rewards : any[]
|
||||
+game_data : any
|
||||
+onLoad() void
|
||||
+do_hero_dead(event, data) void
|
||||
+fight_end() void
|
||||
+mission_start() void
|
||||
+to_fight() void
|
||||
}
|
||||
class VictoryComp {
|
||||
+reward_lv : number
|
||||
+reward_num : number
|
||||
+rewards : any[]
|
||||
+game_data : any
|
||||
+onAdded(args) void
|
||||
+victory_end() void
|
||||
+restart() void
|
||||
+double_reward() void
|
||||
}
|
||||
class MissionHeroCompComp {
|
||||
+Friend_is_dead : boolean
|
||||
+current_hero_uuid : number
|
||||
+heros : any[]
|
||||
+onLoad() void
|
||||
+fight_ready() void
|
||||
+addHero(uuid, is_zhaohuan) void
|
||||
}
|
||||
class MissionMonCompComp {
|
||||
+monsterQueue : Array
|
||||
+spawnInterval : number
|
||||
+spawnCount : number
|
||||
+onLoad() void
|
||||
+fight_ready() void
|
||||
+generateMonstersFromStageConfig(configs) void
|
||||
}
|
||||
class MissionHomeComp {
|
||||
+onLoad() void
|
||||
+home_active() void
|
||||
+mission_end() void
|
||||
}
|
||||
class SingletonModuleComp {
|
||||
+mission : any
|
||||
+vmdata : any
|
||||
+guides : any[]
|
||||
+data : any
|
||||
}
|
||||
MissionComp --> VictoryComp : "触发FightEnd事件"
|
||||
MissionComp --> SingletonModuleComp : "更新游戏状态"
|
||||
VictoryComp --> SingletonModuleComp : "读取游戏数据"
|
||||
MissionHeroCompComp --> SingletonModuleComp : "监控英雄状态"
|
||||
MissionMonCompComp --> SingletonModuleComp : "监控怪物状态"
|
||||
MissionHomeComp --> SingletonModuleComp : "监控关卡状态"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L15-L151)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L15-L75)
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L12-L81)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L15-L240)
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L12-L54)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L25-L195)
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L151)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L75)
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L1-L81)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L1-L54)
|
||||
|
||||
## 事件驱动机制
|
||||
|
||||
### 核心事件流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家
|
||||
participant MissionComp as MissionComp
|
||||
participant GameEvent as GameEvent
|
||||
participant VictoryComp as VictoryComp
|
||||
participant GUI as GUI系统
|
||||
participant SM as SingletonModule
|
||||
Player->>MissionComp : 战斗结束
|
||||
MissionComp->>GameEvent : dispatchEvent(FightEnd)
|
||||
GameEvent->>MissionComp : 监听FightEnd事件
|
||||
MissionComp->>SM : 更新游戏状态
|
||||
MissionComp->>GUI : oops.gui.open(UIID.Victory)
|
||||
GUI->>VictoryComp : 创建胜利界面
|
||||
VictoryComp->>VictoryComp : onAdded(args)
|
||||
VictoryComp->>VictoryComp : 展示奖励数据
|
||||
VictoryComp->>Player : 显示奖励选项
|
||||
Note over Player,SM : 奖励界面完全加载并显示
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L32-L35)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L40-L41)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L12-L13)
|
||||
|
||||
### 事件监听与响应
|
||||
|
||||
系统通过事件总线机制实现组件间的解耦通信:
|
||||
|
||||
1. **FightEnd事件触发**:当所有英雄死亡时,MissionComp检测到战斗结束状态
|
||||
2. **状态更新**:更新SingletonModuleComp中的游戏状态
|
||||
3. **界面打开**:通过GUI系统打开胜利界面
|
||||
4. **数据传递**:将rewards和game_data参数传递给Victory界面
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L55-L65)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L40-L41)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L12-L13)
|
||||
|
||||
## 奖励触发条件
|
||||
|
||||
### 英雄死亡触发机制
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([战斗开始]) --> Monitor[监控英雄状态]
|
||||
Monitor --> CheckHero{检查英雄数量}
|
||||
CheckHero --> |英雄存活| Continue[继续战斗]
|
||||
CheckHero --> |英雄死亡| Decrement[减少英雄数量]
|
||||
Decrement --> CheckAllDead{所有英雄死亡?}
|
||||
CheckAllDead --> |否| Continue
|
||||
CheckAllDead --> |是| TriggerFightEnd[触发FightEnd事件]
|
||||
TriggerFightEnd --> OpenVictory[打开胜利界面]
|
||||
OpenVictory --> PassData[传递奖励数据]
|
||||
PassData --> End([流程结束])
|
||||
Continue --> Monitor
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L55-L65)
|
||||
|
||||
### 怪物击杀触发机制
|
||||
|
||||
系统通过MissionMonComp监控怪物状态,每击杀一只怪物会:
|
||||
- 更新怪物数量计数器
|
||||
- 触发相应的事件通知
|
||||
- 记录战斗统计数据
|
||||
|
||||
### 基地保护触发机制
|
||||
|
||||
MissionHomeComp负责监控基地状态,当基地受到威胁时:
|
||||
- 更新基地保护状态
|
||||
- 触发防御机制
|
||||
- 记录基地受损情况
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L47-L52)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L47-L52)
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts#L25-L35)
|
||||
|
||||
## UI界面展示
|
||||
|
||||
### 胜利界面结构
|
||||
|
||||
VictoryComp负责展示战斗胜利后的奖励界面,包含以下核心元素:
|
||||
|
||||
| 组件名称 | 功能描述 | 数据绑定 |
|
||||
|---------|---------|---------|
|
||||
| title.victory | 胜利标题显示 | 自动激活 |
|
||||
| btns.next | 下一步按钮 | 延迟0.2秒激活 |
|
||||
| reward_lv | 奖励等级 | 动态计算 |
|
||||
| reward_num | 奖励数量 | 固定值2 |
|
||||
| game_data.exp | 经验值奖励 | 从MissionComp传递 |
|
||||
| game_data.gold | 金币奖励 | 从MissionComp传递 |
|
||||
| game_data.diamond | 钻石奖励 | 从MissionComp传递 |
|
||||
|
||||
### 界面初始化流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Load[VictoryComp加载] --> ReceiveArgs[接收参数]
|
||||
ReceiveArgs --> CheckGameData{检查game_data}
|
||||
CheckGameData --> |存在| AssignData[分配游戏数据]
|
||||
CheckGameData --> |不存在| UseDefault[使用默认数据]
|
||||
AssignData --> ShowTitle[显示胜利标题]
|
||||
UseDefault --> ShowTitle
|
||||
ShowTitle --> HideButton[隐藏下一步按钮]
|
||||
HideButton --> DelayShow[延迟0.2秒显示按钮]
|
||||
DelayShow --> Ready[界面准备就绪]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L28-L42)
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L15-L75)
|
||||
|
||||
## 数据绑定与状态管理
|
||||
|
||||
### MVVM数据流
|
||||
|
||||
系统采用MVVM架构实现数据绑定:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "数据层"
|
||||
VMData[vmdata对象]
|
||||
GameData[game_data]
|
||||
Rewards[rewards数组]
|
||||
end
|
||||
subgraph "视图层"
|
||||
VictoryUI[胜利界面UI]
|
||||
HeroStats[英雄统计]
|
||||
RewardDisplay[奖励展示]
|
||||
end
|
||||
subgraph "控制层"
|
||||
VictoryComp[VictoryComp组件]
|
||||
SingletonModule[SingletonModuleComp]
|
||||
end
|
||||
VMData --> VictoryComp
|
||||
GameData --> VictoryComp
|
||||
Rewards --> VictoryComp
|
||||
VictoryComp --> VictoryUI
|
||||
VictoryComp --> HeroStats
|
||||
VictoryComp --> RewardDisplay
|
||||
SingletonModule --> VMData
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L18-L25)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L45-L65)
|
||||
|
||||
### 状态同步机制
|
||||
|
||||
SingletonModuleComp作为全局状态管理中心,维护以下关键状态:
|
||||
|
||||
| 状态字段 | 类型 | 描述 | 更新时机 |
|
||||
|---------|------|------|---------|
|
||||
| mission.status | number | 游戏状态(0:未开始, 1:进行中, 2:胜利, 3:失败) | 战斗开始/结束时 |
|
||||
| mission.play | boolean | 游戏是否在播放 | 战斗开始/结束时 |
|
||||
| mission.pause | boolean | 游戏是否暂停 | 暂停/恢复时 |
|
||||
| vmdata.mission_data.mon_num | number | 怪物数量 | 怪物生成/死亡时 |
|
||||
| vmdata.mission_data.hero_num | number | 英雄数量 | 英雄生成/死亡时 |
|
||||
| vmdata.mission_data.fight_time | number | 战斗时间 | 每帧更新 |
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L25-L45)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L130-L140)
|
||||
|
||||
## 界面过渡动画
|
||||
|
||||
### 打开动画流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant GUI as GUI系统
|
||||
participant VictoryComp as VictoryComp
|
||||
participant UI as UI节点
|
||||
participant Player as 玩家
|
||||
GUI->>VictoryComp : open(UIID.Victory)
|
||||
VictoryComp->>VictoryComp : onAdded(args)
|
||||
VictoryComp->>UI : 设置初始状态
|
||||
UI->>Player : 隐藏胜利标题
|
||||
UI->>Player : 隐藏下一步按钮
|
||||
VictoryComp->>VictoryComp : scheduleOnce(0.2秒)
|
||||
VictoryComp->>UI : 显示下一步按钮
|
||||
UI->>Player : 平滑显示界面
|
||||
Note over Player : 界面完全加载并显示
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L28-L42)
|
||||
|
||||
### 关闭动画流程
|
||||
|
||||
界面关闭时的清理流程:
|
||||
1. 调用victory_end()方法
|
||||
2. 清理游戏数据
|
||||
3. 分发MissionEnd事件
|
||||
4. 通过GUI系统移除界面节点
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L44-L50)
|
||||
|
||||
## 用户交互反馈
|
||||
|
||||
### 按钮交互机制
|
||||
|
||||
胜利界面提供多种用户交互选项:
|
||||
|
||||
| 按钮功能 | 触发事件 | 动作描述 |
|
||||
|---------|---------|---------|
|
||||
| next按钮 | 点击 | 调用victory_end() |
|
||||
| restart按钮 | 点击 | 调用restart() |
|
||||
| double_reward按钮 | 点击 | 调用double_reward() |
|
||||
| watch_ad按钮 | 点击 | 调用watch_ad() |
|
||||
|
||||
### 交互状态管理
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Loading : 界面加载
|
||||
Loading --> Ready : 0.2秒后激活按钮
|
||||
Ready --> Restart : 点击重启
|
||||
Ready --> Next : 点击下一步
|
||||
Ready --> Double : 点击双倍奖励
|
||||
Ready --> Ad : 点击观看广告
|
||||
Restart --> [*] : 重新开始
|
||||
Next --> [*] : 结束战斗
|
||||
Double --> [*] : 双倍奖励
|
||||
Ad --> [*] : 广告奖励
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L44-L65)
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L44-L75)
|
||||
|
||||
## 系统集成流程
|
||||
|
||||
### 完整奖励流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([战斗开始]) --> FightLoop[战斗循环]
|
||||
FightLoop --> CheckConditions{检查胜利条件}
|
||||
CheckConditions --> |英雄存活| ContinueFight[继续战斗]
|
||||
CheckConditions --> |英雄死亡| TriggerFightEnd[触发FightEnd]
|
||||
TriggerFightEnd --> UpdateState[更新游戏状态]
|
||||
UpdateState --> OpenVictory[打开胜利界面]
|
||||
OpenVictory --> BindData[绑定奖励数据]
|
||||
BindData --> ShowRewards[展示奖励选项]
|
||||
ShowRewards --> WaitInput[等待用户输入]
|
||||
WaitInput --> ProcessChoice{用户选择}
|
||||
ProcessChoice --> |继续| NextLevel[下一关卡]
|
||||
ProcessChoice --> |重新开始| Restart[重新开始]
|
||||
ProcessChoice --> |双倍奖励| DoubleReward[双倍奖励]
|
||||
ProcessChoice --> |观看广告| WatchAd[观看广告]
|
||||
NextLevel --> Start
|
||||
Restart --> Start
|
||||
DoubleReward --> Start
|
||||
WatchAd --> Start
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L55-L65)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L44-L75)
|
||||
|
||||
### 错误处理机制
|
||||
|
||||
系统包含完善的错误处理机制:
|
||||
- **网络错误**:通过GUI系统显示错误提示
|
||||
- **数据同步错误**:自动回滚操作并提示用户
|
||||
- **界面加载错误**:提供重试机制
|
||||
- **事件监听错误**:记录日志并尝试恢复
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L151)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L75)
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
| 问题描述 | 可能原因 | 解决方案 |
|
||||
|---------|---------|---------|
|
||||
| 胜利界面无法打开 | UIID配置错误 | 检查GameUIConfig.ts中的UIID.Victory配置 |
|
||||
| 奖励数据不显示 | 数据绑定失败 | 验证SingletonModuleComp中的vmdata结构 |
|
||||
| 事件监听失效 | 组件未正确注册 | 检查@ecs.register装饰器的使用 |
|
||||
| 界面动画异常 | 节点状态错误 | 确保节点的active状态正确管理 |
|
||||
| 数据同步失败 | 网络连接问题 | 实现重试机制并提供用户提示 |
|
||||
|
||||
### 性能优化建议
|
||||
|
||||
1. **事件监听优化**:及时移除不需要的事件监听器
|
||||
2. **内存管理**:确保组件正确销毁避免内存泄漏
|
||||
3. **数据缓存**:合理使用SingletonModuleComp进行数据缓存
|
||||
4. **异步加载**:使用async/await模式处理异步操作
|
||||
|
||||
### 调试技巧
|
||||
|
||||
- 使用console.log记录关键事件的触发
|
||||
- 监控SingletonModuleComp的状态变化
|
||||
- 检查GUI系统的open和remove调用
|
||||
- 验证数据绑定的路径正确性
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L140-L151)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L100-L150)
|
||||
399
.qoder/repowiki/zh/content/奖励系统/奖励UI交互/怪物生成与波次控制.md
Normal file
399
.qoder/repowiki/zh/content/奖励系统/奖励UI交互/怪物生成与波次控制.md
Normal file
@@ -0,0 +1,399 @@
|
||||
# 怪物生成与波次控制
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [MonModelComp.ts](file://assets/script/game/hero/MonModelComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [系统架构](#系统架构)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [怪物生成机制](#怪物生成机制)
|
||||
5. [波次控制逻辑](#波次控制逻辑)
|
||||
6. [随机事件系统](#随机事件系统)
|
||||
7. [状态机图示](#状态机图示)
|
||||
8. [性能优化考虑](#性能优化考虑)
|
||||
9. [故障排除指南](#故障排除指南)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 概述
|
||||
|
||||
MissionMonCompComp是游戏肉鸽模式中负责怪物生成与波次控制的核心组件。它实现了基于关卡配置的动态怪物生成系统,支持不同类型的怪物(普通、精英、Boss),并采用波次节奏控制机制,每5只怪物后暂停5秒形成波次节奏。
|
||||
|
||||
该系统通过RogueConfig提供配置驱动的怪物生成策略,支持怪物强度随关卡递增,同时集成了随机事件系统,为游戏体验增加不确定性。
|
||||
|
||||
## 系统架构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "怪物生成系统"
|
||||
A[MissionMonCompComp] --> B[RogueConfig]
|
||||
A --> C[Monster Queue]
|
||||
A --> D[Timer System]
|
||||
A --> E[Random Event System]
|
||||
end
|
||||
subgraph "配置层"
|
||||
B --> F[Stage Config Rules]
|
||||
B --> G[Monster Type Config]
|
||||
B --> H[Event Config]
|
||||
end
|
||||
subgraph "实体层"
|
||||
I[Monster Entity] --> J[MonModelComp]
|
||||
I --> K[BattleMoveComp]
|
||||
I --> L[TalComp]
|
||||
end
|
||||
A --> I
|
||||
C --> M[Spawn Queue Management]
|
||||
D --> N[Wave Timing Control]
|
||||
E --> O[Event Processing]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L311)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### MissionMonCompComp 主控制器
|
||||
|
||||
MissionMonCompComp作为主要的怪物生成控制器,维护以下关键状态:
|
||||
|
||||
| 状态变量 | 类型 | 描述 |
|
||||
|---------|------|------|
|
||||
| monsterQueue | Array | 怪物生成队列,存储待生成的怪物配置 |
|
||||
| isSpawning | boolean | 是否正在生成怪物的状态标志 |
|
||||
| spawnInterval | number | 单个怪物生成间隔(默认0.1秒) |
|
||||
| spawnTimer | number | 生成计时器,累积时间用于控制生成节奏 |
|
||||
| spawnCount | number | 已生成怪物计数器 |
|
||||
| pauseInterval | number | 波次暂停间隔(默认5秒) |
|
||||
| isPausing | boolean | 是否处于波次暂停状态 |
|
||||
| currentEvent | EventType | 当前关卡的随机事件类型 |
|
||||
| eventProcessed | boolean | 随机事件是否已处理的标志 |
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L18-L35)
|
||||
|
||||
### RogueConfig 配置系统
|
||||
|
||||
RogueConfig提供了完整的配置驱动怪物生成框架:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class RogueConfig {
|
||||
+MonsterType NORMAL
|
||||
+MonsterType ELITE
|
||||
+MonsterType BOSS
|
||||
+StageType NORMAL
|
||||
+StageType ELITE
|
||||
+StageType BOSS
|
||||
+StageType EVENT
|
||||
+EventType TREASURE
|
||||
+EventType TRAP
|
||||
+EventType BUFF
|
||||
+EventType DEBUFF
|
||||
+getStageType(stageNumber, level) StageType
|
||||
+getStageMonsterConfigs(stageNumber, level) Array
|
||||
+calculateMonsterCount(stageNumber, baseCount, minCount, maxCount) number
|
||||
+calculateMonsterStrengthMultiplier(stageNumber, level) number
|
||||
+getRandomEvent() EventType
|
||||
}
|
||||
class StageConfigRules {
|
||||
+NORMAL Monsters
|
||||
+ELITE Monsters
|
||||
+BOSS Monsters
|
||||
+EVENT Monsters
|
||||
}
|
||||
class EventConfig {
|
||||
+TREASURE Probability
|
||||
+TRAP Probability
|
||||
+BUFF Probability
|
||||
+DEBUFF Probability
|
||||
}
|
||||
RogueConfig --> StageConfigRules
|
||||
RogueConfig --> EventConfig
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L25-L132)
|
||||
|
||||
**章节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L311)
|
||||
|
||||
## 怪物生成机制
|
||||
|
||||
### do_mon_wave 方法 - 波次初始化
|
||||
|
||||
do_mon_wave方法是波次生成的入口点,负责初始化所有相关状态并启动怪物生成流程:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[do_mon_wave 开始] --> B[重置生成状态]
|
||||
B --> C[获取当前关卡信息]
|
||||
C --> D[确定关卡类型]
|
||||
D --> E{是否为事件关卡?}
|
||||
E --> |是| F[生成随机事件]
|
||||
E --> |否| G[清除事件状态]
|
||||
F --> H[获取怪物配置]
|
||||
G --> H
|
||||
H --> I[生成怪物队列]
|
||||
I --> J[开始波次生成]
|
||||
B --> B1[spawnCount = 0]
|
||||
B --> B2[isPausing = false]
|
||||
B --> B3[spawnTimer = 0]
|
||||
B --> B4[eventProcessed = false]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L85-L115)
|
||||
|
||||
### generateMonstersFromStageConfig 方法 - 队列生成
|
||||
|
||||
generateMonstersFromStageConfig方法负责解析怪物配置并构建生成队列:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MC as MissionMonComp
|
||||
participant RC as RogueConfig
|
||||
participant MQ as MonsterQueue
|
||||
MC->>RC : getStageMonsterConfigs(stage, level)
|
||||
RC->>RC : generateStageConfig(stage, level)
|
||||
RC->>RC : calculateMonsterStrengthMultiplier(stage, level)
|
||||
loop 每个怪物类型
|
||||
RC->>RC : getMonsterUUIDsByType(type)
|
||||
RC->>RC : 随机选择UUID
|
||||
RC-->>MC : 返回怪物配置
|
||||
end
|
||||
MC->>MC : generateMonstersFromStageConfig(configs)
|
||||
loop 每个怪物配置
|
||||
MC->>MC : 计算位置索引
|
||||
MC->>MQ : addToStageSpawnQueue()
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L147-L185)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L265-L295)
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L147-L185)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L265-L295)
|
||||
|
||||
### 怪物配置结构
|
||||
|
||||
每个怪物配置包含以下关键信息:
|
||||
|
||||
| 字段 | 类型 | 描述 |
|
||||
|------|------|------|
|
||||
| uuid | number | 怪物唯一标识符,对应HeroInfo中的怪物UUID |
|
||||
| position | number | 怪物生成位置索引(0-4) |
|
||||
| type | MonsterType | 怪物类型(NORMAL/ELITE/BOSS) |
|
||||
| level | number | 怪物等级,默认为1 |
|
||||
| strengthMultiplier | number | 强度倍率,随关卡递增 |
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L186-L205)
|
||||
|
||||
## 波次控制逻辑
|
||||
|
||||
### 定时器系统 - update 方法
|
||||
|
||||
update方法实现了精确的波次控制逻辑,每帧更新计时器并管理生成节奏:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[update(dt)] --> B{游戏是否进行中?}
|
||||
B --> |否| C[退出更新]
|
||||
B --> |是| D{有随机事件?}
|
||||
D --> |是且未处理| E[processRandomEvent]
|
||||
D --> |否或已处理| F{有怪物队列?}
|
||||
E --> F
|
||||
F --> |否| C
|
||||
F --> |是| G[累加spawnTimer]
|
||||
G --> H{是否暂停状态?}
|
||||
H --> |是| I{暂停时间到?}
|
||||
I --> |否| C
|
||||
I --> |是| J[结束暂停,重置状态]
|
||||
H --> |否| K{生成时间到?}
|
||||
K --> |否| C
|
||||
K --> |是| L[spawnNextMonster]
|
||||
L --> M{达到5只?}
|
||||
M --> |否| N[重置计时器]
|
||||
M --> |是| O[进入暂停状态]
|
||||
J --> P[继续生成]
|
||||
N --> P
|
||||
O --> Q[暂停5秒]
|
||||
P --> C
|
||||
Q --> C
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L55-L85)
|
||||
|
||||
### 波次节奏控制
|
||||
|
||||
波次控制采用"5+5"模式:
|
||||
- **生成阶段**:每0.1秒生成一只怪物,连续生成5只
|
||||
- **暂停阶段**:生成5只后暂停5秒,然后恢复生成
|
||||
- **计数器**:spawnCount跟踪已生成怪物数量
|
||||
- **状态标志**:isPausing控制暂停状态
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L55-L85)
|
||||
|
||||
### spawnNextMonster 方法 - 怪物实例化
|
||||
|
||||
spawnNextMonster方法从队列中取出怪物配置并创建实体:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MC as MissionMonComp
|
||||
participant ECS as ECS系统
|
||||
participant M as Monster实体
|
||||
participant SM as Scene Manager
|
||||
MC->>MC : 从队列移除第一个怪物
|
||||
MC->>ECS : 获取Monster实体
|
||||
MC->>M : load(position, scale, uuid, isBoss, isCall, strengthMultiplier)
|
||||
M->>SM : 创建怪物节点
|
||||
M->>M : 设置位置和缩放
|
||||
M->>M : 加载怪物资源
|
||||
M->>M : 初始化战斗参数
|
||||
M->>SM : 添加到场景层
|
||||
MC->>MC : 增加spawnCount
|
||||
MC->>MC : 更新怪物计数显示
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L190-L215)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L35-L60)
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L190-L215)
|
||||
|
||||
## 随机事件系统
|
||||
|
||||
### 事件类型与概率
|
||||
|
||||
随机事件系统提供四种不同类型的事件,每种事件都有对应的触发概率:
|
||||
|
||||
| 事件类型 | 概率 | 效果 | 处理方式 |
|
||||
|----------|------|------|----------|
|
||||
| TREASURE | 30% | 增加50金币奖励 | 直接修改游戏数据 |
|
||||
| TRAP | 25% | 对玩家造成伤害 | 需要实现具体伤害逻辑 |
|
||||
| BUFF | 25% | 给玩家临时增益效果 | 需要实现增益系统 |
|
||||
| DEBUFF | 20% | 给玩家临时减益效果 | 需要实现减益系统 |
|
||||
|
||||
### processRandomEvent 方法
|
||||
|
||||
processRandomEvent方法根据当前事件类型执行相应的处理逻辑:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[processRandomEvent] --> B{检查currentEvent}
|
||||
B --> |null| C[无事件,退出]
|
||||
B --> |有效事件| D{switch currentEvent}
|
||||
D --> |TREASURE| E[增加50金币]
|
||||
D --> |TRAP| F[造成伤害逻辑]
|
||||
D --> |BUFF| G[增加临时增益]
|
||||
D --> |DEBUFF| H[增加临时减益]
|
||||
E --> I[标记事件已处理]
|
||||
F --> I
|
||||
G --> I
|
||||
H --> I
|
||||
I --> J[eventProcessed = true]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L117-L145)
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L117-L145)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L105-L132)
|
||||
|
||||
## 状态机图示
|
||||
|
||||
### 怪物生成状态机
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 波次准备
|
||||
波次准备 --> 事件检测 : do_mon_wave()
|
||||
事件检测 --> 事件处理 : 是事件关卡
|
||||
事件检测 --> 怪物生成 : 非事件关卡
|
||||
事件处理 --> 怪物生成 : 事件已处理
|
||||
怪物生成 --> 怪物实例化 : 队列非空
|
||||
怪物实例化 --> 怪物实例化 : 生成间隔到达
|
||||
怪物实例化 --> 波次暂停 : 达到5只
|
||||
波次暂停 --> 怪物实例化 : 暂停结束
|
||||
怪物实例化 --> 波次完成 : 队列为空
|
||||
波次完成 --> [*]
|
||||
```
|
||||
|
||||
### 波次节奏状态机
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 生成中
|
||||
生成中 --> 生成中 : spawnTimer < spawnInterval
|
||||
生成中 --> 怪物实例化 : spawnTimer >= spawnInterval
|
||||
怪物实例化 --> 生成中 : spawnCount < 5
|
||||
怪物实例化 --> 波次暂停 : spawnCount >= 5
|
||||
波次暂停 --> 波次暂停 : pauseTimer < pauseInterval
|
||||
波次暂停 --> 生成中 : pauseTimer >= pauseInterval
|
||||
```
|
||||
|
||||
## 性能优化考虑
|
||||
|
||||
### 内存管理
|
||||
|
||||
1. **实体池化**:Monster实体通过ecs.getEntity获取,避免频繁创建销毁
|
||||
2. **队列管理**:使用shift/pop操作保持队列紧凑
|
||||
3. **资源加载**:怪物资源预加载,减少运行时开销
|
||||
|
||||
### 计算优化
|
||||
|
||||
1. **配置缓存**:RogueConfig中的计算结果可适当缓存
|
||||
2. **随机数优化**:Math.random()调用频率控制在合理范围内
|
||||
3. **事件概率计算**:使用累积概率算法提高效率
|
||||
|
||||
### 渲染优化
|
||||
|
||||
1. **批量渲染**:怪物生成采用批量处理机制
|
||||
2. **层级管理**:怪物添加到专门的EntityLayer
|
||||
3. **碰撞体延迟启用**:避免过早启用碰撞体影响性能
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
| 问题 | 症状 | 可能原因 | 解决方案 |
|
||||
|------|------|----------|----------|
|
||||
| 怪物不生成 | 队列为空但游戏仍在进行 | 配置错误或事件阻塞 | 检查RogueConfig配置和事件处理 |
|
||||
| 波次节奏异常 | 怪物生成过快或过慢 | 时间计算错误 | 验证update方法中的计时逻辑 |
|
||||
| 事件不触发 | 事件关卡没有随机事件 | 概率计算错误 | 检查getRandomEvent函数 |
|
||||
| 怪物位置错误 | 怪物出现在错误位置 | 位置索引计算错误 | 验证position计算逻辑 |
|
||||
|
||||
### 调试技巧
|
||||
|
||||
1. **日志记录**:启用console.log语句跟踪关键状态变化
|
||||
2. **断点调试**:在关键方法设置断点观察变量值
|
||||
3. **状态监控**:实时监控monsterQueue长度和计时器状态
|
||||
|
||||
**章节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L147-L185)
|
||||
|
||||
## 总结
|
||||
|
||||
MissionMonCompComp实现了一个功能完整且灵活的怪物生成与波次控制系统。该系统具有以下特点:
|
||||
|
||||
1. **配置驱动**:通过RogueConfig实现完全可配置的怪物生成策略
|
||||
2. **波次节奏**:采用"5+5"模式确保游戏体验的平衡性
|
||||
3. **随机事件**:集成随机事件系统增加游戏不确定性
|
||||
4. **性能优化**:采用实体池化和批量处理优化性能
|
||||
5. **扩展性强**:模块化设计便于功能扩展和维护
|
||||
|
||||
该系统为游戏肉鸽模式提供了坚实的怪物生成基础,支持复杂的关卡设计和多样化的游戏体验。通过合理的配置和适当的调整,可以满足不同类型游戏的需求。
|
||||
505
.qoder/repowiki/zh/content/奖励系统/奖励UI交互/英雄管理组件交互.md
Normal file
505
.qoder/repowiki/zh/content/奖励系统/奖励UI交互/英雄管理组件交互.md
Normal file
@@ -0,0 +1,505 @@
|
||||
# 英雄管理组件交互
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构概览](#项目结构概览)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [英雄生命周期管理](#英雄生命周期管理)
|
||||
7. [事件处理机制](#事件处理机制)
|
||||
8. [数据绑定关系](#数据绑定关系)
|
||||
9. [时序图示例](#时序图示例)
|
||||
10. [性能考虑](#性能考虑)
|
||||
11. [故障排除指南](#故障排除指南)
|
||||
12. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
MissionHeroCompComp类是游戏战斗系统中负责管理英雄生命周期的核心组件。它通过ECS架构模式,实现了英雄的初始化、召唤、战斗管理和清理等完整生命周期流程。该组件与SingletonModuleComp单例、GameEvent事件系统以及Hero实体组件紧密协作,形成了一个完整的英雄管理系统。
|
||||
|
||||
## 项目结构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "战斗系统架构"
|
||||
MissionHeroComp[MissionHeroCompComp<br/>英雄管理组件]
|
||||
SingletonModule[SingletonModuleComp<br/>单例模块]
|
||||
HeroEntity[Hero实体]
|
||||
GameEvents[GameEvent事件系统]
|
||||
end
|
||||
subgraph "英雄组件体系"
|
||||
HeroView[HeroViewComp<br/>英雄视图组件]
|
||||
BattleMove[BattleMoveComp<br/>战斗移动组件]
|
||||
HeroModel[HeroModelComp<br/>英雄模型组件]
|
||||
end
|
||||
subgraph "配置数据层"
|
||||
HeroSet[heroSet配置]
|
||||
GameConfig[GameEvent配置]
|
||||
SMData[SMC数据]
|
||||
end
|
||||
MissionHeroComp --> SingletonModule
|
||||
MissionHeroComp --> HeroEntity
|
||||
MissionHeroComp --> GameEvents
|
||||
HeroEntity --> HeroView
|
||||
HeroEntity --> BattleMove
|
||||
HeroEntity --> HeroModel
|
||||
SingletonModule --> SMData
|
||||
GameEvents --> GameConfig
|
||||
HeroEntity --> HeroSet
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L1-L81)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L195)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L15-L101)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### MissionHeroCompComp类结构
|
||||
|
||||
MissionHeroCompComp继承自CCComp基类,注册为ECS系统中的MissionHero组件。该类维护以下核心状态:
|
||||
|
||||
- **timer**: 定时器组件,用于控制英雄召唤间隔
|
||||
- **Friend_is_dead**: 标记友方英雄是否死亡
|
||||
- **current_hero_uuid**: 当前英雄的唯一标识符
|
||||
- **current_hero_num**: 当前英雄数量
|
||||
- **heros**: 英雄数组,存储所有战斗中的英雄信息
|
||||
|
||||
**章节来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L11-L18)
|
||||
|
||||
## 架构概览
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MissionHeroCompComp {
|
||||
+Timer timer
|
||||
+boolean Friend_is_dead
|
||||
+number current_hero_uuid
|
||||
+number current_hero_num
|
||||
+any[] heros
|
||||
+onLoad() void
|
||||
+clear_heros() void
|
||||
+fight_ready() void
|
||||
+zhao_huan(event, args) void
|
||||
+addHero(uuid, is_zhaohuan) void
|
||||
+reset() void
|
||||
}
|
||||
class SingletonModuleComp {
|
||||
+number fight_hero
|
||||
+any heros
|
||||
+any vmdata
|
||||
+updateFihgtHero(heroId) void
|
||||
+addHero(hero_uuid) void
|
||||
}
|
||||
class Hero {
|
||||
+HeroModelComp HeroModel
|
||||
+HeroViewComp HeroView
|
||||
+BattleMoveComp BattleMove
|
||||
+load(pos, scale, uuid, fight_pos) void
|
||||
+hero_init(uuid, node) HeroViewComp
|
||||
}
|
||||
class GameEvent {
|
||||
<<enumeration>>
|
||||
FightReady
|
||||
Zhaohuan
|
||||
FightEnd
|
||||
}
|
||||
MissionHeroCompComp --> SingletonModuleComp : "使用"
|
||||
MissionHeroCompComp --> Hero : "创建"
|
||||
MissionHeroCompComp --> GameEvent : "监听"
|
||||
SingletonModuleComp --> Hero : "配置"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L11-L81)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L20-L50)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L15-L101)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### fight_ready方法实现
|
||||
|
||||
fight_ready方法是战斗准备阶段的核心入口点,负责初始化战斗环境中的英雄配置。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as "玩家"
|
||||
participant MissionHero as "MissionHeroCompComp"
|
||||
participant SMC as "SingletonModuleComp"
|
||||
participant Hero as "Hero实体"
|
||||
participant ECS as "ECS系统"
|
||||
Player->>MissionHero : 战斗准备开始
|
||||
MissionHero->>SMC : 获取战斗英雄配置
|
||||
SMC-->>MissionHero : 返回fight_hero配置
|
||||
MissionHero->>MissionHero : 设置hero_num=0
|
||||
MissionHero->>MissionHero : 调用addHero(fight_hero, false)
|
||||
MissionHero->>ECS : 获取Hero实体
|
||||
ECS-->>MissionHero : 返回Hero实例
|
||||
MissionHero->>Hero : load(position, scale, uuid)
|
||||
Hero->>Hero : 初始化英雄属性
|
||||
Hero->>Hero : 设置战斗位置
|
||||
Hero-->>Player : 英雄出现在战场
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L32-L42)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L30-L60)
|
||||
|
||||
该方法执行以下关键步骤:
|
||||
|
||||
1. **状态重置**: 将`smc.vmdata.mission_data.hero_num`设置为0,清空当前英雄计数
|
||||
2. **英雄加载**: 调用`addHero(smc.fight_hero, false)`加载玩家选择的英雄
|
||||
3. **配置应用**: 使用SMC单例中的fight_hero配置作为英雄标识
|
||||
|
||||
**章节来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L32-L42)
|
||||
|
||||
### addHero方法实现
|
||||
|
||||
addHero方法是英雄加载的核心逻辑,负责通过ECS系统获取Hero实体并调用其load方法。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始addHero]) --> GetHero["获取Hero实体<br/>ecs.getEntity<Hero>(Hero)"]
|
||||
GetHero --> SetParams["设置参数<br/>hero_pos=0<br/>scale=1"]
|
||||
SetParams --> GetPos["获取英雄位置<br/>HeroPos[hero_pos].pos"]
|
||||
GetPos --> LoadHero["调用hero.load()<br/>加载英雄实体"]
|
||||
LoadHero --> InitProps["初始化英雄属性<br/>调用hero_init()"]
|
||||
InitProps --> SetDirection["设置移动方向<br/>根据英雄类型"]
|
||||
SetDirection --> UpdateCount["更新英雄计数<br/>smc.vmdata.mission_data.hero_num++"]
|
||||
UpdateCount --> End([结束])
|
||||
LoadHero --> ErrorHandler["错误处理"]
|
||||
ErrorHandler --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L64-L70)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L30-L60)
|
||||
|
||||
addHero方法的具体实现细节:
|
||||
|
||||
1. **实体获取**: 使用`ecs.getEntity<Hero>(Hero)`从ECS系统中获取Hero实体
|
||||
2. **参数设置**: 固定英雄位置索引为0,缩放比例为1
|
||||
3. **位置计算**: 从HeroPos配置中获取英雄的战斗位置
|
||||
4. **英雄加载**: 调用hero.load()方法完成英雄实体的初始化和渲染
|
||||
|
||||
**章节来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L64-L70)
|
||||
|
||||
### zhao_huan事件处理
|
||||
|
||||
zhao_huan方法响应召唤指令事件,实现实时英雄召唤功能。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant UI as "用户界面"
|
||||
participant MissionHero as "MissionHeroCompComp"
|
||||
participant EventSys as "事件系统"
|
||||
participant Hero as "Hero实体"
|
||||
UI->>EventSys : 发送Zhaohuan事件
|
||||
EventSys->>MissionHero : 触发zhao_huan回调
|
||||
MissionHero->>MissionHero : addHero(args.uuid, false)
|
||||
MissionHero->>Hero : 创建新英雄实例
|
||||
Hero-->>UI : 新英雄出现在战场
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L50-L52)
|
||||
|
||||
该方法的特点:
|
||||
- **实时响应**: 接收召唤事件参数中的英雄UUID
|
||||
- **即时召唤**: 直接调用addHero方法加载新英雄
|
||||
- **非召唤模式**: 第二个参数为false,表示这不是召唤模式的英雄
|
||||
|
||||
**章节来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L50-L52)
|
||||
|
||||
### clear_heros方法
|
||||
|
||||
clear_heros方法在战斗结束时执行英雄清理逻辑,确保战斗环境的正确重置。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([战斗结束]) --> ClearMethod["调用clear_heros()"]
|
||||
ClearMethod --> LogCheck{"检查日志输出"}
|
||||
LogCheck --> |启用| LogMessage["打印清理消息"]
|
||||
LogCheck --> |禁用| SkipLog["跳过日志"]
|
||||
LogMessage --> End([清理完成])
|
||||
SkipLog --> End
|
||||
Note1["目前方法体为空<br/>预留扩展空间"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L28-L30)
|
||||
|
||||
当前实现特点:
|
||||
- **空方法体**: 目前方法体为空,但预留了扩展空间
|
||||
- **日志占位**: 包含注释掉的日志输出语句
|
||||
- **扩展性**: 为未来的清理逻辑提供了接口
|
||||
|
||||
**章节来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L28-L30)
|
||||
|
||||
## 英雄生命周期管理
|
||||
|
||||
### 英雄创建流程
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 初始化
|
||||
初始化 --> 配置加载 : fight_ready事件
|
||||
配置加载 --> 实体获取 : ecs.getEntity<Hero>()
|
||||
实体获取 --> 位置设置 : HeroPos配置
|
||||
位置设置 --> 属性初始化 : hero_init()
|
||||
属性初始化 --> 移动设置 : BattleMove配置
|
||||
移动设置 --> 计数更新 : hero_num++
|
||||
计数更新 --> 战场就绪 : 英雄出现在战场
|
||||
战场就绪 --> 战斗中 : 开始战斗
|
||||
战斗中 --> 死亡检测 : 英雄死亡
|
||||
死亡检测 --> 清理处理 : 英雄移除
|
||||
清理处理 --> [*]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L30-L80)
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L64-L70)
|
||||
|
||||
### 英雄属性系统
|
||||
|
||||
HeroViewComp组件负责管理英雄的所有属性和状态:
|
||||
|
||||
| 属性类别 | 属性名称 | 描述 | 类型 |
|
||||
|---------|---------|------|------|
|
||||
| 基础属性 | base_hp/base_mp | 基础生命值/魔法值 | number |
|
||||
| 核心属性 | hp/mp | 当前生命值/魔法值 | number |
|
||||
| 攻击属性 | base_ap/base_map | 基础物理攻击/魔法攻击 | number |
|
||||
| 防御属性 | base_def/mdef | 基础物理防御/魔法防御 | number |
|
||||
| 移动属性 | base_speed/base_dis | 基础移动速度/攻击距离 | number |
|
||||
| BUFF系统 | BUFFS/BUFFS_TEMP | 持久/临时BUFF数组 | Record |
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L72-L120)
|
||||
|
||||
## 事件处理机制
|
||||
|
||||
### 事件监听配置
|
||||
|
||||
MissionHeroCompComp通过on方法注册三个关键事件的处理器:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "事件监听"
|
||||
FightReady[FightReady<br/>战斗准备]
|
||||
Zhaohuan[Zhaohuan<br/>英雄召唤]
|
||||
FightEnd[FightEnd<br/>战斗结束]
|
||||
end
|
||||
subgraph "处理方法"
|
||||
FRHandler[fight_ready]
|
||||
ZHHandler[zhao_huan]
|
||||
FERHandler[clear_heros]
|
||||
end
|
||||
FightReady --> FRHandler
|
||||
Zhaohuan --> ZHHandler
|
||||
FightEnd --> FERHandler
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L19-L23)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L15-L25)
|
||||
|
||||
### 事件触发时机
|
||||
|
||||
| 事件名称 | 触发时机 | 处理内容 |
|
||||
|---------|---------|---------|
|
||||
| FightReady | 战斗开始前 | 初始化战斗英雄配置 |
|
||||
| Zhaohuan | 英雄召唤时 | 动态添加新英雄 |
|
||||
| FightEnd | 战斗结束后 | 清理战斗环境 |
|
||||
|
||||
**章节来源**
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L15-L25)
|
||||
|
||||
## 数据绑定关系
|
||||
|
||||
### SMC单例中的英雄数据
|
||||
|
||||
SingletonModuleComp通过vmdata属性系统实现与UI层的数据绑定:
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
SingletonModuleComp {
|
||||
number fight_hero
|
||||
any heros
|
||||
any monsters
|
||||
object vmdata
|
||||
}
|
||||
VMData {
|
||||
boolean game_over
|
||||
boolean game_pause
|
||||
object mission_data
|
||||
number gold
|
||||
}
|
||||
MissionData {
|
||||
number mon_num
|
||||
number hero_num
|
||||
number wave_time_num
|
||||
boolean in_fight
|
||||
number fight_time
|
||||
number level
|
||||
number max_mission
|
||||
number coin
|
||||
}
|
||||
SingletonModuleComp ||--|| VMData : "包含"
|
||||
VMData ||--|| MissionData : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L40-L60)
|
||||
|
||||
### 数据流映射
|
||||
|
||||
| 数据源 | 目标组件 | 绑定方式 | 更新时机 |
|
||||
|-------|---------|---------|---------|
|
||||
| smc.fight_hero | MissionHeroCompComp | 直接访问 | 战斗准备时 |
|
||||
| smc.heros | UI界面 | MVVM绑定 | 英雄解锁时 |
|
||||
| smc.vmdata.mission_data.hero_num | 战斗计数器 | 自动更新 | 英雄加载时 |
|
||||
| smc.vmdata.gold | 金币显示 | MVVM绑定 | 金币变化时 |
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L40-L60)
|
||||
|
||||
## 时序图示例
|
||||
|
||||
### 完整英雄加载时序
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as "玩家"
|
||||
participant UI as "UI界面"
|
||||
participant SMC as "SMC单例"
|
||||
participant MissionHero as "MissionHeroComp"
|
||||
participant ECS as "ECS系统"
|
||||
participant Hero as "Hero实体"
|
||||
participant BattleMove as "BattleMove组件"
|
||||
Note over Player,BattleMove : 战斗准备阶段
|
||||
Player->>UI : 选择战斗英雄
|
||||
UI->>SMC : updateFihgtHero(5001)
|
||||
SMC->>SMC : 更新fight_hero配置
|
||||
Player->>MissionHero : 触发FightReady事件
|
||||
MissionHero->>SMC : 获取smc.fight_hero
|
||||
SMC-->>MissionHero : 返回英雄UUID 5001
|
||||
MissionHero->>MissionHero : 设置hero_num=0
|
||||
Note over Player,BattleMove : 英雄加载阶段
|
||||
MissionHero->>ECS : ecs.getEntity<Hero>(Hero)
|
||||
ECS-->>MissionHero : 返回Hero实例
|
||||
MissionHero->>Hero : load(v3(-240,100,0), 1, 5001)
|
||||
Hero->>Hero : 初始化英雄属性
|
||||
Hero->>Hero : 设置战斗位置
|
||||
Hero->>BattleMove : 配置移动方向
|
||||
BattleMove-->>Hero : 设置targetX=0
|
||||
Hero->>SMC : 更新hero_num++
|
||||
SMC-->>Player : 英雄出现在战场
|
||||
Note over Player,BattleMove : 战斗进行阶段
|
||||
Player->>MissionHero : 触发Zhaohuan事件
|
||||
MissionHero->>ECS : 再次获取Hero实体
|
||||
ECS-->>MissionHero : 返回新的Hero实例
|
||||
MissionHero->>Hero : load(v3(0,100,0), 1, 新英雄UUID)
|
||||
Hero-->>Player : 新英雄加入战斗
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L32-L70)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L30-L80)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L120-L140)
|
||||
|
||||
### 英雄召唤时序
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as "玩家"
|
||||
participant UI as "UI界面"
|
||||
participant MissionHero as "MissionHeroComp"
|
||||
participant EventSys as "事件系统"
|
||||
participant ECS as "ECS系统"
|
||||
participant Hero as "Hero实体"
|
||||
Player->>UI : 点击召唤按钮
|
||||
UI->>EventSys : dispatchEvent(Zhaohuan, {uuid : 5002})
|
||||
EventSys->>MissionHero : 触发zhao_huan事件
|
||||
MissionHero->>MissionHero : addHero(5002, false)
|
||||
MissionHero->>ECS : ecs.getEntity<Hero>(Hero)
|
||||
ECS-->>MissionHero : 返回Hero实例
|
||||
MissionHero->>Hero : load(v3(0,100,0), 1, 5002)
|
||||
Hero->>Hero : 初始化新英雄属性
|
||||
Hero->>Hero : 设置战斗位置
|
||||
Hero-->>Player : 新英雄出现在战场
|
||||
Note over Player,Hero : 英雄加入战斗
|
||||
Hero->>Hero : 开始参与战斗
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L50-L52)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L30-L60)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### ECS架构优势
|
||||
|
||||
1. **组件化设计**: Hero实体采用ECS架构,避免了传统继承层次的复杂性
|
||||
2. **内存优化**: 通过组件池复用Hero实体,减少内存分配开销
|
||||
3. **系统解耦**: 各组件职责单一,便于维护和扩展
|
||||
|
||||
### 事件处理优化
|
||||
|
||||
1. **事件监听**: 使用事件系统解耦组件间的直接依赖
|
||||
2. **延迟处理**: 通过定时器控制英雄召唤间隔
|
||||
3. **状态管理**: 通过SMC单例集中管理全局状态
|
||||
|
||||
### 渲染性能
|
||||
|
||||
1. **批量操作**: 批量处理英雄位置和属性更新
|
||||
2. **组件缓存**: 缓存HeroViewComp等常用组件引用
|
||||
3. **条件渲染**: 根据战斗状态动态启用/禁用组件
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
| 问题类型 | 症状描述 | 可能原因 | 解决方案 |
|
||||
|---------|---------|---------|---------|
|
||||
| 英雄不出现 | 战斗开始后没有英雄 | fight_hero配置错误 | 检查smc.fight_hero设置 |
|
||||
| 英雄位置错误 | 英雄出现在错误位置 | HeroPos配置问题 | 验证HeroPos数组配置 |
|
||||
| 英雄属性异常 | 英雄属性显示错误 | HeroInfo配置缺失 | 检查HeroInfo中的英雄数据 |
|
||||
| 事件不响应 | Zhaohuan事件无效 | 事件监听未注册 | 确认on方法调用 |
|
||||
|
||||
### 调试技巧
|
||||
|
||||
1. **日志输出**: 启用注释掉的日志语句进行调试
|
||||
2. **断点调试**: 在关键方法设置断点观察变量状态
|
||||
3. **状态检查**: 通过浏览器开发者工具检查SMC状态
|
||||
|
||||
**章节来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L32-L70)
|
||||
|
||||
## 总结
|
||||
|
||||
MissionHeroCompComp类通过精心设计的ECS架构和事件驱动机制,实现了完整的英雄生命周期管理。该系统具有以下核心优势:
|
||||
|
||||
1. **模块化设计**: 清晰的职责分离和组件化架构
|
||||
2. **事件驱动**: 基于事件系统的松耦合设计
|
||||
3. **数据绑定**: 与UI层的无缝数据同步
|
||||
4. **扩展性强**: 预留的扩展点支持未来功能增强
|
||||
5. **性能优化**: 通过ECS架构实现高效的组件管理
|
||||
|
||||
该英雄管理系统为游戏战斗提供了稳定可靠的基础框架,支持动态英雄召唤、战斗状态管理和资源回收等功能,是整个战斗系统的重要组成部分。
|
||||
167
.qoder/repowiki/zh/content/奖励系统/奖励机制/奖励UI集成.md
Normal file
167
.qoder/repowiki/zh/content/奖励系统/奖励机制/奖励UI集成.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# 奖励UI集成
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [Design.md](file://assets/script/Design.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概述](#架构概述)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
本文档详细说明了MissionComp组件如何与胜利界面(Victory)进行集成,重点分析了oops.gui.open(UIID.Victory)调用时传递rewards和game_data参数的具体实现。文档解释了胜利界面如何解析这些数据并渲染三选一奖励选项,描述了从战斗结束到奖励界面展示的完整用户流程,包括延迟调度(scheduleOnce)的时间控制策略。同时提供了UI数据绑定错误的诊断方法,并给出了自定义奖励展示效果的扩展建议。
|
||||
|
||||
## 项目结构
|
||||
项目结构显示了游戏的核心脚本位于assets/script/game目录下,其中map子目录包含了MissionComp和VictoryComp等关键组件。这些组件通过ECS架构进行组织,实现了战斗逻辑与UI展示的分离。资源文件和配置文件分别存放在resources和config目录中,形成了清晰的模块化结构。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Assets"
|
||||
subgraph "Script"
|
||||
subgraph "Game"
|
||||
subgraph "Map"
|
||||
MissionComp --> VictoryComp
|
||||
MissionComp --> TopComp
|
||||
MissionComp --> GuideSetpComp
|
||||
end
|
||||
subgraph "Common"
|
||||
SingletonModuleComp --> GameEvent
|
||||
SingletonModuleComp --> GameUIConfig
|
||||
end
|
||||
end
|
||||
end
|
||||
subgraph "Resources"
|
||||
subgraph "Config"
|
||||
NetCodeJson --> MapJson
|
||||
end
|
||||
LanguageJson --> ZhJson
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
|
||||
## 核心组件
|
||||
核心组件包括MissionComp和VictoryComp,分别负责战斗逻辑管理和胜利界面展示。MissionComp组件通过事件系统监听战斗状态变化,在战斗结束后触发胜利界面的打开,并传递奖励数据。VictoryComp组件接收这些数据并在onAdded方法中进行处理,实现奖励选项的动态渲染。
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L17-L150)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L13-L74)
|
||||
|
||||
## 架构概述
|
||||
系统采用ECS(实体-组件-系统)架构模式,通过事件驱动机制实现组件间的通信。战斗逻辑与UI展示完全分离,MissionComp作为战斗逻辑控制器,负责管理战斗状态和奖励生成;VictoryComp作为UI控制器,负责解析和展示奖励数据。这种架构设计提高了代码的可维护性和可扩展性。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[MissionComp] --> |dispatchEvent| B[GameEvent.FightEnd]
|
||||
B --> C[VictoryComp]
|
||||
C --> |open UIID.Victory| D[奖励界面]
|
||||
D --> |用户选择| E[奖励应用]
|
||||
E --> |dispatchEvent| F[GameEvent.MissionEnd]
|
||||
F --> G[游戏状态更新]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L66-L116)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L13-L74)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### MissionComp分析
|
||||
MissionComp组件是战斗逻辑的核心控制器,负责管理整个战斗流程。当英雄死亡或战斗结束时,该组件会触发相应的事件处理函数,并通过oops.gui.open方法打开胜利界面。
|
||||
|
||||
#### 战斗结束流程
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MissionComp as MissionComp
|
||||
participant VictoryComp as VictoryComp
|
||||
participant OopsGUI as oops.gui
|
||||
MissionComp->>MissionComp : do_hero_dead()
|
||||
MissionComp->>MissionComp : check hero_num <= 0
|
||||
MissionComp->>MissionComp : dispatchEvent(FightEnd)
|
||||
MissionComp->>OopsGUI : open(UIID.Victory, args)
|
||||
OopsGUI->>VictoryComp : instantiate victory prefab
|
||||
VictoryComp->>VictoryComp : onAdded(args)
|
||||
VictoryComp->>VictoryComp : parse rewards and game_data
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L32-L70)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L13-L74)
|
||||
|
||||
### VictoryComp分析
|
||||
VictoryComp组件负责胜利界面的展示和交互处理。该组件通过onAdded方法接收来自MissionComp的数据参数,并在界面上渲染相应的奖励选项。
|
||||
|
||||
#### 数据传递与解析
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([UI打开]) --> OnAdded["onAdded(args)"]
|
||||
OnAdded --> CheckArgs{"args存在?"}
|
||||
CheckArgs --> |是| ParseGameData["解析game_data"]
|
||||
ParseGameData --> UpdateUI["更新UI元素"]
|
||||
UpdateUI --> ScheduleNext["scheduleOnce显示next按钮"]
|
||||
ScheduleNext --> End([界面就绪])
|
||||
CheckArgs --> |否| DefaultValues["使用默认值"]
|
||||
DefaultValues --> UpdateUI
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L13-L37)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L9-L22)
|
||||
|
||||
## 依赖分析
|
||||
组件间的依赖关系清晰明确,MissionComp依赖于GameEvent和UIID枚举来触发界面切换,VictoryComp依赖于SingletonModuleComp来访问全局游戏数据。这种依赖关系通过import语句在代码中显式声明,确保了模块间的松耦合。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[MissionComp] --> B[GameEvent]
|
||||
A --> C[UIID]
|
||||
A --> D[SingletonModuleComp]
|
||||
E[VictoryComp] --> F[GameEvent]
|
||||
E --> G[SingletonModuleComp]
|
||||
E --> H[ItemComp]
|
||||
D --> I[vmdata]
|
||||
G --> I
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L33)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L0-L37)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L0-L41)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L33)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L0-L37)
|
||||
|
||||
## 性能考虑
|
||||
系统在性能方面采用了多种优化策略。首先,通过scheduleOnce方法实现了界面元素的延迟显示,避免了瞬间大量UI更新带来的性能冲击。其次,组件的销毁通过reset方法完成,确保了内存的及时释放。最后,事件系统的使用减少了组件间的直接调用,降低了耦合度和性能开销。
|
||||
|
||||
## 故障排除指南
|
||||
当遇到UI数据绑定错误时,应首先检查数据传递路径。确保MissionComp中的rewards和game_data字段正确初始化,并在oops.gui.open调用时作为参数传递。在VictoryComp的onAdded方法中,验证args参数是否包含预期的数据字段。如果问题仍然存在,检查SingletonModuleComp中的vmdata结构是否与UI绑定要求一致。
|
||||
|
||||
**Section sources**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L13-L74)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#37-L87)
|
||||
|
||||
## 结论
|
||||
MissionComp与Victory界面的集成通过清晰的事件驱动机制和数据传递模式实现。系统利用scheduleOnce方法控制界面元素的显示时机,提供了流畅的用户体验。通过分析代码结构和数据流,可以有效诊断和解决UI集成中的常见问题,并为自定义奖励展示效果提供扩展基础。
|
||||
169
.qoder/repowiki/zh/content/奖励系统/奖励机制/奖励数据流.md
Normal file
169
.qoder/repowiki/zh/content/奖励系统/奖励机制/奖励数据流.md
Normal file
@@ -0,0 +1,169 @@
|
||||
# 奖励数据流
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [奖励数据生命周期](#奖励数据生命周期)
|
||||
3. [rewards数组存储格式与UI展示](#rewards数组存储格式与ui展示)
|
||||
4. [game_data对象累加逻辑](#game_data对象累加逻辑)
|
||||
5. [数据同步策略](#数据同步策略)
|
||||
6. [数据丢失问题调试](#数据丢失问题调试)
|
||||
7. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
本文档系统阐述了奖励数据在MissionComp组件中的完整生命周期管理过程。从data_init方法初始化rewards数组和game_data对象开始,到do_drop方法接收掉落物品参数并更新数据结构的全过程。详细解释了rewards数组的存储格式设计及其与UI展示的对应关系,分析了game_data对象中exp、gold、diamond字段的累加逻辑与数据一致性保障机制,说明了MissionComp与全局状态管理smc.vmdata.mission_data的数据同步策略,并提供了数据丢失问题的调试方法。
|
||||
|
||||
## 奖励数据生命周期
|
||||
|
||||
奖励数据在MissionComp组件中的生命周期始于任务开始时的初始化,终于任务结束时的数据清理。整个生命周期通过事件驱动的方式进行管理,确保数据的准确性和一致性。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["任务开始 MissionStart"] --> B["data_init初始化"]
|
||||
B --> C["do_drop接收掉落物品"]
|
||||
C --> D["更新rewards数组"]
|
||||
D --> E["更新game_data对象"]
|
||||
E --> F["任务结束 FightEnd"]
|
||||
F --> G["数据同步到全局状态"]
|
||||
G --> H["打开胜利界面"]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L150)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L150)
|
||||
|
||||
## rewards数组存储格式与UI展示
|
||||
|
||||
rewards数组用于存储任务过程中获得的所有掉落物品信息。该数组在data_init方法中被初始化为空数组,随着任务进行逐步填充。数组的设计考虑了后续UI展示的需求,每个元素代表一个掉落物品。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MissionComp {
|
||||
+rewards : any[]
|
||||
+game_data : any
|
||||
+data_init()
|
||||
+do_drop(drop_item[], game_data)
|
||||
}
|
||||
class VictoryComp {
|
||||
+rewards : any[]
|
||||
+game_data : any
|
||||
+onAdded(args)
|
||||
}
|
||||
MissionComp --> VictoryComp : "传递数据"
|
||||
```
|
||||
|
||||
当任务结束时,rewards数组作为参数传递给胜利界面(VictoryComp),实现数据的跨组件传递。这种设计模式确保了奖励数据的完整性和可追溯性。
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L33)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L0-L37)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L33)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L0-L37)
|
||||
|
||||
## game_data对象累加逻辑
|
||||
|
||||
game_data对象包含exp、gold、diamond三个核心字段,用于记录任务过程中的经验值、金币和钻石奖励。这些数据的累加逻辑通过do_drop方法实现,确保每次获得奖励时都能正确更新。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["do_drop方法"] --> B["接收game_data参数"]
|
||||
B --> C{"参数有效性检查"}
|
||||
C --> |有效| D["累加exp、gold、diamond"]
|
||||
C --> |无效| E["使用默认值{exp:0,gold:0,diamond:0}"]
|
||||
D --> F["更新本地game_data对象"]
|
||||
F --> G["数据一致性保障"]
|
||||
```
|
||||
|
||||
数据一致性通过以下机制保障:
|
||||
1. 初始化时设置默认值
|
||||
2. 参数传递时提供默认值
|
||||
3. 事件驱动更新,避免直接修改
|
||||
4. 任务结束时统一同步到全局状态
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L32-L70)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L32-L70)
|
||||
|
||||
## 数据同步策略
|
||||
|
||||
MissionComp组件与全局状态管理smc.vmdata.mission_data之间采用事件驱动的数据同步策略。当特定事件发生时,相关数据会被同步到全局状态,确保数据的一致性和可访问性。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MissionComp
|
||||
participant smc_vmdata
|
||||
participant VictoryComp
|
||||
MissionComp->>MissionComp : data_init()
|
||||
MissionComp->>smc_vmdata : 初始化mission_data状态
|
||||
MissionComp->>MissionComp : do_drop(drop_item, game_data)
|
||||
MissionComp->>MissionComp : 更新本地数据
|
||||
MissionComp->>smc_vmdata : 同步关键状态(如mon_num)
|
||||
MissionComp->>VictoryComp : FightEnd事件
|
||||
VictoryComp->>VictoryComp : 接收rewards和game_data
|
||||
VictoryComp->>smc_vmdata : 最终数据持久化
|
||||
```
|
||||
|
||||
除了直接的奖励数据,其他任务相关状态如怪物数量(mon_num)、英雄数量(hero_num)等也会同步到全局状态,为其他组件提供必要的上下文信息。
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L66-L116)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L102-L136)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L57-L93)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L66-L116)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L102-L136)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L57-L93)
|
||||
|
||||
## 数据丢失问题调试
|
||||
|
||||
为确保奖励数据的完整性和可靠性,需要建立系统的调试方法来检测和解决潜在的数据丢失问题。以下是常见的调试策略和检查点:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["数据丢失问题"] --> B["检查事件监听"]
|
||||
A --> C["验证数据初始化"]
|
||||
A --> D["确认数据传递"]
|
||||
A --> E["检查异常处理"]
|
||||
B --> B1["MissionStart事件是否正确触发"]
|
||||
B --> B2["do_drop事件参数是否完整"]
|
||||
B --> B3["FightEnd事件是否携带数据"]
|
||||
C --> C1["data_init是否清空rewards数组"]
|
||||
C --> C2["game_data是否重置为默认值"]
|
||||
D --> D1["胜利界面是否正确接收参数"]
|
||||
D --> D2["数据结构是否匹配"]
|
||||
E --> E1["异常情况下数据是否保存"]
|
||||
E --> E2["网络中断时的恢复机制"]
|
||||
```
|
||||
|
||||
关键调试检查点包括:
|
||||
1. 确认data_init方法在每次任务开始时都被正确调用
|
||||
2. 验证do_drop方法接收的参数格式是否符合预期
|
||||
3. 检查FightEnd事件触发时是否正确传递了rewards和game_data
|
||||
4. 确保异常情况下(如游戏崩溃)有适当的数据恢复机制
|
||||
5. 验证全局状态smc.vmdata.mission_data的更新时机和内容
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L114-L150)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L47-L86)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L114-L150)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L47-L86)
|
||||
|
||||
## 结论
|
||||
MissionComp组件中的奖励数据管理采用了一套完整的生命周期管理体系。通过data_init方法初始化数据结构,do_drop方法处理奖励更新,最终通过事件机制将数据传递给胜利界面展示。rewards数组和game_data对象的设计充分考虑了UI展示需求和数据一致性要求。与全局状态管理smc.vmdata.mission_data的同步策略确保了数据的可靠性和可访问性。为防止数据丢失,建议建立完善的调试机制,重点关注事件触发、数据初始化、参数传递和异常处理等关键环节。
|
||||
272
.qoder/repowiki/zh/content/奖励系统/奖励机制/奖励机制.md
Normal file
272
.qoder/repowiki/zh/content/奖励系统/奖励机制/奖励机制.md
Normal file
@@ -0,0 +1,272 @@
|
||||
# 奖励机制
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [Design.md](file://assets/script/Design.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [奖励系统概述](#奖励系统概述)
|
||||
2. [三选一奖励机制](#三选一奖励机制)
|
||||
3. [FightSet常量配置与奖励类型](#fightset常量配置与奖励类型)
|
||||
4. [奖励数据结构与流程](#奖励数据结构与流程)
|
||||
5. [掉落处理与数据更新](#掉落处理与数据更新)
|
||||
6. [奖励界面触发与数据传递](#奖励界面触发与数据传递)
|
||||
7. [扩展新奖励类型](#扩展新奖励类型)
|
||||
|
||||
## 奖励系统概述
|
||||
|
||||
本游戏采用肉鸽(Roguelike)塔防玩法,奖励系统是核心成长机制之一。玩家通过击败怪物获得金币,并在每波战斗结束后从三个奖励选项中选择一个,用于强化英雄能力。奖励类型包括属性提升、技能升级、装备获取、新技能解锁等,不同奖励具有不同的战力评分和金币消耗,玩家需要根据当前局势进行策略性选择。
|
||||
|
||||
奖励系统通过事件驱动机制实现,主要由`MissionComp`组件负责奖励数据的收集与分发,`VictoryComp`组件负责奖励界面的展示与交互。系统采用ECS架构,通过事件总线(`oops.message`)进行组件间通信,确保了高内聚低耦合的设计原则。
|
||||
|
||||
**Section sources**
|
||||
- [Design.md](file://assets/script/Design.md#L0-L40)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L150)
|
||||
|
||||
## 三选一奖励机制
|
||||
|
||||
三选一奖励机制是游戏的核心决策系统,其触发条件为每波怪物被全部击败后。当`MissionMonComp`组件检测到当前波次怪物全部死亡时,会触发`FightEnd`事件,进而启动奖励选择流程。
|
||||
|
||||
该机制的实现逻辑如下:
|
||||
1. 战斗结束时,`MissionComp`组件监听到`FightEnd`事件
|
||||
2. 收集本局战斗的奖励数据(金币、经验、钻石等)
|
||||
3. 构建奖励选项数组,通常包含三个不同强度的奖励
|
||||
4. 通过GUI系统打开胜利界面(Victory界面),并传递奖励数据
|
||||
5. 玩家在界面中选择一个奖励,系统应用对应效果
|
||||
|
||||
奖励选项的设计遵循"弱、一般、强"的梯度原则,不同选项消耗的金币数量不同,战力评分也不同,鼓励玩家进行策略性决策。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MissionMonComp as MissionMonComp
|
||||
participant MissionComp as MissionComp
|
||||
participant VictoryComp as VictoryComp
|
||||
participant GUI as GUI系统
|
||||
MissionMonComp->>MissionComp : MonDead事件(最后一只怪物死亡)
|
||||
MissionComp->>MissionComp : 检查怪物数量是否为0
|
||||
MissionComp->>MissionComp : 触发FightEnd事件
|
||||
MissionComp->>MissionComp : 收集game_data(金币、经验等)
|
||||
MissionComp->>GUI : 打开Victory界面并传递数据
|
||||
GUI->>VictoryComp : 初始化奖励界面
|
||||
VictoryComp->>Player : 显示三个奖励选项
|
||||
Player->>VictoryComp : 选择奖励
|
||||
VictoryComp->>MissionComp : 应用所选奖励效果
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L23-L70)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L19-L37)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L102-L136)
|
||||
|
||||
## FightSet常量配置与奖励类型
|
||||
|
||||
`FightSet`枚举定义在`Mission.ts`文件中,包含了游戏的核心配置常量,其中与奖励系统直接相关的配置项包括:
|
||||
|
||||
- `GREEN_GOLD=1`:绿色金币,基础奖励单位
|
||||
- `BLUE_GOLD=2`:蓝色金币,中级奖励单位
|
||||
- `PURPLE_GOLD=3`:紫色金币,高级奖励单位
|
||||
- `ORANGE_GOLD=4`:橙色金币,稀有奖励单位
|
||||
- `ATK_ADD_GLOD=1`:伙伴攻击力增加对应的金币奖励值
|
||||
|
||||
这些常量定义了不同品质奖励的数值基准,系统根据这些基准值计算实际奖励数量。例如,普通怪物可能掉落`GREEN_GOLD`数量的金币,而精英怪物或Boss可能掉落`PURPLE_GOLD`或`ORANGE_GOLD`数量的金币。
|
||||
|
||||
此外,`FightSet`还定义了其他影响奖励获取的参数,如`MORE_RC=10`表示通过观看广告可获得的额外次数,这与奖励系统的双倍奖励功能相关联。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||||
|
||||
## 奖励数据结构与流程
|
||||
|
||||
### 数据结构分析
|
||||
|
||||
`MissionComp`组件中定义了两个关键数据结构:
|
||||
|
||||
1. **rewards数组**:用于存储掉落物品列表
|
||||
```typescript
|
||||
rewards:any[]=[]
|
||||
```
|
||||
|
||||
2. **game_data对象**:用于存储游戏数据
|
||||
```typescript
|
||||
game_data:any={
|
||||
exp:0,
|
||||
gold:0,
|
||||
diamond:0
|
||||
}
|
||||
```
|
||||
|
||||
`rewards`数组存储具体的物品奖励,如装备、技能书等;`game_data`对象则存储基础资源类奖励,包括经验值、金币和钻石。
|
||||
|
||||
### 奖励收集流程
|
||||
|
||||
奖励数据的收集与分发流程如下:
|
||||
|
||||
1. **初始化阶段**:在`data_init()`方法中,重置`rewards`数组和`game_data`对象
|
||||
2. **战斗阶段**:通过监听`MonDead`事件,逐步累积奖励数据
|
||||
3. **结束阶段**:当战斗结束时,将收集到的奖励数据传递给胜利界面
|
||||
|
||||
数据流从怪物死亡事件开始,经过`MissionComp`组件的收集处理,最终传递给`VictoryComp`组件进行展示,形成了完整的奖励数据流转闭环。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[怪物死亡] --> B{是否为最后一只}
|
||||
B --> |是| C[触发FightEnd事件]
|
||||
B --> |否| D[继续战斗]
|
||||
C --> E[收集奖励数据]
|
||||
E --> F[填充rewards数组和game_data]
|
||||
F --> G[打开Victory界面]
|
||||
G --> H[展示奖励选项]
|
||||
H --> I[玩家选择奖励]
|
||||
I --> J[应用奖励效果]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L23-L33)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L133-L135)
|
||||
|
||||
## 掉落处理与数据更新
|
||||
|
||||
`do_drop`方法是处理掉落物品和更新游戏数据的核心方法。该方法接收两个参数:`drop_item`数组和`game_data`对象,分别表示掉落的物品列表和基础资源奖励。
|
||||
|
||||
```typescript
|
||||
do_drop(drop_item:any[],game_data:any={exp:0,gold:0,diamond:0}){
|
||||
// console.log("[MissionComp] do_drop",drop_item,game_data)
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
虽然当前实现为空,但从方法签名可以看出其设计意图:
|
||||
- `drop_item`参数接收掉落的物品数组,可能包含装备、道具等
|
||||
- `game_data`参数接收基础资源奖励,默认值为零
|
||||
- 方法内部应实现将掉落物品添加到`rewards`数组,并将资源奖励累加到`game_data`对象中
|
||||
|
||||
在`MissionMonComp`组件中,可以找到实际的奖励发放逻辑。当关卡类型为"event"(事件关卡)时,会触发随机事件,其中`EventType.TREASURE`(宝藏事件)会直接增加50金币:
|
||||
```typescript
|
||||
switch (this.currentEvent) {
|
||||
case EventType.TREASURE:
|
||||
smc.vmdata.mission_data.gold += 50; // 增加50金币
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
这种设计模式表明,实际的奖励发放可能分散在多个组件中,最终由`MissionComp`统一收集和管理。
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L60-L63)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L145-L148)
|
||||
|
||||
## 奖励界面触发与数据传递
|
||||
|
||||
### 事件监听机制
|
||||
|
||||
`MissionComp`组件通过事件监听机制触发奖励界面的展示。在`onLoad`方法中,注册了对`FightEnd`事件的监听:
|
||||
|
||||
```typescript
|
||||
this.on(GameEvent.FightEnd,this.fight_end,this)
|
||||
```
|
||||
|
||||
当战斗结束时,`fight_end`方法会被调用,该方法通过`oops.gui.open`方法打开胜利界面,并传递奖励数据:
|
||||
|
||||
```typescript
|
||||
oops.gui.open(UIID.Victory,{victory:false,rewards:this.rewards,game_data:this.game_data})
|
||||
```
|
||||
|
||||
### 数据传递机制
|
||||
|
||||
数据传递通过`open`方法的参数实现,传递了三个关键数据:
|
||||
- `victory`:布尔值,表示战斗结果
|
||||
- `rewards`:奖励物品数组
|
||||
- `game_data`:基础资源数据对象
|
||||
|
||||
在`VictoryComp`组件的`onAdded`方法中接收这些数据:
|
||||
|
||||
```typescript
|
||||
onAdded(args: any) {
|
||||
if(args.game_data){
|
||||
this.game_data=args.game_data
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这种事件驱动的数据传递机制确保了组件间的松耦合,`MissionComp`只需关注奖励数据的收集,而`VictoryComp`只需关注奖励数据的展示,职责分离清晰。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MissionComp {
|
||||
+rewards : any[]
|
||||
+game_data : any
|
||||
+onLoad()
|
||||
+fight_end()
|
||||
+do_drop()
|
||||
}
|
||||
class VictoryComp {
|
||||
+rewards : any[]
|
||||
+game_data : any
|
||||
+onAdded(args)
|
||||
+victory_end()
|
||||
}
|
||||
class GameEvent {
|
||||
+FightEnd : "FightEnd"
|
||||
+MissionEnd : "MissionEnd"
|
||||
}
|
||||
class UIID {
|
||||
+Victory : 2
|
||||
}
|
||||
MissionComp --> GameEvent : "监听"
|
||||
MissionComp --> UIID : "使用"
|
||||
MissionComp --> VictoryComp : "传递数据"
|
||||
VictoryComp --> GameEvent : "触发"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L23-L33)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L35-L37)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L43)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L30)
|
||||
|
||||
## 扩展新奖励类型
|
||||
|
||||
### 配置修改步骤
|
||||
|
||||
1. **在Mission.ts中添加常量**:在`FightSet`枚举中添加新的奖励类型常量
|
||||
```typescript
|
||||
NEW_REWARD_TYPE=5 // 新奖励类型
|
||||
```
|
||||
|
||||
2. **在RogueConfig.ts中定义事件**:如果涉及新事件类型,需在`EventType`枚举中添加
|
||||
```typescript
|
||||
NEW_EVENT = "new_event"
|
||||
```
|
||||
|
||||
3. **更新事件概率配置**:在`EventConfig`中添加新事件的触发概率
|
||||
|
||||
### 代码集成步骤
|
||||
|
||||
1. **修改MissionComp.ts**:
|
||||
- 在`game_data`对象中添加新奖励字段
|
||||
- 在`do_drop`方法中处理新奖励类型的逻辑
|
||||
- 确保`rewards`数组能正确存储新类型的奖励物品
|
||||
|
||||
2. **更新VictoryComp.ts**:
|
||||
- 在`onAdded`方法中处理新奖励数据
|
||||
- 更新界面展示逻辑以支持新奖励类型的显示
|
||||
|
||||
3. **添加事件处理**:在`MissionMonComp`或相关组件中添加对新奖励事件的处理逻辑
|
||||
|
||||
4. **更新UI配置**:确保GUI系统能正确加载和显示新奖励类型的界面元素
|
||||
|
||||
通过以上步骤,可以无缝集成新的奖励类型,系统的设计具有良好的扩展性,新增奖励类型不会影响现有功能的稳定性。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L47-L86)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L23-L70)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L19-L37)
|
||||
177
.qoder/repowiki/zh/content/奖励系统/奖励机制/奖励触发机制.md
Normal file
177
.qoder/repowiki/zh/content/奖励系统/奖励机制/奖励触发机制.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# 奖励触发机制
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [事件监听注册机制](#事件监听注册机制)
|
||||
3. [战斗事件响应逻辑](#战斗事件响应逻辑)
|
||||
4. [奖励发放触发流程](#奖励发放触发流程)
|
||||
5. [失败情况下的奖励处理](#失败情况下的奖励处理)
|
||||
6. [事件派发与数据更新链条](#事件派发与数据更新链条)
|
||||
7. [常见异常排查方案](#常见异常排查方案)
|
||||
8. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
本文档深入分析基于事件驱动的奖励触发机制,重点解析`MissionComp.ts`中`onLoad`方法注册的事件监听器。详细说明`do_mon_dead`、`do_hero_dead`等方法如何响应战斗事件并累积奖励数据,以及`fight_end`和`to_end_fight`方法中奖励发放的触发时机与条件判断逻辑。
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L20)
|
||||
|
||||
## 事件监听注册机制
|
||||
在`MissionComp`组件的`onLoad`方法中,系统注册了多个关键的游戏事件监听器,包括`GameEvent.FightEnd`、`GameEvent.MonDead`、`GameEvent.HeroDead`等。这些监听器构成了奖励触发系统的核心基础,确保在特定游戏事件发生时能够及时响应并执行相应的奖励逻辑。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[onLoad] --> B[注册GameEvent.MissionStart]
|
||||
A --> C[注册GameEvent.MonDead]
|
||||
A --> D[注册GameEvent.HeroDead]
|
||||
A --> E[注册GameEvent.FightEnd]
|
||||
A --> F[注册GameEvent.MissionEnd]
|
||||
A --> G[注册GameEvent.DO_AD_BACK]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L15-L21)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L15-L21)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
|
||||
## 战斗事件响应逻辑
|
||||
当怪物死亡或英雄死亡事件发生时,系统会通过相应的事件处理器更新战斗状态数据。`do_mon_dead`方法在接收到`GameEvent.MonDead`事件后,会减少当前关卡中的怪物数量计数;而`do_hero_dead`方法在处理`GameEvent.HeroDead`事件时,会减少英雄数量,并在英雄全部阵亡时触发战斗结束事件。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Mon as 怪物
|
||||
participant HeroViewComp as HeroViewComp
|
||||
participant MissionComp as MissionComp
|
||||
Mon->>HeroViewComp : 被击败
|
||||
HeroViewComp->>HeroViewComp : do_dead()
|
||||
HeroViewComp->>HeroViewComp : 调度HeroDead事件
|
||||
HeroViewComp->>MissionComp : dispatchEvent(GameEvent.HeroDead)
|
||||
MissionComp->>MissionComp : do_hero_dead()
|
||||
MissionComp->>MissionComp : 更新英雄数量
|
||||
MissionComp->>MissionComp : 检查是否全部阵亡
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L570-L580)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L58-L67)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L58-L67)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L570-L580)
|
||||
|
||||
## 奖励发放触发流程
|
||||
奖励发放的触发主要通过`fight_end`和`to_end_fight`方法实现。当战斗结束条件满足时,系统会调度`GameEvent.FightEnd`事件,进而触发`fight_end`方法执行。该方法会在0.5秒延迟后清理战斗组件并重置游戏状态,确保奖励发放过程的稳定性和完整性。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[战斗结束条件满足] --> B[dispatchEvent(FightEnd)]
|
||||
B --> C[fight_end方法执行]
|
||||
C --> D[延迟0.5秒]
|
||||
D --> E[设置smc.mission.play=false]
|
||||
D --> F[设置smc.mission.pause=false]
|
||||
D --> G[cleanComponents()]
|
||||
G --> H[销毁HeroViewComp]
|
||||
G --> I[销毁AtkConCom]
|
||||
G --> J[销毁SkillViewCom]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L99-L114)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L99-L114)
|
||||
|
||||
## 失败情况下的奖励处理
|
||||
在战斗失败的情况下,系统会通过`do_hero_dead`方法中的逻辑判断来处理奖励。当英雄数量减至零或以下时,系统会立即派发`GameEvent.FightEnd`事件,并携带`{victory:false}`参数,同时打开胜利/失败界面,传递当前累积的奖励数据和游戏数据。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[英雄死亡] --> B[do_hero_dead执行]
|
||||
B --> C[英雄数量减1]
|
||||
C --> D{英雄数量<=0?}
|
||||
D --> |是| E[派发FightEnd事件]
|
||||
D --> |否| F[继续战斗]
|
||||
E --> G[打开胜利界面]
|
||||
G --> H[传递rewards数组]
|
||||
G --> I[传递game_data对象]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L62-L67)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L62-L67)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L74)
|
||||
|
||||
## 事件派发与数据更新链条
|
||||
整个奖励触发系统依赖于清晰的事件派发与数据更新链条。从怪物死亡到最终奖励展示,每个环节都有明确的数据流转路径。系统使用`smc.vmdata.mission_data`作为共享数据存储,确保各个组件之间能够同步最新的战斗状态信息。
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
MONSTER ||--o{ MISSION_DATA : "死亡时"
|
||||
HERO ||--o{ MISSION_DATA : "死亡时"
|
||||
MISSION_DATA ||--o{ REWARDS : "累积"
|
||||
MISSION_DATA ||--o{ GAME_DATA : "累积"
|
||||
REWARDS ||--o{ VICTORY_UI : "显示"
|
||||
GAME_DATA ||--o{ VICTORY_UI : "显示"
|
||||
class MISSION_DATA {
|
||||
int mon_num
|
||||
int hero_num
|
||||
float fight_time
|
||||
int level
|
||||
}
|
||||
class REWARDS {
|
||||
array rewards[]
|
||||
}
|
||||
class GAME_DATA {
|
||||
int exp
|
||||
int gold
|
||||
int diamond
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L23-L24)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L19-L20)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L23-L24)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L19-L20)
|
||||
|
||||
## 常见异常排查方案
|
||||
在实际运行过程中,可能会遇到一些常见的异常情况。以下是针对这些异常的排查方案:
|
||||
|
||||
1. **事件未正确触发**:检查事件名称是否拼写正确,确认事件监听器是否已正确注册。
|
||||
2. **奖励数据丢失**:验证`rewards`数组和`game_data`对象的初始化时机,确保在战斗开始前已完成初始化。
|
||||
3. **界面显示异常**:检查`VictoryComp`组件的`onAdded`方法中数据接收逻辑,确保参数传递正确。
|
||||
4. **性能问题**:监控`update`方法的执行频率,避免不必要的计算开销。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[问题现象] --> B{问题类型}
|
||||
B --> |事件问题| C[检查事件名称]
|
||||
B --> |数据问题| D[检查数据初始化]
|
||||
B --> |界面问题| E[检查参数传递]
|
||||
B --> |性能问题| F[优化update逻辑]
|
||||
```
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L133-L135)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L32-L33)
|
||||
|
||||
## 结论
|
||||
通过对`MissionComp.ts`中奖励触发逻辑的深入分析,我们了解到该系统采用事件驱动架构,通过注册和监听关键游戏事件来实现奖励的累积和发放。系统设计合理,各组件职责分明,数据流转清晰,为游戏的战斗奖励机制提供了可靠的支撑。
|
||||
234
.qoder/repowiki/zh/content/奖励系统/奖励机制/奖励配置.md
Normal file
234
.qoder/repowiki/zh/content/奖励系统/奖励机制/奖励配置.md
Normal file
@@ -0,0 +1,234 @@
|
||||
# 奖励配置
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [奖励配置概述](#奖励配置概述)
|
||||
2. [FightSet枚举中的奖励配置项](#fightset枚举中的奖励配置项)
|
||||
3. [常量在奖励机制中的作用](#常量在奖励机制中的作用)
|
||||
4. [奖励平衡性调整方法](#奖励平衡性调整方法)
|
||||
5. [新增奖励类型的配置方法](#新增奖励类型的配置方法)
|
||||
6. [配置数据与运行时逻辑的映射关系](#配置数据与运行时逻辑的映射关系)
|
||||
7. [配置变更的正确加载机制](#配置变更的正确加载机制)
|
||||
|
||||
## 奖励配置概述
|
||||
|
||||
本节详细解析Mission.ts文件中FightSet枚举的奖励相关配置项,包括金币、经验、钻石的数值定义与获取规则。同时解释TAL_NUM天赋数量、MORE_RC广告奖励次数等常量在奖励机制中的作用,并提供修改FightSet常量调整奖励平衡性的方法。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L59)
|
||||
|
||||
## FightSet枚举中的奖励配置项
|
||||
|
||||
FightSet枚举定义了游戏中各种奖励相关的配置项,主要包括:
|
||||
|
||||
- **金币奖励配置**:
|
||||
- GREEN_GOLD=1:绿色金币的数值定义
|
||||
- BLUE_GOLD=2:蓝色金币的数值定义
|
||||
- PURPLE_GOLD=3:紫色金币的数值定义
|
||||
- ORANGE_GOLD=4:橙色金币的数值定义
|
||||
|
||||
- **经验奖励**:
|
||||
- ATK_ADD_GLOD=1:攻击增加金币的数量
|
||||
|
||||
- **钻石奖励**:
|
||||
- 通过广告获取的钻石奖励次数由MORE_RC常量控制
|
||||
|
||||
这些配置项在游戏运行时被用于计算玩家完成任务后获得的奖励数量。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||||
|
||||
## 常量在奖励机制中的作用
|
||||
|
||||
### TAL_NUM天赋数量
|
||||
|
||||
TAL_NUM=3定义了玩家可选择的天赋数量。这个常量直接影响玩家在游戏中的成长路径和策略选择,是奖励机制中的重要组成部分。
|
||||
|
||||
### MORE_RC广告奖励次数
|
||||
|
||||
MORE_RC=10定义了通过观看广告可以获得的额外奖励次数。这个常量控制着玩家通过广告获取奖励的频率和数量,是游戏内经济系统的重要调节参数。
|
||||
|
||||
### 其他相关常量
|
||||
|
||||
- ATK_ADD_COUNT=4:伙伴攻击力增加的数量
|
||||
- CRIT_DAMAGE=50:暴击伤害的百分比
|
||||
- ONE_WAVE_TIME=30:单波次的时间长度
|
||||
|
||||
这些常量共同构成了游戏奖励机制的基础框架。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L59)
|
||||
|
||||
## 奖励平衡性调整方法
|
||||
|
||||
通过修改FightSet常量可以调整游戏的奖励平衡性:
|
||||
|
||||
### 调整金币奖励
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始] --> B[修改FightSet中的金币常量]
|
||||
B --> C[GREEN_GOLD=1 -> 2]
|
||||
B --> D[BLUE_GOLD=2 -> 3]
|
||||
B --> E[PURPLE_GOLD=3 -> 4]
|
||||
B --> F[ORANGE_GOLD=4 -> 5]
|
||||
C --> G[增加金币获取速度]
|
||||
D --> G
|
||||
E --> G
|
||||
F --> G
|
||||
G --> H[测试游戏平衡性]
|
||||
H --> I[根据反馈进一步调整]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||||
|
||||
### 调整经验获取
|
||||
|
||||
通过调整ATK_ADD_GLOD等常量可以改变玩家获取经验的速度,从而影响游戏进度和难度曲线。
|
||||
|
||||
### 调整广告奖励
|
||||
|
||||
修改MORE_RC常量可以控制玩家通过广告获取奖励的次数,影响游戏内购和广告收入的平衡。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L59)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L66-L70)
|
||||
|
||||
## 新增奖励类型的配置方法
|
||||
|
||||
### 添加新的奖励类型
|
||||
|
||||
要在游戏中新增奖励类型,需要执行以下步骤:
|
||||
|
||||
1. 在FightSet枚举中添加新的奖励常量
|
||||
2. 在游戏逻辑中添加对新奖励类型的处理
|
||||
3. 在UI界面中添加新奖励类型的显示
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class FightSet {
|
||||
+GREEN_GOLD : number
|
||||
+BLUE_GOLD : number
|
||||
+PURPLE_GOLD : number
|
||||
+ORANGE_GOLD : number
|
||||
+NEW_REWARD_TYPE : number
|
||||
}
|
||||
class MissionComp {
|
||||
+rewards : any[]
|
||||
+game_data : any
|
||||
+do_drop(drop_item[], game_data) : void
|
||||
}
|
||||
class VictoryComp {
|
||||
+rewards : any[]
|
||||
+game_data : any
|
||||
+onAdded(args) : void
|
||||
}
|
||||
FightSet --> MissionComp : "使用"
|
||||
FightSet --> VictoryComp : "使用"
|
||||
MissionComp --> VictoryComp : "传递数据"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L59)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L150)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L0-L74)
|
||||
|
||||
### 特殊道具奖励配置
|
||||
|
||||
要添加特殊道具作为奖励,可以在FightSet枚举中添加新的常量,例如:
|
||||
|
||||
- SPECIAL_ITEM_1=5:特殊道具1的标识
|
||||
- SPECIAL_ITEM_2=6:特殊道具2的标识
|
||||
|
||||
然后在奖励发放逻辑中处理这些新的奖励类型。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L59)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L47-L50)
|
||||
|
||||
## 配置数据与运行时逻辑的映射关系
|
||||
|
||||
### 数据流分析
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MissionComp as MissionComp
|
||||
participant SingletonModuleComp as SingletonModuleComp
|
||||
participant VictoryComp as VictoryComp
|
||||
participant UI as UI界面
|
||||
MissionComp->>SingletonModuleComp : 更新smc.vmdata.mission_data
|
||||
SingletonModuleComp->>VictoryComp : 传递game_data和rewards
|
||||
VictoryComp->>UI : 显示奖励信息
|
||||
UI->>SingletonModuleComp : 确认奖励领取
|
||||
SingletonModuleComp->>MissionComp : 更新全局数据
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L150)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L0-L41)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L0-L74)
|
||||
|
||||
### 配置数据的使用
|
||||
|
||||
FightSet枚举中的常量在多个组件中被引用:
|
||||
|
||||
- MissionComp使用这些常量来计算奖励
|
||||
- VictoryComp使用这些常量来显示奖励信息
|
||||
- SingletonModuleComp使用这些常量来存储全局游戏数据
|
||||
|
||||
这种设计实现了配置数据与运行时逻辑的分离,便于维护和调整。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L59)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L150)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L0-L74)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L0-L41)
|
||||
|
||||
## 配置变更的正确加载机制
|
||||
|
||||
### 配置加载流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[游戏启动] --> B[加载Mission.ts配置]
|
||||
B --> C[初始化FightSet常量]
|
||||
C --> D[创建SingletonModuleComp实例]
|
||||
D --> E[初始化smc.vmdata.mission_data]
|
||||
E --> F[MissionComp引用FightSet常量]
|
||||
F --> G[游戏运行时使用配置]
|
||||
G --> H[配置变更]
|
||||
H --> I[重新加载配置]
|
||||
I --> J[更新所有相关组件]
|
||||
J --> K[应用新配置]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L59)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L0-L41)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L150)
|
||||
|
||||
### 确保配置正确加载
|
||||
|
||||
为确保配置变更在游戏中正确加载,需要遵循以下原则:
|
||||
|
||||
1. 所有组件都应从SingletonModuleComp获取全局数据
|
||||
2. 配置变更后需要通知所有相关组件更新
|
||||
3. 使用事件机制(如oops.message)来同步配置变更
|
||||
|
||||
通过这些机制,可以确保配置变更能够正确地应用到游戏的所有部分。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L59)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L0-L41)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L150)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L0-L74)
|
||||
638
.qoder/repowiki/zh/content/奖励系统/奖励系统.md
Normal file
638
.qoder/repowiki/zh/content/奖励系统/奖励系统.md
Normal file
@@ -0,0 +1,638 @@
|
||||
# 奖励系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts)
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [MissionHomeComp.ts](file://assets/script/game/map/MissionHomeComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [系统架构概览](#系统架构概览)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [奖励类型与配置](#奖励类型与配置)
|
||||
5. [三选一奖励机制](#三选一奖励机制)
|
||||
6. [战斗胜利与奖励选择](#战斗胜利与奖励选择)
|
||||
7. [奖励触发条件](#奖励触发条件)
|
||||
8. [数据绑定与UI展示](#数据绑定与UI展示)
|
||||
9. [扩展新奖励类型](#扩展新奖励类型)
|
||||
10. [性能优化考虑](#性能优化考虑)
|
||||
11. [故障排除指南](#故障排除指南)
|
||||
12. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
奖励系统是本游戏的核心机制之一,采用三选一奖励选择模式,在每波怪物清理后为玩家提供三种不同类型的奖励选项。系统基于肉鸽(Roguelike)游戏设计理念,通过策略性的奖励选择来影响英雄的成长路径,为玩家提供多样化的游戏体验和重玩价值。
|
||||
|
||||
奖励系统的主要特点包括:
|
||||
- **三选一选择机制**:每轮战斗结束后提供三个奖励选项
|
||||
- **多样化奖励类型**:属性提升、技能升级、装备获取、新技能解锁等
|
||||
- **策略性决策**:玩家需要根据当前阵容和游戏进度做出最优选择
|
||||
- **动态权重系统**:奖励权重根据游戏进度和玩家状态动态调整
|
||||
- **可视化反馈**:清晰的奖励预览和效果展示
|
||||
|
||||
## 系统架构概览
|
||||
|
||||
奖励系统采用模块化架构设计,各组件职责明确,通过事件驱动的方式协同工作。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "战斗系统"
|
||||
MC[MissionComp<br/>任务控制器]
|
||||
MMC[MissionMonComp<br/>怪物控制器]
|
||||
MHMC[MissionHeroComp<br/>英雄控制器]
|
||||
end
|
||||
subgraph "奖励系统"
|
||||
VC[VictoryComp<br/>胜利界面]
|
||||
SM[SingletonModule<br/>单例模块]
|
||||
end
|
||||
subgraph "配置系统"
|
||||
MS[Mission.ts<br/>战斗配置]
|
||||
TS[Tasks.ts<br/>任务配置]
|
||||
RS[RogueConfig.ts<br/>肉鸽配置]
|
||||
end
|
||||
subgraph "数据层"
|
||||
GD[GameData<br/>游戏数据]
|
||||
MD[MissionData<br/>关卡数据]
|
||||
end
|
||||
MC --> VC
|
||||
MC --> SM
|
||||
MMC --> MC
|
||||
MHMC --> MC
|
||||
VC --> SM
|
||||
SM --> GD
|
||||
SM --> MD
|
||||
MS --> MC
|
||||
RS --> MMC
|
||||
TS --> MC
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L151)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L75)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L41)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### MissionComp - 任务控制器
|
||||
|
||||
MissionComp是奖励系统的核心控制器,负责整个战斗流程的管理和奖励发放。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MissionComp {
|
||||
+rewards : any[]
|
||||
+game_data : any
|
||||
+onLoad() void
|
||||
+update(dt : number) void
|
||||
+do_reward() void
|
||||
+do_drop(drop_item : any[], game_data : any) void
|
||||
+do_mon_dead(event : any, data : any) void
|
||||
+do_hero_dead(event : any, data : any) void
|
||||
+mission_start() Promise~void~
|
||||
+to_fight() void
|
||||
+fight_end() void
|
||||
+mission_end() void
|
||||
+data_init() void
|
||||
+cleanComponents() void
|
||||
}
|
||||
class SingletonModuleComp {
|
||||
+mission : any
|
||||
+vmdata : any
|
||||
+data : any
|
||||
}
|
||||
class GameEvent {
|
||||
+MissionStart
|
||||
+MonDead
|
||||
+HeroDead
|
||||
+FightEnd
|
||||
+MissionEnd
|
||||
}
|
||||
MissionComp --> SingletonModuleComp : "使用"
|
||||
MissionComp --> GameEvent : "监听"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L15-L151)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L20-L41)
|
||||
|
||||
**节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L151)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L41)
|
||||
|
||||
### VictoryComp - 胜利界面控制器
|
||||
|
||||
VictoryComp负责战斗胜利后的奖励选择界面,处理玩家的选择和奖励发放。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家
|
||||
participant VC as VictoryComp
|
||||
participant SM as SingletonModule
|
||||
participant UI as 用户界面
|
||||
Player->>VC : 战斗胜利
|
||||
VC->>SM : 获取奖励数据
|
||||
SM-->>VC : 返回奖励列表
|
||||
VC->>UI : 显示奖励选项
|
||||
Player->>UI : 选择奖励
|
||||
UI->>VC : 发送选择事件
|
||||
VC->>SM : 处理奖励发放
|
||||
SM-->>VC : 确认奖励生效
|
||||
VC->>Player : 显示奖励效果
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L25-L75)
|
||||
|
||||
**节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L75)
|
||||
|
||||
### MissionHeroComp & MissionMonComp - 奖励触发器
|
||||
|
||||
这两个组件分别负责英雄和怪物的奖励触发条件监控。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[战斗开始] --> B{检查英雄状态}
|
||||
B --> |英雄存活| C[继续战斗]
|
||||
B --> |英雄死亡| D[战斗失败]
|
||||
C --> E{检查怪物状态}
|
||||
E --> |怪物存活| F[继续战斗]
|
||||
E --> |怪物死亡| G[战斗胜利]
|
||||
F --> H[更新战斗数据]
|
||||
H --> B
|
||||
G --> I[触发奖励生成]
|
||||
I --> J[打开胜利界面]
|
||||
J --> K[等待玩家选择]
|
||||
D --> L[打开失败界面]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L1-L81)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
|
||||
**节来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L1-L81)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
|
||||
## 奖励类型与配置
|
||||
|
||||
### 基础奖励配置
|
||||
|
||||
奖励系统基于Mission.ts中的FightSet枚举定义了各种奖励类型的基础配置:
|
||||
|
||||
| 奖励类型 | 配置值 | 描述 |
|
||||
|---------|--------|------|
|
||||
| ATK_ADD_COUNT | 4 | 伙伴攻击力增加数量 |
|
||||
| ATK_ADD_GLOD | 1 | 金币增加数量 |
|
||||
| CRIT_DAMAGE | 50 | 暴击伤害百分比 |
|
||||
| DOUBLE_ATK_RATE | 100 | 额外攻击默认概率 |
|
||||
| GREEN_GOLD | 1 | 绿色金币数量 |
|
||||
| BLUE_GOLD | 2 | 蓝色金币数量 |
|
||||
| PURPLE_GOLD | 3 | 紫色金币数量 |
|
||||
| ORANGE_GOLD | 4 | 橙色金币数量 |
|
||||
|
||||
**节来源**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L1-L60)
|
||||
|
||||
### 英雄属性系统
|
||||
|
||||
英雄属性系统通过HeroAttrs.ts定义了完整的属性体系:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "基础属性"
|
||||
HP[生命值 HP_MAX]
|
||||
MP[魔法值 MP_MAX]
|
||||
AP[攻击力 AP]
|
||||
MAP[魔法攻击力 MAP]
|
||||
end
|
||||
subgraph "防御属性"
|
||||
DEF[物理防御 DEF]
|
||||
MDEF[魔法防御 MDEF]
|
||||
SHIELD[护盾值 SHIELD_MAX]
|
||||
end
|
||||
subgraph "特殊属性"
|
||||
SPEED[移动速度 SPEED]
|
||||
DIS[攻击距离 DIS]
|
||||
CRIT[暴击率 CRITICAL]
|
||||
DODGE[闪避率 DODGE]
|
||||
end
|
||||
HP --> DEF
|
||||
MP --> MDEF
|
||||
AP --> CRIT
|
||||
MAP --> CRIT
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L25-L47)
|
||||
|
||||
**节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L544)
|
||||
|
||||
### 天赋系统配置
|
||||
|
||||
天赋系统通过TalSet.ts定义了丰富的天赋效果:
|
||||
|
||||
| 天赋类型 | 示例 | 效果描述 |
|
||||
|---------|------|----------|
|
||||
| 等级类天赋 | 剑意提升 | 每升5级,攻击力增加10% |
|
||||
| 攻击触发类 | 胡服骑射 | 每3次攻击,攻击速度增加5% |
|
||||
| 受伤触发类 | 坚韧意志 | 每受伤3次,防御力增加2点 |
|
||||
| 特定等级触发 | 兵圣之道 | 20级获得额外技能 |
|
||||
|
||||
**节来源**
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts#L68-L114)
|
||||
|
||||
## 三选一奖励机制
|
||||
|
||||
### 奖励生成算法
|
||||
|
||||
奖励系统采用基于权重的概率算法生成奖励选项:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[战斗胜利] --> B[计算基础权重]
|
||||
B --> C[应用难度系数]
|
||||
C --> D[生成奖励池]
|
||||
D --> E{随机选择奖励}
|
||||
E --> |奖励1| F[验证奖励有效性]
|
||||
E --> |奖励2| F
|
||||
E --> |奖励3| F
|
||||
F --> G{奖励有效?}
|
||||
G --> |是| H[添加到选项列表]
|
||||
G --> |否| I[重新生成]
|
||||
H --> J[返回三个奖励选项]
|
||||
I --> E
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L40-L50)
|
||||
|
||||
### 奖励权重调整
|
||||
|
||||
奖励权重系统根据以下因素动态调整:
|
||||
|
||||
1. **游戏进度**:随着关卡推进,奖励权重逐渐向高级奖励倾斜
|
||||
2. **英雄状态**:根据当前英雄阵容和等级调整奖励偏好
|
||||
3. **玩家行为**:记录玩家的选择历史,优化奖励推荐
|
||||
4. **随机事件**:特殊事件可能临时改变奖励权重
|
||||
|
||||
**节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L40-L50)
|
||||
|
||||
## 战斗胜利与奖励选择
|
||||
|
||||
### 战斗胜利流程
|
||||
|
||||
战斗胜利后,系统按照以下流程处理奖励选择:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Game as 游戏引擎
|
||||
participant MC as MissionComp
|
||||
participant VC as VictoryComp
|
||||
participant SM as SingletonModule
|
||||
participant UI as 用户界面
|
||||
Game->>MC : 战斗结束事件
|
||||
MC->>MC : 检查战斗结果
|
||||
alt 战斗胜利
|
||||
MC->>SM : 获取奖励数据
|
||||
SM-->>MC : 返回奖励列表
|
||||
MC->>VC : 打开胜利界面
|
||||
VC->>UI : 显示奖励选项
|
||||
UI->>VC : 玩家选择奖励
|
||||
VC->>SM : 处理奖励发放
|
||||
SM-->>VC : 确认奖励生效
|
||||
VC->>Game : 关闭胜利界面
|
||||
else 战斗失败
|
||||
MC->>Game : 显示失败界面
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L80-L95)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L25-L40)
|
||||
|
||||
**节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L80-L95)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L25-L40)
|
||||
|
||||
### 奖励选择界面
|
||||
|
||||
胜利界面提供直观的奖励选择功能:
|
||||
|
||||
1. **奖励预览**:每个奖励选项都有详细的属性说明
|
||||
2. **视觉反馈**:通过图标和颜色区分不同类型的奖励
|
||||
3. **选择确认**:提供明确的选择按钮和取消选项
|
||||
4. **即时反馈**:选择后立即显示奖励效果
|
||||
|
||||
**节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L75)
|
||||
|
||||
## 奖励触发条件
|
||||
|
||||
### 英雄奖励触发
|
||||
|
||||
英雄奖励通过MissionHeroComp监控英雄状态变化:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 战斗准备
|
||||
战斗准备 --> 英雄召唤 : Zhaohuan事件
|
||||
英雄召唤 --> 战斗中 : FightReady事件
|
||||
战斗中 --> 英雄存活 : 英雄未死亡
|
||||
战斗中 --> 英雄死亡 : HeroDead事件
|
||||
英雄存活 --> 战斗中 : 继续战斗
|
||||
英雄死亡 --> 战斗失败 : 英雄全灭
|
||||
战斗失败 --> [*]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L15-L30)
|
||||
|
||||
**节来源**
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts#L1-L81)
|
||||
|
||||
### 怪物奖励触发
|
||||
|
||||
怪物奖励通过MissionMonComp监控怪物击杀情况:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[怪物生成] --> B[怪物存活]
|
||||
B --> C{怪物死亡?}
|
||||
C --> |否| D[继续战斗]
|
||||
C --> |是| E[更新怪物计数]
|
||||
E --> F{还有怪物?}
|
||||
F --> |是| B
|
||||
F --> |否| G[战斗胜利]
|
||||
D --> C
|
||||
G --> H[触发奖励生成]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L40-L60)
|
||||
|
||||
**节来源**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L240)
|
||||
|
||||
### 事件奖励触发
|
||||
|
||||
特殊事件通过RogueConfig.ts定义的事件系统触发:
|
||||
|
||||
| 事件类型 | 概率 | 效果 |
|
||||
|---------|------|------|
|
||||
| TREASURE | 40% | 增加50金币奖励 |
|
||||
| TRAP | 20% | 对玩家造成伤害 |
|
||||
| BUFF | 25% | 增加临时增益效果 |
|
||||
| DEBUFF | 15% | 增加临时减益效果 |
|
||||
|
||||
**节来源**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L279-L310)
|
||||
|
||||
## 数据绑定与UI展示
|
||||
|
||||
### 单例模块数据管理
|
||||
|
||||
SingletonModuleComp作为全局数据管理中心,维护奖励系统所需的所有数据:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SingletonModuleComp {
|
||||
+mission : MissionData
|
||||
+vmdata : ViewData
|
||||
+data : GameData
|
||||
+guides : number[]
|
||||
+current_guide : number
|
||||
+openid : string
|
||||
}
|
||||
class MissionData {
|
||||
+status : number
|
||||
+play : boolean
|
||||
+pause : boolean
|
||||
+in_select : boolean
|
||||
+in_fight : boolean
|
||||
}
|
||||
class ViewData {
|
||||
+mission_data : MissionData
|
||||
}
|
||||
class GameData {
|
||||
+gold : number
|
||||
+diamond : number
|
||||
+score : number
|
||||
+mission : number
|
||||
}
|
||||
SingletonModuleComp --> MissionData
|
||||
SingletonModuleComp --> ViewData
|
||||
SingletonModuleComp --> GameData
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L20-L41)
|
||||
|
||||
**节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L41)
|
||||
|
||||
### UI配置与界面管理
|
||||
|
||||
GameUIConfig.ts定义了奖励系统相关的界面配置:
|
||||
|
||||
| UI标识 | 预制件路径 | 层级 |
|
||||
|--------|-----------|------|
|
||||
| Victory | gui/element/victory | UI层 |
|
||||
| Loading | loading/prefab/loading | UI层 |
|
||||
|
||||
**节来源**
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L36)
|
||||
|
||||
## 扩展新奖励类型
|
||||
|
||||
### 添加新奖励类型
|
||||
|
||||
要扩展新的奖励类型,需要修改以下文件:
|
||||
|
||||
1. **Mission.ts** - 添加新的奖励配置常量
|
||||
2. **HeroAttrs.ts** - 定义新属性类型
|
||||
3. **TalSet.ts** - 添加新天赋效果
|
||||
4. **RogueConfig.ts** - 更新事件配置
|
||||
|
||||
### 奖励权重调整
|
||||
|
||||
通过修改FightSet枚举可以调整各类奖励的权重:
|
||||
|
||||
```typescript
|
||||
// 示例:增加高级奖励的权重
|
||||
export enum FightSet {
|
||||
// 高级奖励权重提升
|
||||
PURPLE_GOLD = 5, // 紫色金币权重从3提升到5
|
||||
ORANGE_GOLD = 8, // 橙色金币权重从4提升到8
|
||||
// 中级奖励保持不变
|
||||
BLUE_GOLD = 2,
|
||||
GREEN_GOLD = 1,
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义奖励算法
|
||||
|
||||
可以通过重写MissionComp中的do_reward方法来实现自定义奖励算法:
|
||||
|
||||
```typescript
|
||||
// 示例:基于英雄阵容的奖励算法
|
||||
do_reward() {
|
||||
// 获取当前英雄阵容
|
||||
const heroes = this.getCurrentHeroes();
|
||||
|
||||
// 根据阵容特点调整奖励权重
|
||||
const weightMap = this.calculateRewardWeights(heroes);
|
||||
|
||||
// 生成奖励选项
|
||||
this.rewards = this.generateRewards(weightMap);
|
||||
}
|
||||
```
|
||||
|
||||
## 性能优化考虑
|
||||
|
||||
### 内存管理
|
||||
|
||||
奖励系统采用以下内存优化策略:
|
||||
|
||||
1. **组件生命周期管理**:及时销毁不需要的组件
|
||||
2. **数据缓存策略**:缓存常用的奖励配置数据
|
||||
3. **事件监听优化**:避免不必要的事件监听器
|
||||
|
||||
### 渲染优化
|
||||
|
||||
1. **延迟加载**:奖励界面按需加载资源
|
||||
2. **对象池**:复用奖励预览对象
|
||||
3. **批量更新**:合并UI更新操作
|
||||
|
||||
### 算法优化
|
||||
|
||||
1. **权重计算缓存**:缓存复杂的权重计算结果
|
||||
2. **随机数优化**:使用高效的随机数生成算法
|
||||
3. **数据结构优化**:使用合适的数据结构提高查找效率
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 奖励不显示问题
|
||||
|
||||
**症状**:战斗胜利后没有显示奖励选项
|
||||
|
||||
**原因分析**:
|
||||
1. 奖励数据为空
|
||||
2. UI界面未正确打开
|
||||
3. 事件监听器未正确注册
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 检查奖励数据
|
||||
if (!this.rewards || this.rewards.length === 0) {
|
||||
console.error("奖励数据为空");
|
||||
// 重新生成奖励
|
||||
this.rewards = this.generateDefaultRewards();
|
||||
}
|
||||
|
||||
// 确保UI正确打开
|
||||
oops.gui.open(UIID.Victory, {
|
||||
victory: true,
|
||||
rewards: this.rewards,
|
||||
game_data: this.game_data
|
||||
});
|
||||
```
|
||||
|
||||
#### 奖励权重异常
|
||||
|
||||
**症状**:奖励权重分布不合理
|
||||
|
||||
**原因分析**:
|
||||
1. 权重配置错误
|
||||
2. 动态权重计算逻辑问题
|
||||
3. 随机数种子问题
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 验证权重配置
|
||||
validateRewardWeights() {
|
||||
const weights = Object.values(FightSet).filter(v => typeof v === 'number');
|
||||
const sum = weights.reduce((a, b) => a + b, 0);
|
||||
|
||||
if (sum === 0) {
|
||||
console.error("奖励权重总和为0");
|
||||
// 使用默认权重
|
||||
return this.getDefaultWeights();
|
||||
}
|
||||
|
||||
return weights;
|
||||
}
|
||||
```
|
||||
|
||||
#### 性能问题
|
||||
|
||||
**症状**:奖励生成过程卡顿
|
||||
|
||||
**原因分析**:
|
||||
1. 奖励算法复杂度过高
|
||||
2. 数据库查询频繁
|
||||
3. UI渲染过于复杂
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 优化奖励生成算法
|
||||
async generateRewardsOptimized() {
|
||||
// 使用Web Worker异步处理
|
||||
const worker = new Worker('reward_worker.js');
|
||||
|
||||
worker.postMessage({
|
||||
monsters: this.monsters,
|
||||
heroes: this.heroes,
|
||||
difficulty: this.difficulty
|
||||
});
|
||||
|
||||
worker.onmessage = (e) => {
|
||||
this.rewards = e.data;
|
||||
this.displayRewards();
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
奖励系统是本游戏的核心机制,通过精心设计的三选一奖励选择模式,为玩家提供了丰富的策略选择空间。系统采用模块化架构,各组件职责明确,通过事件驱动的方式实现松耦合设计。
|
||||
|
||||
### 主要特性
|
||||
|
||||
1. **多样化奖励类型**:涵盖属性提升、技能升级、装备获取等多个方面
|
||||
2. **策略性决策**:玩家需要根据当前阵容和游戏进度做出最优选择
|
||||
3. **动态权重系统**:奖励权重根据游戏进度和玩家状态动态调整
|
||||
4. **可视化反馈**:清晰的奖励预览和效果展示
|
||||
5. **扩展性强**:易于添加新的奖励类型和调整奖励权重
|
||||
|
||||
### 设计优势
|
||||
|
||||
- **平衡性**:通过权重系统确保奖励的平衡性
|
||||
- **可玩性**:多样的奖励选项提供重玩价值
|
||||
- **可维护性**:模块化设计便于维护和扩展
|
||||
- **性能优化**:采用多种优化策略确保流畅运行
|
||||
|
||||
### 未来发展方向
|
||||
|
||||
1. **智能推荐系统**:基于玩家行为的奖励推荐
|
||||
2. **社交元素**:好友间的奖励分享和比较
|
||||
3. **成就系统**:与奖励系统结合的成就解锁
|
||||
4. **动态难度**:根据玩家表现调整奖励难度
|
||||
|
||||
奖励系统的设计体现了游戏设计理念的核心思想:通过简单的机制创造复杂的策略深度,为玩家提供持续的游戏动力和成就感。
|
||||
446
.qoder/repowiki/zh/content/奖励系统/奖励配置/任务奖励配置.md
Normal file
446
.qoder/repowiki/zh/content/奖励系统/奖励配置/任务奖励配置.md
Normal file
@@ -0,0 +1,446 @@
|
||||
# 任务奖励配置
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [MissionHeroComp.ts](file://assets/script/game/map/MissionHeroComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
本文档全面解析了《英雄传说》游戏中基于Tasks.ts文件的任务奖励配置系统。该系统负责管理游戏中的各种任务类型,包括新手指引任务和每日任务,并实现了完整的奖励发放机制。系统采用模块化设计,支持任务配置的动态加载、运行时查询和奖励数据的实时更新。
|
||||
|
||||
## 项目结构
|
||||
|
||||
任务奖励配置系统在项目中的组织结构如下:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
Tasks[Tasks.ts<br/>任务配置常量]
|
||||
GameEvent[GameEvent.ts<br/>游戏事件定义]
|
||||
Guide[Guide.ts<br/>引导系统]
|
||||
end
|
||||
subgraph "数据管理层"
|
||||
SingletonModule[SingletonModuleComp.ts<br/>单例模块管理]
|
||||
Initialize[Initialize.ts<br/>初始化系统]
|
||||
end
|
||||
subgraph "业务逻辑层"
|
||||
MissionComp[MissionComp.ts<br/>任务控制组件]
|
||||
VictoryComp[VictoryComp.ts<br/>胜利界面组件]
|
||||
MissionHeroComp[MissionHeroComp.ts<br/>英雄任务组件]
|
||||
end
|
||||
subgraph "UI展示层"
|
||||
MInfoComp[MInfoComp.ts<br/>任务信息组件]
|
||||
MapViewComp[MapViewComp.ts<br/>地图视图组件]
|
||||
end
|
||||
Tasks --> MissionComp
|
||||
GameEvent --> MissionComp
|
||||
SingletonModule --> MissionComp
|
||||
MissionComp --> VictoryComp
|
||||
MissionComp --> MInfoComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L13-L28)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L30)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L50)
|
||||
|
||||
**章节来源**
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L1-L28)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L151)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 任务配置常量
|
||||
|
||||
Tasks.ts文件定义了游戏中的任务配置常量数组,包含以下关键字段:
|
||||
|
||||
| 字段名 | 类型 | 描述 | 示例值 |
|
||||
|--------|------|------|--------|
|
||||
| id | number | 任务唯一标识符 | 0, 1 |
|
||||
| name | string | 任务名称 | "新手指引", "每日任务" |
|
||||
| description | string | 任务描述 | "新手指引描述", "每日任务描述" |
|
||||
| reward | number | 奖励数值 | 100 |
|
||||
| type | number | 任务类型(可选) | 0 |
|
||||
|
||||
### 用户数据管理
|
||||
|
||||
SingletonModuleComp.ts提供了完整的用户数据管理系统,包含以下核心数据结构:
|
||||
|
||||
| 数据字段 | 类型 | 默认值 | 描述 |
|
||||
|----------|------|--------|------|
|
||||
| score | number | 0 | 游戏分数 |
|
||||
| mission | number | 1 | 当前关卡 |
|
||||
| diamond | number | 100 | 钻石数量 |
|
||||
| meat | number | 0 | 肉类资源 |
|
||||
| exp | number | 0 | 经验值 |
|
||||
| task | number | 0 | 任务进度 |
|
||||
|
||||
**章节来源**
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L13-L28)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L37-L50)
|
||||
|
||||
## 架构概览
|
||||
|
||||
任务奖励配置系统采用分层架构设计,确保了良好的可维护性和扩展性:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家
|
||||
participant MissionComp as 任务控制器
|
||||
participant SingletonModule as 数据管理器
|
||||
participant Tasks as 任务配置
|
||||
participant VictoryComp as 胜利界面
|
||||
Player->>MissionComp : 开始任务
|
||||
MissionComp->>Tasks : 查询任务配置
|
||||
Tasks-->>MissionComp : 返回任务信息
|
||||
MissionComp->>MissionComp : 执行任务逻辑
|
||||
MissionComp->>Player : 显示任务进度
|
||||
Player->>MissionComp : 完成任务
|
||||
MissionComp->>SingletonModule : 更新用户数据
|
||||
SingletonModule->>SingletonModule : 存储到云端/本地
|
||||
MissionComp->>VictoryComp : 显示奖励界面
|
||||
VictoryComp->>Player : 展示奖励结果
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L70-L90)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L81-L121)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L30-L50)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 任务配置组件
|
||||
|
||||
#### Tasks.ts - 任务配置核心
|
||||
|
||||
任务配置组件负责定义所有可用的任务类型及其奖励规则:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class TaskConfig {
|
||||
+number id
|
||||
+string name
|
||||
+string description
|
||||
+number reward
|
||||
+number type
|
||||
+validateTask() boolean
|
||||
+getRewardAmount() number
|
||||
}
|
||||
class Tasks {
|
||||
+TaskConfig[] tasks
|
||||
+findTaskById(id) TaskConfig
|
||||
+getDailyRewards() number[]
|
||||
+getTypeRewards(type) TaskConfig[]
|
||||
}
|
||||
Tasks --> TaskConfig : "包含多个"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L13-L28)
|
||||
|
||||
#### 任务类型与奖励规则
|
||||
|
||||
系统支持多种任务类型,每种类型具有不同的奖励计算规则:
|
||||
|
||||
| 任务类型 | ID | 奖励计算 | 特殊规则 |
|
||||
|----------|----|---------|---------|
|
||||
| 新手指引 | 0 | 固定奖励 | 一次性奖励,不可重复 |
|
||||
| 每日任务 | 1 | 固定奖励 | 每日刷新,可重复完成 |
|
||||
|
||||
**章节来源**
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L13-L28)
|
||||
|
||||
### 任务执行组件
|
||||
|
||||
#### MissionComp.ts - 任务控制中心
|
||||
|
||||
任务控制组件管理整个任务生命周期,包括任务开始、执行和完成:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([任务开始]) --> LoadConfig["加载任务配置"]
|
||||
LoadConfig --> InitData["初始化任务数据"]
|
||||
InitData --> MonitorEvents["监控游戏事件"]
|
||||
MonitorEvents --> EventCheck{"事件检查"}
|
||||
EventCheck --> |怪物死亡| UpdateProgress["更新任务进度"]
|
||||
EventCheck --> |英雄死亡| CheckGameOver{"检查游戏结束"}
|
||||
EventCheck --> |任务完成| RewardCalculation["计算奖励"]
|
||||
UpdateProgress --> MonitorEvents
|
||||
CheckGameOver --> |失败| EndMission["结束任务"]
|
||||
CheckGameOver --> |继续| MonitorEvents
|
||||
RewardCalculation --> AwardRewards["发放奖励"]
|
||||
AwardRewards --> ShowVictory["显示胜利界面"]
|
||||
ShowVictory --> EndMission
|
||||
EndMission --> ResetData["重置任务数据"]
|
||||
ResetData --> End([任务结束])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L70-L150)
|
||||
|
||||
#### 奖励发放机制
|
||||
|
||||
奖励发放通过以下流程实现:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MissionComp as 任务控制器
|
||||
participant SingletonModule as 数据管理器
|
||||
participant VictoryComp as 胜利界面
|
||||
participant Player as 玩家
|
||||
MissionComp->>MissionComp : 检查任务完成条件
|
||||
MissionComp->>MissionComp : 计算奖励数值
|
||||
MissionComp->>SingletonModule : 更新用户数据
|
||||
SingletonModule->>SingletonModule : 验证数据完整性
|
||||
SingletonModule->>SingletonModule : 同步到云端/本地
|
||||
SingletonModule-->>MissionComp : 确认更新成功
|
||||
MissionComp->>VictoryComp : 打开胜利界面
|
||||
VictoryComp->>Player : 显示奖励详情
|
||||
Player->>VictoryComp : 确认奖励领取
|
||||
VictoryComp->>MissionComp : 完成奖励流程
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L47-L50)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L30-L50)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L120-L140)
|
||||
|
||||
**章节来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L47-L50)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L30-L50)
|
||||
|
||||
### 用户数据管理组件
|
||||
|
||||
#### SingletonModuleComp.ts - 数据管理中心
|
||||
|
||||
数据管理中心负责维护玩家的全局状态和持久化存储:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SingletonModuleComp {
|
||||
+Object data
|
||||
+Object vmdata
|
||||
+number fight_hero
|
||||
+Array heros
|
||||
+Array monsters
|
||||
+updateGold(amount) boolean
|
||||
+updateFihgtHero(heroId) boolean
|
||||
+addHero(hero_uuid) boolean
|
||||
+updateCloudData() boolean
|
||||
+getCloudData() void
|
||||
}
|
||||
class UserData {
|
||||
+number gold
|
||||
+number exp
|
||||
+number diamond
|
||||
+number meat
|
||||
+number task
|
||||
+number score
|
||||
+number mission
|
||||
}
|
||||
class MissionData {
|
||||
+number mon_num
|
||||
+number hero_num
|
||||
+number fight_time
|
||||
+boolean in_fight
|
||||
+number level
|
||||
+number coin
|
||||
}
|
||||
SingletonModuleComp --> UserData : "管理"
|
||||
SingletonModuleComp --> MissionData : "管理"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L37-L50)
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L37-L87)
|
||||
|
||||
### 初始化系统
|
||||
|
||||
#### Initialize.ts - 系统初始化
|
||||
|
||||
初始化系统负责在游戏启动时加载必要的配置和数据:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([游戏启动]) --> CheckPlatform{"检查平台"}
|
||||
CheckPlatform --> |微信客户端| LoadCloud["加载云端数据"]
|
||||
CheckPlatform --> |其他平台| LoadLocal["加载本地数据"]
|
||||
LoadCloud --> LoginCloud["云端登录"]
|
||||
LoginCloud --> ValidateData{"验证数据"}
|
||||
ValidateData --> |成功| OverrideLocal["覆盖本地数据"]
|
||||
ValidateData --> |失败| UseDefault["使用默认数据"]
|
||||
LoadLocal --> UseDefault
|
||||
OverrideLocal --> InitComplete["初始化完成"]
|
||||
UseDefault --> InitComplete
|
||||
InitComplete --> StartGame["启动游戏"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L80-L140)
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L80-L140)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
任务奖励配置系统的依赖关系如下:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "外部依赖"
|
||||
OopsFramework[Oops Framework]
|
||||
WeChatAPI[微信API]
|
||||
end
|
||||
subgraph "内部模块"
|
||||
Tasks[Tasks配置]
|
||||
GameEvent[游戏事件]
|
||||
SingletonModule[单例模块]
|
||||
MissionComp[任务组件]
|
||||
VictoryComp[胜利组件]
|
||||
end
|
||||
Tasks --> MissionComp
|
||||
GameEvent --> MissionComp
|
||||
SingletonModule --> MissionComp
|
||||
MissionComp --> VictoryComp
|
||||
SingletonModule --> WeChatAPI
|
||||
MissionComp --> OopsFramework
|
||||
VictoryComp --> OopsFramework
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L1-L10)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L15)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L15)
|
||||
|
||||
**章节来源**
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L1-L10)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L15)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 任务配置加载优化
|
||||
|
||||
1. **静态配置缓存**:任务配置作为常量数组,在游戏启动时一次性加载到内存
|
||||
2. **按需查询**:通过ID索引快速定位特定任务配置
|
||||
3. **类型检查**:运行时验证任务配置的完整性
|
||||
|
||||
### 数据更新性能
|
||||
|
||||
1. **批量更新**:将多个数据变更合并为单次更新操作
|
||||
2. **异步处理**:云端数据同步采用异步方式,避免阻塞主线程
|
||||
3. **增量更新**:只更新发生变化的数据项
|
||||
|
||||
### 内存管理
|
||||
|
||||
1. **对象池**:复用任务相关对象,减少垃圾回收压力
|
||||
2. **弱引用**:对临时对象使用弱引用,便于及时回收
|
||||
3. **定时清理**:定期清理过期的任务数据
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 任务奖励未发放
|
||||
|
||||
**问题症状**:任务完成后未获得预期奖励
|
||||
|
||||
**排查步骤**:
|
||||
1. 检查任务配置中的reward字段是否正确设置
|
||||
2. 验证用户数据更新逻辑是否正常执行
|
||||
3. 确认云端同步功能是否工作正常
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 检查任务配置
|
||||
if (!task.reward || task.reward <= 0) {
|
||||
console.error("任务奖励配置错误:", task);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 验证数据更新
|
||||
if (!smc.updateGold(task.reward)) {
|
||||
console.error("奖励发放失败");
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
#### 任务进度不更新
|
||||
|
||||
**问题症状**:任务进度显示异常或不更新
|
||||
|
||||
**排查步骤**:
|
||||
1. 检查GameEvent监听器是否正确注册
|
||||
2. 验证任务完成条件判断逻辑
|
||||
3. 确认UI组件的数据绑定是否正确
|
||||
|
||||
#### 云端数据同步失败
|
||||
|
||||
**问题症状**:本地数据与云端数据不一致
|
||||
|
||||
**排查步骤**:
|
||||
1. 检查网络连接状态
|
||||
2. 验证微信API初始化是否成功
|
||||
3. 查看错误日志获取详细信息
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 云端数据同步检查
|
||||
async function syncDataWithCloud() {
|
||||
try {
|
||||
const result = await smc.updateCloudData();
|
||||
if (!result) {
|
||||
throw new Error("云端数据同步失败");
|
||||
}
|
||||
console.log("数据同步成功");
|
||||
} catch (error) {
|
||||
console.error("数据同步异常:", error);
|
||||
// 回滚到本地数据
|
||||
smc.getCloudData();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L81-L121)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L47-L50)
|
||||
|
||||
## 结论
|
||||
|
||||
《英雄传说》任务奖励配置系统通过模块化的设计和清晰的职责分离,实现了高效、可靠的任务管理功能。系统支持多种任务类型,具备完善的奖励发放机制,并提供了灵活的扩展接口。
|
||||
|
||||
### 系统优势
|
||||
|
||||
1. **配置灵活**:通过Tasks.ts文件集中管理任务配置
|
||||
2. **数据安全**:支持云端和本地双重存储机制
|
||||
3. **性能优化**:采用缓存和异步处理提升响应速度
|
||||
4. **易于维护**:清晰的代码结构和完善的错误处理
|
||||
|
||||
### 扩展建议
|
||||
|
||||
1. **任务类型扩展**:增加更多任务类型如成就任务、挑战任务
|
||||
2. **奖励多样化**:支持多种奖励类型如道具、技能等
|
||||
3. **数据分析**:添加任务完成率统计和玩家行为分析
|
||||
4. **社交功能**:支持任务分享和好友竞争功能
|
||||
|
||||
该系统为游戏提供了坚实的任务管理基础,能够有效支撑游戏的核心玩法和用户粘性。
|
||||
670
.qoder/repowiki/zh/content/奖励系统/奖励配置/奖励提示类型定义.md
Normal file
670
.qoder/repowiki/zh/content/奖励系统/奖励配置/奖励提示类型定义.md
Normal file
@@ -0,0 +1,670 @@
|
||||
# 奖励提示类型定义
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts)
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts)
|
||||
- [Tooltip.ts](file://assets/script/game/skill/Tooltip.ts)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [TooltipTypes常量定义](#tooltiptypes常量定义)
|
||||
3. [类型映射关系](#类型映射关系)
|
||||
4. [UI奖励提示系统架构](#ui奖励提示系统架构)
|
||||
5. [具体类型应用场景](#具体类型应用场景)
|
||||
6. [代码实现分析](#代码实现分析)
|
||||
7. [新增提示类型的配置步骤](#新增提示类型的配置步骤)
|
||||
8. [常见集成问题及解决方案](#常见集成问题及解决方案)
|
||||
9. [性能优化建议](#性能优化建议)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
奖励提示系统是游戏中的重要视觉反馈机制,用于向玩家展示各种奖励效果和状态变化。本文档详细解析了Mission.ts中TooltipTypes常量的定义,说明了各种提示类型对应的数值标识及其在游戏中的实际应用场景,并解释了这些类型如何与UI奖励提示系统(如TooltipCom.ts)协同工作,实现不同奖励效果的视觉反馈。
|
||||
|
||||
## TooltipTypes常量定义
|
||||
|
||||
### 核心常量结构
|
||||
|
||||
TooltipTypes常量定义在Mission.ts文件中,采用简洁的对象字面量形式:
|
||||
|
||||
```typescript
|
||||
export const TooltipTypes = {
|
||||
life:1,
|
||||
health:2,
|
||||
skill:3,
|
||||
crit:4,
|
||||
uskill:5,
|
||||
lvup:6,
|
||||
apup:7,
|
||||
hpup:8,
|
||||
}
|
||||
```
|
||||
|
||||
### 类型定义说明
|
||||
|
||||
| 类型名称 | 数值标识 | 描述 |
|
||||
|---------|---------|------|
|
||||
| life | 1 | 减少生命值提示 |
|
||||
| health | 2 | 增加生命值提示 |
|
||||
| skill | 3 | 技能激活提示 |
|
||||
| crit | 4 | 暴击伤害提示 |
|
||||
| uskill | 5 | 特殊技能效果提示 |
|
||||
| lvup | 6 | 等级提升提示 |
|
||||
| apup | 7 | 攻击力提升提示 |
|
||||
| hpup | 8 | 生命值上限提升提示 |
|
||||
|
||||
**节来源**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L44-L52)
|
||||
|
||||
## 类型映射关系
|
||||
|
||||
### 枚举与数值映射
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[TooltipTypes常量] --> B[life: 1]
|
||||
A --> C[health: 2]
|
||||
A --> D[skill: 3]
|
||||
A --> E[crit: 4]
|
||||
A --> F[uskill: 5]
|
||||
A --> G[lvup: 6]
|
||||
A --> H[apup: 7]
|
||||
A --> I[hpup: 8]
|
||||
B --> J[减少生命值效果]
|
||||
C --> K[增加生命值效果]
|
||||
D --> L[技能激活效果]
|
||||
E --> M[特殊技能效果]
|
||||
F --> N[等级提升效果]
|
||||
G --> O[攻击力提升效果]
|
||||
H --> P[生命值上限提升效果]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L44-L52)
|
||||
|
||||
### 对应的UI元素结构
|
||||
|
||||
每种类型对应不同的UI子节点和显示内容:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[TooltipCom.start] --> B{stype判断}
|
||||
B --> |1 - life| C[loss_life节点]
|
||||
B --> |2 - health| D[add_life节点]
|
||||
B --> |3 - skill| E[skill节点]
|
||||
B --> |4 - crit| F[bloss节点]
|
||||
B --> |5 - uskill| G[uskill节点]
|
||||
B --> |6 - lvup| H[lvup节点]
|
||||
B --> |7 - apup| I[apup节点]
|
||||
B --> |8 - hpup| J[hpup节点]
|
||||
C --> K[显示伤害数值]
|
||||
D --> L[显示恢复数值]
|
||||
E --> M[显示技能名称]
|
||||
F --> N[显示暴击数值]
|
||||
G --> O[显示特殊效果]
|
||||
H --> P[显示升级效果]
|
||||
I --> Q[显示攻击力提升]
|
||||
J --> R[显示生命值提升]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L26-L101)
|
||||
|
||||
## UI奖励提示系统架构
|
||||
|
||||
### 系统组件关系
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Tooltip {
|
||||
+TooltipView : TooltipCom
|
||||
+load(pos, type, value, s_uuid, parent, cd)
|
||||
+destroy()
|
||||
}
|
||||
class TooltipCom {
|
||||
+stype : number
|
||||
+value : string
|
||||
+s_uuid : number
|
||||
+alive_time : number
|
||||
+start()
|
||||
+do_up()
|
||||
+to_destroy()
|
||||
+reset()
|
||||
}
|
||||
class BuffComp {
|
||||
+tooltip(type, value, s_uuid, y)
|
||||
+hp_tip(type, value, s_uuid, y)
|
||||
+show_shield(shield, shield_max)
|
||||
+hp_show(hp, hp_max)
|
||||
+ap_up()
|
||||
+lv_up()
|
||||
}
|
||||
class HeroViewComp {
|
||||
+do_atked(remainingDamage, CAttrs, s_uuid)
|
||||
+check_dodge()
|
||||
+check_crit(crit)
|
||||
+playSkillEffect(skill_id)
|
||||
+showDamage(damage, isCrit, anm)
|
||||
}
|
||||
Tooltip --> TooltipCom : "管理"
|
||||
BuffComp --> Tooltip : "使用"
|
||||
HeroViewComp --> BuffComp : "调用"
|
||||
HeroViewComp --> Tooltip : "直接调用"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Tooltip.ts](file://assets/script/game/skill/Tooltip.ts#L10-L30)
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L12-L25)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L10-L30)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L540-L580)
|
||||
|
||||
### 数据流向
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家操作
|
||||
participant Hero as HeroViewComp
|
||||
participant Buff as BuffComp
|
||||
participant Tooltip as Tooltip
|
||||
participant Com as TooltipCom
|
||||
Player->>Hero : 触发事件(攻击/技能/死亡等)
|
||||
Hero->>Hero : 计算结果
|
||||
Hero->>Buff : 调用tooltip()方法
|
||||
Buff->>Tooltip : 获取Tooltip实体
|
||||
Tooltip->>Tooltip : 加载预制件
|
||||
Tooltip->>Com : 创建TooltipCom实例
|
||||
Com->>Com : 根据stype设置UI
|
||||
Com->>Com : 启动动画和定时器
|
||||
Com->>Com : 自动销毁
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L540-L580)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L185-L210)
|
||||
- [Tooltip.ts](file://assets/script/game/skill/Tooltip.ts#L35-L49)
|
||||
|
||||
**节来源**
|
||||
- [Tooltip.ts](file://assets/script/game/skill/Tooltip.ts#L10-L49)
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L12-L101)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L10-L210)
|
||||
|
||||
## 具体类型应用场景
|
||||
|
||||
### life类型 - 减少生命值提示
|
||||
|
||||
**应用场景:**
|
||||
- 英雄受到伤害时显示
|
||||
- 怪物攻击玩家时显示
|
||||
- 各种负面效果造成的伤害
|
||||
|
||||
**实现特点:**
|
||||
- 使用`loss_life`节点显示
|
||||
- 数值显示在`hp`标签中
|
||||
- 动画效果:从当前位置向上移动
|
||||
- 持续时间:0.5秒后自动销毁
|
||||
|
||||
**节来源**
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L26-L33)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L774)
|
||||
|
||||
### health类型 - 增加生命值提示
|
||||
|
||||
**应用场景:**
|
||||
- 回复技能效果
|
||||
- 治疗道具使用
|
||||
- 生命值恢复效果
|
||||
|
||||
**实现特点:**
|
||||
- 使用`add_life`节点显示
|
||||
- 数值显示在`hp`标签中
|
||||
- 层级索引:110(高于其他提示)
|
||||
- 动画效果:从当前位置向上移动
|
||||
|
||||
**节来源**
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L35-L42)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L540-L550)
|
||||
|
||||
### skill类型 - 技能激活提示
|
||||
|
||||
**应用场景:**
|
||||
- 主要技能激活
|
||||
- 技能冷却完成
|
||||
- 特殊技能触发
|
||||
|
||||
**实现特点:**
|
||||
- 使用`skill`节点显示
|
||||
- 显示技能名称(从SkillSet获取)
|
||||
- 位置偏移:y坐标+30
|
||||
- 持续时间:0.5秒
|
||||
|
||||
**节来源**
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L52-L60)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L730)
|
||||
|
||||
### crit类型 - 暴击伤害提示
|
||||
|
||||
**应用场景:**
|
||||
- 暴击攻击造成伤害
|
||||
- 暴击回复效果
|
||||
- 暴击触发的特殊效果
|
||||
|
||||
**实现特点:**
|
||||
- 使用`bloss`节点显示
|
||||
- 数值显示在`hp`标签中
|
||||
- 层级索引:200(最高层级)
|
||||
- 动画效果:从当前位置向上移动
|
||||
|
||||
**节来源**
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L43-L50)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L771)
|
||||
|
||||
### uskill类型 - 特殊技能效果提示
|
||||
|
||||
**应用场景:**
|
||||
- 闪避成功
|
||||
- 护盾吸收伤害
|
||||
- 其他特殊技能效果
|
||||
|
||||
**实现特点:**
|
||||
- 使用`uskill`节点显示
|
||||
- 直接显示预设文本(如"*吸收*"、"*闪避*")
|
||||
- 位置偏移:y坐标+30
|
||||
- 持续时间:0.5秒
|
||||
|
||||
**节来源**
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L60-L68)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L667)
|
||||
|
||||
### lvup类型 - 等级提升提示
|
||||
|
||||
**应用场景:**
|
||||
- 英雄等级提升
|
||||
- 经验值达到新等级
|
||||
- 系统通知等级变化
|
||||
|
||||
**实现特点:**
|
||||
- 使用`lvup`节点显示
|
||||
- 位置偏移:y坐标-30
|
||||
- 持续时间:0.5秒
|
||||
- (注:当前实现中未显示具体数值)
|
||||
|
||||
**节来源**
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L68-L76)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L110-L115)
|
||||
|
||||
### apup类型 - 攻击力提升提示
|
||||
|
||||
**应用场景:**
|
||||
- 攻击力属性提升
|
||||
- 攻击力增益效果
|
||||
- 装备强化效果
|
||||
|
||||
**实现特点:**
|
||||
- 使用`apup`节点显示
|
||||
- 数值显示在`num`标签中,带"+"前缀
|
||||
- 位置偏移:y坐标-60
|
||||
- 持续时间:0.5秒
|
||||
|
||||
**节来源**
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L76-L84)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L115-L120)
|
||||
|
||||
### hpup类型 - 生命值上限提升提示
|
||||
|
||||
**应用场景:**
|
||||
- 生命值上限增加
|
||||
- 生命值成长效果
|
||||
- 生命值相关增益
|
||||
|
||||
**实现特点:**
|
||||
- 使用`hpup`节点显示
|
||||
- 数值显示在`num`标签中,带"+"前缀
|
||||
- 位置偏移:y坐标-60
|
||||
- 持续时间:0.5秒
|
||||
|
||||
**节来源**
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L84-L92)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L120-L125)
|
||||
|
||||
## 代码实现分析
|
||||
|
||||
### TooltipCom核心逻辑
|
||||
|
||||
TooltipCom组件负责具体的UI显示逻辑,其核心switch语句处理不同类型:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[TooltipCom.start] --> B[接收stype参数]
|
||||
B --> C{switch(stype)}
|
||||
C --> |1| D[life类型处理]
|
||||
C --> |2| E[health类型处理]
|
||||
C --> |3| F[skill类型处理]
|
||||
C --> |4| G[crit类型处理]
|
||||
C --> |5| H[uskill类型处理]
|
||||
C --> |6| I[lvup类型处理]
|
||||
C --> |7| J[apup类型处理]
|
||||
C --> |8| K[hpup类型处理]
|
||||
D --> L[设置位置和层级]
|
||||
D --> M[显示loss_life节点]
|
||||
D --> N[设置数值文本]
|
||||
D --> O[启动定时器销毁]
|
||||
E --> P[设置层级110]
|
||||
E --> Q[显示add_life节点]
|
||||
E --> R[设置数值文本]
|
||||
E --> S[启动定时器销毁]
|
||||
F --> T[显示skill节点]
|
||||
F --> U[设置技能名称]
|
||||
F --> V[调整位置]
|
||||
F --> W[启动定时器销毁]
|
||||
G --> X[设置层级200]
|
||||
G --> Y[显示bloss节点]
|
||||
G --> Z[设置数值文本]
|
||||
G --> AA[启动定时器销毁]
|
||||
H --> BB[显示uskill节点]
|
||||
H --> CC[设置预设文本]
|
||||
H --> DD[调整位置]
|
||||
H --> EE[启动定时器销毁]
|
||||
I --> FF[显示lvup节点]
|
||||
I --> GG[调整位置]
|
||||
I --> HH[启动定时器销毁]
|
||||
J --> II[显示apup节点]
|
||||
J --> JJ[设置带+的数值]
|
||||
J --> KK[调整位置]
|
||||
J --> LL[启动定时器销毁]
|
||||
K --> MM[显示hpup节点]
|
||||
K --> NN[设置带+的数值]
|
||||
K --> OO[调整位置]
|
||||
K --> PP[启动定时器销毁]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TooltipCom.ts](file://assets/script/game/skill/TooltipCom.ts#L26-L101)
|
||||
|
||||
### Tooltip加载流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 调用方
|
||||
participant Tooltip as Tooltip实体
|
||||
participant ResMgr as 资源管理器
|
||||
participant Prefab as 提示预制件
|
||||
participant Com as TooltipCom组件
|
||||
Client->>Tooltip : load(pos, type, value, s_uuid, parent)
|
||||
Tooltip->>ResMgr : 获取"game/skill/buff/tooltip"预制件
|
||||
ResMgr-->>Tooltip : 返回Prefab实例
|
||||
Tooltip->>Prefab : instantiate(prefab)
|
||||
Prefab-->>Tooltip : 返回Node实例
|
||||
Tooltip->>Tooltip : 设置父节点和位置
|
||||
Tooltip->>Tooltip : 检查父节点缩放
|
||||
Tooltip->>Com : 获取TooltipCom组件
|
||||
Tooltip->>Com : 设置stype、value、s_uuid、alive_time
|
||||
Tooltip->>Tooltip : 添加到实体
|
||||
Tooltip-->>Client : 完成加载
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Tooltip.ts](file://assets/script/game/skill/Tooltip.ts#L35-L49)
|
||||
|
||||
### BuffComp工具方法
|
||||
|
||||
BuffComp提供了两个主要的工具方法来简化Tooltip的使用:
|
||||
|
||||
#### tooltip()方法
|
||||
- 通用提示方法
|
||||
- 参数:type(类型)、value(数值)、s_uuid(技能UUID)、y(垂直偏移)
|
||||
- 位置计算:基于节点的相对位置
|
||||
|
||||
#### hp_tip()方法
|
||||
- 生命值相关提示专用方法
|
||||
- 参数:type(类型)、value(数值)、s_uuid(技能UUID)、y(垂直偏移)
|
||||
- 位置计算:基于节点高度的绝对位置
|
||||
|
||||
**节来源**
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L185-L210)
|
||||
|
||||
## 新增提示类型的配置步骤
|
||||
|
||||
### 步骤1:修改TooltipTypes常量
|
||||
|
||||
在Mission.ts中添加新的类型定义:
|
||||
|
||||
```typescript
|
||||
export const TooltipTypes = {
|
||||
// ... 现有类型
|
||||
newType: 9, // 新增类型,使用下一个可用数值
|
||||
}
|
||||
```
|
||||
|
||||
### 步骤2:更新TooltipCom处理逻辑
|
||||
|
||||
在TooltipCom.ts的switch语句中添加新的case分支:
|
||||
|
||||
```typescript
|
||||
case TooltipTypes.newType:
|
||||
this.node.getChildByName("newType").getChildByName("value").getComponent(Label).string = this.value;
|
||||
this.node.getChildByName("newType").active = true;
|
||||
this.node.setPosition(v3(this.node.position.x, this.node.position.y + offset));
|
||||
this.scheduleOnce(() => {
|
||||
this.ent.destroy()
|
||||
}, this.alive_time);
|
||||
break
|
||||
```
|
||||
|
||||
### 步骤3:创建对应的UI节点
|
||||
|
||||
在提示预制件中添加新的UI节点:
|
||||
- 在Canvas下创建名为`newType`的子节点
|
||||
- 添加必要的子节点(如数值显示标签)
|
||||
- 设置适当的层级和初始状态
|
||||
|
||||
### 步骤4:测试和验证
|
||||
|
||||
1. **功能测试**:确保新类型能够正确显示
|
||||
2. **层级测试**:验证显示层级是否符合预期
|
||||
3. **动画测试**:确认动画效果正常
|
||||
4. **性能测试**:检查是否存在性能问题
|
||||
|
||||
### 注意事项
|
||||
|
||||
1. **数值唯一性**:确保每个类型的数值都是唯一的
|
||||
2. **层级管理**:合理设置显示层级,避免遮挡
|
||||
3. **资源管理**:及时销毁不需要的提示对象
|
||||
4. **兼容性**:确保新类型与现有系统兼容
|
||||
5. **国际化**:如果支持多语言,考虑文本本地化
|
||||
|
||||
## 常见集成问题及解决方案
|
||||
|
||||
### 问题1:提示显示位置不正确
|
||||
|
||||
**症状**:提示出现在错误的位置
|
||||
|
||||
**原因**:
|
||||
- 父节点变换影响
|
||||
- 缩放比例问题
|
||||
- 坐标系转换错误
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 在Tooltip.ts中已处理
|
||||
if(parent.scale.x < 0){
|
||||
node.setScale(-node.scale.x, node.scale.y, 0);
|
||||
}
|
||||
```
|
||||
|
||||
### 问题2:提示层级混乱
|
||||
|
||||
**症状**:某些提示被其他UI元素遮挡
|
||||
|
||||
**原因**:
|
||||
- 层级索引设置不当
|
||||
- 动态层级管理缺失
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 在TooltipCom.ts中已处理
|
||||
case TooltipTypes.health:
|
||||
this.node.setSiblingIndex(110); // 明确设置层级
|
||||
break
|
||||
```
|
||||
|
||||
### 问题3:提示消失过快或过慢
|
||||
|
||||
**症状**:提示持续时间不符合预期
|
||||
|
||||
**原因**:
|
||||
- alive_time设置不当
|
||||
- 销毁时机错误
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 在Tooltip.ts中统一设置
|
||||
sv.alive_time = 0.5; // 统一的持续时间
|
||||
```
|
||||
|
||||
### 问题4:内存泄漏
|
||||
|
||||
**症状**:长时间运行后出现内存占用过高
|
||||
|
||||
**原因**:
|
||||
- 提示对象未正确销毁
|
||||
- 事件监听器未清理
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 在TooltipCom.ts中确保正确销毁
|
||||
scheduleOnce(() => {
|
||||
this.ent.destroy()
|
||||
}, this.alive_time);
|
||||
```
|
||||
|
||||
### 问题5:动画效果异常
|
||||
|
||||
**症状**:提示动画不流畅或不正确
|
||||
|
||||
**原因**:
|
||||
- Tween动画配置错误
|
||||
- 更新频率不匹配
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 在TooltipCom.ts中使用正确的动画配置
|
||||
tween(this.node).to(
|
||||
this.alive_time,
|
||||
{ position: v3(this.node.position.x, this.node.position.y + 60) },
|
||||
{
|
||||
onComplete: () => { this.ent.destroy() },
|
||||
easing: "linear"
|
||||
}
|
||||
).start()
|
||||
```
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
### 1. 对象池化
|
||||
|
||||
对于频繁使用的提示类型,可以考虑使用对象池:
|
||||
|
||||
```typescript
|
||||
class TooltipPool {
|
||||
private pool: TooltipCom[] = [];
|
||||
|
||||
public acquire(): TooltipCom {
|
||||
if (this.pool.length > 0) {
|
||||
return this.pool.pop()!;
|
||||
}
|
||||
return new TooltipCom();
|
||||
}
|
||||
|
||||
public release(tooltip: TooltipCom): void {
|
||||
// 重置状态
|
||||
tooltip.reset();
|
||||
this.pool.push(tooltip);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 批量处理
|
||||
|
||||
对于连续的相同类型提示,可以考虑批量处理:
|
||||
|
||||
```typescript
|
||||
private damageQueue: DamageInfo[] = [];
|
||||
|
||||
public showDamage(damage: number, isCrit: boolean, anm: string = "atked") {
|
||||
this.damageQueue.push({
|
||||
damage,
|
||||
isCrit,
|
||||
delay: this.damageInterval,
|
||||
anm
|
||||
});
|
||||
}
|
||||
|
||||
private processDamageQueue() {
|
||||
if (this.isProcessingDamage || this.damageQueue.length === 0) return;
|
||||
|
||||
this.isProcessingDamage = true;
|
||||
const damageInfo = this.damageQueue.shift()!;
|
||||
|
||||
this.showDamageImmediate(damageInfo.damage, damageInfo.isCrit, damageInfo.anm);
|
||||
|
||||
this.scheduleOnce(() => {
|
||||
this.isProcessingDamage = false;
|
||||
}, this.damageInterval);
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 条件渲染
|
||||
|
||||
对于某些不常用的提示类型,可以考虑延迟加载:
|
||||
|
||||
```typescript
|
||||
private cachedNodes: Map<number, Node> = new Map();
|
||||
|
||||
private getCachedNode(type: number): Node {
|
||||
if (!this.cachedNodes.has(type)) {
|
||||
// 延迟加载UI节点
|
||||
const node = this.createNodeForType(type);
|
||||
this.cachedNodes.set(type, node);
|
||||
}
|
||||
return this.cachedNodes.get(type)!;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 异步加载
|
||||
|
||||
对于大型UI资源,可以考虑异步加载:
|
||||
|
||||
```typescript
|
||||
async loadTooltipAsync(type: number, pos: Vec3, value: string, s_uuid: number, parent: any) {
|
||||
// 异步加载UI资源
|
||||
const prefab = await oops.res.getAsync("game/skill/buff/tooltip", Prefab);
|
||||
// 继续后续逻辑...
|
||||
}
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
奖励提示系统是游戏体验的重要组成部分,通过TooltipTypes常量定义的八种提示类型,系统能够有效地向玩家传达各种游戏状态和奖励信息。
|
||||
|
||||
### 关键特性
|
||||
|
||||
1. **类型化设计**:通过数值化的类型系统,实现了清晰的功能分类
|
||||
2. **灵活的UI适配**:每种类型都有专门的UI节点和显示逻辑
|
||||
3. **良好的扩展性**:新增类型只需遵循既定的配置步骤
|
||||
4. **完善的生命周期管理**:自动化的创建和销毁机制
|
||||
5. **丰富的应用场景**:覆盖了游戏中的各种奖励和状态变化
|
||||
|
||||
### 最佳实践
|
||||
|
||||
1. **合理使用类型**:根据具体场景选择合适的提示类型
|
||||
2. **注意层级管理**:确保提示不会被其他UI元素遮挡
|
||||
3. **控制显示时机**:避免过多的提示同时显示
|
||||
4. **关注性能表现**:对于高频使用的提示类型进行优化
|
||||
5. **保持一致性**:确保相似效果使用相同的提示类型
|
||||
|
||||
通过深入理解和正确使用这个奖励提示系统,开发者可以为玩家创造更加丰富和直观的游戏体验。
|
||||
195
.qoder/repowiki/zh/content/奖励系统/奖励配置/奖励配置.md
Normal file
195
.qoder/repowiki/zh/content/奖励系统/奖励配置/奖励配置.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# 奖励配置
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts)
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [奖励系统概述](#奖励系统概述)
|
||||
2. [波次常量与奖励触发时机](#波次常量与奖励触发时机)
|
||||
3. [任务系统与奖励配置](#任务系统与奖励配置)
|
||||
4. [奖励类型的数据结构](#奖励类型的数据结构)
|
||||
5. [属性提升与技能升级奖励](#属性提升与技能升级奖励)
|
||||
6. [配置数据的加载与使用](#配置数据的加载与使用)
|
||||
7. [奖励配置的修改与扩展](#奖励配置的修改与扩展)
|
||||
|
||||
## 奖励系统概述
|
||||
|
||||
奖励系统是游戏核心机制的重要组成部分,通过配置文件定义各类奖励的参数和触发条件。系统主要由`Mission.ts`中的`FightSet`枚举和`TooltipTypes`常量、`Tasks.ts`中的任务配置以及`HeroAttrs.ts`中的属性定义共同构成。奖励系统不仅包括任务完成后的金币、经验奖励,还涵盖了战斗中属性提升、技能升级、装备获取等多种奖励类型。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L1-L59)
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L1-L29)
|
||||
|
||||
## 波次常量与奖励触发时机
|
||||
|
||||
波次常量定义了游戏中各种事件的触发时机,直接影响奖励的发放。`FightSet`枚举中的常量精确控制了伙伴、BOSS、装备和技能的登场波次,这些波次是奖励触发的关键节点。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class FightSet {
|
||||
+FRIEND_WAVE_UP = 3 : 伙伴登场波次
|
||||
+BOSS_WAVE_UP_1 = 3 : BOSS登场波次
|
||||
+BOSS_WAVE_UP_2 = 5 : BOSS登场波次
|
||||
+BOSS_WAVE_UP_3 = 7 : BOSS登场波次
|
||||
+EQUIP_WAVE_UP_1 = 4 : 装备登场波次
|
||||
+EQUIP_WAVE_UP_2 = 6 : 装备登场波次
|
||||
+EQUIP_WAVE_UP_3 = 8 : 装备登场波次
|
||||
+SKILL_WAVE_UP_1 = 2 : 技能登场波次
|
||||
+SKILL_WAVE_UP_2 = 5 : 技能登场波次
|
||||
+SKILL_WAVE_UP_3 = 7 : 技能登场波次
|
||||
+MON_WAVE_TIME = 10 : 怪物波次时间
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L1-L20)
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L1-L35)
|
||||
|
||||
## 任务系统与奖励配置
|
||||
|
||||
任务系统通过`Tasks.ts`文件中的`Tasks`常量定义,每个任务包含ID、名称、描述和奖励等属性。任务完成后,系统会根据配置发放相应的奖励。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Tasks {
|
||||
+id : number
|
||||
+name : string
|
||||
+description : string
|
||||
+reward : number
|
||||
+type? : number
|
||||
}
|
||||
class Speeks {
|
||||
+randomSpeek() : string[]
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L1-L29)
|
||||
|
||||
**Section sources**
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L1-L29)
|
||||
|
||||
## 奖励类型的数据结构
|
||||
|
||||
奖励系统定义了多种奖励类型,每种类型都有其特定的数据结构。`TooltipTypes`常量定义了各种奖励的类型标识,用于在UI中显示相应的奖励效果。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class TooltipTypes {
|
||||
+life = 1 : 生命值变化
|
||||
+health = 2 : 治疗效果
|
||||
+skill = 3 : 技能获得
|
||||
+crit = 4 : 暴击提示
|
||||
+uskill = 5 : 使用技能
|
||||
+lvup = 6 : 升级提示
|
||||
+apup = 7 : 攻击力提升
|
||||
+hpup = 8 : 生命值提升
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L50-L59)
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L50-L59)
|
||||
|
||||
## 属性提升与技能升级奖励
|
||||
|
||||
属性提升和技能升级奖励通过`HeroAttrs.ts`文件中的`Attrs`枚举和`AttrsType`配置表定义。系统区分数值型和百分比型属性,确保奖励计算的准确性。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Attrs {
|
||||
+HP_MAX = 0 : 最大生命值
|
||||
+MP_MAX = 1 : 最大魔法值
|
||||
+SHIELD_MAX = 2 : 最大护盾值
|
||||
+AP = 10 : 攻击力
|
||||
+MAP = 11 : 魔法攻击力
|
||||
+CRITICAL = 30 : 暴击率
|
||||
+CRITICAL_DMG = 31 : 暴击伤害
|
||||
+GOLD_GAIN = 65 : 金币获取
|
||||
+EXP_GAIN = 64 : 经验获取
|
||||
}
|
||||
class BType {
|
||||
+VALUE = 0 : 数值型
|
||||
+RATIO = 1 : 百分比型
|
||||
}
|
||||
class AttrsType {
|
||||
+[Attrs.HP_MAX] : BType.VALUE
|
||||
+[Attrs.AP] : BType.VALUE
|
||||
+[Attrs.CRITICAL] : BType.RATIO
|
||||
+[Attrs.GOLD_GAIN] : BType.RATIO
|
||||
}
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L100)
|
||||
|
||||
**Section sources**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L100)
|
||||
|
||||
## 配置数据的加载与使用
|
||||
|
||||
配置数据通过单例模式的`SingletonModuleComp`进行管理,确保数据在游戏运行时的一致性和可访问性。奖励数据在战斗结束时通过`VictoryComp`组件显示给玩家。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MissionComp as MissionComp
|
||||
participant SingletonModule as SingletonModuleComp
|
||||
participant VictoryComp as VictoryComp
|
||||
MissionComp->>SingletonModule : 更新游戏数据(vmdata)
|
||||
SingletonModule->>MissionComp : 返回数据更新结果
|
||||
MissionComp->>VictoryComp : 传递奖励数据和游戏数据
|
||||
VictoryComp->>Player : 显示胜利界面和奖励
|
||||
VictoryComp->>SingletonModule : 更新金币等永久数据
|
||||
SingletonModule->>VictoryComp : 返回数据更新结果
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L70)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L74)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L194)
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L70)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L74)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L194)
|
||||
|
||||
## 奖励配置的修改与扩展
|
||||
|
||||
奖励配置可以通过修改相应的TS文件进行调整和扩展。开发者可以调整奖励权重、添加新的奖励配置项,或创建新的奖励类型。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始修改奖励配置]) --> ModifyMission["修改Mission.ts中的FightSet常量"]
|
||||
ModifyMission --> ModifyTasks["修改Tasks.ts中的任务奖励"]
|
||||
ModifyTasks --> ModifyHeroAttrs["修改HeroAttrs.ts中的属性定义"]
|
||||
ModifyHeroAttrs --> Test["测试配置变更"]
|
||||
Test --> Validate["验证奖励效果"]
|
||||
Validate --> Deploy["部署到游戏"]
|
||||
Deploy --> End([完成])
|
||||
ModifyMission --> AddNewReward["添加新的奖励类型到TooltipTypes"]
|
||||
AddNewReward --> UpdateUI["更新UI显示逻辑"]
|
||||
UpdateUI --> Test
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L1-L59)
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L1-L29)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L546)
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L1-L59)
|
||||
- [Tasks.ts](file://assets/script/game/common/config/Tasks.ts#L1-L29)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L546)
|
||||
343
.qoder/repowiki/zh/content/奖励系统/奖励配置/战斗奖励配置.md
Normal file
343
.qoder/repowiki/zh/content/奖励系统/奖励配置/战斗奖励配置.md
Normal file
@@ -0,0 +1,343 @@
|
||||
# 战斗奖励配置
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [战斗奖励机制概述](#战斗奖励机制概述)
|
||||
2. [FightSet枚举常量详解](#fightset枚举常量详解)
|
||||
3. [奖励触发波次机制](#奖励触发波次机制)
|
||||
4. [奖励数值影响参数](#奖励数值影响参数)
|
||||
5. [奖励类型配置逻辑](#奖励类型配置逻辑)
|
||||
6. [配置加载与运行时访问](#配置加载与运行时访问)
|
||||
7. [常见问题排查](#常见问题排查)
|
||||
8. [代码示例](#代码示例)
|
||||
|
||||
## 战斗奖励机制概述
|
||||
|
||||
本系统基于Mission.ts文件中的FightSet枚举实现战斗奖励触发机制,通过波次常量控制奖励生成时机,结合参数配置实现多样化的奖励效果。系统通过事件驱动模式,在特定战斗阶段触发相应的奖励逻辑,包括属性提升、金币获取和技能解锁等。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L33)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L0-L69)
|
||||
|
||||
## FightSet枚举常量详解
|
||||
|
||||
FightSet枚举定义了战斗中的关键配置常量,主要分为三类:波次触发常量、数值影响常量和资源类型常量。
|
||||
|
||||
### 波次触发常量
|
||||
|
||||
| 常量名称 | 数值 | 业务含义 |
|
||||
|---------|------|---------|
|
||||
| FRIEND_WAVE_UP | 3 | 伙伴登场的战斗波次 |
|
||||
| BOSS_WAVE_UP_1 | 3 | 第一波BOSS登场波次 |
|
||||
| BOSS_WAVE_UP_2 | 5 | 第二波BOSS登场波次 |
|
||||
| BOSS_WAVE_UP_3 | 7 | 第三波BOSS登场波次 |
|
||||
| EQUIP_WAVE_UP_1 | 4 | 第一波装备登场波次 |
|
||||
| EQUIP_WAVE_UP_2 | 6 | 第二波装备登场波次 |
|
||||
| EQUIP_WAVE_UP_3 | 8 | 第三波装备登场波次 |
|
||||
| SKILL_WAVE_UP_1 | 2 | 第一波技能登场波次 |
|
||||
| SKILL_WAVE_UP_2 | 5 | 第二波技能登场波次 |
|
||||
| SKILL_WAVE_UP_3 | 7 | 第三波技能登场波次 |
|
||||
|
||||
### 数值影响常量
|
||||
|
||||
| 常量名称 | 数值 | 业务含义 |
|
||||
|---------|------|---------|
|
||||
| ATK_ADD_COUNT | 4 | 伙伴攻击力增加基数 |
|
||||
| ATK_ADD_GLOD | 1 | 金币增加基数 |
|
||||
| CRIT_DAMAGE | 50 | 暴击伤害百分比 |
|
||||
| DOUBLE_ATK_RATE | 100 | 额外攻击默认概率 |
|
||||
| ATKED_TO_POWER | 15 | 被攻击涨能量值 |
|
||||
| ATK_TO_POWER | 10 | 攻击涨能量值 |
|
||||
|
||||
### 资源类型常量
|
||||
|
||||
| 常量名称 | 数值 | 业务含义 |
|
||||
|---------|------|---------|
|
||||
| GREEN_GOLD | 1 | 绿色金币类型 |
|
||||
| BLUE_GOLD | 2 | 蓝色金币类型 |
|
||||
| PURPLE_GOLD | 3 | 紫色金币类型 |
|
||||
| ORANGE_GOLD | 4 | 橙色金币类型 |
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||||
|
||||
## 奖励触发波次机制
|
||||
|
||||
战斗奖励的触发与波次系统紧密关联,通过FightSet中的波次常量控制不同奖励类型的出现时机。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MissionComp as MissionComp
|
||||
participant MissionMonComp as MissionMonComp
|
||||
participant RogueConfig as RogueConfig
|
||||
MissionComp->>MissionMonComp : dispatchEvent(FightStart)
|
||||
MissionMonComp->>RogueConfig : getStageType(stage,level)
|
||||
RogueConfig-->>MissionMonComp : 返回关卡类型
|
||||
MissionMonComp->>RogueConfig : getStageMonsterConfigs()
|
||||
RogueConfig-->>MissionMonComp : 返回怪物配置
|
||||
MissionMonComp->>MissionMonComp : generateMonstersFromStageConfig()
|
||||
MissionMonComp->>MissionMonComp : processRandomEvent()
|
||||
alt 事件触发
|
||||
MissionMonComp->>MissionMonComp : TREASURE事件
|
||||
MissionMonComp->>MissionComp : 增加金币奖励
|
||||
end
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L66-L116)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L102-L136)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L129-L168)
|
||||
|
||||
### 波次与地图系统联动
|
||||
|
||||
波次常量与地图系统通过关卡配置实现联动,具体关系如下:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始战斗] --> B{判断关卡类型}
|
||||
B --> |普通关卡| C[按波次生成怪物]
|
||||
B --> |精英关卡| D[增加精英怪物]
|
||||
B --> |BOSS关卡| E[生成BOSS怪物]
|
||||
B --> |事件关卡| F[触发随机事件]
|
||||
F --> G{随机事件类型}
|
||||
G --> |宝箱事件| H[增加金币奖励]
|
||||
G --> |陷阱事件| I[对玩家造成伤害]
|
||||
G --> |增益事件| J[给予临时增益]
|
||||
G --> |减益事件| K[给予临时减益]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L86-L132)
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L135-L169)
|
||||
|
||||
## 奖励数值影响参数
|
||||
|
||||
奖励数值通过FightSet中的参数进行配置,影响各种奖励效果的强度。
|
||||
|
||||
### 攻击力与金币影响机制
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class FightSet {
|
||||
+FRIEND_WAVE_UP : number
|
||||
+BOSS_WAVE_UP_1 : number
|
||||
+EQUIP_WAVE_UP_1 : number
|
||||
+SKILL_WAVE_UP_1 : number
|
||||
+ATK_ADD_COUNT : number
|
||||
+ATK_ADD_GLOD : number
|
||||
+CRIT_DAMAGE : number
|
||||
}
|
||||
class HeroViewComp {
|
||||
+Attrs : number[]
|
||||
+base_ap : number
|
||||
+hp : number
|
||||
}
|
||||
class TalComp {
|
||||
+FStats : Stats
|
||||
+checkTrigger(tal) : boolean
|
||||
+doTalEffect(tal) : void
|
||||
}
|
||||
FightSet --> HeroViewComp : 影响属性计算
|
||||
FightSet --> TalComp : 影响天赋触发
|
||||
TalComp --> HeroViewComp : 修改英雄属性
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L0-L22)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L102-L139)
|
||||
|
||||
### 能量增长参数
|
||||
|
||||
| 参数 | 数值 | 触发条件 |
|
||||
|------|------|---------|
|
||||
| ATKED_TO_POWER | 15 | 被攻击时增长能量 |
|
||||
| ATK_TO_POWER | 10 | 攻击时增长能量 |
|
||||
| CRIT_TO_POWER | 15 | 暴击时增长能量 |
|
||||
| DODGE_TO_POWER | 15 | 闪避时增长能量 |
|
||||
|
||||
这些参数在英雄战斗过程中实时影响能量值的增长,进而影响技能释放频率。
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L582-L622)
|
||||
|
||||
## 奖励类型配置逻辑
|
||||
|
||||
系统实现了多种奖励类型,每种类型都有特定的配置逻辑和触发条件。
|
||||
|
||||
### 属性提升奖励
|
||||
|
||||
属性提升通过天赋系统实现,当满足特定条件时触发:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[战斗开始] --> B{检查天赋触发条件}
|
||||
B --> |等级提升| C[触发LEVEL_UP天赋]
|
||||
B --> |行动次数| D[触发ACTION_COUNT天赋]
|
||||
B --> |技能使用| E[触发SKILL_COUNT天赋]
|
||||
B --> |受到伤害| F[触发DAMAGE_COUNT天赋]
|
||||
C --> G[执行天赋效果]
|
||||
D --> G
|
||||
E --> G
|
||||
F --> G
|
||||
G --> H[属性提升]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L134-L169)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L281-L316)
|
||||
|
||||
### 金币获取奖励
|
||||
|
||||
金币获取主要通过两种方式实现:
|
||||
|
||||
1. **战斗掉落**:怪物死亡时随机掉落金币
|
||||
2. **事件奖励**:事件关卡触发宝箱事件获得固定金币
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Mon as Monster
|
||||
participant MissionComp as MissionComp
|
||||
participant TopComp as TopComp
|
||||
Mon->>MissionComp : dispatchEvent(MonDead)
|
||||
MissionComp->>MissionComp : do_mon_dead()
|
||||
MissionComp->>MissionComp : 增加金币
|
||||
MissionComp->>TopComp : dispatchEvent(GOLD_UPDATE)
|
||||
TopComp->>TopComp : 更新金币UI显示
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L32-L70)
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L0-L28)
|
||||
|
||||
### 技能解锁奖励
|
||||
|
||||
技能解锁通过技能波次常量控制,在特定波次解锁新技能:
|
||||
|
||||
- SKILL_WAVE_UP_1=2:第二波解锁第一个技能
|
||||
- SKILL_WAVE_UP_2=5:第五波解锁第二个技能
|
||||
- SKILL_WAVE_UP_3=7:第七波解锁第三个技能
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L102-L139)
|
||||
|
||||
## 配置加载与运行时访问
|
||||
|
||||
系统通过模块化方式加载和访问配置数据,确保配置的可维护性和可扩展性。
|
||||
|
||||
### 配置加载流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[游戏启动] --> B[加载Mission.ts配置]
|
||||
B --> C[初始化FightSet常量]
|
||||
C --> D[加载地图配置]
|
||||
D --> E[初始化关卡数据]
|
||||
E --> F[战斗开始]
|
||||
F --> G[运行时访问配置]
|
||||
G --> H[根据波次触发奖励]
|
||||
```
|
||||
|
||||
### 运行时访问路径
|
||||
|
||||
配置数据在运行时通过以下路径访问:
|
||||
|
||||
- FightSet常量:`import { FightSet } from "../common/config/Mission"`
|
||||
- 关卡配置:`import { getStageMonsterConfigs } from "./RogueConfig"`
|
||||
- 事件配置:`import { getRandomEvent } from "./RogueConfig"`
|
||||
|
||||
**Section sources**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L0-L33)
|
||||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L246-L281)
|
||||
|
||||
## 常见问题排查
|
||||
|
||||
### 奖励未触发的可能原因
|
||||
|
||||
1. **波次配置错误**
|
||||
- 检查FightSet中波次常量设置是否正确
|
||||
- 确认波次值与实际战斗进度匹配
|
||||
|
||||
2. **事件监听缺失**
|
||||
- 确保MissionComp正确监听FightStart事件
|
||||
- 检查事件派发是否正常
|
||||
|
||||
3. **配置加载失败**
|
||||
- 验证Mission.ts文件是否正确导入
|
||||
- 检查路径引用是否正确
|
||||
|
||||
4. **条件未满足**
|
||||
- 天赋触发条件未达到
|
||||
- 关卡类型不符合奖励条件
|
||||
|
||||
### 调试方法
|
||||
|
||||
1. **日志输出**
|
||||
- 在关键节点添加console.log输出
|
||||
- 监控波次变化和事件触发
|
||||
|
||||
2. **断点调试**
|
||||
- 在MissionMonComp的do_mon_wave方法设置断点
|
||||
- 检查怪物生成和事件处理逻辑
|
||||
|
||||
3. **配置验证**
|
||||
- 确认FightSet常量值在合理范围内
|
||||
- 验证关卡配置与波次设置的匹配性
|
||||
|
||||
**Section sources**
|
||||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L69-L105)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L114-L150)
|
||||
|
||||
## 代码示例
|
||||
|
||||
### 调整奖励触发波次
|
||||
|
||||
```typescript
|
||||
// 修改技能登场波次
|
||||
export enum FightSet {
|
||||
SKILL_WAVE_UP_1 = 1, // 提前到第一波
|
||||
SKILL_WAVE_UP_2 = 4, // 提前到第四波
|
||||
SKILL_WAVE_UP_3 = 6, // 提前到第六波
|
||||
// 其他配置...
|
||||
}
|
||||
```
|
||||
|
||||
### 修改奖励数值
|
||||
|
||||
```typescript
|
||||
// 增加金币奖励数值
|
||||
export enum FightSet {
|
||||
ATK_ADD_GLOD = 2, // 金币增加从1提升到2
|
||||
CRIT_DAMAGE = 75, // 暴击伤害从50%提升到75%
|
||||
// 其他配置...
|
||||
}
|
||||
```
|
||||
|
||||
### 添加新的奖励类型
|
||||
|
||||
```typescript
|
||||
// 在Mission.ts中添加新的奖励常量
|
||||
export enum FightSet {
|
||||
NEW_REWARD_TYPE = 5, // 新的奖励类型
|
||||
REWARD_VALUE = 100, // 奖励数值
|
||||
// 其他配置...
|
||||
}
|
||||
```
|
||||
|
||||
**Section sources**
|
||||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L0-L74)
|
||||
268
.qoder/repowiki/zh/content/开发指南.md
Normal file
268
.qoder/repowiki/zh/content/开发指南.md
Normal file
@@ -0,0 +1,268 @@
|
||||
# 开发指南
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [README.md](file://doc/using.md)
|
||||
- [using.md](file://doc/using.md)
|
||||
- [tsconfig.json](file://tsconfig.json)
|
||||
- [package.json](file://package.json)
|
||||
- [cankao.md](file://assets/script/cankao.md)
|
||||
- [todo.md](file://assets/script/todo.md)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [builder.json](file://settings/v2/packages/builder.json)
|
||||
- [deploy.md](file://build-templates/wechatgame/cloud_functions/cocos_cloud/deploy.md)
|
||||
- [cloud package.json](file://build-templates/wechatgame/cloud_functions/cocos_cloud/package.json)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [环境搭建](#环境搭建)
|
||||
2. [代码规范与配置](#代码规范与配置)
|
||||
3. [调试技巧](#调试技巧)
|
||||
4. [项目维护流程](#项目维护流程)
|
||||
5. [常见问题解决方案](#常见问题解决方案)
|
||||
6. [性能优化建议](#性能优化建议)
|
||||
|
||||
## 环境搭建
|
||||
|
||||
本项目基于 Cocos Creator 引擎开发,采用 Oops Framework 插件架构。以下是详细的开发环境配置步骤:
|
||||
|
||||
### Cocos Creator 版本要求
|
||||
根据 `package.json` 文件中的信息,本项目使用 **Cocos Creator 3.8.6** 版本开发。建议开发者使用相同版本以确保兼容性。
|
||||
|
||||
### 框架安装与更新
|
||||
Oops Framework 以插件形式集成到项目中,位于 `extensions/oops-plugin-framework` 目录。可通过以下命令自动更新至最新版本:
|
||||
|
||||
**Windows 系统**
|
||||
```bash
|
||||
md extensions
|
||||
cd extensions
|
||||
git clone -b master https://gitee.com/dgflash/oops-plugin-framework.git
|
||||
git pull
|
||||
```
|
||||
|
||||
**macOS 系统**
|
||||
```bash
|
||||
mkdir -p extensions
|
||||
cd extensions
|
||||
git clone -b master https://gitee.com/dgflash/oops-plugin-framework.git
|
||||
git pull
|
||||
```
|
||||
|
||||
### 微信开发者工具集成
|
||||
项目已配置微信小游戏平台支持。在构建时选择 "wechatgame" 平台,系统会自动应用 `builder.json` 中的子包压缩设置,确保符合微信小游戏的包大小限制。
|
||||
|
||||
**Section sources**
|
||||
- [package.json](file://package.json#L1-L13)
|
||||
- [using.md](file://doc/using.md#L1-L20)
|
||||
- [builder.json](file://settings/v2/packages/builder.json#L1-L128)
|
||||
|
||||
## 代码规范与配置
|
||||
|
||||
### TypeScript 编译设置
|
||||
`tsconfig.json` 文件定义了项目的 TypeScript 编译选项:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": "./temp/tsconfig.cocos.json",
|
||||
"compilerOptions": {
|
||||
"strict": false,
|
||||
"target": "es2017",
|
||||
"lib": ["es2017", "dom"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **extends**: 继承 Cocos Creator 自动生成的基础配置
|
||||
- **strict**: 关闭严格模式,提供更灵活的类型检查
|
||||
- **target**: 编译目标为 ES2017,确保现代 JavaScript 特性支持
|
||||
- **lib**: 包含 ES2017 和 DOM 类型定义,支持浏览器环境开发
|
||||
|
||||
### 项目依赖管理
|
||||
`package.json` 文件定义了项目的基本信息和依赖:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "pixel_hero",
|
||||
"dependencies": {
|
||||
"crypto-es": "^2.1.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **name**: 项目名称为 "pixel_hero"
|
||||
- **dependencies**: 使用 `crypto-es` 库进行加密操作
|
||||
|
||||
### 云函数配置
|
||||
微信云函数位于 `build-templates/wechatgame/cloud_functions/cocos_cloud` 目录,其 `package.json` 依赖如下:
|
||||
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"wx-server-sdk": "~3.0.1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
该配置确保云函数能够使用微信官方的服务器 SDK 进行数据库操作和用户认证。
|
||||
|
||||
**Section sources**
|
||||
- [tsconfig.json](file://tsconfig.json#L1-L12)
|
||||
- [package.json](file://package.json#L1-L13)
|
||||
- [cloud package.json](file://build-templates/wechatgame/cloud_functions/cocos_cloud/package.json#L1-L15)
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### 启动流程分析
|
||||
`Main.ts` 是游戏的主入口文件,负责初始化核心系统:
|
||||
|
||||
```typescript
|
||||
export class Main extends Root {
|
||||
protected async run() {
|
||||
smc.initialize = ecs.getEntity<Initialize>(Initialize);
|
||||
smc.vmAdd()
|
||||
}
|
||||
|
||||
protected initGui() {
|
||||
oops.gui.init(UIConfigData);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **run()**: 初始化 ECS 实体和单例模块
|
||||
- **initGui()**: 初始化 GUI 系统,加载 UI 配置
|
||||
|
||||
### 单例模块调试
|
||||
`SingletonModuleComp.ts` 提供了全局游戏状态管理,通过 `smc` 全局变量访问:
|
||||
|
||||
```typescript
|
||||
export var smc: SingletonModuleComp = ecs.getSingleton(SingletonModuleComp);
|
||||
```
|
||||
|
||||
该模块包含:
|
||||
- 游戏初始化状态
|
||||
- 地图数据
|
||||
- 用户数据(金币、英雄等)
|
||||
- MVVM 数据绑定
|
||||
|
||||
### 云函数调试
|
||||
`WxCloudApi.ts` 封装了微信云函数调用:
|
||||
|
||||
```typescript
|
||||
public static async login(): Promise<...> {
|
||||
return await wx?.cloud.callFunction({
|
||||
name: 'cocos_cloud',
|
||||
data: { cmd: "login" }
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
调试时可检查:
|
||||
- 云环境 ID 是否正确初始化
|
||||
- 网络连接状态
|
||||
- 云函数返回的错误码
|
||||
|
||||
**Section sources**
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L41)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L195)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L1-L94)
|
||||
|
||||
## 项目维护流程
|
||||
|
||||
### 参考信息管理
|
||||
`cankao.md` 文件包含游戏设计参考数据,主要用于:
|
||||
|
||||
- 角色特性平衡设计
|
||||
- 技能效果参数设定
|
||||
- 游戏数值策划参考
|
||||
|
||||
文件采用 Markdown 表格格式,突出显示核心机制(加粗文本),便于快速查阅。
|
||||
|
||||
### 待办事项管理
|
||||
`todo.md` 文件采用 Markdown 任务列表管理开发进度:
|
||||
|
||||
```markdown
|
||||
- [ ] 整个对战流程制作
|
||||
- [x] cards 展示逻辑修改
|
||||
- [x] 攻击加80%
|
||||
```
|
||||
|
||||
该文件还定义了**装备系统三维度分层模型**:
|
||||
1. **基础值**: 单件装备的初始强度
|
||||
2. **品质系数**: 决定特效能力与成长潜力
|
||||
3. **等级成长系数**: 强化基础值和特效
|
||||
|
||||
此模型为装备系统提供了清晰的设计框架。
|
||||
|
||||
**Section sources**
|
||||
- [cankao.md](file://assets/script/cankao.md#L1-L45)
|
||||
- [todo.md](file://assets/script/todo.md#L1-L110)
|
||||
|
||||
## 常见问题解决方案
|
||||
|
||||
### 构建失败
|
||||
**问题**: 构建时出现资源打包错误
|
||||
**解决方案**:
|
||||
1. 检查 `builder.json` 中的压缩设置
|
||||
2. 确保 `resources` 目录下的资源正确标记
|
||||
3. 清理临时文件后重新构建
|
||||
|
||||
### 云函数部署错误
|
||||
**问题**: `Error: Cannot find module 'wx-server-sdk'`
|
||||
**解决方案**(参考 `deploy.md`):
|
||||
|
||||
1. **安装依赖**
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
2. **验证依赖**
|
||||
```bash
|
||||
ls node_modules/wx-server-sdk
|
||||
```
|
||||
|
||||
3. **重新部署**
|
||||
使用微信开发者工具上传并部署云函数
|
||||
|
||||
4. **检查配置**
|
||||
- 确认云开发环境已初始化
|
||||
- 检查云函数名称一致性
|
||||
- 验证网络连接和 npm 源
|
||||
|
||||
### UI绑定异常
|
||||
**问题**: MVVM 数据绑定失效
|
||||
**解决方案**:
|
||||
1. 确保调用 `vmAdd()` 方法注册数据
|
||||
2. 检查数据字段命名一致性
|
||||
3. 验证 UI 组件的绑定路径
|
||||
|
||||
**Section sources**
|
||||
- [deploy.md](file://build-templates/wechatgame/cloud_functions/cocos_cloud/deploy.md#L1-L32)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L195)
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
### 资源管理
|
||||
- 合理使用 `resources` 目录,避免资源冗余
|
||||
- 利用 Cocos Creator 的自动图集功能减少 Draw Call
|
||||
- 对非关键资源采用异步加载
|
||||
|
||||
### 代码优化
|
||||
- 减少 `update()` 方法中的复杂计算
|
||||
- 复用对象实例,避免频繁创建销毁
|
||||
- 使用对象池管理频繁创建的节点
|
||||
|
||||
### 网络优化
|
||||
- 批量处理云函数调用,减少网络请求次数
|
||||
- 对游戏数据进行增量同步而非全量覆盖
|
||||
- 在弱网环境下提供本地缓存机制
|
||||
|
||||
### 构建优化
|
||||
- 合理划分资源包,利用微信小游戏的子包机制
|
||||
- 压缩纹理资源,平衡画质与包大小
|
||||
- 移除未使用的依赖库
|
||||
|
||||
**Section sources**
|
||||
- [builder.json](file://settings/v2/packages/builder.json#L1-L128)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L195)
|
||||
488
.qoder/repowiki/zh/content/技术架构/ECS架构.md
Normal file
488
.qoder/repowiki/zh/content/技术架构/ECS架构.md
Normal file
@@ -0,0 +1,488 @@
|
||||
# ECS架构深度解析
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
- [EcsPositionSystem.ts](file://assets/script/game/common/ecs/position/EcsPositionSystem.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [ecs.md](file://doc/ecs/ecs.md)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [ECS架构概述](#ecs架构概述)
|
||||
3. [组件系统详解](#组件系统详解)
|
||||
4. [实体生命周期管理](#实体生命周期管理)
|
||||
5. [系统架构与执行机制](#系统架构与执行机制)
|
||||
6. [实际案例分析](#实际案例分析)
|
||||
7. [性能优化与最佳实践](#性能优化与最佳实践)
|
||||
8. [扩展开发指南](#扩展开发指南)
|
||||
9. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
ECS(Entity-Component-System)是一种流行的游戏架构模式,它通过将数据与行为分离来实现高度模块化和可扩展的系统设计。本项目采用TypeScript版本的ECS框架,实现了游戏逻辑的数据与行为解耦,为复杂的游戏系统提供了清晰的架构基础。
|
||||
|
||||
## ECS架构概述
|
||||
|
||||
### 核心概念
|
||||
|
||||
ECS架构由三个核心元素组成:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "ECS架构核心"
|
||||
Entity["实体 (Entity)<br/>唯一标识符"]
|
||||
Component["组件 (Component)<br/>数据容器"]
|
||||
System["系统 (System)<br/>逻辑处理器"]
|
||||
end
|
||||
subgraph "交互关系"
|
||||
Entity --> Component
|
||||
System --> Entity
|
||||
System -.-> Component
|
||||
end
|
||||
subgraph "执行流程"
|
||||
System --> Filter["筛选机制"]
|
||||
Filter --> Entities["符合条件的实体"]
|
||||
Entities --> Update["系统更新"]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [ecs.md](file://doc/ecs/ecs.md#L1-L27)
|
||||
|
||||
### 架构优势
|
||||
|
||||
1. **数据与行为分离**:组件只存储数据,系统处理逻辑
|
||||
2. **高度模块化**:通过组合不同组件创建复杂实体
|
||||
3. **性能优化**:批量处理相同类型的操作
|
||||
4. **易于扩展**:新增功能只需添加新组件和系统
|
||||
|
||||
## 组件系统详解
|
||||
|
||||
### 组件注册机制
|
||||
|
||||
组件通过装饰器`@ecs.register`进行注册,框架自动管理组件的生命周期和内存回收。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Component {
|
||||
<<abstract>>
|
||||
+reset() void
|
||||
}
|
||||
class BattleMoveComp {
|
||||
+number direction
|
||||
+number targetX
|
||||
+boolean moving
|
||||
+reset() void
|
||||
}
|
||||
class HeroViewComp {
|
||||
+string hero_name
|
||||
+number fac
|
||||
+boolean is_dead
|
||||
+number[] Attrs
|
||||
+reset() void
|
||||
}
|
||||
class MapModelComp {
|
||||
+number id
|
||||
+string resPrefab
|
||||
+reset() void
|
||||
}
|
||||
Component <|-- BattleMoveComp
|
||||
Component <|-- HeroViewComp
|
||||
Component <|-- MapModelComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L1-L16)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L50)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
|
||||
|
||||
### 组件添加与移除机制
|
||||
|
||||
组件的添加和移除遵循严格的生命周期管理:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Entity as 实体
|
||||
participant ECS as ECS框架
|
||||
participant Pool as 组件池
|
||||
participant System as 系统
|
||||
Entity->>ECS : add(Component)
|
||||
ECS->>Pool : 获取可用组件
|
||||
alt 组件池中有可用组件
|
||||
Pool-->>ECS : 返回组件实例
|
||||
else 组件池为空
|
||||
ECS->>ECS : 创建新组件
|
||||
end
|
||||
ECS->>Entity : 绑定组件
|
||||
System->>Entity : 筛选实体
|
||||
Entity-->>System : 返回实体列表
|
||||
Entity->>ECS : remove(Component)
|
||||
ECS->>Component : reset()重置状态
|
||||
ECS->>Pool : 回收组件到池中
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [ecs.md](file://doc/ecs/ecs.md#L45-L87)
|
||||
|
||||
**章节来源**
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L1-L16)
|
||||
- [ecs.md](file://doc/ecs/ecs.md#L15-L45)
|
||||
|
||||
## 实体生命周期管理
|
||||
|
||||
### 实体创建与销毁
|
||||
|
||||
实体通过继承`ecs.Entity`创建,并支持父子实体关系管理:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Created : createEntity()
|
||||
Created --> Active : addComponents()
|
||||
Active --> Updated : systemUpdate()
|
||||
Updated --> Active : continue
|
||||
Active --> Removed : removeComponents()
|
||||
Removed --> Destroyed : destroy()
|
||||
Destroyed --> [*]
|
||||
Active --> Paused : systemPause()
|
||||
Paused --> Active : systemResume()
|
||||
```
|
||||
|
||||
### 实体管理操作
|
||||
|
||||
| 操作 | 方法 | 描述 |
|
||||
|------|------|------|
|
||||
| 创建实体 | `ecs.getEntity<Entity>()` | 从实体池中获取或创建新实体 |
|
||||
| 添加组件 | `entity.add(Component)` | 优先从组件池获取,否则创建新实例 |
|
||||
| 移除组件 | `entity.remove(Component)` | 组件重置后放回组件池 |
|
||||
| 销毁实体 | `entity.destroy()` | 清理所有组件并回收实体 |
|
||||
| 子实体管理 | `addChild(Entity)` | 管理实体间的父子关系 |
|
||||
|
||||
**章节来源**
|
||||
- [ecs.md](file://doc/ecs/ecs.md#L29-L87)
|
||||
|
||||
## 系统架构与执行机制
|
||||
|
||||
### 系统层次结构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class System {
|
||||
<<abstract>>
|
||||
+execute(dt) void
|
||||
}
|
||||
class ComblockSystem {
|
||||
+filter() IMatcher
|
||||
+update(entity) void
|
||||
+entityEnter(entity) void
|
||||
+entityRemove(entity) void
|
||||
}
|
||||
class BattleMoveSystem {
|
||||
+filter() IMatcher
|
||||
+update(entity) void
|
||||
-checkEnemiesExist(entity) boolean
|
||||
-findNearestEnemy(entity) HeroViewComp
|
||||
-validatePosition(x, move) boolean
|
||||
}
|
||||
class EcsPositionSystem {
|
||||
+constructor()
|
||||
}
|
||||
System <|-- ComblockSystem
|
||||
ComblockSystem <|-- BattleMoveSystem
|
||||
System <|-- EcsPositionSystem
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L50)
|
||||
- [EcsPositionSystem.ts](file://assets/script/game/common/ecs/position/EcsPositionSystem.ts#L1-L9)
|
||||
|
||||
### 筛选机制
|
||||
|
||||
系统通过`filter()`方法筛选符合条件的实体:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([系统执行]) --> Filter["filter()筛选"]
|
||||
Filter --> Matcher{"IMatcher匹配"}
|
||||
Matcher --> |allOf| AllMatch["所有组件都存在"]
|
||||
Matcher --> |anyOf| AnyMatch["至少有一个组件存在"]
|
||||
Matcher --> |excludeOf| ExcludeMatch["不包含指定组件"]
|
||||
Matcher --> |onlyOf| OnlyMatch["只有指定组件"]
|
||||
AllMatch --> ProcessEntities["处理实体列表"]
|
||||
AnyMatch --> ProcessEntities
|
||||
ExcludeMatch --> ProcessEntities
|
||||
OnlyMatch --> ProcessEntities
|
||||
ProcessEntities --> Update["系统更新"]
|
||||
Update --> End([完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [ecs.md](file://doc/ecs/ecs.md#L88-L128)
|
||||
|
||||
### 系统执行流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Root as RootSystem
|
||||
participant System as ComblockSystem
|
||||
participant Entity as Entity
|
||||
participant Component as Component
|
||||
Root->>System : execute(dt)
|
||||
System->>System : filter()筛选实体
|
||||
loop 遍历符合条件的实体
|
||||
System->>Entity : entityEnter()首次进入
|
||||
System->>Entity : update()每帧更新
|
||||
Entity->>Component : get(Component)
|
||||
Component-->>Entity : 返回组件实例
|
||||
System->>Entity : 处理业务逻辑
|
||||
end
|
||||
System->>Entity : entityRemove()移除处理
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L10-L30)
|
||||
|
||||
**章节来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L272)
|
||||
- [EcsPositionSystem.ts](file://assets/script/game/common/ecs/position/EcsPositionSystem.ts#L1-L9)
|
||||
|
||||
## 实际案例分析
|
||||
|
||||
### BattleMoveSystem详细分析
|
||||
|
||||
BattleMoveSystem展示了ECS架构在游戏AI中的应用:
|
||||
|
||||
#### 组件依赖关系
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
Entity["游戏实体"] --> BattleMoveComp["BattleMoveComp<br/>移动控制"]
|
||||
Entity --> HeroViewComp["HeroViewComp<br/>视图控制"]
|
||||
BattleMoveComp --> Direction["direction<br/>移动方向"]
|
||||
BattleMoveComp --> TargetX["targetX<br/>目标位置"]
|
||||
BattleMoveComp --> Moving["moving<br/>移动状态"]
|
||||
HeroViewComp --> HP["hp/mp<br/>生命值"]
|
||||
HeroViewComp --> Status["status<br/>状态"]
|
||||
HeroViewComp --> Position["node.position<br/>位置信息"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L10-L20)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L4-L12)
|
||||
|
||||
#### 系统更新逻辑
|
||||
|
||||
BattleMoveSystem的核心更新逻辑体现了ECS的优势:
|
||||
|
||||
1. **数据分离**:移动逻辑完全封装在系统中
|
||||
2. **条件筛选**:只处理同时拥有BattleMoveComp和HeroViewComp的实体
|
||||
3. **状态管理**:根据游戏状态动态调整行为
|
||||
4. **性能优化**:只处理活跃实体,避免不必要的计算
|
||||
|
||||
#### 关键算法实现
|
||||
|
||||
| 算法 | 功能 | 实现位置 |
|
||||
|------|------|----------|
|
||||
| 敌人检测 | 检查攻击范围内是否有敌人 | `checkEnemiesInRange()` |
|
||||
| 最近敌人查找 | 寻找最近的敌对单位 | `findNearestEnemy()` |
|
||||
| 位置验证 | 验证移动位置的有效性 | `validatePosition()` |
|
||||
| 渲染层级更新 | 根据位置更新渲染顺序 | `updateRenderOrder()` |
|
||||
|
||||
**章节来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L15-L272)
|
||||
|
||||
### HeroViewComp综合组件分析
|
||||
|
||||
HeroViewComp展示了组件如何存储复杂的游戏状态:
|
||||
|
||||
#### 属性管理系统
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class HeroViewComp {
|
||||
+Record~number,Array~ BUFFS
|
||||
+Record~number,Array~ BUFFS_TEMP
|
||||
+number[] Attrs
|
||||
+number[] NeAttrs
|
||||
+addBuff(conf) void
|
||||
+recalculateSingleAttr(attrIndex) void
|
||||
+updateTemporaryBuffsDebuffs(dt) void
|
||||
}
|
||||
class BuffInstance {
|
||||
+number value
|
||||
+BType BType
|
||||
+number remainTime
|
||||
}
|
||||
HeroViewComp --> BuffInstance : 管理
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L60-L120)
|
||||
|
||||
#### BUFF系统架构
|
||||
|
||||
HeroViewComp实现了复杂的BUFF/DEBUFF管理系统:
|
||||
|
||||
1. **持久BUFF**:存储在`BUFFS`数组中,永久存在直到手动移除
|
||||
2. **临时BUFF**:存储在`BUFFS_TEMP`数组中,带有剩余时间
|
||||
3. **属性计算**:根据数值型和百分比型BUFF计算最终属性值
|
||||
4. **自动更新**:每帧更新临时BUFF的剩余时间
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L780)
|
||||
|
||||
## 性能优化与最佳实践
|
||||
|
||||
### 内存管理策略
|
||||
|
||||
ECS框架通过以下机制优化内存使用:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Create["创建组件"] --> Pool{"组件池检查"}
|
||||
Pool --> |有可用| Reuse["重用组件实例"]
|
||||
Pool --> |无可用| New["创建新实例"]
|
||||
Reuse --> Use["使用组件"]
|
||||
New --> Use
|
||||
Use --> Remove["移除组件"]
|
||||
Remove --> Reset["reset()重置"]
|
||||
Reset --> Pool
|
||||
Destroy["销毁实体"] --> Clear["清理所有组件"]
|
||||
Clear --> Recycle["回收到池中"]
|
||||
```
|
||||
|
||||
### 性能优化技巧
|
||||
|
||||
1. **组件池化**:避免频繁的垃圾回收
|
||||
2. **批量处理**:系统一次性处理所有符合条件的实体
|
||||
3. **条件筛选**:精确的过滤机制减少不必要的遍历
|
||||
4. **状态缓存**:避免重复计算相同的状态
|
||||
|
||||
### 开发最佳实践
|
||||
|
||||
| 实践 | 原则 | 示例 |
|
||||
|------|------|------|
|
||||
| 组件职责单一 | 一个组件只负责一种数据类型 | BattleMoveComp只处理移动相关数据 |
|
||||
| 系统逻辑集中 | 系统处理相关的业务逻辑 | BattleMoveSystem处理所有移动逻辑 |
|
||||
| 避免循环依赖 | 组件间不应有强耦合关系 | 通过系统协调组件交互 |
|
||||
| 合理使用筛选器 | 精确的过滤条件提高性能 | `ecs.allOf(BattleMoveComp, HeroViewComp)` |
|
||||
|
||||
## 扩展开发指南
|
||||
|
||||
### 定义新组件
|
||||
|
||||
创建新组件的基本步骤:
|
||||
|
||||
```typescript
|
||||
// 1. 继承ecs.Comp
|
||||
@ecs.register('NewComponent')
|
||||
export class NewComponent extends ecs.Comp {
|
||||
// 2. 定义组件数据
|
||||
public data: any;
|
||||
public enabled: boolean = true;
|
||||
|
||||
// 3. 实现reset方法
|
||||
reset() {
|
||||
this.data = null;
|
||||
this.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 在实体中声明
|
||||
export class NewEntity extends ecs.Entity {
|
||||
New: NewComponent;
|
||||
}
|
||||
```
|
||||
|
||||
### 创建新系统
|
||||
|
||||
系统开发的标准流程:
|
||||
|
||||
```typescript
|
||||
@ecs.register('NewSystem')
|
||||
export class NewSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
|
||||
// 1. 定义筛选条件
|
||||
filter(): ecs.IMatcher {
|
||||
return ecs.allOf(NewComponent, AnotherComponent);
|
||||
}
|
||||
|
||||
// 2. 实现更新逻辑
|
||||
update(e: ecs.Entity) {
|
||||
const comp = e.get(NewComponent);
|
||||
const another = e.get(AnotherComponent);
|
||||
|
||||
// 处理业务逻辑
|
||||
if (comp.enabled) {
|
||||
// ...具体逻辑
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 系统接口选择
|
||||
|
||||
| 接口 | 用途 | 使用场景 |
|
||||
|------|------|----------|
|
||||
| `ISystemUpdate` | 每帧更新 | 需要持续处理的逻辑 |
|
||||
| `IEntityEnterSystem` | 实体首次进入 | 初始化实体状态 |
|
||||
| `IEntityRemoveSystem` | 实体移除处理 | 清理资源和状态 |
|
||||
| `ISystemFirstUpdate` | 系统首次更新 | 系统初始化逻辑 |
|
||||
|
||||
### 扩展示例
|
||||
|
||||
基于现有架构扩展新功能:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "扩展架构"
|
||||
NewComp["NewComponent<br/>新功能组件"]
|
||||
NewSys["NewSystem<br/>新功能系统"]
|
||||
ExistingComp["ExistingComponent<br/>现有组件"]
|
||||
end
|
||||
subgraph "系统集成"
|
||||
BattleMove["BattleMoveSystem"]
|
||||
NewSys --> BattleMove
|
||||
NewComp --> BattleMove
|
||||
end
|
||||
subgraph "实体组合"
|
||||
Entity["游戏实体"]
|
||||
Entity --> NewComp
|
||||
Entity --> ExistingComp
|
||||
end
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [ecs.md](file://doc/ecs/ecs.md#L129-L272)
|
||||
|
||||
## 总结
|
||||
|
||||
本项目采用的ECS架构展现了现代游戏开发的最佳实践:
|
||||
|
||||
### 核心优势
|
||||
|
||||
1. **高度模块化**:通过组件组合创建复杂实体
|
||||
2. **清晰的职责分离**:数据存储在组件,逻辑处理在系统
|
||||
3. **优秀的性能表现**:批量处理和精确筛选机制
|
||||
4. **良好的可扩展性**:易于添加新功能和修改现有逻辑
|
||||
|
||||
### 架构特点
|
||||
|
||||
- **数据驱动**:系统通过筛选机制处理数据
|
||||
- **事件驱动**:支持实体进入和移除事件
|
||||
- **类型安全**:TypeScript提供完整的类型检查
|
||||
- **内存友好**:组件池化和自动回收机制
|
||||
|
||||
### 应用价值
|
||||
|
||||
ECS架构特别适合:
|
||||
- 复杂的游戏AI系统
|
||||
- 大量相似但行为不同的实体
|
||||
- 需要高性能处理的游戏逻辑
|
||||
- 需要频繁扩展和修改的系统
|
||||
|
||||
通过深入理解和正确应用ECS架构,开发者可以构建出既高效又易于维护的游戏系统,为玩家提供流畅的游戏体验。
|
||||
245
.qoder/repowiki/zh/content/技术架构/MVVM框架.md
Normal file
245
.qoder/repowiki/zh/content/技术架构/MVVM框架.md
Normal file
@@ -0,0 +1,245 @@
|
||||
# MVVM框架
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md)
|
||||
- [VMBase.md](file://doc/mvvm/VMBase.md)
|
||||
- [VMCustom.md](file://doc/mvvm/VMCustom.md)
|
||||
- [VMLabel.md](file://doc/mvvm/VMLabel.md)
|
||||
- [VMState.md](file://doc/mvvm/VMState.md)
|
||||
- [VMProgress.md](file://doc/mvvm/VMProgress.md)
|
||||
- [VMEvent.md](file://doc/mvvm/VMEvent.md)
|
||||
- [VMParent.md](file://doc/mvvm/VMParent.md)
|
||||
- [ViewModelScript.md](file://doc/mvvm/ViewModelScript.md)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts)
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [核心组件](#核心组件)
|
||||
3. [数据模型注册与管理](#数据模型注册与管理)
|
||||
4. [UI组件与数据绑定机制](#ui组件与数据绑定机制)
|
||||
5. [UI自动更新机制](#ui自动更新机制)
|
||||
6. [编辑器配置与使用示例](#编辑器配置与使用示例)
|
||||
7. [高级功能与最佳实践](#高级功能与最佳实践)
|
||||
|
||||
## 简介
|
||||
|
||||
Oops Plugin Framework的MVVM实现机制旨在通过数据驱动的方式简化UI逻辑开发,实现无代码或低代码的UI开发模式。该框架借鉴了Vue的设计理念,通过观察者模式和事件系统,实现了数据与UI的双向绑定。开发者无需频繁使用`cc.find`、`getChildByName`、`getComponent`等繁琐的DOM操作,而是通过简单的配置即可实现复杂的UI逻辑。
|
||||
|
||||
该框架的核心优势在于其组件化的实现方式,提供了多个低耦合的VM组件,如VMLabel、VMState、VMProgress等,这些组件可以直接在Cocos Creator编辑器中挂载和配置,极大地提高了开发效率和可维护性。
|
||||
|
||||
**Section sources**
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L1-L51)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### ViewModel
|
||||
ViewModel是MVVM框架的核心模块,负责动态管理数据模型,并通过`cc.director.emit`通知游戏内的节点组件状态变化。它是数据模型的包装器,提供了数据绑定、监听和通知的功能。
|
||||
|
||||
### VMBase
|
||||
VMBase是所有VM组件的基类,实现了基础的数据绑定功能。其他VM组件如VMLabel、VMState等都继承自VMBase。它提供了路径监听、值变化回调等核心功能。
|
||||
|
||||
### VM组件类型
|
||||
- **VMCustom**:通用组件,可自定义绑定任意组件的属性
|
||||
- **VMLabel**:专门用于文本显示,支持模板语法和格式化
|
||||
- **VMState**:根据数据值控制节点状态(激活、显示、颜色等)
|
||||
- **VMProgress**:用于进度条显示,支持双向绑定
|
||||
- **VMEvent**:在值变化时触发事件,调用其他组件的方法
|
||||
- **VMParent**:用于定义局部范围的ViewModel数据
|
||||
|
||||
**Section sources**
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L14-L29)
|
||||
- [VMBase.md](file://doc/mvvm/VMBase.md#L1-L38)
|
||||
|
||||
## 数据模型注册与管理
|
||||
|
||||
### 数据模型注册
|
||||
通过`VM.add(data, 'tag')`方法注册数据模型,其中`data`是要绑定的数据对象,`tag`是该数据模型的唯一标识标签。注册后,该数据模型将被VMManager管理,可以通过标签进行访问和操作。
|
||||
|
||||
```typescript
|
||||
// 构建数据对象
|
||||
let data = {
|
||||
name: 'user',
|
||||
gold: 12200,
|
||||
info: {
|
||||
id: 0
|
||||
}
|
||||
}
|
||||
// 创建VM对象并添加到VMManager进行管理,标记为'user'标签
|
||||
VM.add(data, 'user');
|
||||
```
|
||||
|
||||
### 数据模型管理API
|
||||
- `add(data, tag)`:创建并添加ViewModel对象
|
||||
- `get(tag)`:获取指定标签的ViewModel实例
|
||||
- `remove(tag)`:移除指定标签的ViewModel对象
|
||||
- `setValue(path, value)`:设置值(支持全局路径)
|
||||
- `addValue(path, value)`:累加值
|
||||
- `getValue(path, defaultValue)`:获取值(支持默认值)
|
||||
|
||||
**Section sources**
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L30-L51)
|
||||
- [ViewModelScript.md](file://doc/mvvm/ViewModelScript.md#L20-L67)
|
||||
|
||||
## UI组件与数据绑定机制
|
||||
|
||||
### VMCustom组件
|
||||
VMCustom是通用的绑定组件,可以绑定任意组件的任意属性。在编辑器中挂载VMCustom组件后,需要设置以下属性:
|
||||
- **Controller**:启用后支持双向绑定
|
||||
- **Watch Path**:要监听的数据路径
|
||||
- **Component Name**:要绑定的组件名称
|
||||
- **Component Property**:要绑定的组件属性
|
||||
- **refreshRate**:刷新频率(仅在Controller启用时生效)
|
||||
|
||||
### VMLabel组件
|
||||
VMLabel专门用于文本显示,支持模板语法和多种格式化方式。其主要特性包括:
|
||||
- 支持单路径和多路径监听
|
||||
- 使用`{{0}}`、`{{1}}`等模板语法
|
||||
- 支持多种格式化:`int`(整数)、`fix(n)`(小数位数)、`kmbt`(千位分隔)、`per`(百分比)等
|
||||
|
||||
### VMState组件
|
||||
VMState根据数据值控制节点状态,可以实现条件显示、颜色变化等功能。主要配置包括:
|
||||
- **Watch Path**:监听的数据路径
|
||||
- **Condition**:判断条件(如等于、大于等)
|
||||
- **Value Action**:满足条件时执行的操作(如节点激活、可见性、不透明度、颜色等)
|
||||
|
||||
### VMProgress组件
|
||||
VMProgress用于进度条显示,需要设置两个监听路径(最小值和最大值)。其配置与VMCustom类似,但专门针对进度条组件。
|
||||
|
||||
**Section sources**
|
||||
- [VMCustom.md](file://doc/mvvm/VMCustom.md#L1-L17)
|
||||
- [VMLabel.md](file://doc/mvvm/VMLabel.md#L1-L33)
|
||||
- [VMState.md](file://doc/mvvm/VMState.md#L1-L41)
|
||||
- [VMProgress.md](file://doc/mvvm/VMProgress.md#L1-L14)
|
||||
|
||||
## UI自动更新机制
|
||||
|
||||
### 事件驱动更新
|
||||
当数据模型的值发生变化时,ViewModel会通过`cc.director.emit`触发事件,通知所有监听该路径的组件进行更新。这种事件驱动的机制确保了数据变化能够实时反映到UI上。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[修改数据模型] --> B{数据变化}
|
||||
B --> C[ViewModel检测到变化]
|
||||
C --> D[cc.director.emit触发事件]
|
||||
D --> E[VM组件接收到通知]
|
||||
E --> F[更新UI显示]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [ViewModelScript.md](file://doc/mvvm/ViewModelScript.md#L69-L107)
|
||||
|
||||
### 双向绑定
|
||||
通过启用VMCustom组件的Controller功能,可以实现UI到数据的反向绑定。例如,当用户拖动进度条时,不仅可以更新UI显示,还可以自动更新对应的数据模型值。
|
||||
|
||||
### 局部数据管理
|
||||
对于局部组件,可以继承VMParent组件来管理局部数据。这种方式适用于弹窗等需要独立数据管理的场景。VMParent会在`onLoad`时自动将`*.name`形式的路径中的`*`替换为实际的ViewModel标签。
|
||||
|
||||
**Section sources**
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L30-L51)
|
||||
- [VMParent.md](file://doc/mvvm/VMParent.md#L1-L23)
|
||||
|
||||
## 编辑器配置与使用示例
|
||||
|
||||
### HInfoComp组件分析
|
||||
HInfoComp是英雄信息显示组件,展示了如何通过VM组件实现数据绑定:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class HInfoComp {
|
||||
+h_uuid : number
|
||||
+heroNodes : Node[]
|
||||
+update_data(uuid : number)
|
||||
+load_all_hero(uuid : number)
|
||||
+next_hero()
|
||||
+prev_hero()
|
||||
}
|
||||
HInfoComp --> VMLabel : "使用"
|
||||
HInfoComp --> VMProgress : "使用"
|
||||
HInfoComp --> VMState : "使用"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L343)
|
||||
|
||||
### SIconComp组件分析
|
||||
SIconComp是技能图标组件,展示了简单的数据绑定:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SIconCompComp {
|
||||
+update_data(s_uuid : number)
|
||||
}
|
||||
SIconCompComp --> VMCustom : "使用"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L1-L27)
|
||||
|
||||
### 编辑器配置步骤
|
||||
1. 在节点上添加VM组件(如VMLabel、VMState等)
|
||||
2. 设置Watch Path为对应的数据路径(如`user.gold`)
|
||||
3. 配置组件特定属性(如VMLabel的模板格式)
|
||||
4. 运行游戏,数据变化将自动反映到UI上
|
||||
|
||||
### 数值格式化示例
|
||||
```typescript
|
||||
// 在VMLabel中使用模板语法
|
||||
// {{0:int}} 显示整数
|
||||
// {{0:fix(2)}} 显示两位小数
|
||||
// {{0:kmbt}} 使用K/M/B/T单位缩写
|
||||
// {{0:per}} 显示百分比
|
||||
// {{0:sep}} 使用千位分隔符
|
||||
```
|
||||
|
||||
### 节点状态切换示例
|
||||
```typescript
|
||||
// 使用VMState控制节点状态
|
||||
// Condition: value >= 30
|
||||
// Value Action: NODE_VISIBLE
|
||||
// Watch Nodes: 指定要控制的节点
|
||||
```
|
||||
|
||||
### 进度条更新示例
|
||||
```typescript
|
||||
// 使用VMProgress更新进度条
|
||||
// Watch Path Arr: [currentValue, maxValue]
|
||||
// Component Name: ProgressBar
|
||||
// Component Property: progress
|
||||
```
|
||||
|
||||
**Section sources**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L343)
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L1-L27)
|
||||
|
||||
## 高级功能与最佳实践
|
||||
|
||||
### VMEvent组件
|
||||
VMEvent组件可以在值变化时触发事件,调用其他组件的方法。适用于需要自定义处理逻辑的场景,如数值变化时播放动画、播放音效等。
|
||||
|
||||
### VMModify组件
|
||||
VMModify组件提供了便捷的数据修改方法,可以通过事件调用实现数据的增减操作:
|
||||
- `vAddInt`:增加整数
|
||||
- `vSubInt`:减少整数
|
||||
- `vMulInt`:乘以整数
|
||||
- `vDivInt`:除以整数
|
||||
- `vString`:设置字符串
|
||||
- `vNumber`:设置数值
|
||||
|
||||
### 性能优化建议
|
||||
1. 合理使用局部数据管理(VMParent),避免全局数据的过度监听
|
||||
2. 控制刷新频率(refreshRate),避免不必要的频繁更新
|
||||
3. 及时移除不再使用的ViewModel,防止内存泄漏
|
||||
4. 避免过度嵌套使用VMParent,以免影响性能
|
||||
|
||||
### 调试技巧
|
||||
1. 使用`VM.get(tag)`获取ViewModel实例进行调试
|
||||
2. 通过`vm.active = false`临时关闭通知功能进行问题排查
|
||||
3. 利用编辑器的组件配置界面直观地查看和修改绑定关系
|
||||
|
||||
**Section sources**
|
||||
- [VMEvent.md](file://doc/mvvm/VMEvent.md#L1-L21)
|
||||
- [VMModify.md](file://doc/mvvm/VMModify.md#L13-L29)
|
||||
465
.qoder/repowiki/zh/content/技术架构/单例模式管理.md
Normal file
465
.qoder/repowiki/zh/content/技术架构/单例模式管理.md
Normal file
@@ -0,0 +1,465 @@
|
||||
# 单例模式管理
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [系统架构](#系统架构)
|
||||
3. [SingletonModuleComp核心设计](#singletonmodulecompcore设计)
|
||||
4. [初始化流程分析](#初始化流程分析)
|
||||
5. [MVVM数据绑定机制](#mvvm数据绑定机制)
|
||||
6. [云同步与数据管理](#云同步与数据管理)
|
||||
7. [单例模式实现](#单例模式实现)
|
||||
8. [数据操作方法](#数据操作方法)
|
||||
9. [性能优化与最佳实践](#性能优化与最佳实践)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 概述
|
||||
|
||||
SingletonModuleComp是游戏核心数据容器,采用单例模式设计,作为整个游戏应用的全局状态管理中心。它负责集中管理initialize、map、vmdata、heros等关键对象和状态,通过MVVM数据绑定机制实现视图与数据的同步,支持微信云同步功能,确保游戏数据的一致性和可靠性。
|
||||
|
||||
## 系统架构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "游戏启动流程"
|
||||
Main[Main.ts] --> Run[run方法]
|
||||
Run --> InitSMC[初始化SMC]
|
||||
InitSMC --> VMAdd[vmAdd绑定]
|
||||
end
|
||||
subgraph "SingletonModuleComp核心"
|
||||
SMC[SingletonModuleComp] --> VMData[vmdata数据层]
|
||||
SMC --> Initialize[initialize模块]
|
||||
SMC --> Map[GameMap]
|
||||
SMC --> Cloud[WxCloudApi]
|
||||
end
|
||||
subgraph "数据流"
|
||||
VMData --> MVVM[MVVM绑定]
|
||||
Cloud --> Sync[云同步]
|
||||
Sync --> Local[本地数据]
|
||||
end
|
||||
subgraph "外部依赖"
|
||||
ECS[ECS框架] --> SMC
|
||||
Oops[Oops框架] --> SMC
|
||||
WX[微信API] --> Cloud
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L25-L30)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L20-L195)
|
||||
|
||||
**章节来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L41)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L195)
|
||||
|
||||
## SingletonModuleComp核心设计
|
||||
|
||||
### 类结构与职责
|
||||
|
||||
SingletonModuleComp继承自ecs.Comp,作为ECS框架中的核心组件,承担以下主要职责:
|
||||
|
||||
- **全局状态管理**:维护游戏的核心状态数据
|
||||
- **数据持久化**:处理本地存储和云端同步
|
||||
- **业务逻辑协调**:管理英雄、金币、任务等业务数据
|
||||
- **事件通信**:通过GameEvent分发状态变更事件
|
||||
|
||||
### 核心数据结构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SingletonModuleComp {
|
||||
+Initialize initialize
|
||||
+GameMap map
|
||||
+string openid
|
||||
+object mission
|
||||
+array guides
|
||||
+number current_guide
|
||||
+object data
|
||||
+number fight_hero
|
||||
+array heros
|
||||
+array monsters
|
||||
+object vmdata
|
||||
+vmAdd() void
|
||||
+reset() void
|
||||
+updateGold(gold) boolean
|
||||
+addHero(hero_uuid) boolean
|
||||
+updateFihgtHero(heroId) boolean
|
||||
+finishGuide(index) void
|
||||
+updateCloudData() boolean
|
||||
+getCloudData() void
|
||||
+overrideLocalDataWithRemote(CloudData) void
|
||||
}
|
||||
class VMData {
|
||||
+boolean game_over
|
||||
+boolean game_pause
|
||||
+object mission_data
|
||||
+number gold
|
||||
}
|
||||
class MissionData {
|
||||
+number mon_num
|
||||
+number hero_num
|
||||
+number wave_time_num
|
||||
+boolean in_fight
|
||||
+number fight_time
|
||||
+number level
|
||||
+number max_mission
|
||||
+number coin
|
||||
}
|
||||
SingletonModuleComp --> VMData : "包含"
|
||||
VMData --> MissionData : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L20-L87)
|
||||
|
||||
### 数据层次结构
|
||||
|
||||
| 数据类型 | 字段名 | 描述 | 用途 |
|
||||
|---------|--------|------|------|
|
||||
| 基础状态 | `mission` | 游戏任务状态 | 控制游戏流程状态 |
|
||||
| 引导系统 | `guides` | 引导步骤记录 | 管理新手引导进度 |
|
||||
| 游戏数据 | `data` | 基础游戏属性 | 存储分数、钻石、肉等 |
|
||||
| 英雄管理 | `heros` | 英雄列表 | 管理解锁的英雄 |
|
||||
| 战斗配置 | `fight_hero` | 当前战斗英雄 | 指定出战英雄 |
|
||||
| 地图数据 | `monsters` | 怪物配置 | 关卡怪物数据 |
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L25-L87)
|
||||
|
||||
## 初始化流程分析
|
||||
|
||||
### Main.ts中的启动流程
|
||||
|
||||
游戏启动时,Main类的run方法负责初始化SingletonModuleComp实例:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Main as Main.ts
|
||||
participant ECS as ECS框架
|
||||
participant SMC as SingletonModuleComp
|
||||
participant VM as ViewModel
|
||||
Main->>ECS : 获取Initialize实体
|
||||
Main->>SMC : 设置initialize属性
|
||||
Main->>SMC : 调用vmAdd()
|
||||
SMC->>VM : 注册vmdata到VMManager
|
||||
VM-->>SMC : 绑定完成
|
||||
SMC-->>Main : 初始化完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L25-L30)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L89-L91)
|
||||
|
||||
### Initialize.ts的初始化过程
|
||||
|
||||
Initialize类负责统一的游戏数据加载流程,根据运行环境选择不同的数据源:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始初始化]) --> CheckEnv{检查运行环境}
|
||||
CheckEnv --> |微信客户端| LoadCloud[加载云端数据]
|
||||
CheckEnv --> |非微信客户端| LoadLocal[加载本地调试数据]
|
||||
LoadCloud --> InitWX[初始化微信云环境]
|
||||
InitWX --> WXLogin[微信登录]
|
||||
WXLogin --> GetCloudData[获取云端数据]
|
||||
GetCloudData --> OverrideLocal[覆盖本地数据]
|
||||
LoadLocal --> LoadDebug[加载本地调试数据]
|
||||
OverrideLocal --> Complete([初始化完成])
|
||||
LoadDebug --> Complete
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L85-L120)
|
||||
|
||||
**章节来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L25-L30)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L85-L120)
|
||||
|
||||
## MVVM数据绑定机制
|
||||
|
||||
### ViewModel集成
|
||||
|
||||
SingletonModuleComp通过VM.add方法将vmdata注册到ViewModel管理系统:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "MVVM架构"
|
||||
VMData[vmdata对象] --> VMManager[VMManager]
|
||||
VMManager --> VMBase[VMBase组件]
|
||||
VMBase --> UI[UI组件]
|
||||
end
|
||||
subgraph "绑定类型"
|
||||
VMCustom[VMCustom] --> Label[cc.Label]
|
||||
VMProgress[VMProgress] --> ProgressBar[cc.ProgressBar]
|
||||
VMState[VMState] --> NodeState[节点状态]
|
||||
end
|
||||
VMBase --> VMCustom
|
||||
VMBase --> VMProgress
|
||||
VMBase --> VMState
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L89-L91)
|
||||
|
||||
### 数据绑定示例
|
||||
|
||||
| 绑定类型 | 监听路径 | 绑定组件 | 更新时机 |
|
||||
|---------|----------|----------|----------|
|
||||
| 金币显示 | `vmdata.gold` | VMLabel | 每次金币变更 |
|
||||
| 任务进度 | `vmdata.mission_data.coin` | VMProgress | 金币变化时 |
|
||||
| 游戏状态 | `vmdata.game_over` | VMState | 状态切换时 |
|
||||
| 英雄数量 | `vmdata.mission_data.hero_num` | VMLabel | 英雄加入时 |
|
||||
|
||||
### 事件驱动更新
|
||||
|
||||
系统通过GameEvent实现数据变更的通知机制:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User as 用户操作
|
||||
participant SMC as SingletonModuleComp
|
||||
participant VM as ViewModel
|
||||
participant UI as UI组件
|
||||
User->>SMC : updateGold(100)
|
||||
SMC->>SMC : 修改vmdata.gold
|
||||
SMC->>VM : dispatchEvent(GOLD_UPDATE)
|
||||
VM->>UI : 更新绑定组件
|
||||
UI-->>User : 显示新数值
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L175-L185)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L65-L66)
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L89-L91)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L65-L66)
|
||||
|
||||
## 云同步与数据管理
|
||||
|
||||
### 微信云API集成
|
||||
|
||||
系统集成了WxCloudApi用于云端数据同步:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class WxCloudApi {
|
||||
+init(env) void
|
||||
+login() Promise
|
||||
+save(gameData) Promise
|
||||
+get() Promise
|
||||
}
|
||||
class CloudData {
|
||||
+string openid
|
||||
+GameDate data
|
||||
}
|
||||
class GameDate {
|
||||
+number gold
|
||||
+any heros
|
||||
+number fight_hero
|
||||
}
|
||||
WxCloudApi --> CloudData : "处理"
|
||||
CloudData --> GameDate : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L1-L94)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L11-L18)
|
||||
|
||||
### 数据同步流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant SMC as SingletonModuleComp
|
||||
participant WX as WxCloudApi
|
||||
participant Cloud as 微信云数据库
|
||||
SMC->>WX : updateCloudData()
|
||||
WX->>Cloud : save(gameData)
|
||||
Cloud-->>WX : 保存结果
|
||||
WX-->>SMC : 返回状态
|
||||
alt 同步成功
|
||||
SMC->>SMC : 继续业务逻辑
|
||||
else 同步失败
|
||||
SMC->>SMC : 回滚操作
|
||||
SMC->>SMC : 显示错误提示
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L93-L118)
|
||||
|
||||
### 数据覆盖策略
|
||||
|
||||
系统实现了智能的数据覆盖机制:
|
||||
|
||||
| 数据类型 | 覆盖条件 | 回滚策略 |
|
||||
|---------|----------|----------|
|
||||
| openid | 存在时覆盖 | 无 |
|
||||
| gold | 存在时覆盖 | 撤销变更 |
|
||||
| heros | 存在时覆盖 | 删除新增英雄 |
|
||||
| fight_hero | 存在时覆盖 | 恢复原配置 |
|
||||
|
||||
**章节来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L1-L94)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L93-L118)
|
||||
|
||||
## 单例模式实现
|
||||
|
||||
### ECS框架集成
|
||||
|
||||
SingletonModuleComp通过ECS.register装饰器注册为单例组件:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "ECS生命周期"
|
||||
Register[ecs.register] --> Create[创建实例]
|
||||
Create --> Get[ecs.getSingleton]
|
||||
Get --> Use[全局使用]
|
||||
end
|
||||
subgraph "单例保证"
|
||||
Instance[SingletonInstance] --> GlobalVar[smc全局变量]
|
||||
GlobalVar --> Consistency[状态一致性]
|
||||
end
|
||||
Register --> Instance
|
||||
Create --> Instance
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L19-L20)
|
||||
|
||||
### 全局访问机制
|
||||
|
||||
通过全局变量smc提供便捷的单例访问:
|
||||
|
||||
```typescript
|
||||
// 全局访问方式
|
||||
import { smc } from 'SingletonModuleComp';
|
||||
|
||||
// 使用示例
|
||||
smc.updateGold(100);
|
||||
smc.addHero(5003);
|
||||
```
|
||||
|
||||
### 状态一致性保障
|
||||
|
||||
单例模式确保:
|
||||
- **全局唯一性**:整个应用中只有一个实例
|
||||
- **状态同步**:所有组件访问相同的数据状态
|
||||
- **内存效率**:避免重复创建和销毁
|
||||
- **线程安全**:在单线程环境下天然安全
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L19-L20)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L195)
|
||||
|
||||
## 数据操作方法
|
||||
|
||||
### 安全的数据修改
|
||||
|
||||
系统提供了多层安全保障的数据操作方法:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Operation[数据操作请求] --> Validate{验证操作}
|
||||
Validate --> |有效| LocalUpdate[本地更新]
|
||||
Validate --> |无效| Reject[拒绝操作]
|
||||
LocalUpdate --> CheckWX{微信环境?}
|
||||
CheckWX --> |是| CloudSync[云端同步]
|
||||
CheckWX --> |否| DispatchEvent[分发事件]
|
||||
CloudSync --> SyncResult{同步结果}
|
||||
SyncResult --> |成功| DispatchEvent
|
||||
SyncResult --> |失败| Rollback[回滚操作]
|
||||
Rollback --> ErrorMsg[错误提示]
|
||||
DispatchEvent --> Complete[操作完成]
|
||||
Reject --> ErrorMsg
|
||||
ErrorMsg --> Complete
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L120-L194)
|
||||
|
||||
### 核心数据操作方法
|
||||
|
||||
| 方法名 | 参数 | 功能 | 安全特性 |
|
||||
|-------|------|------|----------|
|
||||
| `updateGold` | `gold: number` | 增减金币 | 自动同步失败回滚 |
|
||||
| `addHero` | `hero_uuid: number` | 添加英雄 | 检查重复,同步失败删除 |
|
||||
| `updateFihgtHero` | `heroId: number` | 设置战斗英雄 | 微信环境自动同步 |
|
||||
| `finishGuide` | `index: number` | 完成引导步骤 | 计划中云端存储 |
|
||||
|
||||
### 错误处理机制
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "错误类型"
|
||||
Network[网络错误]
|
||||
Sync[同步错误]
|
||||
Data[数据错误]
|
||||
Security[安全错误]
|
||||
end
|
||||
subgraph "处理策略"
|
||||
Retry[重试机制]
|
||||
Rollback[数据回滚]
|
||||
Notify[用户通知]
|
||||
Log[错误日志]
|
||||
end
|
||||
Network --> Retry
|
||||
Sync --> Rollback
|
||||
Data --> Notify
|
||||
Security --> Log
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L120-L194)
|
||||
|
||||
## 性能优化与最佳实践
|
||||
|
||||
### 内存管理
|
||||
|
||||
- **延迟初始化**:仅在需要时创建子组件
|
||||
- **及时清理**:通过reset方法清理不必要的数据
|
||||
- **弱引用**:避免循环引用导致的内存泄漏
|
||||
|
||||
### 数据同步优化
|
||||
|
||||
- **批量操作**:合并多个数据变更减少同步次数
|
||||
- **增量更新**:只传输变更的数据而非全量数据
|
||||
- **缓存策略**:本地缓存常用数据减少网络请求
|
||||
|
||||
### MVVM性能优化
|
||||
|
||||
- **路径监听**:精确监听必要的数据路径
|
||||
- **事件节流**:限制频繁的数据变更事件
|
||||
- **组件复用**:合理使用UI组件的复用机制
|
||||
|
||||
### 最佳实践建议
|
||||
|
||||
1. **数据验证**:在修改数据前进行有效性检查
|
||||
2. **错误恢复**:实现完善的错误恢复机制
|
||||
3. **日志记录**:记录关键操作的日志便于调试
|
||||
4. **版本兼容**:考虑数据结构的向前兼容性
|
||||
|
||||
## 总结
|
||||
|
||||
SingletonModuleComp作为游戏的核心数据容器,通过单例模式确保了全局状态的一致性,结合MVVM数据绑定机制实现了视图与数据的高效同步。其设计充分考虑了移动端游戏的特点,支持微信云同步功能,提供了安全可靠的数据操作方法。
|
||||
|
||||
### 核心优势
|
||||
|
||||
- **全局统一**:单例模式保证状态一致性
|
||||
- **数据绑定**:MVVM机制简化UI开发
|
||||
- **云端同步**:支持跨设备数据共享
|
||||
- **安全可靠**:多重验证和回滚机制
|
||||
- **易于扩展**:模块化设计便于功能扩展
|
||||
|
||||
### 应用价值
|
||||
|
||||
该设计模式为游戏开发提供了标准化的状态管理解决方案,特别适用于需要云端同步和复杂数据交互的移动端游戏项目。通过合理的架构设计和性能优化,确保了游戏在各种环境下的稳定运行。
|
||||
451
.qoder/repowiki/zh/content/技术架构/技术架构.md
Normal file
451
.qoder/repowiki/zh/content/技术架构/技术架构.md
Normal file
@@ -0,0 +1,451 @@
|
||||
# 技术架构
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [EcsPositionSystem.ts](file://assets/script/game/common/ecs/position/EcsPositionSystem.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [HeroModelComp.ts](file://assets/script/game/hero/HeroModelComp.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts)
|
||||
- [ecs.md](file://doc/ecs/ecs.md)
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目架构概览](#项目架构概览)
|
||||
3. [ECS架构支柱](#ecs架构支柱)
|
||||
4. [MVVM架构支柱](#mvvm架构支柱)
|
||||
5. [单例模式架构支柱](#单例模式架构支柱)
|
||||
6. [核心组件深度分析](#核心组件深度分析)
|
||||
7. [架构协作机制](#架构协作机制)
|
||||
8. [生命周期管理](#生命周期管理)
|
||||
9. [性能优化策略](#性能优化策略)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 引言
|
||||
|
||||
本项目采用了一套高度集成的技术架构,以ECS(实体-组件-系统)、MVVM(模型-视图-视图模型)和单例模式三大支柱为核心,构建了一个高度解耦、可扩展的游戏引擎。这种架构设计不仅提升了代码的可维护性,还为游戏逻辑的复杂性管理提供了强有力的支撑。
|
||||
|
||||
## 项目架构概览
|
||||
|
||||
项目采用了分层架构设计,每一层都有明确的职责分工:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "表现层"
|
||||
UI[用户界面]
|
||||
GUI[图形用户界面]
|
||||
end
|
||||
subgraph "业务逻辑层"
|
||||
ECS[ECS系统]
|
||||
MVVM[MVVM框架]
|
||||
SM[单例模块]
|
||||
end
|
||||
subgraph "数据层"
|
||||
DATA[游戏数据]
|
||||
CONFIG[配置数据]
|
||||
RESOURCES[资源管理]
|
||||
end
|
||||
UI --> ECS
|
||||
GUI --> MVVM
|
||||
ECS --> DATA
|
||||
MVVM --> DATA
|
||||
SM --> CONFIG
|
||||
DATA --> RESOURCES
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L41)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L207)
|
||||
|
||||
**章节来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L41)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L207)
|
||||
|
||||
## ECS架构支柱
|
||||
|
||||
### ECS核心概念
|
||||
|
||||
ECS(Entity-Component-System)架构是一种面向组件的设计模式,将游戏对象分解为三个核心元素:
|
||||
|
||||
1. **实体(Entity)**:纯粹的标识符,用于组合组件
|
||||
2. **组件(Component)**:携带数据的简单容器
|
||||
3. **系统(System)**:处理具有特定组件组合的实体
|
||||
|
||||
### 组件系统设计
|
||||
|
||||
项目中的组件系统展现了高度的模块化和可复用性:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ecs_Comp {
|
||||
+reset() void
|
||||
+canRecycle boolean
|
||||
+ent Entity
|
||||
}
|
||||
class BattleMoveComp {
|
||||
+direction number
|
||||
+targetX number
|
||||
+moving boolean
|
||||
+reset() void
|
||||
}
|
||||
class HeroViewComp {
|
||||
+status string
|
||||
+hero_uuid number
|
||||
+hp number
|
||||
+mp number
|
||||
+Attrs any
|
||||
+BUFFS any
|
||||
+update(dt) void
|
||||
}
|
||||
class HeroModelComp {
|
||||
+reset() void
|
||||
}
|
||||
ecs_Comp <|-- BattleMoveComp
|
||||
ecs_Comp <|-- HeroViewComp
|
||||
ecs_Comp <|-- HeroModelComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L1-L16)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L780)
|
||||
- [HeroModelComp.ts](file://assets/script/game/hero/HeroModelComp.ts#L1-L13)
|
||||
|
||||
### 系统协作机制
|
||||
|
||||
系统通过过滤器机制实现高效的实体管理:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant RS as RootSystem
|
||||
participant BS as BattleMoveSystem
|
||||
participant ECS as ECS引擎
|
||||
participant Entity as 实体
|
||||
participant Comp as 组件
|
||||
RS->>ECS : 执行系统
|
||||
ECS->>BS : filter()匹配实体
|
||||
BS->>Entity : 获取BattleMoveComp
|
||||
BS->>Entity : 获取HeroViewComp
|
||||
BS->>Entity : update()处理逻辑
|
||||
Entity->>Comp : 更新状态
|
||||
Comp-->>Entity : 返回结果
|
||||
Entity-->>BS : 完成处理
|
||||
BS-->>RS : 系统执行完毕
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L272)
|
||||
- [EcsPositionSystem.ts](file://assets/script/game/common/ecs/position/EcsPositionSystem.ts#L1-L9)
|
||||
|
||||
### ECS解耦优势
|
||||
|
||||
ECS架构在游戏逻辑中实现了以下解耦效果:
|
||||
|
||||
1. **数据与行为分离**:组件只负责数据存储,系统负责逻辑处理
|
||||
2. **灵活组合**:通过不同组件的组合实现多样化的游戏对象
|
||||
3. **高效处理**:系统可以批量处理具有相同组件组合的实体
|
||||
4. **易于扩展**:新增功能只需添加新组件和系统,无需修改现有代码
|
||||
|
||||
**章节来源**
|
||||
- [ecs.md](file://doc/ecs/ecs.md#L1-L357)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L272)
|
||||
|
||||
## MVVM架构支柱
|
||||
|
||||
### Oops Plugin Framework概述
|
||||
|
||||
Oops Plugin Framework是一个专为Cocos Creator设计的MVVM框架,提供了完整的双向数据绑定解决方案:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "ViewModel层"
|
||||
VM[ViewModel]
|
||||
VMData[数据模型]
|
||||
end
|
||||
subgraph "View层"
|
||||
UI[用户界面]
|
||||
Components[UI组件]
|
||||
end
|
||||
subgraph "Binding层"
|
||||
VMCustom[VMCustom]
|
||||
VMLabel[VMLabel]
|
||||
VMState[VMState]
|
||||
VMProgress[VMProgress]
|
||||
end
|
||||
VM --> VMData
|
||||
VMData --> VMCustom
|
||||
VMCustom --> UI
|
||||
VMLabel --> UI
|
||||
VMState --> UI
|
||||
VMProgress --> UI
|
||||
Components --> VMCustom
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L1-L52)
|
||||
|
||||
### 双向绑定机制
|
||||
|
||||
MVVM框架通过观察者模式实现了数据的自动同步:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([数据变更]) --> Notify[通知ViewModel]
|
||||
Notify --> Emit[触发cc.director.emit]
|
||||
Emit --> Listen[UI组件监听]
|
||||
Listen --> Update[更新界面显示]
|
||||
Update --> End([界面刷新完成])
|
||||
Start2([用户交互]) --> Trigger[触发事件]
|
||||
Trigger --> Modify[修改数据模型]
|
||||
Modify --> Notify
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L30-L51)
|
||||
|
||||
### ViewModel数据管理
|
||||
|
||||
项目中的数据模型通过SingletonModuleComp进行统一管理:
|
||||
|
||||
| 数据类型 | 管理方式 | 生命周期 | 用途 |
|
||||
|---------|---------|---------|------|
|
||||
| 游戏状态数据 | VM.add() | 全局 | UI绑定、状态同步 |
|
||||
| 用户配置数据 | 直接访问 | 持久化 | 设置保存、偏好记录 |
|
||||
| 实时战斗数据 | 动态更新 | 帧级 | 战斗界面、技能显示 |
|
||||
| 网络同步数据 | 异步处理 | 会话级 | 云端保存、数据同步 |
|
||||
|
||||
**章节来源**
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L1-L52)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L195)
|
||||
|
||||
## 单例模式架构支柱
|
||||
|
||||
### 全局模块管理
|
||||
|
||||
SingletonModuleComp作为全局状态管理的核心,实现了以下功能:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SingletonModuleComp {
|
||||
+initialize Initialize
|
||||
+map GameMap
|
||||
+openid string
|
||||
+mission any
|
||||
+guides any
|
||||
+data any
|
||||
+fight_hero number
|
||||
+heros any
|
||||
+monsters any
|
||||
+vmdata any
|
||||
+vmAdd() void
|
||||
+reset() void
|
||||
+updateCloudData() boolean
|
||||
+overrideLocalDataWithRemote() void
|
||||
+addHero() boolean
|
||||
+updateFihgtHero() boolean
|
||||
+updateGold() boolean
|
||||
}
|
||||
class smc {
|
||||
<<singleton>>
|
||||
}
|
||||
SingletonModuleComp --> smc : 实例
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L195)
|
||||
|
||||
### 单例模式优势
|
||||
|
||||
1. **全局访问**:任何地方都可以通过smc访问全局状态
|
||||
2. **状态一致性**:确保整个应用的状态统一
|
||||
3. **内存效率**:避免重复创建相同功能的对象
|
||||
4. **生命周期管理**:集中管理应用的初始化和销毁
|
||||
|
||||
### 数据同步机制
|
||||
|
||||
项目实现了云端与本地数据的双向同步:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 客户端
|
||||
participant SMC as SingletonModuleComp
|
||||
participant Cloud as 微信云API
|
||||
participant Local as 本地存储
|
||||
Client->>SMC : updateCloudData()
|
||||
SMC->>Cloud : save(gameData)
|
||||
Cloud-->>SMC : 保存结果
|
||||
SMC-->>Client : 返回状态
|
||||
Client->>SMC : getCloudData()
|
||||
SMC->>Cloud : get()
|
||||
Cloud-->>SMC : 云端数据
|
||||
SMC->>SMC : overrideLocalDataWithRemote()
|
||||
SMC-->>Client : 数据同步完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L80-L150)
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L195)
|
||||
|
||||
## 核心组件深度分析
|
||||
|
||||
### 主入口组件分析
|
||||
|
||||
Main.ts作为应用的主入口,负责整体初始化流程:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([应用启动]) --> Run[run方法]
|
||||
Run --> InitECS[初始化ECS系统]
|
||||
InitECS --> InitGUI[初始化GUI]
|
||||
InitGUI --> InitSMC[初始化SingletonModuleComp]
|
||||
InitSMC --> Complete([初始化完成])
|
||||
InitECS --> CreateEntity[创建Initialize实体]
|
||||
CreateEntity --> AddToSMC[添加到SMC]
|
||||
InitGUI --> LoadConfig[加载UI配置]
|
||||
LoadConfig --> SetupGUI[设置GUI框架]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L15-L41)
|
||||
|
||||
### 初始化流程详解
|
||||
|
||||
Initialize.ts实现了复杂的游戏初始化流程:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Init[Initialize实体创建] --> Queue[AsyncQueue队列]
|
||||
Queue --> Custom[加载自定义资源]
|
||||
Custom --> Lang[加载语言包]
|
||||
Lang --> Common[加载公共资源]
|
||||
Common --> Progress[加载进度界面]
|
||||
Progress --> Start[开始游戏]
|
||||
Custom --> Font[加载字体资源]
|
||||
Font --> Unified[统一数据加载]
|
||||
Unified --> Cloud{检测微信客户端}
|
||||
Cloud --> |是| CloudLoad[云端数据加载]
|
||||
Cloud --> |否| LocalLoad[本地数据加载]
|
||||
CloudLoad --> Login[微信登录]
|
||||
Login --> Sync[数据同步]
|
||||
LocalLoad --> Debug[调试数据]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L20-L207)
|
||||
|
||||
### 游戏状态管理
|
||||
|
||||
HeroViewComp展示了复杂的游戏状态管理:
|
||||
|
||||
| 状态类型 | 管理方式 | 更新频率 | 用途 |
|
||||
|---------|---------|---------|------|
|
||||
| 基础属性 | 直接计算 | 帧级 | 生命值、魔法值、防御力 |
|
||||
| Buff效果 | 数组管理 | 帧级 | 增益效果、持续时间 |
|
||||
| 负面状态 | 对象管理 | 帧级 | 减益效果、眩晕、冰冻 |
|
||||
| 战斗状态 | 状态机 | 事件触发 | 移动、攻击、死亡 |
|
||||
| 技能效果 | 特殊处理 | 事件触发 | 技能释放、特效显示 |
|
||||
|
||||
**章节来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L41)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L207)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L780)
|
||||
|
||||
## 架构协作机制
|
||||
|
||||
### 三大支柱的协同工作
|
||||
|
||||
三个架构支柱在项目中形成了紧密的协作关系:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "ECS系统"
|
||||
ECS_Entities[实体管理]
|
||||
ECS_Components[组件系统]
|
||||
ECS_Systems[系统处理]
|
||||
end
|
||||
subgraph "MVVM框架"
|
||||
VM_Manager[ViewModel管理]
|
||||
UI_Binding[UI绑定]
|
||||
Event_Handler[事件处理]
|
||||
end
|
||||
subgraph "单例模式"
|
||||
Global_State[全局状态]
|
||||
Data_Sync[数据同步]
|
||||
Config_Manage[配置管理]
|
||||
end
|
||||
ECS_Entities --> VM_Manager
|
||||
ECS_Components --> UI_Binding
|
||||
ECS_Systems --> Event_Handler
|
||||
VM_Manager --> Global_State
|
||||
UI_Binding --> Data_Sync
|
||||
Event_Handler --> Config_Manage
|
||||
Global_State --> ECS_Entities
|
||||
Data_Sync --> ECS_Components
|
||||
Config_Manage --> ECS_Systems
|
||||
```
|
||||
|
||||
### 生命周期管理
|
||||
|
||||
项目实现了完整的组件生命周期管理:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Created : 实体创建
|
||||
Created --> Initialized : 初始化
|
||||
Initialized --> Active : 激活状态
|
||||
Active --> Updating : 帧更新
|
||||
Updating --> Active : 继续运行
|
||||
Active --> Paused : 暂停状态
|
||||
Paused --> Active : 恢复运行
|
||||
Active --> Destroyed : 销毁
|
||||
Destroyed --> [*]
|
||||
Initialized --> Error : 初始化失败
|
||||
Error --> [*] : 清理资源
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L15-L41)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L20-L50)
|
||||
|
||||
## 性能优化策略
|
||||
|
||||
### ECS性能优化
|
||||
|
||||
1. **组件缓存池**:重用组件对象,减少垃圾回收压力
|
||||
2. **系统批处理**:同一系统的实体批量处理,提高CPU缓存命中率
|
||||
3. **过滤器优化**:精确的实体筛选,避免不必要的遍历
|
||||
4. **延迟销毁**:延迟实体销毁,减少频繁的内存分配
|
||||
|
||||
### MVVM性能优化
|
||||
|
||||
1. **脏检查优化**:智能的变更检测,避免不必要的UI更新
|
||||
2. **事件节流**:高频事件的防抖处理
|
||||
3. **组件懒加载**:按需加载UI组件,减少内存占用
|
||||
4. **绑定优化**:选择性的数据绑定,避免过度监听
|
||||
|
||||
### 单例模式优化
|
||||
|
||||
1. **延迟初始化**:按需创建单例对象
|
||||
2. **弱引用管理**:避免循环引用导致的内存泄漏
|
||||
3. **状态压缩**:定期清理无效状态数据
|
||||
4. **异步处理**:耗时操作的异步化处理
|
||||
|
||||
## 总结
|
||||
|
||||
本项目的技术架构通过ECS、MVVM和单例模式三大支柱,构建了一个高度解耦、可扩展的游戏引擎。这种架构设计带来了以下显著优势:
|
||||
|
||||
1. **代码可维护性**:清晰的职责分离,便于团队协作和长期维护
|
||||
2. **系统可扩展性**:模块化设计支持快速功能迭代和扩展
|
||||
3. **性能优化空间**:多层次的优化策略确保良好的运行性能
|
||||
4. **开发效率提升**:标准化的开发模式降低学习成本
|
||||
5. **质量保证**:完善的测试和调试机制确保代码质量
|
||||
|
||||
通过这种架构设计,项目不仅能够应对当前的功能需求,还为未来的功能扩展和技术升级奠定了坚实的基础。三大支柱的协同工作使得整个系统既灵活又稳定,为游戏开发提供了强有力的技术支撑。
|
||||
685
.qoder/repowiki/zh/content/数据管理/云数据同步.md
Normal file
685
.qoder/repowiki/zh/content/数据管理/云数据同步.md
Normal file
@@ -0,0 +1,685 @@
|
||||
# 云数据同步
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
- [config.json](file://build-templates/wechatgame/cloud_functions/cocos_cloud/config.json)
|
||||
- [deploy.md](file://build-templates/wechatgame/cloud_functions/cocos_cloud/deploy.md)
|
||||
- [wx.aip.d.ts](file://assets/script/game/wx_clound_client_api/wx.aip.d.ts)
|
||||
- [NetCode.json](file://assets/resources/config/game/NetCode.json)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [系统架构概览](#系统架构概览)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [WxCloudApi.ts详解](#wxcloudapits详解)
|
||||
5. [云函数服务端实现](#云函数服务端实现)
|
||||
6. [数据流与调用流程](#数据流与调用流程)
|
||||
7. [错误处理与状态码](#错误处理与状态码)
|
||||
8. [前端调用示例](#前端调用示例)
|
||||
9. [部署与配置](#部署与配置)
|
||||
10. [安全性与最佳实践](#安全性与最佳实践)
|
||||
11. [故障排除与优化](#故障排除与优化)
|
||||
12. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
本项目实现了基于微信云开发的云数据同步解决方案,为Cocos Creator游戏提供云端用户数据存储与同步功能。系统采用前后端分离架构,通过云函数处理业务逻辑,确保数据安全性和一致性。
|
||||
|
||||
核心功能包括:
|
||||
- 用户身份认证与自动创建
|
||||
- 游戏进度数据的云端存储与获取
|
||||
- 数据版本控制与冲突解决
|
||||
- 错误处理与重试机制
|
||||
- 安全性保障与权限控制
|
||||
|
||||
## 系统架构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "客户端层"
|
||||
Game[游戏客户端]
|
||||
WxCloud[WxCloudApi.ts]
|
||||
end
|
||||
subgraph "微信云开发平台"
|
||||
CloudFunc[云函数:cocos_cloud]
|
||||
Database[(云数据库)]
|
||||
Storage[(云存储)]
|
||||
end
|
||||
subgraph "微信服务器"
|
||||
WXServer[微信服务器]
|
||||
OpenID[用户OpenID]
|
||||
end
|
||||
Game --> WxCloud
|
||||
WxCloud --> CloudFunc
|
||||
CloudFunc --> Database
|
||||
CloudFunc --> WXServer
|
||||
WXServer --> OpenID
|
||||
Database --> Storage
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L1-L94)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js#L1-L85)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### 前端组件
|
||||
|
||||
**WxCloudApi类** 提供了统一的云服务接口,封装了微信云开发的复杂性,为游戏逻辑提供简洁的API。
|
||||
|
||||
**主要特性:**
|
||||
- 单例模式设计,确保全局唯一实例
|
||||
- 异步操作支持,避免阻塞主线程
|
||||
- 泛型类型安全,提供完整的TypeScript支持
|
||||
- 错误码标准化,便于统一处理
|
||||
|
||||
### 后端组件
|
||||
|
||||
**云函数服务** 运行在微信云开发环境中,负责处理所有业务逻辑和数据操作。
|
||||
|
||||
**核心功能:**
|
||||
- 用户身份验证与自动注册
|
||||
- 数据持久化与查询
|
||||
- 权限控制与安全验证
|
||||
- 错误日志记录与监控
|
||||
|
||||
**章节来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L1-L94)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js#L1-L85)
|
||||
|
||||
## WxCloudApi.ts详解
|
||||
|
||||
### 类结构设计
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class WxCloudApi {
|
||||
+init(env : string) void
|
||||
+login() Promise~CloudCallFunctionResult~
|
||||
+save(gameData : any) Promise~CloudCallFunctionResult~
|
||||
+get() Promise~CloudCallFunctionResult~
|
||||
}
|
||||
class CloudReturnType {
|
||||
+code : number
|
||||
+msg? : string
|
||||
+data? : T
|
||||
}
|
||||
class CloudCallFunctionResult {
|
||||
+result : T
|
||||
+errMsg : string
|
||||
+requestID : string
|
||||
}
|
||||
WxCloudApi --> CloudReturnType : "返回"
|
||||
CloudReturnType --> CloudCallFunctionResult : "嵌套"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L1-L94)
|
||||
- [wx.aip.d.ts](file://assets/script/game/wx_clound_client_api/wx.aip.d.ts#L1-L29)
|
||||
|
||||
### init方法实现机制
|
||||
|
||||
**功能描述:** 初始化微信云开发环境,建立客户端与云服务的连接。
|
||||
|
||||
**实现特点:**
|
||||
- 单次调用原则:每个游戏会话只需初始化一次
|
||||
- 环境参数配置:支持动态环境切换
|
||||
- 平台兼容性:条件调用,避免非微信环境下报错
|
||||
|
||||
**调用时机:** 游戏启动时,在主场景加载完成后调用。
|
||||
|
||||
### login方法实现机制
|
||||
|
||||
**功能描述:** 执行用户登录流程,获取用户身份信息和游戏数据。
|
||||
|
||||
**数据结构定义:**
|
||||
|
||||
| 字段名 | 类型 | 描述 | 必填 |
|
||||
|--------|------|------|------|
|
||||
| code | number | 状态码,200表示成功 | 是 |
|
||||
| msg | string | 错误信息(失败时) | 否 |
|
||||
| data | object | 用户数据对象 | 是 |
|
||||
| data.openid | string | 微信平台用户标识 | 是 |
|
||||
| data.regist_time | number | 用户注册时间戳 | 是 |
|
||||
| data.game_data | object | 游戏自定义数据 | 否 |
|
||||
|
||||
**调用流程:**
|
||||
1. 调用微信云函数cocos_cloud
|
||||
2. 传递cmd参数值为"login"
|
||||
3. 云函数验证用户身份
|
||||
4. 自动创建或查询用户记录
|
||||
5. 返回用户完整信息
|
||||
|
||||
### save方法实现机制
|
||||
|
||||
**功能描述:** 将游戏数据保存到云端,实现数据的持久化存储。
|
||||
|
||||
**数据结构:**
|
||||
- 接收任意类型的gameData对象
|
||||
- 执行全覆盖式写入操作
|
||||
- 支持复杂嵌套数据结构
|
||||
|
||||
**安全特性:**
|
||||
- 数据完整性校验
|
||||
- 操作日志记录
|
||||
- 版本控制支持
|
||||
|
||||
### get方法实现机制
|
||||
|
||||
**功能描述:** 从云端获取用户的最新游戏数据。
|
||||
|
||||
**实现特点:**
|
||||
- 实时数据拉取
|
||||
- 缓存策略支持
|
||||
- 数据一致性保障
|
||||
|
||||
**章节来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L1-L94)
|
||||
|
||||
## 云函数服务端实现
|
||||
|
||||
### 服务端架构设计
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 客户端
|
||||
participant CloudFunc as 云函数
|
||||
participant Database as 云数据库
|
||||
participant WXServer as 微信服务器
|
||||
Client->>CloudFunc : 调用云函数
|
||||
CloudFunc->>WXServer : 获取用户OpenID
|
||||
WXServer-->>CloudFunc : 返回用户标识
|
||||
CloudFunc->>Database : 查询用户记录
|
||||
Database-->>CloudFunc : 返回用户数据
|
||||
alt 用户不存在
|
||||
CloudFunc->>Database : 创建新用户记录
|
||||
Database-->>CloudFunc : 返回新记录ID
|
||||
end
|
||||
CloudFunc->>Database : 执行数据操作
|
||||
Database-->>CloudFunc : 返回操作结果
|
||||
CloudFunc-->>Client : 返回处理结果
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js#L10-L85)
|
||||
|
||||
### getOrCreaterUser函数实现
|
||||
|
||||
**功能描述:** 核心用户管理逻辑,确保每个微信用户都有对应的数据库记录。
|
||||
|
||||
**实现细节:**
|
||||
- 使用OpenID作为唯一标识符
|
||||
- 自动检测用户是否存在
|
||||
- 原子性操作保证数据一致性
|
||||
- 异常处理机制
|
||||
|
||||
**数据模型:**
|
||||
|
||||
| 字段名 | 类型 | 描述 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| _openid | string | 微信OpenID | 必填 |
|
||||
| regist_time | number | 注册时间戳 | 当前时间 |
|
||||
| game_data | object | 游戏数据 | {} |
|
||||
|
||||
### 登录处理逻辑
|
||||
|
||||
**流程分析:**
|
||||
1. **身份验证**:通过cloud.getWXContext()获取用户上下文
|
||||
2. **用户查询**:根据OpenID查找用户记录
|
||||
3. **用户创建**:如用户不存在则自动创建
|
||||
4. **数据返回**:返回完整的用户信息
|
||||
|
||||
**错误处理:**
|
||||
- 数据库连接失败
|
||||
- 用户查询超时
|
||||
- 记录创建失败
|
||||
|
||||
### 数据保存逻辑
|
||||
|
||||
**操作流程:**
|
||||
1. **数据验证**:检查传入的游戏数据格式
|
||||
2. **用户确认**:确保用户记录存在
|
||||
3. **数据更新**:使用原子更新操作
|
||||
4. **结果反馈**:返回操作统计信息
|
||||
|
||||
**性能优化:**
|
||||
- 批量操作支持
|
||||
- 索引优化
|
||||
- 连接池管理
|
||||
|
||||
**章节来源**
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js#L1-L85)
|
||||
|
||||
## 数据流与调用流程
|
||||
|
||||
### 完整数据同步流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([游戏启动]) --> Init["WxCloudApi.init()"]
|
||||
Init --> Login["WxCloudApi.login()"]
|
||||
Login --> LoginSuccess{"登录成功?"}
|
||||
LoginSuccess --> |否| LoginFail["显示登录错误"]
|
||||
LoginSuccess --> |是| LoadGameData["加载用户数据"]
|
||||
LoadGameData --> GameLoop["游戏主循环"]
|
||||
GameLoop --> SaveCheck{"需要保存数据?"}
|
||||
SaveCheck --> |否| GameLoop
|
||||
SaveCheck --> |是| SaveData["WxCloudApi.save()"]
|
||||
SaveData --> SaveSuccess{"保存成功?"}
|
||||
SaveSuccess --> |否| Retry["重试机制"]
|
||||
SaveSuccess --> |是| GameLoop
|
||||
Retry --> RetryCount{"重试次数<3?"}
|
||||
RetryCount --> |是| SaveData
|
||||
RetryCount --> |否| SaveFail["保存失败处理"]
|
||||
LoginFail --> End([结束])
|
||||
SaveFail --> End
|
||||
SaveSuccess --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L15-L94)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js#L15-L50)
|
||||
|
||||
### 请求响应数据结构
|
||||
|
||||
**登录请求:**
|
||||
```typescript
|
||||
// 请求格式
|
||||
{
|
||||
cmd: "login"
|
||||
}
|
||||
|
||||
// 响应格式
|
||||
{
|
||||
code: 200,
|
||||
data: {
|
||||
openid: "wx_openid_string",
|
||||
regist_time: 1640995200000,
|
||||
game_data: {
|
||||
level: 10,
|
||||
coins: 1000,
|
||||
inventory: [...],
|
||||
achievements: {...}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**保存请求:**
|
||||
```typescript
|
||||
// 请求格式
|
||||
{
|
||||
cmd: "save",
|
||||
data: {
|
||||
level: 11,
|
||||
coins: 1200,
|
||||
inventory: [...],
|
||||
achievements: {...}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应格式
|
||||
{
|
||||
code: 200,
|
||||
data: {
|
||||
errMsg: "document.update:ok",
|
||||
stats: {
|
||||
updated: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**获取请求:**
|
||||
```typescript
|
||||
// 请求格式
|
||||
{
|
||||
cmd: "get"
|
||||
}
|
||||
|
||||
// 响应格式
|
||||
{
|
||||
code: 200,
|
||||
data: {
|
||||
_id: "mongodb_document_id",
|
||||
_openid: "wx_openid_string",
|
||||
regist_time: 1640995200000,
|
||||
game_data: {...}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 错误处理与状态码
|
||||
|
||||
### 状态码定义
|
||||
|
||||
| 状态码 | 含义 | 处理方式 | 示例场景 |
|
||||
|--------|------|----------|----------|
|
||||
| 200 | 成功 | 正常处理 | 登录成功、数据保存成功 |
|
||||
| -1 | 通用错误 | 重试或提示用户 | 网络超时、数据库错误 |
|
||||
| -2 | 命令未知 | 检查参数 | 云函数参数错误 |
|
||||
| -3 | 权限不足 | 提示授权 | 用户未授权 |
|
||||
|
||||
### 错误分类处理
|
||||
|
||||
**网络错误:**
|
||||
- 连接超时:自动重试3次
|
||||
- 断线重连:本地缓存待发送数据
|
||||
- 网络恢复:批量同步缓存数据
|
||||
|
||||
**业务错误:**
|
||||
- 用户不存在:触发重新登录
|
||||
- 数据冲突:采用最后修改时间策略
|
||||
- 权限验证失败:引导用户重新授权
|
||||
|
||||
**系统错误:**
|
||||
- 云函数异常:降级到本地存储
|
||||
- 数据库不可用:启用离线模式
|
||||
- 服务端维护:显示维护公告
|
||||
|
||||
**章节来源**
|
||||
- [NetCode.json](file://assets/resources/config/game/NetCode.json#L1-L11)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js#L15-L85)
|
||||
|
||||
## 前端调用示例
|
||||
|
||||
### 基础使用示例
|
||||
|
||||
```typescript
|
||||
// 初始化云服务
|
||||
WxCloudApi.init('your-cloud-env');
|
||||
|
||||
// 用户登录
|
||||
async function handleLogin() {
|
||||
try {
|
||||
const result = await WxCloudApi.login();
|
||||
|
||||
if (result.result.code === 200) {
|
||||
const userData = result.result.data;
|
||||
console.log('登录成功:', userData);
|
||||
// 更新游戏状态
|
||||
game.user = userData;
|
||||
loadGameProgress(userData.game_data);
|
||||
} else {
|
||||
console.error('登录失败:', result.result.msg);
|
||||
showErrorMessage(result.result.msg);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('登录异常:', error);
|
||||
showNetworkError();
|
||||
}
|
||||
}
|
||||
|
||||
// 保存游戏进度
|
||||
async function saveGameProgress(progressData: any) {
|
||||
try {
|
||||
const result = await WxCloudApi.save(progressData);
|
||||
|
||||
if (result.result.code === 200) {
|
||||
console.log('保存成功');
|
||||
game.lastSyncTime = Date.now();
|
||||
} else {
|
||||
console.error('保存失败:', result.result.msg);
|
||||
// 触发重试机制
|
||||
scheduleRetry(() => saveGameProgress(progressData));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存异常:', error);
|
||||
scheduleRetry(() => saveGameProgress(progressData));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 高级使用模式
|
||||
|
||||
**批量操作:**
|
||||
```typescript
|
||||
async function batchSaveOperations(operations: Array<{type: string, data: any}>) {
|
||||
for (const op of operations) {
|
||||
switch (op.type) {
|
||||
case 'progress':
|
||||
await saveGameProgress(op.data);
|
||||
break;
|
||||
case 'achievement':
|
||||
await saveAchievement(op.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**数据同步策略:**
|
||||
```typescript
|
||||
class SyncManager {
|
||||
private pendingSaves: Array<any> = [];
|
||||
|
||||
async queueSave(data: any) {
|
||||
this.pendingSaves.push({
|
||||
data,
|
||||
timestamp: Date.now(),
|
||||
retryCount: 0
|
||||
});
|
||||
await this.processQueue();
|
||||
}
|
||||
|
||||
private async processQueue() {
|
||||
while (this.pendingSaves.length > 0) {
|
||||
const item = this.pendingSaves[0];
|
||||
try {
|
||||
await WxCloudApi.save(item.data);
|
||||
this.pendingSaves.shift();
|
||||
} catch (error) {
|
||||
if (item.retryCount < 3) {
|
||||
item.retryCount++;
|
||||
await new Promise(resolve => setTimeout(resolve, 1000 * item.retryCount));
|
||||
} else {
|
||||
// 移除失败项,可能需要手动处理
|
||||
this.pendingSaves.shift();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 部署与配置
|
||||
|
||||
### 云函数部署流程
|
||||
|
||||
**步骤1:环境准备**
|
||||
```bash
|
||||
# 进入云函数目录
|
||||
cd build-templates/wechatgame/cloud_functions/cocos_cloud
|
||||
|
||||
# 安装依赖
|
||||
npm install
|
||||
|
||||
# 验证安装
|
||||
ls node_modules/wx-server-sdk
|
||||
```
|
||||
|
||||
**步骤2:配置环境**
|
||||
编辑config.json文件:
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"openapi": [
|
||||
// 可选的开放API列表
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**步骤3:部署云函数**
|
||||
使用微信开发者工具:
|
||||
1. 打开项目根目录
|
||||
2. 选择云函数cocos_cloud
|
||||
3. 点击上传并部署
|
||||
4. 验证部署状态
|
||||
|
||||
### 环境配置
|
||||
|
||||
**config.json配置项:**
|
||||
|
||||
| 配置项 | 类型 | 描述 | 示例值 |
|
||||
|--------|------|------|--------|
|
||||
| permissions.openapi | Array | 公开API权限列表 | [] |
|
||||
| database | string | 数据库环境ID | "prod-123456" |
|
||||
| storage | string | 存储环境ID | "storage-123456" |
|
||||
|
||||
**环境变量:**
|
||||
- DYNAMIC_CURRENT_ENV:动态环境变量
|
||||
- OPENID:用户唯一标识
|
||||
- APP_ID:小程序APP ID
|
||||
|
||||
**章节来源**
|
||||
- [deploy.md](file://build-templates/wechatgame/cloud_functions/cocos_cloud/deploy.md#L1-L32)
|
||||
- [config.json](file://build-templates/wechatgame/cloud_functions/cocos_cloud/config.json#L1-L6)
|
||||
|
||||
## 安全性与最佳实践
|
||||
|
||||
### 权限控制机制
|
||||
|
||||
**_openid权限控制:**
|
||||
- 每个用户只能访问自己的数据
|
||||
- 数据操作必须通过云函数验证
|
||||
- 防止跨用户数据泄露
|
||||
|
||||
**数据加密策略:**
|
||||
- 敏感数据本地加密
|
||||
- 传输过程使用HTTPS
|
||||
- 定期轮换加密密钥
|
||||
|
||||
### 性能优化建议
|
||||
|
||||
**数据库优化:**
|
||||
```javascript
|
||||
// 在getOrCreaterUser函数中添加索引
|
||||
await db.collection(user_db_name)
|
||||
.where({ _openid: openid })
|
||||
.orderBy('regist_time', 'desc')
|
||||
.limit(1)
|
||||
.get();
|
||||
```
|
||||
|
||||
**缓存策略:**
|
||||
- 客户端缓存最近使用的数据
|
||||
- 设置合理的缓存过期时间
|
||||
- 实现智能预加载机制
|
||||
|
||||
### 监控与日志
|
||||
|
||||
**关键指标监控:**
|
||||
- API调用成功率
|
||||
- 平均响应时间
|
||||
- 错误率分布
|
||||
- 用户活跃度
|
||||
|
||||
**日志记录:**
|
||||
```javascript
|
||||
// 在index.js中添加详细日志
|
||||
console.log(`[${new Date().toISOString()}] User action:`, {
|
||||
action: cmd,
|
||||
openid: wxContext.OPENID,
|
||||
timestamp: Date.now(),
|
||||
duration: Date.now() - startTime
|
||||
});
|
||||
```
|
||||
|
||||
## 故障排除与优化
|
||||
|
||||
### 常见问题解决
|
||||
|
||||
**问题1:云函数部署失败**
|
||||
```bash
|
||||
# 错误:Cannot find module 'wx-server-sdk'
|
||||
# 解决方案:
|
||||
npm install wx-server-sdk --save
|
||||
```
|
||||
|
||||
**问题2:登录失败**
|
||||
- 检查微信登录状态
|
||||
- 验证云环境配置
|
||||
- 确认用户授权范围
|
||||
|
||||
**问题3:数据同步延迟**
|
||||
- 优化网络连接
|
||||
- 减少不必要的同步
|
||||
- 实现增量同步机制
|
||||
|
||||
### 性能监控
|
||||
|
||||
**关键性能指标:**
|
||||
- API响应时间:<200ms
|
||||
- 成功率:>99%
|
||||
- 错误率:<0.1%
|
||||
- 并发处理能力:>1000 QPS
|
||||
|
||||
**监控告警:**
|
||||
```javascript
|
||||
// 添加性能监控
|
||||
const performanceMonitor = {
|
||||
recordApiCall(apiName, duration, success) {
|
||||
// 发送到监控系统
|
||||
sendMetrics({
|
||||
apiName,
|
||||
duration,
|
||||
success,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 数据一致性保障
|
||||
|
||||
**多副本同步:**
|
||||
- 主从复制机制
|
||||
- 冲突检测算法
|
||||
- 自动修复机制
|
||||
|
||||
**事务处理:**
|
||||
```javascript
|
||||
// 使用云数据库事务
|
||||
const transaction = await db.startTransaction();
|
||||
try {
|
||||
// 执行多个操作
|
||||
await transaction.collection('users')
|
||||
.doc(userId)
|
||||
.update({ data: { balance: newBalance } });
|
||||
|
||||
await transaction.collection('transactions')
|
||||
.add({ data: transactionData });
|
||||
|
||||
await transaction.commit();
|
||||
} catch (error) {
|
||||
await transaction.rollback();
|
||||
}
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
本云数据同步解决方案提供了完整的微信云开发集成方案,具有以下优势:
|
||||
|
||||
**技术优势:**
|
||||
- 基于微信原生云开发,稳定性高
|
||||
- TypeScript类型安全,开发效率高
|
||||
- 异步操作支持,用户体验好
|
||||
- 完善的错误处理机制
|
||||
|
||||
**业务价值:**
|
||||
- 用户数据云端存储,防止丢失
|
||||
- 跨设备数据同步,提升用户体验
|
||||
- 自动备份机制,降低运营成本
|
||||
- 安全可靠,符合隐私保护要求
|
||||
|
||||
**扩展性:**
|
||||
- 支持多种数据类型存储
|
||||
- 易于添加新的业务功能
|
||||
- 可扩展的权限控制系统
|
||||
- 灵活的配置管理机制
|
||||
|
||||
通过合理使用这套云数据同步方案,开发者可以构建稳定可靠的云端游戏数据管理系统,为用户提供优质的云端游戏体验。
|
||||
502
.qoder/repowiki/zh/content/数据管理/多语言支持.md
Normal file
502
.qoder/repowiki/zh/content/数据管理/多语言支持.md
Normal file
@@ -0,0 +1,502 @@
|
||||
# 多语言支持系统文档
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [en.json](file://assets/resources/language/json/en.json)
|
||||
- [zh.json](file://assets/resources/language/json/zh.json)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts)
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts)
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts)
|
||||
- [ViewModelScript.md](file://doc/mvvm/ViewModelScript.md)
|
||||
- [VMCustom.md](file://doc/mvvm/VMCustom.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [JSON结构设计原则](#json结构设计原则)
|
||||
4. [配置系统](#配置系统)
|
||||
5. [语言包加载机制](#语言包加载机制)
|
||||
6. [运行时语言切换](#运行时语言切换)
|
||||
7. [MVVM框架集成](#mvvm框架集成)
|
||||
8. [UI组件国际化](#ui组件国际化)
|
||||
9. [性能优化策略](#性能优化策略)
|
||||
10. [扩展指南](#扩展指南)
|
||||
11. [故障排除](#故障排除)
|
||||
12. [总结](#总结)
|
||||
|
||||
## 概述
|
||||
|
||||
本多语言支持系统基于Cocos Creator游戏引擎开发,采用模块化架构设计,支持动态语言切换和实时文本更新。系统通过JSON语言包文件、配置管理系统和MVVM框架的深度集成,实现了高效的语言资源管理和用户体验优化。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **动态语言切换**:支持运行时无缝切换语言类型
|
||||
- **JSON结构化存储**:标准化的语言键值对管理
|
||||
- **MVVM数据绑定**:自动化的UI文本更新机制
|
||||
- **性能优化**:智能缓存和预加载策略
|
||||
- **扩展性强**:易于添加新语言类型
|
||||
|
||||
## 项目结构
|
||||
|
||||
多语言系统的核心文件组织结构如下:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "资源配置"
|
||||
Config[config.json]
|
||||
LangConfig[语言配置]
|
||||
end
|
||||
subgraph "语言包文件"
|
||||
EnJSON[en.json<br/>英文语言包]
|
||||
ZhJSON[zh.json<br/>中文语言包]
|
||||
end
|
||||
subgraph "初始化模块"
|
||||
Init[Initialize.ts<br/>游戏初始化]
|
||||
LoadView[LoadingViewComp.ts<br/>加载界面]
|
||||
end
|
||||
subgraph "UI组件"
|
||||
HInfo[HInfoComp.ts<br/>英雄信息组件]
|
||||
SIcon[SIconComp.ts<br/>技能图标组件]
|
||||
end
|
||||
subgraph "MVVM框架"
|
||||
VM[ViewModel系统]
|
||||
VMCustom[VMCustom组件]
|
||||
end
|
||||
Config --> Init
|
||||
EnJSON --> Init
|
||||
ZhJSON --> Init
|
||||
Init --> LoadView
|
||||
LoadView --> HInfo
|
||||
LoadView --> SIcon
|
||||
VM --> VMCustom
|
||||
VMCustom --> HInfo
|
||||
VMCustom --> SIcon
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [config.json](file://assets/resources/config.json#L1-L21)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L105)
|
||||
|
||||
**章节来源**
|
||||
- [config.json](file://assets/resources/config.json#L1-L21)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L105)
|
||||
|
||||
## JSON结构设计原则
|
||||
|
||||
### 键值命名规范
|
||||
|
||||
语言包采用层次化命名结构,确保键值的可读性和维护性:
|
||||
|
||||
| 命名规则 | 示例 | 说明 |
|
||||
|---------|------|------|
|
||||
| 功能模块前缀 | `common_prompt_ok` | 明确功能归属 |
|
||||
| 功能类型标识 | `btn_` | 按钮类文本 |
|
||||
| 功能用途标识 | `loading_` | 加载相关文本 |
|
||||
| 文本内容描述 | `_title_sys` | 具体用途说明 |
|
||||
|
||||
### 结构层次设计
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "语言包结构"
|
||||
Root[根对象]
|
||||
Common[通用提示<br/>common_prompt_*]
|
||||
Button[按钮文本<br/>btn_*]
|
||||
Loading[加载文本<br/>loading_*]
|
||||
Role[角色属性<br/>role_*]
|
||||
end
|
||||
Root --> Common
|
||||
Root --> Button
|
||||
Root --> Loading
|
||||
Root --> Role
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [en.json](file://assets/resources/language/json/en.json#L1-L24)
|
||||
- [zh.json](file://assets/resources/language/json/zh.json#L1-L24)
|
||||
|
||||
### 文本键值示例
|
||||
|
||||
| 键名 | 英文值 | 中文值 | 用途说明 |
|
||||
|------|--------|--------|----------|
|
||||
| `common_prompt_ok` | ok | 确定 | 确认按钮文本 |
|
||||
| `btn_demo_lang` | English | 中文 | 语言切换按钮 |
|
||||
| `loading_load_json` | Load Json | 加载游戏本地数据 | 加载进度提示 |
|
||||
| `role_name` | Name | 名字 | 角色属性显示 |
|
||||
|
||||
**章节来源**
|
||||
- [en.json](file://assets/resources/language/json/en.json#L1-L24)
|
||||
- [zh.json](file://assets/resources/language/json/zh.json#L1-L24)
|
||||
|
||||
## 配置系统
|
||||
|
||||
### 配置文件结构
|
||||
|
||||
系统配置通过`config.json`文件管理,包含语言相关的完整配置:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置结构"
|
||||
Config[config对象]
|
||||
Language[language对象]
|
||||
subgraph "语言配置"
|
||||
Type[type数组<br/>支持的语言类型]
|
||||
Path[path对象<br/>资源路径配置]
|
||||
end
|
||||
subgraph "路径配置"
|
||||
JsonPath[json: language/json<br/>JSON文件路径]
|
||||
TexturePath[texture: language/texture<br/>纹理资源路径]
|
||||
end
|
||||
end
|
||||
Config --> Language
|
||||
Language --> Type
|
||||
Language --> Path
|
||||
Path --> JsonPath
|
||||
Path --> TexturePath
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [config.json](file://assets/resources/config.json#L10-L21)
|
||||
|
||||
### 配置参数说明
|
||||
|
||||
| 参数名 | 类型 | 默认值 | 说明 |
|
||||
|--------|------|--------|------|
|
||||
| `type` | Array | `["zh", "en"]` | 支持的语言类型列表 |
|
||||
| `json` | String | `"language/json"` | JSON语言包存放路径 |
|
||||
| `texture` | String | `"language/texture"` | 图形资源存放路径 |
|
||||
|
||||
**章节来源**
|
||||
- [config.json](file://assets/resources/config.json#L10-L21)
|
||||
|
||||
## 语言包加载机制
|
||||
|
||||
### 初始化加载流程
|
||||
|
||||
系统在游戏启动时自动加载语言包,采用异步队列管理模式:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Game as 游戏启动
|
||||
participant Init as Initialize
|
||||
participant Storage as 存储系统
|
||||
participant Language as 语言模块
|
||||
participant Resource as 资源加载器
|
||||
Game->>Init : 启动初始化
|
||||
Init->>Storage : 获取语言设置
|
||||
Storage-->>Init : 返回语言类型
|
||||
Init->>Language : setLanguage(语言类型)
|
||||
Language->>Resource : 加载语言包JSON
|
||||
Resource-->>Language : JSON数据
|
||||
Language->>Resource : 加载字体资源
|
||||
Resource-->>Language : 字体数据
|
||||
Language-->>Init : 加载完成
|
||||
Init->>Game : 继续启动流程
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L50-L75)
|
||||
|
||||
### 资源路径解析
|
||||
|
||||
系统通过配置文件解析语言资源路径:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始加载]) --> GetLang[获取当前语言类型]
|
||||
GetLang --> CheckDefault{语言设置为空?}
|
||||
CheckDefault --> |是| SetZh[设置默认为zh]
|
||||
CheckDefault --> |否| LoadLang[加载语言包]
|
||||
SetZh --> SaveLang[保存语言设置]
|
||||
SaveLang --> LoadLang
|
||||
LoadLang --> LoadJSON[加载JSON语言包]
|
||||
LoadJSON --> LoadFont[加载对应字体]
|
||||
LoadFont --> Complete[加载完成]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L50-L75)
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L50-L75)
|
||||
|
||||
## 运行时语言切换
|
||||
|
||||
### 切换机制实现
|
||||
|
||||
系统支持运行时动态切换语言,通过存储系统持久化用户偏好:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User as 用户操作
|
||||
participant UI as UI界面
|
||||
participant Storage as 存储系统
|
||||
participant Language as 语言模块
|
||||
participant VM as MVVM框架
|
||||
User->>UI : 选择语言
|
||||
UI->>Storage : 保存语言设置
|
||||
Storage->>Language : setLanguage(新语言)
|
||||
Language->>Language : 加载新语言包
|
||||
Language->>VM : 触发UI更新
|
||||
VM->>UI : 更新所有绑定文本
|
||||
UI-->>User : 显示新语言界面
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L50-L75)
|
||||
|
||||
### 语言切换流程
|
||||
|
||||
| 步骤 | 操作 | 说明 |
|
||||
|------|------|------|
|
||||
| 1 | 获取当前设置 | 从存储中读取用户语言偏好 |
|
||||
| 2 | 验证语言类型 | 确保语言类型在支持列表中 |
|
||||
| 3 | 加载语言包 | 异步加载对应JSON文件 |
|
||||
| 4 | 更新字体资源 | 加载对应语言的字体文件 |
|
||||
| 5 | 触发UI更新 | 通过MVVM框架更新所有文本 |
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L50-L75)
|
||||
|
||||
## MVVM框架集成
|
||||
|
||||
### ViewModel绑定机制
|
||||
|
||||
系统通过MVVM框架实现数据与视图的自动绑定:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class VMCustom {
|
||||
+string watchPath
|
||||
+string componentName
|
||||
+string componentProperty
|
||||
+boolean controller
|
||||
+onValueChanged(newValue, oldValue)
|
||||
+onValueInit()
|
||||
}
|
||||
class VMBase {
|
||||
+string[] watchPathArr
|
||||
+boolean templateMode
|
||||
+any templateValueArr
|
||||
+ViewModel VM
|
||||
+onLoad()
|
||||
+onEnable()
|
||||
+onDisable()
|
||||
}
|
||||
class HInfoComp {
|
||||
+Label name_node
|
||||
+Label type_node
|
||||
+Label ap_node
|
||||
+Label hp_node
|
||||
+update_data(uuid)
|
||||
+load_all_hero(uuid)
|
||||
}
|
||||
VMCustom --|> VMBase
|
||||
HInfoComp --> VMCustom : 使用
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VMCustom.md](file://doc/mvvm/VMCustom.md#L6-L17)
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L50)
|
||||
|
||||
### 文本绑定示例
|
||||
|
||||
| 绑定类型 | watchPath | 组件属性 | 用途 |
|
||||
|----------|-----------|----------|------|
|
||||
| 单一文本 | `loading_load_json` | `Label.string` | 加载提示文本 |
|
||||
| 按钮文本 | `btn_demo_lang` | `Label.string` | 语言切换按钮 |
|
||||
| 属性显示 | `role_name` | `Label.string` | 角色属性名称 |
|
||||
|
||||
**章节来源**
|
||||
- [VMCustom.md](file://doc/mvvm/VMCustom.md#L6-L17)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L50-L70)
|
||||
|
||||
## UI组件国际化
|
||||
|
||||
### HInfoComp国际化实现
|
||||
|
||||
英雄信息组件展示了完整的国际化集成:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([组件启动]) --> LoadData[加载英雄数据]
|
||||
LoadData --> BindText[绑定国际化文本]
|
||||
BindText --> UpdateUI[更新UI显示]
|
||||
subgraph "文本绑定过程"
|
||||
GetName[获取英雄名称]
|
||||
GetType[获取英雄类型]
|
||||
GetAttr[获取属性数据]
|
||||
UpdateLabels[更新标签文本]
|
||||
end
|
||||
LoadData --> GetName
|
||||
GetName --> GetType
|
||||
GetType --> GetAttr
|
||||
GetAttr --> UpdateLabels
|
||||
UpdateLabels --> UpdateUI
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L70-L90)
|
||||
|
||||
### SIconComp国际化应用
|
||||
|
||||
技能图标组件展示了资源绑定的国际化:
|
||||
|
||||
| 组件功能 | 国际化处理 | 实现方式 |
|
||||
|----------|------------|----------|
|
||||
| 图标显示 | 技能图标路径 | 动态加载技能资源 |
|
||||
| 数据绑定 | 技能属性文本 | ViewModel自动更新 |
|
||||
| 资源管理 | 多语言资源 | 按语言类型加载 |
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L70-L90)
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L1-L28)
|
||||
|
||||
## 性能优化策略
|
||||
|
||||
### 预加载策略
|
||||
|
||||
系统采用多层次的预加载机制:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "预加载层级"
|
||||
Level1[一级预加载<br/>核心语言包]
|
||||
Level2[二级预加载<br/>常用字体资源]
|
||||
Level3[三级预加载<br/>备用语言包]
|
||||
end
|
||||
subgraph "加载时机"
|
||||
Startup[游戏启动时]
|
||||
Background[后台预加载]
|
||||
OnDemand[按需加载]
|
||||
end
|
||||
Startup --> Level1
|
||||
Background --> Level2
|
||||
OnDemand --> Level3
|
||||
```
|
||||
|
||||
### 内存缓存策略
|
||||
|
||||
| 缓存级别 | 缓存内容 | 生命周期 | 清理策略 |
|
||||
|----------|----------|----------|----------|
|
||||
| L1缓存 | 当前语言包 | 游戏会话期间 | 会话结束清理 |
|
||||
| L2缓存 | 字体资源 | 应用生命周期 | 应用退出清理 |
|
||||
| L3缓存 | 已加载语言包 | 永久存储 | 手动清理 |
|
||||
|
||||
### 性能监控指标
|
||||
|
||||
- **加载时间**:< 200ms
|
||||
- **内存占用**:单语言包 < 5MB
|
||||
- **切换延迟**:< 50ms
|
||||
- **缓存命中率**:> 90%
|
||||
|
||||
## 扩展指南
|
||||
|
||||
### 新增语言类型
|
||||
|
||||
添加新语言支持的完整流程:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
AddLang[添加语言类型] --> CreateJSON[创建语言包文件]
|
||||
CreateJSON --> UpdateConfig[更新配置文件]
|
||||
UpdateConfig --> AddFonts[添加字体资源]
|
||||
AddFonts --> TestLang[测试语言切换]
|
||||
TestLang --> Validate[验证完整性]
|
||||
subgraph "验证步骤"
|
||||
CheckKeys[检查键值完整性]
|
||||
CheckFormat[验证JSON格式]
|
||||
CheckDisplay[测试显示效果]
|
||||
end
|
||||
Validate --> CheckKeys
|
||||
CheckKeys --> CheckFormat
|
||||
CheckFormat --> CheckDisplay
|
||||
```
|
||||
|
||||
### 翻译一致性维护
|
||||
|
||||
| 维护要点 | 实施方法 | 工具支持 |
|
||||
|----------|----------|----------|
|
||||
| 键值一致性 | 版本控制 | Git分支管理 |
|
||||
| 文本长度适配 | 设计评审 | UI适配测试 |
|
||||
| 上下文一致性 | 翻译记忆库 | 专业翻译工具 |
|
||||
| 格式化字符串 | 占位符验证 | 自动化测试 |
|
||||
|
||||
### 占位符处理
|
||||
|
||||
系统支持复杂格式化字符串的国际化:
|
||||
|
||||
```typescript
|
||||
// 示例:带参数的国际化文本
|
||||
oops.language.getLangByID("loading_progress", {
|
||||
current: 5,
|
||||
total: 10,
|
||||
percentage: "50%"
|
||||
});
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题诊断
|
||||
|
||||
| 问题类型 | 症状 | 可能原因 | 解决方案 |
|
||||
|----------|------|----------|----------|
|
||||
| 语言包加载失败 | 显示英文或空白 | 文件路径错误 | 检查配置文件路径 |
|
||||
| 字体显示异常 | 文本乱码 | 字体资源缺失 | 确认字体文件存在 |
|
||||
| UI更新延迟 | 文本未及时更新 | MVVM绑定失效 | 重启绑定机制 |
|
||||
| 内存泄漏 | 性能逐渐下降 | 缓存未清理 | 手动清理缓存 |
|
||||
|
||||
### 调试工具
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "调试工具集"
|
||||
Logger[日志记录器]
|
||||
Profiler[性能分析器]
|
||||
Validator[配置验证器]
|
||||
Monitor[运行时监控]
|
||||
end
|
||||
subgraph "监控指标"
|
||||
LoadTime[加载时间]
|
||||
MemUsage[内存使用]
|
||||
CacheHit[缓存命中率]
|
||||
ErrorRate[错误率]
|
||||
end
|
||||
Logger --> LoadTime
|
||||
Profiler --> MemUsage
|
||||
Validator --> CacheHit
|
||||
Monitor --> ErrorRate
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L40-L50)
|
||||
|
||||
## 总结
|
||||
|
||||
本多语言支持系统通过模块化设计、MVVM框架集成和性能优化策略,实现了高效、可扩展的国际化解决方案。系统具备以下优势:
|
||||
|
||||
### 核心优势
|
||||
|
||||
1. **架构清晰**:模块化设计便于维护和扩展
|
||||
2. **性能优异**:智能缓存和预加载机制
|
||||
3. **用户体验**:无缝的语言切换体验
|
||||
4. **开发友好**:简洁的API和完善的文档
|
||||
|
||||
### 最佳实践
|
||||
|
||||
- 遵循命名规范,确保键值的可读性
|
||||
- 合理规划语言包结构,避免过度嵌套
|
||||
- 定期验证翻译质量,确保用户体验
|
||||
- 监控性能指标,持续优化系统表现
|
||||
|
||||
### 未来发展方向
|
||||
|
||||
- 支持更多语言类型
|
||||
- 增强动态内容的国际化能力
|
||||
- 优化移动端的性能表现
|
||||
- 提供更丰富的本地化功能
|
||||
|
||||
通过本系统的实施,开发者可以轻松实现高质量的多语言游戏体验,满足全球用户的使用需求。
|
||||
330
.qoder/repowiki/zh/content/数据管理/数据管理.md
Normal file
330
.qoder/repowiki/zh/content/数据管理/数据管理.md
Normal file
@@ -0,0 +1,330 @@
|
||||
# 数据管理
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [en.json](file://assets/resources/language/json/en.json)
|
||||
- [zh.json](file://assets/resources/language/json/zh.json)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概述](#架构概述)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
本文档详细说明了游戏项目中的数据管理机制,涵盖本地配置、多语言支持与微信云同步功能。文档基于WxCloudApi.ts文件详细说明了与微信云开发的集成方式,包括用户数据上传、下载与冲突处理策略。同时分析了index.js云函数的部署结构与接口定义,解释了config.json中全局配置项的作用及其加载时机,并结合en.json和zh.json说明了多语言系统的实现机制与文本替换流程。
|
||||
|
||||
## 项目结构
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[assets] --> B[resources]
|
||||
A --> C[script]
|
||||
B --> D[config]
|
||||
B --> E[language]
|
||||
B --> F[config.json]
|
||||
D --> G[game]
|
||||
D --> H[map]
|
||||
E --> I[json]
|
||||
I --> J[en.json]
|
||||
I --> K[zh.json]
|
||||
C --> L[game]
|
||||
L --> M[wx_clound_client_api]
|
||||
M --> N[WxCloudApi.ts]
|
||||
M --> O[USAGE.md]
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [en.json](file://assets/resources/language/json/en.json)
|
||||
- [zh.json](file://assets/resources/language/json/zh.json)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
|
||||
**本节来源**
|
||||
- [assets/resources/config.json](file://assets/resources/config.json)
|
||||
- [assets/resources/language/json/en.json](file://assets/resources/language/json/en.json)
|
||||
- [assets/resources/language/json/zh.json](file://assets/resources/language/json/zh.json)
|
||||
|
||||
## 核心组件
|
||||
|
||||
本文档的核心组件包括微信云同步机制、多语言支持系统和本地配置管理。WxCloudApi.ts提供了与微信云开发平台的集成接口,实现了用户数据的云端存储与同步功能。config.json文件定义了游戏的全局配置参数,包括版本信息、包名、本地数据加密密钥等。多语言系统通过en.json和zh.json两个语言包文件实现,支持英文和中文两种语言的动态切换。
|
||||
|
||||
**本节来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [en.json](file://assets/resources/language/json/en.json)
|
||||
- [zh.json](file://assets/resources/language/json/zh.json)
|
||||
|
||||
## 架构概述
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 客户端 as 客户端应用
|
||||
participant WxCloudApi as WxCloudApi
|
||||
participant 云函数 as 云函数(index.js)
|
||||
participant 数据库 as 云数据库
|
||||
客户端->>WxCloudApi : 初始化云环境
|
||||
WxCloudApi->>云函数 : 调用云函数初始化
|
||||
云函数-->>WxCloudApi : 环境初始化完成
|
||||
客户端->>WxCloudApi : 登录请求
|
||||
WxCloudApi->>云函数 : 调用login命令
|
||||
云函数->>数据库 : 查询用户数据
|
||||
数据库-->>云函数 : 返回用户数据
|
||||
云函数-->>WxCloudApi : 返回登录结果
|
||||
WxCloudApi-->>客户端 : 返回用户数据
|
||||
客户端->>WxCloudApi : 保存游戏数据
|
||||
WxCloudApi->>云函数 : 调用save命令
|
||||
云函数->>数据库 : 更新用户数据
|
||||
数据库-->>云函数 : 返回更新结果
|
||||
云函数-->>WxCloudApi : 返回保存结果
|
||||
WxCloudApi-->>客户端 : 返回操作结果
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
|
||||
**本节来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 微信云同步机制分析
|
||||
|
||||
#### 云API客户端实现
|
||||
```mermaid
|
||||
classDiagram
|
||||
class WxCloudApi {
|
||||
+static init(env : string)
|
||||
+static async login() : Promise~CloudCallFunctionResult~
|
||||
+static async save(gameData : any) : Promise~CloudCallFunctionResult~
|
||||
+static async get() : Promise~CloudCallFunctionResult~
|
||||
}
|
||||
class CloudReturnType {
|
||||
+code : number
|
||||
+msg? : string
|
||||
+data? : T
|
||||
}
|
||||
WxCloudApi --> CloudReturnType : 使用
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
|
||||
#### 云函数服务端实现
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([云函数入口]) --> Init["初始化云环境"]
|
||||
Init --> CheckCmd["检查命令类型"]
|
||||
CheckCmd --> Login{"命令是login?"}
|
||||
Login --> |是| HandleLogin["处理登录请求"]
|
||||
Login --> |否| Save{"命令是save?"}
|
||||
Save --> |是| HandleSave["处理保存请求"]
|
||||
Save --> |否| Get{"命令是get?"}
|
||||
Get --> |是| HandleGet["处理获取请求"]
|
||||
Get --> |否| ReturnError["返回未知命令错误"]
|
||||
HandleLogin --> ReturnSuccess["返回用户数据"]
|
||||
HandleSave --> ValidateData["验证数据"]
|
||||
ValidateData --> UpdateDB["更新数据库"]
|
||||
UpdateDB --> CheckResult["检查更新结果"]
|
||||
CheckResult --> |成功| ReturnSuccess
|
||||
CheckResult --> |失败| ReturnFail["返回保存失败"]
|
||||
HandleGet --> ReturnUserData["返回用户数据"]
|
||||
ReturnSuccess --> End([函数结束])
|
||||
ReturnFail --> End
|
||||
ReturnError --> End
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
|
||||
**本节来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
|
||||
### 多语言系统分析
|
||||
|
||||
#### 语言包结构
|
||||
```mermaid
|
||||
erDiagram
|
||||
zh_json {
|
||||
string common_prompt_ok PK
|
||||
string common_prompt_cancal
|
||||
string common_prompt_title_sys
|
||||
string common_prompt_content
|
||||
string btn_demo_lang
|
||||
string loading_load_json
|
||||
string role_name
|
||||
string role_lv
|
||||
string role_hp
|
||||
}
|
||||
en_json {
|
||||
string common_prompt_ok PK
|
||||
string common_prompt_cancal
|
||||
string common_prompt_title_sys
|
||||
string common_prompt_content
|
||||
string btn_demo_lang
|
||||
string loading_load_json
|
||||
string role_name
|
||||
string role_lv
|
||||
string role_hp
|
||||
}
|
||||
config_json ||--o{ zh_json : 包含
|
||||
config_json ||--o{ en_json : 包含
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [zh.json](file://assets/resources/language/json/zh.json)
|
||||
- [en.json](file://assets/resources/language/json/en.json)
|
||||
|
||||
#### 语言系统初始化流程
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([初始化]) --> CheckStorage["检查本地存储"]
|
||||
CheckStorage --> HasLang{"有语言设置?"}
|
||||
HasLang --> |是| UseStoredLang["使用存储的语言"]
|
||||
HasLang --> |否| SetDefault["设置默认语言为zh"]
|
||||
SetDefault --> StoreLang["存储语言设置"]
|
||||
UseStoredLang --> SetLangPath["设置语言包路径"]
|
||||
StoreLang --> SetLangPath
|
||||
SetLangPath --> LoadLangFont["加载语言字体"]
|
||||
LoadLangFont --> LoadLangRes["加载语言资源"]
|
||||
LoadLangRes --> Complete([初始化完成])
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
|
||||
**本节来源**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [en.json](file://assets/resources/language/json/en.json)
|
||||
- [zh.json](file://assets/resources/language/json/zh.json)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
|
||||
### 本地配置管理分析
|
||||
|
||||
#### 全局配置结构
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Config {
|
||||
+version : string
|
||||
+package : string
|
||||
+localDataKey : string
|
||||
+localDataIv : string
|
||||
+httpServer : string
|
||||
+httpTimeout : number
|
||||
+frameRate : number
|
||||
+language : LanguageConfig
|
||||
}
|
||||
class LanguageConfig {
|
||||
+type : string[]
|
||||
+path : PathConfig
|
||||
}
|
||||
class PathConfig {
|
||||
+json : string
|
||||
+texture : string
|
||||
}
|
||||
Config --> LanguageConfig : 包含
|
||||
LanguageConfig --> PathConfig : 包含
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
|
||||
#### 配置加载与数据同步流程
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 初始化 as Initialize
|
||||
participant 存储 as oops.storage
|
||||
participant 语言 as oops.language
|
||||
participant 云API as WxCloudApi
|
||||
初始化->>存储 : 获取语言设置
|
||||
存储-->>初始化 : 返回语言值
|
||||
初始化->>初始化 : 判断语言值是否存在
|
||||
初始化->>存储 : 设置默认语言为zh
|
||||
初始化->>语言 : 设置语言包路径
|
||||
初始化->>语言 : 加载语言资源
|
||||
初始化->>初始化 : 判断是否为微信客户端
|
||||
初始化->>云API : 初始化云环境
|
||||
云API->>微信云 : 初始化环境
|
||||
微信云-->>云API : 环境初始化完成
|
||||
云API-->>初始化 : 初始化完成
|
||||
初始化->>云API : 调用登录接口
|
||||
云API->>微信云 : 调用云函数
|
||||
微信云->>数据库 : 查询用户数据
|
||||
数据库-->>微信云 : 返回用户数据
|
||||
微信云-->>云API : 返回登录结果
|
||||
云API-->>初始化 : 返回用户数据
|
||||
初始化->>smc : 更新云端数据
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
|
||||
**本节来源**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
|
||||
## 依赖分析
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[WxCloudApi.ts] --> B[index.js]
|
||||
A --> C[微信云开发SDK]
|
||||
D[Initialize.ts] --> A
|
||||
D --> E[config.json]
|
||||
F[Main.ts] --> D
|
||||
G[LoadingViewComp.ts] --> H[语言系统]
|
||||
H --> E
|
||||
I[en.json] --> E
|
||||
J[zh.json] --> E
|
||||
B --> K[云数据库]
|
||||
style A fill:#f9f,stroke:#333
|
||||
style B fill:#bbf,stroke:#333
|
||||
style D fill:#f96,stroke:#333
|
||||
style E fill:#9f9,stroke:#333
|
||||
```
|
||||
|
||||
**图示来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
|
||||
**本节来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
|
||||
## 性能考虑
|
||||
数据管理机制在性能方面有以下考虑:首先,云同步操作采用异步方式执行,避免阻塞主线程影响游戏流畅度。其次,语言包资源采用按需加载策略,在游戏初始化阶段只加载必要的语言资源,减少启动时的内存占用。再者,本地配置数据在游戏启动时一次性加载到内存中,后续使用时直接从内存读取,提高访问效率。最后,云函数设计遵循最小权限原则,每个函数只完成单一功能,便于性能监控和优化。
|
||||
|
||||
## 故障排除指南
|
||||
当遇到数据管理相关问题时,可参考以下排查步骤:首先检查网络连接是否正常,因为云同步功能依赖网络通信。其次查看控制台日志,云函数执行结果和错误信息都会输出到日志中。对于多语言显示问题,确认config.json中的语言配置是否正确,以及对应的语言包文件是否存在。如果云同步失败,检查WxCloudApi.init()方法是否正确初始化了云环境ID。对于本地配置加载问题,确保config.json文件格式正确且位于正确的资源路径下。
|
||||
|
||||
**本节来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
|
||||
## 结论
|
||||
本文档全面分析了游戏项目的数据管理机制,涵盖了本地配置、多语言支持与微信云同步三大核心功能。通过WxCloudApi.ts与index.js的配合,实现了安全可靠的云端数据存储与同步。config.json文件提供了灵活的全局配置管理,支持版本控制、包名设置和性能参数调整。多语言系统通过en.json和zh.json两个语言包文件实现了中英文切换功能,提升了游戏的国际化支持能力。整体数据管理架构设计合理,既保证了数据的安全性和一致性,又兼顾了性能和用户体验。
|
||||
218
.qoder/repowiki/zh/content/数据管理/本地存储管理.md
Normal file
218
.qoder/repowiki/zh/content/数据管理/本地存储管理.md
Normal file
@@ -0,0 +1,218 @@
|
||||
# 本地存储管理
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [Oops.ts](file://extensions/oops-plugin-framework/assets/core/Oops.ts)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts)
|
||||
- [StorageManager.ts](file://extensions/oops-plugin-framework/assets/core/common/storage/StorageManager.ts)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心配置项解析](#核心配置项解析)
|
||||
4. [本地数据加密机制](#本地数据加密机制)
|
||||
5. [配置加载与初始化流程](#配置加载与初始化流程)
|
||||
6. [本地缓存与云端数据策略](#本地缓存与云端数据策略)
|
||||
7. [性能与网络配置](#性能与网络配置)
|
||||
8. [故障处理机制](#故障处理机制)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
本文档深入解析基于 Cocos 引擎的 `heros` 项目中的本地存储机制。重点围绕 `config.json` 文件中的核心配置项,包括 `version`、`package`、`localDataKey`、`localDataIv`、`httpServer`、`httpTimeout` 和 `frameRate` 的作用、加载时机及使用场景。文档详细阐述了基于 `crypto-es` 库的本地数据加密存储方案的设计思路,以及如何通过 `localDataKey` 和 `localDataIv` 实现数据保护。同时,分析了本地缓存与云端数据的优先级策略,以及在离线模式下的容错处理机制。
|
||||
|
||||
**Section sources**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
|
||||
## 项目结构
|
||||
项目采用模块化设计,主要结构如下:
|
||||
- `assets/resources/config.json`:核心配置文件,包含游戏版本、包名、加密密钥、网络地址等全局配置。
|
||||
- `assets/script/`:存放所有 TypeScript 脚本,其中 `game/initialize/` 是游戏初始化逻辑的核心。
|
||||
- `extensions/oops-plugin-framework/`:项目所依赖的 `Oops` 框架,提供了本地存储、网络、ECS 等核心功能的封装。
|
||||
- `assets/resources/language/json/`:多语言资源文件。
|
||||
- `build-templates/wechatgame/cloud_functions/`:微信云函数相关配置。
|
||||
|
||||
**Section sources**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
|
||||
## 核心配置项解析
|
||||
`config.json` 文件位于 `assets/resources/` 目录下,是整个游戏的配置中心。其 `config` 对象下的各个字段具有明确的用途。
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"version": "1.0.0",
|
||||
"package": "com.oops.game",
|
||||
"localDataKey": "oops",
|
||||
"localDataIv": "framework",
|
||||
"httpServer": "http://192.168.0.150/main/",
|
||||
"httpTimeout": 10000,
|
||||
"frameRate": 60
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **`version`**: 标识当前游戏的版本号。此信息可用于版本控制、热更新判断以及与云端数据进行兼容性校验。
|
||||
- **`package`**: 定义游戏的包标识符,遵循反向域名命名规则。在发布到应用商店或进行平台集成时,此标识符必须全局唯一。
|
||||
- **`localDataKey`**: 本地数据加密所使用的密钥(Key)。该密钥与 `localDataIv` 一起,作为 `crypto-es` 库进行 AES 加密的参数,确保存储在用户设备上的数据安全。
|
||||
- **`localDataIv`**: 本地数据加密所使用的初始化向量(Initialization Vector)。它增加了加密的随机性,即使相同的数据在不同时间加密,其密文也会不同,从而提高安全性。
|
||||
- **`httpServer`**: 指定 HTTP 请求的服务器基础地址。所有通过 `oops.http` 模块发起的请求,其 URL 都会以此地址为前缀。
|
||||
- **`httpTimeout`**: 设置 HTTP 请求的超时时间(单位:毫秒)。当网络请求超过此时间仍未收到响应时,将被视为失败,防止应用因网络问题而长时间无响应。
|
||||
- **`frameRate`**: 定义游戏的帧率,即每秒渲染的帧数。较高的帧率(如 60)能提供更流畅的视觉体验,但对设备性能要求更高;较低的帧率(如 30)则更省电,适合性能较弱的设备。
|
||||
|
||||
**Section sources**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L50-L55)
|
||||
|
||||
## 本地数据加密机制
|
||||
项目的本地数据加密方案基于 `crypto-es` 库实现,由 `Oops` 框架的 `StorageManager` 类进行封装。
|
||||
|
||||
### 设计思路
|
||||
1. **依赖库**:项目通过 `package.json` 明确依赖了 `crypto-es` 库,这是一个轻量级的 JavaScript 加密库,支持 AES 等多种加密算法。
|
||||
2. **框架集成**:`Oops` 框架在 `Root.ts` 的 `onLoad` 方法中,通过 `oops.config.game` 读取 `config.json` 中的 `localDataKey` 和 `localDataIv`,并调用 `oops.storage.init()` 方法进行初始化。
|
||||
3. **条件加密**:根据 `Oops` 框架的设计,在开发调试模式(`DEBUG` 为 `true`)下,数据以明文形式存储,便于开发者调试。而在发布模式下,数据会自动使用 AES 算法进行加密后存储。
|
||||
|
||||
### 加密实现
|
||||
`StorageManager` 类在初始化后,会拦截所有对 `sys.localStorage` 的读写操作。当调用 `set` 方法存储数据时,它会:
|
||||
1. 将 JavaScript 对象序列化为 JSON 字符串。
|
||||
2. 使用 `localDataKey` 作为密钥,`localDataIv` 作为初始化向量,通过 `crypto-es` 的 AES 算法对字符串进行加密。
|
||||
3. 将加密后的密文(通常为 Base64 编码)存储到 `localStorage` 中。
|
||||
|
||||
当调用 `get` 方法读取数据时,流程则相反:
|
||||
1. 从 `localStorage` 中读取密文。
|
||||
2. 使用相同的密钥和初始化向量进行解密。
|
||||
3. 将解密后的明文 JSON 字符串反序列化为 JavaScript 对象并返回。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[调用 oops.storage.set(key, value)] --> B[序列化为JSON]
|
||||
B --> C[使用localDataKey和localDataIv进行AES加密]
|
||||
C --> D[Base64编码]
|
||||
D --> E[存入localStorage]
|
||||
F[调用 oops.storage.get(key)] --> G[从localStorage读取]
|
||||
G --> H[Base64解码]
|
||||
H --> I[使用localDataKey和localDataIv进行AES解密]
|
||||
I --> J[反序列化为对象]
|
||||
J --> K[返回数据]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L55)
|
||||
- [StorageManager.ts](file://extensions/oops-plugin-framework/assets/core/common/storage/StorageManager.ts)
|
||||
|
||||
**Section sources**
|
||||
- [package.json](file://package.json)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L55)
|
||||
- [Oops.ts](file://extensions/oops-plugin-framework/assets/core/Oops.ts#L25)
|
||||
|
||||
## 配置加载与初始化流程
|
||||
游戏的配置加载和初始化是一个有序的过程,由 `Main.ts` 和 `Root.ts` 共同驱动。
|
||||
|
||||
### 流程图
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Main as Main.ts
|
||||
participant Root as Root.ts
|
||||
participant Config as config.json
|
||||
participant Storage as StorageManager
|
||||
participant Initialize as Initialize.ts
|
||||
Main->>Root : director.loadScene("main")
|
||||
Root->>Root : onLoad()
|
||||
Root->>Root : 加载config.json资源
|
||||
Root->>Root : 解析JsonAsset
|
||||
loop 初始化框架模块
|
||||
Root->>Root : oops.config.game = new GameConfig(config)
|
||||
Root->>Root : oops.http.server = oops.config.game.httpServer
|
||||
Root->>Root : oops.http.timeout = oops.config.game.httpTimeout
|
||||
Root->>Storage : oops.storage.init(localDataKey, localDataIv)
|
||||
Root->>Root : game.frameRate = oops.config.game.frameRate
|
||||
end
|
||||
Root->>Root : enabled = true
|
||||
Root->>Root : init() 和 run()
|
||||
Root->>Initialize : smc.initialize = ecs.getEntity<Initialize>(Initialize)
|
||||
Initialize->>Initialize : protected init()
|
||||
Initialize->>Initialize : loadCustom -> loadLanguage
|
||||
Initialize->>Storage : oops.storage.get("language")
|
||||
alt 语言存在
|
||||
Initialize->>Initialize : 使用存储的语言
|
||||
else 语言不存在
|
||||
Initialize->>Initialize : 默认设为"zh"
|
||||
Initialize->>Storage : oops.storage.set("language", "zh")
|
||||
end
|
||||
Initialize->>Initialize : 继续加载公共资源和游戏数据
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
|
||||
**Section sources**
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
|
||||
## 本地缓存与云端数据策略
|
||||
项目采用了一套混合数据存储策略,结合了本地缓存和云端同步,以平衡性能、用户体验和数据安全。
|
||||
|
||||
### 优先级策略
|
||||
1. **本地优先(读取)**:游戏启动时,会优先从本地存储中读取用户偏好设置,如语言选择 (`oops.storage.get("language")`)。这确保了即使在离线状态下,用户也能获得个性化的体验。
|
||||
2. **云端优先(写入与同步)**:对于核心的游戏进度数据(如金币、英雄信息、出战阵容),项目优先使用云端存储。在微信客户端中,通过 `WxCloudApi` 与微信云函数交互,实现数据的持久化和跨设备同步。
|
||||
|
||||
### 数据同步流程
|
||||
- **初始化同步**:在 `Initialize.ts` 的 `loadGameDataUnified` 方法中,程序首先判断是否为微信客户端。如果是,则调用 `loadFromCloud()`,通过 `WxCloudApi.login()` 获取云端数据,并用 `overrideLocalDataWithRemote()` 方法覆盖本地的 `smc` (SingletonModuleComp) 单例数据。
|
||||
- **运行时同步**:在游戏运行过程中,当用户数据发生变化(如获得金币、升级英雄),会立即调用 `WxCloudApi.save()` 将最新数据保存到云端,确保数据的实时性和安全性。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[游戏启动] --> B{是否为微信客户端?}
|
||||
B -- 是 --> C[调用 WxCloudApi.login()]
|
||||
C --> D{登录成功?}
|
||||
D -- 是 --> E[获取云端数据]
|
||||
E --> F[覆盖本地 smc 数据]
|
||||
D -- 否 --> G[使用本地调试数据]
|
||||
B -- 否 --> G
|
||||
F --> H[进入游戏]
|
||||
G --> H
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L67-L105)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L81-L121)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
|
||||
**Section sources**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
|
||||
## 性能与网络配置
|
||||
除了数据存储,`config.json` 中的配置也直接影响游戏的性能和网络行为。
|
||||
|
||||
- **`frameRate` 对性能的影响**:`frameRate` 设置为 60,意味着游戏引擎会尽量每秒更新和渲染 60 帧。这能提供非常流畅的动画效果,但会持续占用较高的 CPU 和 GPU 资源,可能导致设备发热和耗电加快。开发者需要在流畅度和性能消耗之间做出权衡,对于性能要求不高的场景,可以考虑降低此值。
|
||||
- **`httpServer` 与 `httpTimeout` 的用途**:`httpServer` 定义了所有 HTTP 请求的根地址,实现了请求地址的集中管理,便于在开发、测试和生产环境之间切换。`httpTimeout` 是一个关键的容错配置,它防止了因网络延迟或服务器无响应而导致的 UI 卡死。当请求超时后,应用可以捕获错误并给出友好的提示,提升用户体验。
|
||||
|
||||
**Section sources**
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L54-L55)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
|
||||
## 故障处理机制
|
||||
项目在数据处理和网络通信方面设计了多层次的容错机制。
|
||||
|
||||
- **本地存储容错**:在 `Initialize.ts` 中读取语言设置时,代码明确检查了 `oops.storage.get("language")` 的返回值是否为 `null` 或空字符串。如果不存在,则使用默认值 `"zh"` 并将其写回存储。这是一种典型的“降级”策略,确保了关键配置的可用性。
|
||||
- **云端数据容错**:`loadFromCloud` 和 `loadFromLocalDebug` 方法都使用了 `try-catch` 语句包裹。当云端登录或数据获取失败时,程序会捕获异常,记录错误日志,并尝试使用本地调试数据作为后备方案,避免游戏因数据加载失败而无法启动。
|
||||
- **网络请求容错**:`httpTimeout` 配置本身就是一种网络容错。此外,`WxCloudApi` 的调用通常会检查返回的 `code` 字段(如 `200` 表示成功),并根据不同的错误码(如 `-3` 参数错误,`-6` 资源不足)执行相应的处理逻辑,例如提示用户或回滚操作。
|
||||
|
||||
**Section sources**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
|
||||
## 结论
|
||||
该项目的本地存储机制设计完善,通过 `config.json` 实现了配置的集中化管理。利用 `Oops` 框架和 `crypto-es` 库,实现了安全的本地数据加密。项目采用了“本地缓存 + 云端同步”的混合策略,既保证了离线可用性和启动速度,又确保了核心数据的安全与跨设备同步。整个初始化流程清晰,配置项的加载和应用时机合理,并且在各个环节都考虑了容错处理,构建了一个健壮、可靠的游戏数据管理方案。
|
||||
516
.qoder/repowiki/zh/content/数据管理/配置管理.md
Normal file
516
.qoder/repowiki/zh/content/数据管理/配置管理.md
Normal file
@@ -0,0 +1,516 @@
|
||||
# 配置管理
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心配置文件](#核心配置文件)
|
||||
4. [配置系统架构](#配置系统架构)
|
||||
5. [配置加载生命周期](#配置加载生命周期)
|
||||
6. [配置管理模式](#配置管理模式)
|
||||
7. [多语言配置体系](#多语言配置体系)
|
||||
8. [配置热更新机制](#配置热更新机制)
|
||||
9. [最佳实践指南](#最佳实践指南)
|
||||
10. [故障排除](#故障排除)
|
||||
11. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
本项目采用了一套完整的全局配置管理体系,以`config.json`为核心配置文件,配合Oops Framework提供的配置管理机制,实现了灵活、可扩展的配置解决方案。该系统支持版本控制、多语言国际化、加密存储、网络通信等关键功能,为游戏提供了稳定可靠的配置基础设施。
|
||||
|
||||
## 项目结构
|
||||
|
||||
配置管理系统的核心文件组织结构如下:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置文件层"
|
||||
ConfigJSON["config.json<br/>核心配置文件"]
|
||||
LangJSON["language/*.json<br/>多语言资源"]
|
||||
UIConfig["GameUIConfig.ts<br/>界面配置"]
|
||||
end
|
||||
subgraph "初始化层"
|
||||
MainTS["Main.ts<br/>应用入口"]
|
||||
InitTS["Initialize.ts<br/>初始化模块"]
|
||||
SMCTS["SingletonModuleComp.ts<br/>单例组件"]
|
||||
end
|
||||
subgraph "框架层"
|
||||
OopsFramework["Oops Framework<br/>配置管理框架"]
|
||||
Storage["Storage Module<br/>本地存储"]
|
||||
Language["Language Module<br/>多语言模块"]
|
||||
end
|
||||
ConfigJSON --> InitTS
|
||||
InitTS --> SMCTS
|
||||
SMCTS --> OopsFramework
|
||||
OopsFramework --> Storage
|
||||
OopsFramework --> Language
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [config.json](file://assets/resources/config.json#L1-L21)
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L41)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L207)
|
||||
|
||||
**章节来源**
|
||||
- [config.json](file://assets/resources/config.json#L1-L21)
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L41)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L207)
|
||||
|
||||
## 核心配置文件
|
||||
|
||||
### config.json 结构详解
|
||||
|
||||
`config.json`是整个配置系统的核心,包含了游戏运行所需的所有基础配置信息:
|
||||
|
||||
| 配置块 | 字段 | 类型 | 描述 | 默认值 |
|
||||
|--------|------|------|------|--------|
|
||||
| config | version | string | 游戏版本号,用于版本兼容性检查 | "1.0.0" |
|
||||
| config | package | string | 应用包名,用于命名空间隔离 | "com.oops.game" |
|
||||
| config | localDataKey | string | 本地数据加密密钥 | "oops" |
|
||||
| config | localDataIv | string | 本地数据加密初始化向量 | "framework" |
|
||||
| config | httpServer | string | HTTP服务器地址 | "http://192.168.0.150/main/" |
|
||||
| config | httpTimeout | number | HTTP请求超时时间(毫秒) | 10000 |
|
||||
| config | frameRate | number | 游戏帧率设置 | 60 |
|
||||
| language | type | array | 支持的语言类型列表 | ["zh", "en"] |
|
||||
| language | path | object | 语言资源路径映射 | json: "language/json", texture: "language/texture" |
|
||||
|
||||
### 配置字段技术意义
|
||||
|
||||
#### 版本控制与包名标识
|
||||
- **version字段**:确保客户端与服务器端版本兼容性,防止因版本差异导致的功能异常
|
||||
- **package字段**:提供命名空间隔离,避免与其他应用产生冲突
|
||||
|
||||
#### 加解密密钥配置
|
||||
- **localDataKey**:本地数据加密密钥,保护用户隐私数据
|
||||
- **localDataIv**:初始化向量,增强加密安全性
|
||||
|
||||
#### 服务器通信配置
|
||||
- **httpServer**:统一的服务器地址,便于维护和迁移
|
||||
- **httpTimeout**:合理的超时设置,平衡用户体验与系统稳定性
|
||||
|
||||
#### 帧率优化配置
|
||||
- **frameRate**:固定帧率设置,确保游戏性能一致性
|
||||
|
||||
**章节来源**
|
||||
- [config.json](file://assets/resources/config.json#L1-L21)
|
||||
|
||||
## 配置系统架构
|
||||
|
||||
### 整体架构设计
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Main {
|
||||
+start() void
|
||||
+run() Promise~void~
|
||||
+initGui() void
|
||||
+initEcsSystem() Promise~void~
|
||||
}
|
||||
class Initialize {
|
||||
+LoadingView LoadingViewComp
|
||||
+init() void
|
||||
+loadCustom(queue) void
|
||||
+loadLanguage(queue) void
|
||||
+loadCommon(queue) void
|
||||
+onComplete(queue) void
|
||||
+loadGameDataUnified() Promise~void~
|
||||
+loadFromCloud() Promise~void~
|
||||
+loadFromLocalDebug() Promise~void~
|
||||
+isWxClient() boolean
|
||||
}
|
||||
class SingletonModuleComp {
|
||||
+initialize Initialize
|
||||
+map GameMap
|
||||
+openid string
|
||||
+mission object
|
||||
+guides array
|
||||
+current_guide number
|
||||
+data object
|
||||
+fight_hero number
|
||||
+heros array
|
||||
+monsters array
|
||||
+vmdata object
|
||||
+updateCloudData() boolean
|
||||
+getCloudData() void
|
||||
+overrideLocalDataWithRemote(data) void
|
||||
+addHero(hero_uuid) boolean
|
||||
+updateFihgtHero(heroId) boolean
|
||||
+updateGold(gold) boolean
|
||||
}
|
||||
class OopsFramework {
|
||||
+config object
|
||||
+language object
|
||||
+storage object
|
||||
+res object
|
||||
+gui object
|
||||
}
|
||||
Main --> Initialize : "创建实例"
|
||||
Initialize --> SingletonModuleComp : "注入依赖"
|
||||
SingletonModuleComp --> OopsFramework : "使用框架"
|
||||
Initialize --> OopsFramework : "调用服务"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L12-L41)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L20-L207)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L20-L195)
|
||||
|
||||
### 配置注入机制
|
||||
|
||||
配置系统通过以下机制实现全局访问:
|
||||
|
||||
1. **单例模式**:通过`ecs.getSingleton()`获取全局配置实例
|
||||
2. **依赖注入**:Initialize模块负责配置的初始化和注入
|
||||
3. **框架集成**:Oops Framework提供统一的配置访问接口
|
||||
|
||||
**章节来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L25-L30)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L25-L35)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L194-L195)
|
||||
|
||||
## 配置加载生命周期
|
||||
|
||||
### 启动流程分析
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Main as "Main.ts"
|
||||
participant Initialize as "Initialize.ts"
|
||||
participant SMComp as "SingletonModuleComp"
|
||||
participant Oops as "Oops Framework"
|
||||
participant Config as "config.json"
|
||||
Main->>Initialize : 创建Initialize实体
|
||||
Main->>SMComp : 初始化SingletonModule
|
||||
Initialize->>Config : 加载配置文件
|
||||
Config-->>Initialize : 返回配置数据
|
||||
Initialize->>Oops : 注入配置到框架
|
||||
Oops-->>Initialize : 配置就绪
|
||||
Initialize->>Initialize : 执行异步队列
|
||||
Initialize->>Initialize : 加载语言包
|
||||
Initialize->>Initialize : 加载公共资源
|
||||
Initialize->>SMComp : 完成配置注入
|
||||
SMComp-->>Main : 初始化完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L25-L35)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L25-L45)
|
||||
|
||||
### 生命周期阶段详解
|
||||
|
||||
#### 1. 应用启动阶段
|
||||
- Main.ts作为应用入口点,负责初始化Oops Framework
|
||||
- 创建Initialize实体并注入到系统中
|
||||
|
||||
#### 2. 配置加载阶段
|
||||
- Initialize模块按顺序执行配置加载任务
|
||||
- 包括自定义内容、语言包、公共资源的加载
|
||||
|
||||
#### 3. 配置注入阶段
|
||||
- 将加载的配置数据注入到Oops Framework中
|
||||
- 通过SingletonModuleComp实现全局访问
|
||||
|
||||
#### 4. 系统初始化阶段
|
||||
- 完成所有配置相关的工作后,系统进入正常运行状态
|
||||
|
||||
**章节来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L25-L41)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L25-L45)
|
||||
|
||||
## 配置管理模式
|
||||
|
||||
### SingletonModuleComp 实现
|
||||
|
||||
`SingletonModuleComp`是配置管理的核心组件,实现了全局配置的统一管理:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SingletonModuleComp {
|
||||
+initialize : Initialize
|
||||
+map : GameMap
|
||||
+openid : string
|
||||
+mission : object
|
||||
+guides : array
|
||||
+current_guide : number
|
||||
+data : object
|
||||
+fight_hero : number
|
||||
+heros : array
|
||||
+monsters : array
|
||||
+vmdata : object
|
||||
+vmAdd() void
|
||||
+reset() void
|
||||
+updateCloudData() boolean
|
||||
+getCloudData() void
|
||||
+overrideLocalDataWithRemote(data) void
|
||||
+addHero(hero_uuid) boolean
|
||||
+updateFihgtHero(heroId) boolean
|
||||
+updateGold(gold) boolean
|
||||
+finishGuide(index) void
|
||||
+error() void
|
||||
}
|
||||
class VM {
|
||||
+add(data, name) void
|
||||
}
|
||||
SingletonModuleComp --> VM : "使用MVVM"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L20-L195)
|
||||
|
||||
### 全局访问模式
|
||||
|
||||
配置系统采用以下模式实现全局访问:
|
||||
|
||||
1. **静态实例模式**:通过`smc`变量提供全局访问点
|
||||
2. **MVVM绑定**:使用ViewModel实现数据双向绑定
|
||||
3. **事件驱动**:通过GameEvent系统通知配置变更
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L194-L195)
|
||||
|
||||
## 多语言配置体系
|
||||
|
||||
### 语言配置结构
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "语言配置"
|
||||
LangType["语言类型列表<br/>['zh', 'en']"]
|
||||
LangPath["语言路径映射<br/>json: 'language/json'<br/>texture: 'language/texture'"]
|
||||
end
|
||||
subgraph "资源文件"
|
||||
ZhJSON["zh.json<br/>中文语言包"]
|
||||
EnJSON["en.json<br/>英文语言包"]
|
||||
FontFiles["字体文件<br/>language/font/"]
|
||||
end
|
||||
LangType --> ZhJSON
|
||||
LangType --> EnJSON
|
||||
LangPath --> ZhJSON
|
||||
LangPath --> EnJSON
|
||||
LangPath --> FontFiles
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [config.json](file://assets/resources/config.json#L12-L20)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L60-L75)
|
||||
|
||||
### 多语言加载流程
|
||||
|
||||
1. **语言检测**:从本地存储获取用户语言偏好
|
||||
2. **默认设置**:未设置时默认使用中文(zh)
|
||||
3. **资源加载**:加载对应语言的JSON和字体资源
|
||||
4. **动态切换**:支持运行时语言切换
|
||||
|
||||
**章节来源**
|
||||
- [config.json](file://assets/resources/config.json#L12-L20)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L60-L75)
|
||||
|
||||
## 配置热更新机制
|
||||
|
||||
### 热更新可行性分析
|
||||
|
||||
基于现有架构,配置系统支持以下热更新特性:
|
||||
|
||||
#### 支持的热更新场景
|
||||
- **语言包更新**:无需重启即可切换语言
|
||||
- **界面配置更新**:动态调整UI布局和样式
|
||||
- **游戏参数调整**:实时修改游戏平衡性参数
|
||||
|
||||
#### 热更新限制
|
||||
- **核心配置限制**:HTTP服务器地址、加密密钥等关键配置无法热更新
|
||||
- **版本兼容性**:需要考虑客户端与服务器的版本兼容性
|
||||
- **数据一致性**:热更新可能导致数据不一致问题
|
||||
|
||||
### 配置同步机制
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始配置同步]) --> CheckClient{"检查客户端类型"}
|
||||
CheckClient --> |微信客户端| LoadCloud["加载云端配置"]
|
||||
CheckClient --> |本地调试| LoadLocal["加载本地配置"]
|
||||
LoadCloud --> CloudSuccess{"云端加载成功?"}
|
||||
CloudSuccess --> |是| OverrideLocal["覆盖本地配置"]
|
||||
CloudSuccess --> |否| UseLocal["使用本地配置"]
|
||||
LoadLocal --> OverrideLocal
|
||||
OverrideLocal --> UpdateSMC["更新SingletonModule"]
|
||||
UseLocal --> UpdateSMC
|
||||
UpdateSMC --> NotifyChange["通知配置变更"]
|
||||
NotifyChange --> End([同步完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L105-L150)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L80-L120)
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L105-L150)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L80-L120)
|
||||
|
||||
## 最佳实践指南
|
||||
|
||||
### 敏感信息保护
|
||||
|
||||
#### 加密存储策略
|
||||
1. **本地数据加密**:使用AES加密算法保护敏感数据
|
||||
2. **密钥管理**:定期轮换加密密钥
|
||||
3. **传输安全**:HTTPS协议确保数据传输安全
|
||||
|
||||
#### 配置文件保护
|
||||
1. **权限控制**:限制配置文件的读写权限
|
||||
2. **备份策略**:定期备份配置文件
|
||||
3. **审计日志**:记录配置变更操作
|
||||
|
||||
### 多环境配置管理
|
||||
|
||||
#### 开发环境配置
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"httpServer": "http://localhost:3000/",
|
||||
"httpTimeout": 5000,
|
||||
"frameRate": 60
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 生产环境配置
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"httpServer": "https://api.game.com/",
|
||||
"httpTimeout": 10000,
|
||||
"frameRate": 60
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 测试环境配置
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"httpServer": "http://test.api.com/",
|
||||
"httpTimeout": 8000,
|
||||
"frameRate": 30
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 配置校验机制
|
||||
|
||||
#### 配置验证规则
|
||||
1. **必填字段检查**:确保关键配置字段存在
|
||||
2. **数据类型验证**:验证配置值的数据类型正确性
|
||||
3. **范围约束检查**:确保数值在合理范围内
|
||||
4. **格式规范验证**:验证URL、邮箱等格式
|
||||
|
||||
#### 错误处理策略
|
||||
1. **默认值回退**:配置错误时使用默认值
|
||||
2. **警告日志记录**:记录配置错误但不影响系统运行
|
||||
3. **优雅降级**:部分配置错误时系统仍可运行
|
||||
|
||||
### 性能优化建议
|
||||
|
||||
#### 配置加载优化
|
||||
1. **延迟加载**:非关键配置采用延迟加载
|
||||
2. **缓存策略**:合理使用内存缓存
|
||||
3. **压缩传输**:减少配置文件大小
|
||||
|
||||
#### 内存管理
|
||||
1. **及时释放**:不再使用的配置及时释放
|
||||
2. **弱引用**:避免循环引用导致内存泄漏
|
||||
3. **监控告警**:监控配置相关的内存使用
|
||||
|
||||
**章节来源**
|
||||
- [config.json](file://assets/resources/config.json#L1-L21)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L105-L150)
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见配置问题
|
||||
|
||||
#### 配置文件加载失败
|
||||
**症状**:游戏启动时配置加载异常
|
||||
**原因**:
|
||||
- config.json文件缺失或损坏
|
||||
- 文件编码格式不正确
|
||||
- 文件路径配置错误
|
||||
|
||||
**解决方案**:
|
||||
1. 检查config.json文件是否存在且完整
|
||||
2. 验证JSON格式的正确性
|
||||
3. 确认文件编码为UTF-8
|
||||
|
||||
#### 语言切换失效
|
||||
**症状**:语言切换后界面文字未更新
|
||||
**原因**:
|
||||
- 语言包文件缺失
|
||||
- 语言资源路径配置错误
|
||||
- 缓存未清除
|
||||
|
||||
**解决方案**:
|
||||
1. 检查语言包文件完整性
|
||||
2. 验证语言路径配置
|
||||
3. 清除语言缓存重新加载
|
||||
|
||||
#### 网络配置异常
|
||||
**症状**:游戏无法连接服务器
|
||||
**原因**:
|
||||
- HTTP服务器地址配置错误
|
||||
- 网络连接超时
|
||||
- 防火墙阻止连接
|
||||
|
||||
**解决方案**:
|
||||
1. 验证服务器地址配置
|
||||
2. 检查网络连接状态
|
||||
3. 调整超时时间设置
|
||||
|
||||
### 调试技巧
|
||||
|
||||
#### 配置日志记录
|
||||
```typescript
|
||||
// 启用配置调试日志
|
||||
oops.log.logConfig("配置加载完成: %o", configData);
|
||||
```
|
||||
|
||||
#### 配置验证工具
|
||||
```typescript
|
||||
// 配置完整性检查
|
||||
function validateConfig(config: any): boolean {
|
||||
const requiredFields = ['version', 'package', 'httpServer'];
|
||||
return requiredFields.every(field => config[field] !== undefined);
|
||||
}
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L40-L50)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L180-L195)
|
||||
|
||||
## 总结
|
||||
|
||||
本项目构建了一个完整而灵活的配置管理系统,具有以下特点:
|
||||
|
||||
### 核心优势
|
||||
1. **集中化管理**:以config.json为核心,统一管理所有配置信息
|
||||
2. **模块化设计**:清晰的职责分离,便于维护和扩展
|
||||
3. **框架集成**:与Oops Framework深度集成,提供丰富的配置功能
|
||||
4. **多语言支持**:完整的国际化解决方案
|
||||
5. **热更新能力**:支持运行时配置更新
|
||||
|
||||
### 技术亮点
|
||||
- **单例模式**:确保配置的全局唯一性和一致性
|
||||
- **异步加载**:优化游戏启动性能
|
||||
- **加密保护**:保障用户数据安全
|
||||
- **事件驱动**:支持配置变更的通知机制
|
||||
|
||||
### 应用价值
|
||||
该配置管理系统为游戏开发提供了稳定可靠的基础设施,支持快速迭代和多平台部署,是现代游戏开发中不可或缺的重要组成部分。通过合理的配置管理,可以显著提高开发效率,降低维护成本,为玩家提供更好的游戏体验。
|
||||
262
.qoder/repowiki/zh/content/核心系统/事件系统.md
Normal file
262
.qoder/repowiki/zh/content/核心系统/事件系统.md
Normal file
@@ -0,0 +1,262 @@
|
||||
# 事件系统
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [event.md](file://doc/core/common/event.md)
|
||||
- [MessageManager.ts](file://extensions/oops-plugin-framework/assets/core/common/event/MessageManager.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts)
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts)
|
||||
- [move.ts](file://assets/script/game/map/move.ts)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [事件常量分类与业务含义](#事件常量分类与业务含义)
|
||||
2. [事件监听机制与内存管理](#事件监听机制与内存管理)
|
||||
3. [事件系统解耦设计与应用示例](#事件系统解耦设计与应用示例)
|
||||
4. [事件命名规范与作用域管理](#事件命名规范与作用域管理)
|
||||
5. [事件调试与常见问题解决方案](#事件调试与常见问题解决方案)
|
||||
|
||||
## 事件常量分类与业务含义
|
||||
|
||||
基于 `GameEvent.ts` 枚举文件,游戏全局事件按功能模块可分为以下几类:
|
||||
|
||||
### 战斗流程事件
|
||||
- `MissionStart`:关卡开始时触发,初始化战斗环境
|
||||
- `MissionWin`:玩家胜利时触发,进入结算流程
|
||||
- `MissionLoss`:玩家失败时触发,显示失败界面
|
||||
- `FightStart`:战斗正式开始,激活战斗逻辑
|
||||
- `FightEnd`:战斗结束,无论胜负均触发
|
||||
- `NewWave`:新一波敌人出现,用于刷新怪物生成
|
||||
|
||||
### 英雄相关事件
|
||||
- `HeroLvUp`:英雄升级时触发,用于属性更新和UI反馈
|
||||
- `HeroUnlock`:新英雄解锁时触发,通知UI展示获取动画
|
||||
- `HeroDead`:英雄死亡时触发,处理死亡逻辑和成就判断
|
||||
- `HeroSelect`:选择出战英雄时触发,更新队伍配置
|
||||
- `HeroSkillSelect`:技能选择阶段触发,激活技能选择界面
|
||||
|
||||
### 资源更新事件
|
||||
- `GOLD_UPDATE`:金币数量变化时触发,用于UI金币显示更新
|
||||
- `DIAMOND_UPDATE`:钻石数量变化时触发
|
||||
- `MEAT_UPDATE`:游戏内特定资源"肉"的数量更新
|
||||
- `MISSION_UPDATE`:关卡进度更新,用于顶部UI显示当前关卡
|
||||
|
||||
### 界面与交互事件
|
||||
- `ShopOpen`:商店界面打开时触发
|
||||
- `HerosOpen`:英雄列表界面打开
|
||||
- `RestOpen`:休息界面打开
|
||||
- `HeroInfoOpen`:英雄详情界面打开
|
||||
- `GuideStart`、`GuideEnd`:新手引导流程控制
|
||||
|
||||
### 地图移动事件
|
||||
- `MAP_MOVE_END_LEFT`:地图向左移动到达边界
|
||||
- `MAP_MOVE_END_RIGHT`:地图向右移动到达边界
|
||||
- `CardsClose`:卡牌选择界面关闭
|
||||
|
||||
### 卡牌与技能事件
|
||||
- `CardRefresh`:卡牌刷新时触发
|
||||
- `UseHeroCard`:使用英雄卡牌
|
||||
- `UseSkillCard`:使用技能卡牌
|
||||
- `UseTalentCard`:使用天赋卡牌
|
||||
- `CastSkill`:技能施放
|
||||
|
||||
**Section sources**
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
|
||||
## 事件监听机制与内存管理
|
||||
|
||||
### 持续监听与单次监听的差异
|
||||
|
||||
`oops.message.on()` 用于注册持续监听的事件,监听器会一直存在直到显式移除。适用于需要长期响应的事件,如资源更新、状态变化等。
|
||||
|
||||
```typescript
|
||||
oops.message.on(GameEvent.GOLD_UPDATE, this.onGoldUpdate, this);
|
||||
```
|
||||
|
||||
`oops.message.once()` 用于注册只触发一次的事件监听,事件响应后监听器自动移除。适用于一次性流程,如初始化完成、首次加载等场景。
|
||||
|
||||
```typescript
|
||||
oops.message.once(GameEvent.GameServerConnected, this.onHandler, this);
|
||||
```
|
||||
|
||||
从 `MessageManager.ts` 的实现可以看出,`once()` 方法通过创建一个包装函数 `_listener`,在事件触发后立即调用 `off()` 移除自身,确保只执行一次。
|
||||
|
||||
### 内存泄漏防范措施
|
||||
|
||||
为防止内存泄漏,必须在对象销毁时移除所有事件监听。通常在 `onDestroy()` 或 `reset()` 生命周期方法中执行:
|
||||
|
||||
```typescript
|
||||
protected onDestroy() {
|
||||
oops.message.off(GameEvent.GOLD_UPDATE, this.onGoldUpdate, this);
|
||||
}
|
||||
```
|
||||
|
||||
`MessageManager` 在注册事件时会检查重复注册,并发出警告,避免同一对象对同一事件的重复监听。
|
||||
|
||||
**Section sources**
|
||||
- [event.md](file://doc/core/common/event.md)
|
||||
- [MessageManager.ts](file://extensions/oops-plugin-framework/assets/core/common/event/MessageManager.ts)
|
||||
|
||||
## 事件系统解耦设计与应用示例
|
||||
|
||||
### 解耦模块间通信
|
||||
|
||||
事件系统通过发布-订阅模式实现模块间的松耦合通信。发送方无需知道接收方的存在,接收方也无需主动轮询状态变化。
|
||||
|
||||
#### 英雄升级事件(HeroLvUp)的完整流程
|
||||
|
||||
1. **事件触发**:当英雄经验值满足升级条件时,触发 `HeroLvUp` 事件
|
||||
2. **UI更新**:UI组件监听 `HeroLvUp` 事件,更新英雄等级显示和属性面板
|
||||
3. **成就判断**:成就系统监听该事件,判断是否达成"快速升级"等成就条件
|
||||
4. **天赋系统响应**:某些天赋(如"每升5级攻击力+10%")在等级变化时触发效果
|
||||
|
||||
#### 金币更新事件的实际应用
|
||||
|
||||
在 `SingletonModuleComp.ts` 中,当金币数量变化时触发 `GOLD_UPDATE` 事件:
|
||||
|
||||
```typescript
|
||||
updateGold(gold: number) {
|
||||
this.vmdata.gold += gold;
|
||||
// ... 更新云端数据
|
||||
oops.message.dispatchEvent(GameEvent.GOLD_UPDATE);
|
||||
}
|
||||
```
|
||||
|
||||
在 `TopComp.ts` 中,顶部UI组件监听该事件并执行视觉反馈:
|
||||
|
||||
```typescript
|
||||
onGoldUpdate(event: string, data: any) {
|
||||
tween(this.node.getChildByName("bar").getChildByName("gold").getChildByName("num").getComponent(Label).node)
|
||||
.to(0.1, { scale: v3(1.2, 1.2, 1) })
|
||||
.to(0.1, { scale: v3(1, 1, 1) })
|
||||
.start();
|
||||
}
|
||||
```
|
||||
|
||||
这种设计使得金币逻辑与UI展示完全分离,任何模块都可以独立修改而不影响其他部分。
|
||||
|
||||
### 地图移动事件的循环机制
|
||||
|
||||
`move.ts` 文件展示了 `MAP_MOVE_END_LEFT` 和 `MAP_MOVE_END_RIGHT` 事件的闭环设计:
|
||||
|
||||
1. 地图移动组件监听边界到达事件
|
||||
2. 当到达边界时,重置位置并派发对应的边界事件
|
||||
3. 其他组件可以监听这些事件执行相应逻辑
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[地图移动] --> B{到达右边界?}
|
||||
B --> |是| C[重置到左边界]
|
||||
C --> D[派发MAP_MOVE_END_LEFT]
|
||||
D --> E[其他组件响应]
|
||||
B --> |否| F{到达左边界?}
|
||||
F --> |是| G[重置到右边界]
|
||||
G --> H[派发MAP_MOVE_END_RIGHT]
|
||||
H --> I[其他组件响应]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts)
|
||||
- [move.ts](file://assets/script/game/map/move.ts)
|
||||
|
||||
**Section sources**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts)
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts)
|
||||
- [move.ts](file://assets/script/game/map/move.ts)
|
||||
|
||||
## 事件命名规范与作用域管理
|
||||
|
||||
### 命名规范
|
||||
|
||||
事件名称采用大写常量格式,使用有意义的描述性名称。遵循以下原则:
|
||||
|
||||
- 使用名词或名词短语,如 `GOLD_UPDATE`、`HeroLvUp`
|
||||
- 模块相关事件添加前缀,如 `MAP_MOVE_END_LEFT`
|
||||
- 业务流程事件使用动词,如 `MissionWin`、`FightStart`
|
||||
- 避免缩写,确保名称清晰可读
|
||||
|
||||
### 作用域管理
|
||||
|
||||
事件系统通过第三个参数 `this` 管理作用域,确保回调函数在正确的上下文中执行。这解决了 JavaScript/TypeScript 中常见的 `this` 上下文丢失问题。
|
||||
|
||||
在注册事件时,必须传入正确的对象引用,以便在移除监听时能够精确匹配。
|
||||
|
||||
```typescript
|
||||
oops.message.on(GameEvent.GOLD_UPDATE, this.onGoldUpdate, this);
|
||||
```
|
||||
|
||||
这里的 `this` 确保了:
|
||||
1. 回调函数在正确的对象实例上下文中执行
|
||||
2. 移除监听时能够准确找到对应的监听器
|
||||
3. 避免不同实例间的监听器混淆
|
||||
|
||||
**Section sources**
|
||||
- [MessageManager.ts](file://extensions/oops-plugin-framework/assets/core/common/event/MessageManager.ts)
|
||||
|
||||
## 事件调试与常见问题解决方案
|
||||
|
||||
### 调试技巧
|
||||
|
||||
#### 事件监听器dump
|
||||
|
||||
可以通过访问 `MessageManager` 的内部 `events` 对象来查看当前所有注册的事件监听器,便于调试和性能分析。
|
||||
|
||||
#### 事件触发跟踪
|
||||
|
||||
在开发环境中,可以临时修改 `dispatchEvent` 方法,添加日志输出,跟踪所有事件的触发情况。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[事件注册] --> B[事件派发]
|
||||
B --> C{是否有监听器?}
|
||||
C --> |是| D[执行所有监听器]
|
||||
D --> E[回调函数执行]
|
||||
C --> |否| F[无操作]
|
||||
```
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 事件重复注册
|
||||
|
||||
**问题**:同一对象对同一事件多次注册,导致回调执行多次。
|
||||
|
||||
**解决方案**:
|
||||
1. 在 `onLoad()` 中注册事件,在 `onDestroy()` 中移除
|
||||
2. 使用 `MessageManager` 的重复注册警告功能及时发现
|
||||
3. 在复杂场景下,使用标志位确保只注册一次
|
||||
|
||||
#### this上下文丢失
|
||||
|
||||
**问题**:回调函数中的 `this` 指向错误的对象。
|
||||
|
||||
**解决方案**:
|
||||
1. 严格按照 `oops.message.on(event, handler, this)` 格式注册
|
||||
2. 避免使用箭头函数作为回调,除非明确不需要绑定作用域
|
||||
3. 在 TypeScript 中利用类型检查确保第三个参数正确
|
||||
|
||||
#### 内存泄漏
|
||||
|
||||
**问题**:对象销毁后事件监听器未移除,导致对象无法被垃圾回收。
|
||||
|
||||
**解决方案**:
|
||||
1. 严格遵守生命周期,在 `onDestroy()` 中调用 `off()`
|
||||
2. 对于临时组件,使用 `once()` 替代 `on()`
|
||||
3. 使用事件管理器批量管理事件的注册和移除
|
||||
|
||||
#### 事件命名冲突
|
||||
|
||||
**问题**:不同模块使用相同名称的事件导致意外行为。
|
||||
|
||||
**解决方案**:
|
||||
1. 使用模块前缀,如 `MAP_`、`HERO_`
|
||||
2. 在 `GameEvent` 枚举中统一管理所有事件名称
|
||||
3. 避免使用过于通用的名称
|
||||
|
||||
**Section sources**
|
||||
- [MessageManager.ts](file://extensions/oops-plugin-framework/assets/core/common/event/MessageManager.ts)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts)
|
||||
684
.qoder/repowiki/zh/content/核心系统/初始化系统.md
Normal file
684
.qoder/repowiki/zh/content/核心系统/初始化系统.md
Normal file
@@ -0,0 +1,684 @@
|
||||
# 初始化系统
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [USAGE.md](file://assets/script/game/wx_clound_client_api/USAGE.md)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
游戏初始化系统是一个基于ECS架构的复杂初始化流程,负责在游戏启动时完成资源加载、数据初始化、界面显示和环境配置等关键任务。该系统采用异步队列机制确保各个初始化步骤按顺序执行,同时支持云端数据加载和本地调试两种模式。
|
||||
|
||||
初始化系统的核心目标是:
|
||||
- 提供流畅的游戏启动体验
|
||||
- 支持云端数据同步和本地调试
|
||||
- 实现模块化的初始化流程
|
||||
- 确保错误处理和性能优化
|
||||
|
||||
## 项目结构
|
||||
|
||||
初始化系统的主要文件组织结构如下:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "初始化模块"
|
||||
A[Initialize.ts<br/>主初始化类]
|
||||
B[LoadingViewComp.ts<br/>加载界面组件]
|
||||
end
|
||||
subgraph "云服务模块"
|
||||
C[WxCloudApi.ts<br/>微信云API封装]
|
||||
D[USAGE.md<br/>使用指南]
|
||||
end
|
||||
subgraph "共享模块"
|
||||
E[SingletonModuleComp.ts<br/>单例模块组件]
|
||||
end
|
||||
subgraph "配置文件"
|
||||
F[config.json<br/>配置信息]
|
||||
G[index.js<br/>云函数实现]
|
||||
end
|
||||
A --> B
|
||||
A --> C
|
||||
A --> E
|
||||
C --> G
|
||||
E --> C
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L207)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L1-L91)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L1-L94)
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L207)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L1-L91)
|
||||
|
||||
## 核心组件
|
||||
|
||||
初始化系统由以下核心组件构成:
|
||||
|
||||
### Initialize 主初始化类
|
||||
负责协调整个初始化流程,包含四个主要阶段:
|
||||
- **loadCustom**: 加载自定义资源和字体
|
||||
- **loadLanguage**: 加载多语言包
|
||||
- **loadCommon**: 加载公共资源
|
||||
- **onComplete**: 完成初始化并显示加载界面
|
||||
|
||||
### LoadingViewComp 加载界面组件
|
||||
提供可视化的加载进度反馈,支持多语言提示和进度监控。
|
||||
|
||||
### WxCloudApi 微信云API
|
||||
封装微信云开发接口,提供登录、数据存储和获取功能。
|
||||
|
||||
### SingletonModuleComp 单例模块
|
||||
管理全局游戏数据和状态,处理云端数据同步。
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L20-L40)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L18-L35)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L8-L30)
|
||||
|
||||
## 架构概览
|
||||
|
||||
初始化系统采用基于ECS架构的设计模式,通过异步队列实现串行任务执行:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Game as 游戏引擎
|
||||
participant Init as Initialize
|
||||
participant Queue as AsyncQueue
|
||||
participant View as LoadingViewComp
|
||||
participant Cloud as WxCloudApi
|
||||
participant SMC as SingletonModuleComp
|
||||
Game->>Init : 创建Initialize实例
|
||||
Init->>Queue : 创建异步队列
|
||||
Init->>Queue : 添加loadCustom任务
|
||||
Init->>Queue : 添加loadLanguage任务
|
||||
Init->>Queue : 添加loadCommon任务
|
||||
Init->>Queue : 添加onComplete任务
|
||||
Init->>Queue : 执行queue.play()
|
||||
Queue->>Init : 执行loadCustom
|
||||
Init->>Init : 加载字体资源
|
||||
Init->>Init : 调用loadGameDataUnified
|
||||
alt 微信客户端
|
||||
Init->>Cloud : initWxCloudEnv()
|
||||
Init->>Cloud : WxCloudApi.login()
|
||||
Cloud-->>Init : 返回云端数据
|
||||
Init->>SMC : 更新本地数据
|
||||
else 非微信客户端
|
||||
Init->>Init : 使用本地调试数据
|
||||
end
|
||||
Queue->>Init : 执行loadLanguage
|
||||
Init->>Init : 设置默认语言
|
||||
Init->>Init : 加载语言包
|
||||
Queue->>Init : 执行loadCommon
|
||||
Init->>Init : 加载公共资源
|
||||
Queue->>View : 执行onComplete
|
||||
View->>View : 显示加载界面
|
||||
View->>View : 开始游戏资源加载
|
||||
Note over Game,SMC : 初始化流程完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L25-L40)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L45-L65)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L37-L50)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### Initialize 类详细分析
|
||||
|
||||
Initialize类是初始化系统的核心控制器,采用ECS实体模式设计:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Initialize {
|
||||
+LoadingViewComp LoadingView
|
||||
+init() void
|
||||
-loadCustom(queue : AsyncQueue) void
|
||||
-loadLanguage(queue : AsyncQueue) void
|
||||
-loadCommon(queue : AsyncQueue) void
|
||||
-onComplete(queue : AsyncQueue) void
|
||||
-loadGameDataUnified() Promise~void~
|
||||
-loadFromCloud() Promise~void~
|
||||
-loadFromLocalDebug() Promise~void~
|
||||
-initWxCloudEnv() void
|
||||
-isWxClient() boolean
|
||||
}
|
||||
class AsyncQueue {
|
||||
+push(task : Function) void
|
||||
+play() void
|
||||
+complete : Function
|
||||
}
|
||||
class LoadingViewComp {
|
||||
+data : Object
|
||||
+reset() void
|
||||
+start() void
|
||||
-loadRes() Promise~void~
|
||||
-loadCustom() void
|
||||
-loadGameRes() void
|
||||
-onProgressCallback() void
|
||||
-onCompleteCallback() void
|
||||
}
|
||||
Initialize --> AsyncQueue : 使用
|
||||
Initialize --> LoadingViewComp : 创建
|
||||
LoadingViewComp --> SingletonModuleComp : 通信
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L20-L40)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L18-L35)
|
||||
|
||||
#### 初始化流程详解
|
||||
|
||||
初始化过程分为四个关键阶段:
|
||||
|
||||
1. **loadCustom阶段**:加载自定义资源和字体
|
||||
- 加载多语言对应的字体资源
|
||||
- 调用统一数据加载流程
|
||||
- 错误处理:即使失败也继续执行
|
||||
|
||||
2. **loadLanguage阶段**:处理多语言支持
|
||||
- 检查并设置默认语言(zh)
|
||||
- 从本地存储读取语言偏好
|
||||
- 加载对应的语言包资源
|
||||
|
||||
3. **loadCommon阶段**:加载公共资源
|
||||
- 加载common目录下的所有资源
|
||||
- 包括游戏必需的基础资源
|
||||
|
||||
4. **onComplete阶段**:完成初始化
|
||||
- 注册UI回调函数
|
||||
- 打开加载界面
|
||||
- 准备进入游戏内容加载
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L42-L85)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L107-L135)
|
||||
|
||||
### 加载界面组件分析
|
||||
|
||||
LoadingViewComp负责提供可视化的加载体验:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始加载] --> B[设置提示文本]
|
||||
B --> C[加载自定义资源]
|
||||
C --> D[加载游戏资源]
|
||||
D --> E{加载完成?}
|
||||
E --> |否| F[更新进度]
|
||||
F --> G[计算百分比]
|
||||
G --> H[更新UI显示]
|
||||
H --> E
|
||||
E --> |是| I[移除组件]
|
||||
I --> J[加载地图]
|
||||
J --> K[打开角色控制界面]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L50-L90)
|
||||
|
||||
#### 加载进度监控机制
|
||||
|
||||
加载界面通过以下机制实现实时进度反馈:
|
||||
|
||||
- **进度回调**:监听资源加载进度事件
|
||||
- **百分比计算**:实时计算并格式化进度百分比
|
||||
- **多语言支持**:根据当前语言显示相应提示
|
||||
- **资源释放**:加载完成后及时释放临时资源
|
||||
|
||||
**章节来源**
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L70-L90)
|
||||
|
||||
### 云端数据加载机制
|
||||
|
||||
初始化系统支持两种数据加载模式:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始数据加载] --> B{检测运行环境}
|
||||
B --> |微信客户端| C[使用云端数据]
|
||||
B --> |非微信客户端| D[使用本地调试数据]
|
||||
C --> E[初始化微信云环境]
|
||||
E --> F[调用WxCloudApi.login]
|
||||
F --> G{登录成功?}
|
||||
G --> |是| H[获取云端数据]
|
||||
G --> |否| I[使用本地数据]
|
||||
H --> J[更新本地数据]
|
||||
J --> K[覆盖游戏配置]
|
||||
D --> L[加载本地调试数据]
|
||||
L --> M[使用默认配置]
|
||||
I --> N[记录警告日志]
|
||||
M --> O[继续初始化]
|
||||
N --> O
|
||||
K --> O
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L107-L170)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L37-L50)
|
||||
|
||||
#### 微信云环境初始化
|
||||
|
||||
微信云环境的初始化过程包括:
|
||||
|
||||
1. **环境配置**:设置云环境ID
|
||||
2. **API初始化**:调用微信云SDK初始化
|
||||
3. **错误处理**:捕获并记录初始化异常
|
||||
|
||||
#### 用户登录流程
|
||||
|
||||
用户登录通过WxCloudApi.login()实现:
|
||||
|
||||
- **函数调用**:调用微信云函数`cocos_cloud`
|
||||
- **命令参数**:发送`cmd: "login"`指令
|
||||
- **数据验证**:检查返回结果的状态码
|
||||
- **数据覆盖**:成功时直接覆盖本地游戏数据
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L172-L206)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L10-L50)
|
||||
|
||||
### 单例模块组件
|
||||
|
||||
SingletonModuleComp作为全局状态管理器:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SingletonModuleComp {
|
||||
+initialize : Initialize
|
||||
+map : GameMap
|
||||
+openid : string
|
||||
+mission : Object
|
||||
+guides : Array
|
||||
+current_guide : number
|
||||
+data : Object
|
||||
+fight_hero : number
|
||||
+heros : Array
|
||||
+monsters : Array
|
||||
+vmdata : Object
|
||||
+vmAdd() void
|
||||
+reset() void
|
||||
+updateCloudData() Promise~boolean~
|
||||
+getCloudData() void
|
||||
+overrideLocalDataWithRemote() void
|
||||
+getGameDate() Object
|
||||
+addHero() boolean
|
||||
+updateFihgtHero() boolean
|
||||
+updateGold() boolean
|
||||
+error() void
|
||||
}
|
||||
class WxCloudApi {
|
||||
+init(env : string) void
|
||||
+login() Promise
|
||||
+save(gameData : any) Promise
|
||||
+get() Promise
|
||||
}
|
||||
SingletonModuleComp --> WxCloudApi : 使用
|
||||
SingletonModuleComp --> Initialize : 被引用
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L25-L60)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L8-L30)
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L120-L159)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
初始化系统的依赖关系图展示了各组件间的交互:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "外部依赖"
|
||||
A[Cocos引擎]
|
||||
B[Oops框架]
|
||||
C[微信云开发]
|
||||
end
|
||||
subgraph "核心模块"
|
||||
D[Initialize]
|
||||
E[LoadingViewComp]
|
||||
F[WxCloudApi]
|
||||
G[SingletonModuleComp]
|
||||
end
|
||||
subgraph "配置资源"
|
||||
H[config.json]
|
||||
I[语言包]
|
||||
J[游戏资源]
|
||||
end
|
||||
A --> D
|
||||
B --> D
|
||||
B --> E
|
||||
B --> G
|
||||
C --> F
|
||||
D --> E
|
||||
D --> F
|
||||
D --> G
|
||||
F --> G
|
||||
H --> D
|
||||
I --> D
|
||||
J --> D
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L15)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L1-L5)
|
||||
|
||||
### 组件耦合度分析
|
||||
|
||||
- **Initialize与LoadingViewComp**:松耦合,通过UI回调机制通信
|
||||
- **Initialize与WxCloudApi**:中等耦合,直接调用API方法
|
||||
- **SingletonModuleComp与其他组件**:高耦合,作为全局状态中心
|
||||
- **各组件与Oops框架**:强耦合,依赖框架提供的功能
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L15)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L10)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 异步队列调度优化
|
||||
|
||||
初始化系统采用异步队列机制确保任务按序执行,避免阻塞主线程:
|
||||
|
||||
- **串行执行**:每个任务完成后才执行下一个
|
||||
- **错误隔离**:单个任务失败不影响整体流程
|
||||
- **资源管理**:及时释放不需要的资源
|
||||
|
||||
### 资源预加载策略
|
||||
|
||||
- **字体预加载**:优先加载多语言字体
|
||||
- **公共资源缓存**:提前加载常用资源
|
||||
- **渐进式加载**:分阶段加载不同类型的资源
|
||||
|
||||
### 内存管理
|
||||
|
||||
- **及时释放**:加载完成后立即释放临时资源
|
||||
- **引用清理**:避免循环引用导致内存泄漏
|
||||
- **组件卸载**:完成初始化后移除不必要的组件
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 1. 云环境ID未配置
|
||||
|
||||
**症状**:微信客户端初始化失败,控制台显示云环境初始化错误
|
||||
|
||||
**原因**:WxCloudApi.init()中的cloudEnvId未正确设置
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 修改Initialize.ts中的initWxCloudEnv方法
|
||||
private initWxCloudEnv() {
|
||||
try {
|
||||
// 替换为您的实际云环境ID
|
||||
const cloudEnvId = "您的云环境ID"; // 必须配置
|
||||
WxCloudApi.init(cloudEnvId);
|
||||
console.log("[Initialize]: 微信云环境初始化完成");
|
||||
} catch (error) {
|
||||
console.error("[Initialize]: 微信云环境初始化失败:", error);
|
||||
// 提供降级方案
|
||||
this.useFallbackMode();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 语言包加载失败
|
||||
|
||||
**症状**:游戏界面显示英文或乱码
|
||||
|
||||
**原因**:语言包资源加载失败或语言文件损坏
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
private loadLanguage(queue: AsyncQueue) {
|
||||
queue.push((next: NextFunction, params: any, args: any) => {
|
||||
try {
|
||||
let lan = oops.storage.get("language");
|
||||
if (!lan || lan === "") {
|
||||
lan = "zh"; // 默认语言
|
||||
oops.storage.set("language", lan);
|
||||
}
|
||||
|
||||
// 添加语言包加载超时处理
|
||||
const timeout = setTimeout(() => {
|
||||
console.warn("[Initialize]: 语言包加载超时,使用默认语言");
|
||||
oops.language.setLanguage("zh", next);
|
||||
}, 5000);
|
||||
|
||||
oops.language.setLanguage(lan, () => {
|
||||
clearTimeout(timeout);
|
||||
next();
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("[Initialize]: 语言包加载失败:", error);
|
||||
// 使用默认语言
|
||||
oops.language.setLanguage("zh", next);
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 云端数据同步失败
|
||||
|
||||
**症状**:游戏数据无法从云端获取,使用默认数据
|
||||
|
||||
**原因**:网络问题或云端服务异常
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
private async loadFromCloud() {
|
||||
try {
|
||||
this.initWxCloudEnv();
|
||||
|
||||
// 添加重试机制
|
||||
let retryCount = 0;
|
||||
const maxRetries = 3;
|
||||
|
||||
while (retryCount < maxRetries) {
|
||||
try {
|
||||
const loginResult = await WxCloudApi.login();
|
||||
|
||||
if (loginResult.result.code === 200) {
|
||||
console.log("[Initialize]: 云端登录成功");
|
||||
this.overrideLocalDataWithRemote(loginResult.result.data);
|
||||
return;
|
||||
} else {
|
||||
console.warn(`[Initialize]: 云端登录失败,尝试次数 ${retryCount + 1}`);
|
||||
retryCount++;
|
||||
await this.delay(1000 * retryCount); // 指数退避
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[Initialize]: 云端数据加载异常:", error);
|
||||
retryCount++;
|
||||
await this.delay(1000 * retryCount);
|
||||
}
|
||||
}
|
||||
|
||||
// 最终使用本地数据
|
||||
console.warn("[Initialize]: 云端数据加载多次失败,使用本地数据");
|
||||
this.useLocalDataFallback();
|
||||
|
||||
} catch (error) {
|
||||
console.error("[Initialize]: 云端数据加载最终失败:", error);
|
||||
this.useLocalDataFallback();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. 加载界面显示异常
|
||||
|
||||
**症状**:加载进度不更新或界面显示错误
|
||||
|
||||
**原因**:LoadingViewComp组件初始化失败或数据绑定问题
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
private onComplete(queue: AsyncQueue) {
|
||||
queue.complete = () => {
|
||||
try {
|
||||
var uic: UICallbacks = {
|
||||
onAdded: (node: Node, params: any) => {
|
||||
try {
|
||||
var comp = node.getComponent(LoadingViewComp) as ecs.Comp;
|
||||
if (comp) {
|
||||
this.add(comp);
|
||||
console.log("[Initialize]: 加载界面组件添加成功");
|
||||
} else {
|
||||
console.error("[Initialize]: 加载界面组件获取失败");
|
||||
this.useAlternativeLoading();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[Initialize]: 加载界面组件处理异常:", error);
|
||||
this.useAlternativeLoading();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 界面管理 - 打开游戏内容资源加载进度提示界面
|
||||
oops.gui.open(UIID.Loading, null, uic);
|
||||
} catch (error) {
|
||||
console.error("[Initialize]: 加载界面打开失败:", error);
|
||||
this.useAlternativeLoading();
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 性能优化建议
|
||||
|
||||
#### 1. 资源预加载优化
|
||||
|
||||
```typescript
|
||||
// 在初始化早期阶段预加载关键资源
|
||||
private preloadCriticalResources(queue: AsyncQueue) {
|
||||
queue.push((next: NextFunction, params: any, args: any) => {
|
||||
// 预加载关键字体和UI资源
|
||||
const criticalResources = [
|
||||
"language/font/zh",
|
||||
"common/ui/loading",
|
||||
"common/audio/bgm"
|
||||
];
|
||||
|
||||
let loaded = 0;
|
||||
const total = criticalResources.length;
|
||||
|
||||
criticalResources.forEach(resource => {
|
||||
oops.res.load(resource, () => {
|
||||
loaded++;
|
||||
if (loaded === total) {
|
||||
next();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 并行加载优化
|
||||
|
||||
```typescript
|
||||
// 对于独立的资源组,可以考虑并行加载
|
||||
private loadResourcesParallel(queue: AsyncQueue) {
|
||||
queue.push((next: NextFunction, params: any, args: any) => {
|
||||
// 并行加载多个资源组
|
||||
const groups = [
|
||||
{ name: "fonts", path: "language/font" },
|
||||
{ name: "ui", path: "common/ui" },
|
||||
{ name: "audio", path: "common/audio" }
|
||||
];
|
||||
|
||||
let completed = 0;
|
||||
const total = groups.length;
|
||||
|
||||
groups.forEach(group => {
|
||||
oops.res.loadDir(group.path, () => {
|
||||
console.log(`[${group.name}] 资源加载完成`);
|
||||
completed++;
|
||||
if (completed === total) {
|
||||
next();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 内存使用监控
|
||||
|
||||
```typescript
|
||||
// 添加内存使用监控
|
||||
private monitorMemoryUsage() {
|
||||
setInterval(() => {
|
||||
if (typeof performance !== 'undefined' && performance.memory) {
|
||||
const memory = performance.memory;
|
||||
console.log(`内存使用情况:
|
||||
已用: ${(memory.usedJSHeapSize / 1024 / 1024).toFixed(2)}MB
|
||||
总计: ${(memory.totalJSHeapSize / 1024 / 1024).toFixed(2)}MB
|
||||
限制: ${(memory.jsHeapSizeLimit / 1024 / 1024).toFixed(2)}MB`);
|
||||
|
||||
// 如果内存使用过高,触发垃圾回收
|
||||
if (memory.usedJSHeapSize > memory.jsHeapSizeLimit * 0.8) {
|
||||
console.warn("内存使用过高,触发垃圾回收");
|
||||
if (typeof global !== 'undefined') {
|
||||
global.gc && global.gc();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
```
|
||||
|
||||
## 结论
|
||||
|
||||
游戏初始化系统是一个设计精良的模块化架构,通过ECS模式实现了高度解耦和可扩展性。系统的主要优势包括:
|
||||
|
||||
### 技术优势
|
||||
|
||||
1. **模块化设计**:每个初始化阶段职责明确,便于维护和扩展
|
||||
2. **异步处理**:采用异步队列确保流畅的用户体验
|
||||
3. **环境适配**:支持云端和本地两种运行环境
|
||||
4. **错误恢复**:完善的错误处理和降级机制
|
||||
|
||||
### 架构特点
|
||||
|
||||
1. **ECS集成**:充分利用ECS架构的优势
|
||||
2. **组件化**:清晰的组件边界和职责划分
|
||||
3. **事件驱动**:基于事件的松耦合通信
|
||||
4. **状态管理**:集中式的全局状态管理
|
||||
|
||||
### 性能特性
|
||||
|
||||
1. **渐进式加载**:分阶段加载减少首屏时间
|
||||
2. **资源优化**:智能的资源管理和释放
|
||||
3. **内存控制**:有效的内存使用和垃圾回收
|
||||
4. **并发处理**:合理的并行加载策略
|
||||
|
||||
### 扩展性
|
||||
|
||||
系统设计充分考虑了未来的扩展需求,可以通过以下方式轻松扩展:
|
||||
|
||||
- **新增初始化阶段**:通过AsyncQueue.push()添加新任务
|
||||
- **自定义加载逻辑**:继承或组合现有组件
|
||||
- **多环境支持**:通过条件判断支持更多运行环境
|
||||
- **插件化架构**:支持第三方插件集成
|
||||
|
||||
初始化系统为游戏开发提供了坚实的基础架构,确保了游戏能够稳定、高效地启动,并为后续的功能扩展奠定了良好的基础。
|
||||
253
.qoder/repowiki/zh/content/核心系统/数据存储系统.md
Normal file
253
.qoder/repowiki/zh/content/核心系统/数据存储系统.md
Normal file
@@ -0,0 +1,253 @@
|
||||
# 数据存储系统
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [storage.md](file://doc/core/common/storage.md)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [本地数据持久化机制](#本地数据持久化机制)
|
||||
2. [初始化与用户数据区分](#初始化与用户数据区分)
|
||||
3. [基本操作方法](#基本操作方法)
|
||||
4. [调试与发布模式差异](#调试与发布模式差异)
|
||||
5. [数据安全策略](#数据安全策略)
|
||||
6. [存储需求与应用示例](#存储需求与应用示例)
|
||||
7. [异常处理与最佳实践](#异常处理与最佳实践)
|
||||
8. [跨设备同步与本地缓存](#跨设备同步与本地缓存)
|
||||
|
||||
## 本地数据持久化机制
|
||||
|
||||
本游戏项目采用Oops Framework提供的本地存储模块,该模块封装了Cocos Creator引擎的`sys.localStorage`对象,实现了跨平台的本地数据存储功能。存储系统不仅支持基础的增删改查操作,还集成了数据加密和多用户数据区分功能,确保玩家数据的安全性和独立性。
|
||||
|
||||
系统通过`oops.storage`接口提供统一的数据访问方法,所有数据最终存储在设备本地,同时支持与云端数据同步的混合存储策略。本地存储主要用于保存玩家配置、语言设置、游戏进度等关键数据,确保即使在离线状态下也能正常访问游戏内容。
|
||||
|
||||
**Section sources**
|
||||
- [storage.md](file://doc/core/common/storage.md#L1-L38)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L57)
|
||||
|
||||
## 初始化与用户数据区分
|
||||
|
||||
### 初始化本地存储加密
|
||||
|
||||
本地存储加密通过`oops.storage.init()`方法进行初始化,该方法需要传入加密密钥和初始化向量(IV)两个参数。在项目启动时,系统会从配置文件中读取加密参数并完成初始化。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 游戏启动
|
||||
participant Root组件
|
||||
participant 存储系统
|
||||
participant 配置文件
|
||||
游戏启动->>Root组件 : onLoad()
|
||||
Root组件->>配置文件 : 加载config.json
|
||||
配置文件-->>Root组件 : 返回配置数据
|
||||
Root组件->>存储系统 : oops.storage.init(key, vi)
|
||||
存储系统-->>Root组件 : 初始化完成
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L57)
|
||||
- [config.json](file://assets/resources/config.json#L1-L20)
|
||||
|
||||
### 区分用户数据
|
||||
|
||||
通过`oops.storage.setUser()`方法可以为不同用户设置唯一标识,从而实现多账号数据隔离。系统使用用户ID作为数据存储的命名空间,避免不同账号之间的数据覆盖问题。
|
||||
|
||||
当用户登录时,系统会调用此方法设置当前用户ID,后续的所有数据操作都将基于该用户ID进行。这对于支持多账号切换的游戏尤为重要,确保每个玩家的游戏进度和设置都能独立保存。
|
||||
|
||||
**Section sources**
|
||||
- [storage.md](file://doc/core/common/storage.md#L10-L15)
|
||||
|
||||
## 基本操作方法
|
||||
|
||||
本地存储系统提供了一套完整的数据操作API,包括设置、获取、删除和清空等基本操作。
|
||||
|
||||
### 设置数据
|
||||
|
||||
使用`oops.storage.set(key, value)`方法可以将指定键值对保存到本地存储中。该方法接受两个参数:键名和值。值可以是字符串、数字、布尔值或对象等数据类型。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始] --> B["oops.storage.set(key, value)"]
|
||||
B --> C{数据类型检查}
|
||||
C --> |基本类型| D[直接存储]
|
||||
C --> |对象类型| E[JSON序列化]
|
||||
E --> F[加密处理]
|
||||
F --> G[保存到localStorage]
|
||||
G --> H[结束]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [storage.md](file://doc/core/common/storage.md#L20-L22)
|
||||
|
||||
### 获取数据
|
||||
|
||||
通过`oops.storage.get(key)`方法可以从本地存储中读取指定键的数据。如果键不存在,则返回null。该方法会自动处理数据的解密和反序列化过程,向调用者返回原始数据类型。
|
||||
|
||||
### 删除数据
|
||||
|
||||
`oops.storage.remove(key)`方法用于删除指定键的数据。执行后,该键对应的数据将从本地存储中永久移除。
|
||||
|
||||
### 清空存储
|
||||
|
||||
`oops.storage.clear()`方法会清空当前用户的所有本地存储数据。这是一个危险操作,通常只在用户注销或重置游戏时使用。
|
||||
|
||||
**Section sources**
|
||||
- [storage.md](file://doc/core/common/storage.md#L24-L38)
|
||||
|
||||
## 调试与发布模式差异
|
||||
|
||||
本地存储系统在调试模式和发布模式下表现出不同的行为特征,这是为了平衡开发效率和生产环境安全性的设计。
|
||||
|
||||
### 调试模式
|
||||
|
||||
在调试模式下,系统不会对存储数据进行加密,所有数据以明文形式保存。这一设计便于开发者调试时直接查看和修改存储内容,提高了开发效率。开发者可以通过浏览器的开发者工具直接查看`localStorage`中的数据内容。
|
||||
|
||||
### 发布模式
|
||||
|
||||
在发布模式下,系统会自动启用数据加密功能。所有写入本地存储的数据都会经过加密处理,读取时再进行解密。这种机制有效防止了玩家通过直接修改存储文件来作弊的行为,保护了游戏的公平性。
|
||||
|
||||
加密算法基于项目配置文件中定义的密钥和IV参数,确保了加密过程的一致性和安全性。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A[数据操作] --> B{运行模式}
|
||||
B --> |调试模式| C[明文存储]
|
||||
B --> |发布模式| D[加密存储]
|
||||
C --> E[便于调试]
|
||||
D --> F[防止篡改]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [storage.md](file://doc/core/common/storage.md#L10-L15)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L57)
|
||||
|
||||
## 数据安全策略
|
||||
|
||||
### 加密机制
|
||||
|
||||
系统采用对称加密算法保护本地存储数据,加密密钥和IV参数定义在`assets/resources/config.json`配置文件中。这种集中管理的方式便于统一维护和更新加密参数。
|
||||
|
||||
项目依赖`crypto-es`库实现加密功能,这是一个轻量级的JavaScript加密库,支持多种加密算法。通过在`package.json`中声明依赖,确保了加密库的版本一致性。
|
||||
|
||||
### 防篡改机制
|
||||
|
||||
除了数据加密外,系统还通过用户ID区分机制防止数据篡改。每个用户的数据都有独立的存储空间,避免了通过修改用户ID来访问他人数据的可能性。
|
||||
|
||||
对于关键数据,系统建议采用双重保护策略:既在本地加密存储,又在云端备份。当检测到本地数据异常时,可以从云端恢复,确保玩家数据不丢失。
|
||||
|
||||
**Section sources**
|
||||
- [config.json](file://assets/resources/config.json#L1-L20)
|
||||
- [package.json](file://package.json#L1-L11)
|
||||
|
||||
## 存储需求与应用示例
|
||||
|
||||
### 碰撞分组配置存储
|
||||
|
||||
`BoxSet.ts`文件定义了游戏中的碰撞分组配置,这些配置数据可以通过本地存储系统进行持久化保存。玩家可以自定义碰撞规则,系统将这些设置保存到本地,确保每次启动游戏时都能恢复个性化配置。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class BoxSet {
|
||||
+SKILL_TAG : number
|
||||
+ATK_RANGE : number
|
||||
+DEFAULT : number
|
||||
+MONSTER : number
|
||||
+HERO : number
|
||||
+PLAYER : number
|
||||
+BOSS : number
|
||||
+BOX_WIDTH : number
|
||||
+BOX_HEIGHT : number
|
||||
}
|
||||
class StorageManager {
|
||||
+setCollisionConfig(config)
|
||||
+getCollisionConfig()
|
||||
+saveToLocalStorage()
|
||||
+loadFromLocalStorage()
|
||||
}
|
||||
StorageManager --> BoxSet : "使用"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L1-L108)
|
||||
- [storage.md](file://doc/core/common/storage.md#L20-L22)
|
||||
|
||||
### 游戏进度管理
|
||||
|
||||
系统通过`SingletonModuleComp.ts`管理游戏核心数据,包括玩家金币、英雄列表和出战阵容等。这些数据在游戏运行时存储在内存中,同时定期同步到本地存储。
|
||||
|
||||
当玩家完成游戏或退出应用时,系统会自动保存当前进度。下次启动游戏时,先从本地存储加载数据,再根据需要从云端同步最新状态,实现了本地与云端的数据一致性。
|
||||
|
||||
**Section sources**
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L1-L108)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L41)
|
||||
|
||||
## 异常处理与最佳实践
|
||||
|
||||
### 数据序列化
|
||||
|
||||
在存储复杂数据类型时,需要先进行序列化处理。系统推荐使用`JSON.stringify()`将对象转换为字符串,然后再调用存储方法。读取数据时,使用`JSON.parse()`进行反序列化。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[原始数据] --> B[JSON.stringify]
|
||||
B --> C[加密]
|
||||
C --> D[存储]
|
||||
D --> E[读取]
|
||||
E --> F[解密]
|
||||
F --> G[JSON.parse]
|
||||
G --> H[恢复数据]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L105-L139)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L119-L159)
|
||||
|
||||
### 异常处理
|
||||
|
||||
在进行数据操作时,必须考虑各种异常情况,如存储空间不足、数据损坏、加密失败等。系统建议采用try-catch结构包裹存储操作,并提供相应的错误处理机制。
|
||||
|
||||
对于关键数据的保存操作,建议实现事务性处理:先写入临时位置,验证成功后再替换原数据,确保数据完整性。
|
||||
|
||||
**Section sources**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L105-L139)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L81-L121)
|
||||
|
||||
## 跨设备同步与本地缓存
|
||||
|
||||
### 云端同步机制
|
||||
|
||||
系统实现了本地存储与微信云开发的集成,通过`WxCloudApi.ts`提供的接口实现数据云端同步。在微信客户端环境下,游戏启动时会自动从云端加载最新数据;在非微信环境下,则使用本地调试数据。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 客户端
|
||||
participant 云端
|
||||
participant 本地存储
|
||||
客户端->>云端 : login()
|
||||
云端-->>客户端 : 用户数据
|
||||
客户端->>本地存储 : 保存云端数据
|
||||
本地存储-->>客户端 : 确认
|
||||
客户端->>云端 : save(gameData)
|
||||
云端-->>客户端 : 保存结果
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L0-L93)
|
||||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js#L0-L53)
|
||||
|
||||
### 本地缓存协调
|
||||
|
||||
系统采用"本地优先,云端同步"的策略。日常游戏过程中主要使用本地存储,定期或在关键节点将数据同步到云端。这样既保证了游戏性能,又实现了数据备份。
|
||||
|
||||
当玩家在不同设备上登录同一账号时,系统会优先使用云端最新数据,然后与本地数据进行合并,确保游戏进度的一致性。对于冲突数据,采用"最后写入获胜"的策略。
|
||||
|
||||
**Section sources**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L105-L139)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L81-L121)
|
||||
420
.qoder/repowiki/zh/content/核心系统/核心系统.md
Normal file
420
.qoder/repowiki/zh/content/核心系统/核心系统.md
Normal file
@@ -0,0 +1,420 @@
|
||||
# 核心系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [event.md](file://doc/core/common/event.md)
|
||||
- [loader.md](file://doc/core/common/loader.md)
|
||||
- [storage.md](file://doc/core/common/storage.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目架构概览](#项目架构概览)
|
||||
3. [初始化系统](#初始化系统)
|
||||
4. [事件系统](#事件系统)
|
||||
5. [资源加载系统](#资源加载系统)
|
||||
6. [本地存储系统](#本地存储系统)
|
||||
7. [碰撞分组配置](#碰撞分组配置)
|
||||
8. [系统集成与工作流程](#系统集成与工作流程)
|
||||
9. [最佳实践与优化建议](#最佳实践与优化建议)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
本游戏采用基于Oops Framework的模块化架构,核心运行系统包含初始化流程、事件系统、资源加载与本地存储四大核心模块。系统通过异步队列管理初始化顺序,使用事件总线实现模块间解耦,采用分层资源管理模式,并提供安全可靠的本地存储机制。
|
||||
|
||||
## 项目架构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "游戏入口"
|
||||
Main[Main.ts]
|
||||
Root[Root基类]
|
||||
end
|
||||
subgraph "初始化系统"
|
||||
Init[Initialize.ts]
|
||||
Loading[LoadingViewComp.ts]
|
||||
end
|
||||
subgraph "核心模块"
|
||||
SMC[SingletonModuleComp]
|
||||
Event[GameEvent.ts]
|
||||
Box[BoxSet.ts]
|
||||
end
|
||||
subgraph "资源管理"
|
||||
ResMgr[资源加载器]
|
||||
Storage[本地存储]
|
||||
Loader[异步队列]
|
||||
end
|
||||
subgraph "游戏内容"
|
||||
Map[GameMap]
|
||||
Scene[场景管理]
|
||||
end
|
||||
Main --> Init
|
||||
Init --> Loading
|
||||
Init --> SMC
|
||||
Loading --> Map
|
||||
SMC --> Event
|
||||
SMC --> Storage
|
||||
Init --> ResMgr
|
||||
ResMgr --> Loader
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L41)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L207)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L1-L91)
|
||||
|
||||
## 初始化系统
|
||||
|
||||
### Initialize.ts - 游戏启动核心
|
||||
|
||||
Initialize.ts作为游戏初始化的核心模块,负责管理整个启动流程,采用异步队列模式确保资源按序加载。
|
||||
|
||||
#### 初始化流程架构
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Main as Main.ts
|
||||
participant Init as Initialize
|
||||
participant Queue as AsyncQueue
|
||||
participant Loading as LoadingViewComp
|
||||
participant SMC as SingletonModuleComp
|
||||
Main->>Init : 创建Initialize实体
|
||||
Init->>Queue : 创建异步队列
|
||||
Init->>Queue : 添加loadCustom任务
|
||||
Init->>Queue : 添加loadLanguage任务
|
||||
Init->>Queue : 添加loadCommon任务
|
||||
Init->>Queue : 添加onComplete回调
|
||||
Queue->>Queue : 执行队列任务
|
||||
Queue->>Loading : 打开加载界面
|
||||
Loading->>SMC : 初始化游戏数据
|
||||
Loading->>SMC : 加载地图资源
|
||||
SMC->>SMC : 完成初始化
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L25-L40)
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L75-L91)
|
||||
|
||||
#### 核心初始化步骤
|
||||
|
||||
1. **自定义内容加载**:支持动态加载多语言字体和游戏配置
|
||||
2. **语言包加载**:自动检测并设置默认语言
|
||||
3. **公共资源加载**:加载游戏必需的基础资源
|
||||
4. **加载界面显示**:展示资源加载进度
|
||||
|
||||
#### 微信客户端适配
|
||||
|
||||
系统具备智能客户端识别能力,能够根据运行环境选择不同的数据加载策略:
|
||||
|
||||
- **微信客户端**:连接云端数据库,实现数据实时同步
|
||||
- **本地调试**:使用本地预设数据,便于开发调试
|
||||
|
||||
**章节来源**
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L42-L207)
|
||||
|
||||
### LoadingViewComp.ts - 启动画面交互
|
||||
|
||||
LoadingViewComp负责管理游戏启动过程中的视觉反馈和用户体验。
|
||||
|
||||
#### 加载状态管理
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 初始化
|
||||
初始化 --> 加载自定义资源 : loadCustom()
|
||||
加载自定义资源 --> 加载游戏资源 : loadGameRes()
|
||||
加载游戏资源 --> 加载完成 : onCompleteCallback()
|
||||
加载完成 --> 销毁组件 : remove(LoadingViewComp)
|
||||
销毁组件 --> [*]
|
||||
加载自定义资源 : 显示"加载JSON数据"
|
||||
加载游戏资源 : 显示"加载游戏内容"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L50-L91)
|
||||
|
||||
#### 进度监控机制
|
||||
|
||||
系统提供实时的资源加载进度监控,包括:
|
||||
- 当前完成数量
|
||||
- 总资源数量
|
||||
- 进度百分比计算
|
||||
- 多语言提示文本更新
|
||||
|
||||
**章节来源**
|
||||
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L1-L91)
|
||||
|
||||
## 事件系统
|
||||
|
||||
### GameEvent.ts - 事件枚举定义
|
||||
|
||||
GameEvent.ts定义了游戏中的所有自定义事件类型,采用枚举方式组织,确保事件名称的一致性和可维护性。
|
||||
|
||||
#### 事件分类体系
|
||||
|
||||
| 事件类别 | 事件名称 | 描述 |
|
||||
|---------|---------|------|
|
||||
| 游戏连接 | GameServerConnected | 游戏服务器连接成功 |
|
||||
| 登录认证 | LoginSuccess | 登录成功事件 |
|
||||
| 地图移动 | MAP_MOVE_END_LEFT/RIGHT | 地图移动结束事件 |
|
||||
| 引导系统 | GuideStart/End/Complete | 引导流程控制事件 |
|
||||
| 英雄系统 | UpdateHero/UpdateFightHero | 英雄数据更新事件 |
|
||||
| 技能系统 | CastSkill/CastHeroSkill | 技能释放事件 |
|
||||
| 战斗系统 | FightStart/Pause/Resume/End | 战斗状态控制事件 |
|
||||
| 资源更新 | GOLD_UPDATE/DIAMOND_UPDATE/MEAT_UPDATE | 资源变化事件 |
|
||||
|
||||
#### 事件总线使用模式
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[事件发布者] --> B[oops.message.on/once]
|
||||
B --> C[事件监听器]
|
||||
C --> D[业务逻辑处理]
|
||||
D --> E[事件响应完成]
|
||||
F[事件取消] --> G[oops.message.off]
|
||||
G --> H[移除监听器]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
- [event.md](file://doc/core/common/event.md#L1-L44)
|
||||
|
||||
### 事件系统最佳实践
|
||||
|
||||
1. **持续监听**:适用于长期关注的事件
|
||||
2. **一次性监听**:适用于仅需响应一次的事件
|
||||
3. **内存管理**:及时取消不再需要的事件监听
|
||||
|
||||
**章节来源**
|
||||
- [event.md](file://doc/core/common/event.md#L1-L44)
|
||||
|
||||
## 资源加载系统
|
||||
|
||||
### loader.md - 资源管理最佳实践
|
||||
|
||||
系统提供了完整的资源管理解决方案,涵盖从加载到释放的全生命周期管理。
|
||||
|
||||
#### 资源加载模式
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "资源类型"
|
||||
A[单个资源]
|
||||
B[资源文件夹]
|
||||
C[远程资源]
|
||||
D[Bundle资源]
|
||||
end
|
||||
subgraph "加载方式"
|
||||
E[同步加载]
|
||||
F[异步加载]
|
||||
G[进度回调]
|
||||
H[完成回调]
|
||||
end
|
||||
A --> E
|
||||
B --> F
|
||||
C --> G
|
||||
D --> H
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [loader.md](file://doc/core/common/loader.md#L1-L91)
|
||||
|
||||
#### 核心API功能
|
||||
|
||||
1. **远程资源加载**:支持网络图片和音频资源
|
||||
2. **Bundle管理**:支持多资源包的版本控制
|
||||
3. **进度监控**:提供实时加载进度反馈
|
||||
4. **资源释放**:自动清理无用资源,优化内存使用
|
||||
|
||||
#### 异步加载队列
|
||||
|
||||
系统采用AsyncQueue实现资源加载的有序执行,确保关键资源优先加载,提升用户体验。
|
||||
|
||||
**章节来源**
|
||||
- [loader.md](file://doc/core/common/loader.md#L1-L91)
|
||||
|
||||
## 本地存储系统
|
||||
|
||||
### storage.md - 数据持久化机制
|
||||
|
||||
本地存储系统提供安全可靠的数据持久化解决方案,支持数据加密和多用户隔离。
|
||||
|
||||
#### 存储架构设计
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "存储层次"
|
||||
A[应用层API]
|
||||
B[加密层]
|
||||
C[平台层]
|
||||
end
|
||||
subgraph "存储介质"
|
||||
D[Web Storage]
|
||||
E[IndexedDB]
|
||||
F[File System]
|
||||
end
|
||||
A --> B
|
||||
B --> C
|
||||
C --> D
|
||||
C --> E
|
||||
C --> F
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [storage.md](file://doc/core/common/storage.md#L1-L39)
|
||||
|
||||
#### 核心功能特性
|
||||
|
||||
1. **数据加密**:发布模式自动启用数据加密
|
||||
2. **用户隔离**:支持多用户账号数据分离
|
||||
3. **跨平台兼容**:统一的API接口适配不同平台
|
||||
4. **类型安全**:支持多种数据类型的序列化存储
|
||||
|
||||
#### 数据操作示例
|
||||
|
||||
| 操作类型 | API方法 | 功能描述 |
|
||||
|---------|---------|----------|
|
||||
| 初始化 | `oops.storage.init(key, vi)` | 设置加密密钥 |
|
||||
| 用户设置 | `oops.storage.setUser(uid)` | 设置用户标识 |
|
||||
| 数据存储 | `oops.storage.set(key, value)` | 保存数据 |
|
||||
| 数据读取 | `oops.storage.get(key)` | 获取数据 |
|
||||
| 数据删除 | `oops.storage.remove(key)` | 删除数据 |
|
||||
| 清空存储 | `oops.storage.clear()` | 清空所有数据 |
|
||||
|
||||
**章节来源**
|
||||
- [storage.md](file://doc/core/common/storage.md#L1-L39)
|
||||
|
||||
## 碰撞分组配置
|
||||
|
||||
### BoxSet.ts - 物理碰撞系统
|
||||
|
||||
BoxSet.ts定义了游戏中的物理碰撞分组,为2D物理引擎提供精确的碰撞检测规则。
|
||||
|
||||
#### 碰撞分组体系
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "角色分组"
|
||||
A[HERO - 英雄]
|
||||
B[MONSTER - 怪物]
|
||||
C[BOSS - BOSS]
|
||||
D[PLAYER - 玩家]
|
||||
end
|
||||
subgraph "技能分组"
|
||||
E[HERO_SKILL - 英雄技能]
|
||||
F[MONSTER_SKILL - 怪物技能]
|
||||
G[SKILL_TAG - 技能标记]
|
||||
end
|
||||
subgraph "范围分组"
|
||||
H[ATK_RANGE - 攻击范围]
|
||||
I[DEFAULT - 默认分组]
|
||||
end
|
||||
A --> E
|
||||
B --> F
|
||||
C --> F
|
||||
D --> E
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L1-L109)
|
||||
|
||||
#### 配置参数详解
|
||||
|
||||
| 参数类别 | 参数名称 | 数值 | 用途 |
|
||||
|---------|---------|------|------|
|
||||
| 分组掩码 | DEFAULT | 1 | 默认碰撞分组 |
|
||||
| 分组掩码 | MONSTER | 2 | 怪物专用分组 |
|
||||
| 分组掩码 | HERO | 4 | 英雄专用分组 |
|
||||
| 分组掩码 | MONSTER_SKILL | 8 | 怪物技能分组 |
|
||||
| 分组掩码 | HERO_SKILL | 16 | 英雄技能分组 |
|
||||
| 分组掩码 | PLAYER | 32 | 玩家区域分组 |
|
||||
| 分组掩码 | BOSS | 64 | BOSS专用分组 |
|
||||
| 地图边界 | LETF_END | -420 | 左边界坐标 |
|
||||
| 地图边界 | RIGHT_END | 420 | 右边界坐标 |
|
||||
| 地图边界 | HERO_START | -360 | 英雄起始位置 |
|
||||
| 地图边界 | MONSTER_START | 360 | 怪物起始位置 |
|
||||
| 攻击范围 | ATK_RANGE_X | 150 | 攻击距离X轴 |
|
||||
| 移动范围 | MOVE_RANGE_X | 20 | 移动范围X轴 |
|
||||
|
||||
**章节来源**
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L1-L109)
|
||||
|
||||
## 系统集成与工作流程
|
||||
|
||||
### 整体工作流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Main.ts启动] --> B[Root初始化]
|
||||
B --> C[SMC单例创建]
|
||||
C --> D[Initialize初始化]
|
||||
D --> E[AsyncQueue执行]
|
||||
E --> F[资源加载]
|
||||
F --> G[LoadingView显示]
|
||||
G --> H[数据初始化]
|
||||
H --> I[地图加载]
|
||||
I --> J[游戏界面打开]
|
||||
K[事件系统] --> L[GameEvent监听]
|
||||
L --> M[业务逻辑处理]
|
||||
N[存储系统] --> O[本地数据读取]
|
||||
O --> P[云端数据同步]
|
||||
Q[资源系统] --> R[异步加载队列]
|
||||
R --> S[进度监控]
|
||||
S --> T[资源释放]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L41)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L1-L207)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L194)
|
||||
|
||||
### 数据流管理
|
||||
|
||||
系统采用单例模式管理全局状态,通过事件驱动实现模块间的松耦合通信。
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L194)
|
||||
|
||||
## 最佳实践与优化建议
|
||||
|
||||
### 初始化优化策略
|
||||
|
||||
1. **并行加载**:利用异步队列实现资源的并行加载
|
||||
2. **错误处理**:对加载失败的资源进行优雅降级
|
||||
3. **进度反馈**:提供详细的加载进度和状态提示
|
||||
4. **内存管理**:及时释放不需要的资源
|
||||
|
||||
### 事件系统优化
|
||||
|
||||
1. **命名规范**:使用语义化的事件名称
|
||||
2. **监听管理**:及时移除不需要的事件监听器
|
||||
3. **参数传递**:合理设计事件参数结构
|
||||
4. **性能考虑**:避免在高频事件中执行复杂操作
|
||||
|
||||
### 资源管理最佳实践
|
||||
|
||||
1. **预加载策略**:提前加载常用资源
|
||||
2. **按需加载**:根据游戏进度动态加载资源
|
||||
3. **缓存管理**:合理利用资源缓存机制
|
||||
4. **内存监控**:定期检查和释放内存占用
|
||||
|
||||
### 存储系统安全
|
||||
|
||||
1. **数据加密**:在生产环境中启用数据加密
|
||||
2. **用户隔离**:确保不同用户的存储数据相互独立
|
||||
3. **备份策略**:建立数据备份和恢复机制
|
||||
4. **权限控制**:限制对敏感数据的访问权限
|
||||
|
||||
## 总结
|
||||
|
||||
本游戏的核心运行系统通过模块化设计实现了高度的可维护性和扩展性。初始化系统确保游戏启动的稳定性和效率,事件系统提供了灵活的模块间通信机制,资源管理系统支持复杂的资源加载和管理需求,本地存储系统保障了数据的安全性和持久性。
|
||||
|
||||
系统采用的异步队列模式、事件驱动架构和单例管理模式,为游戏开发提供了坚实的基础框架。通过合理的配置和优化,这套系统能够支持大型游戏项目的开发需求,同时保持良好的性能表现和用户体验。
|
||||
1602
.qoder/repowiki/zh/content/核心系统/资源加载系统.md
Normal file
1602
.qoder/repowiki/zh/content/核心系统/资源加载系统.md
Normal file
File diff suppressed because it is too large
Load Diff
140
.qoder/repowiki/zh/content/用户界面系统/怪物信息显示.md
Normal file
140
.qoder/repowiki/zh/content/用户界面系统/怪物信息显示.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# 怪物信息显示
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [怪物信息显示功能概述](#怪物信息显示功能概述)
|
||||
2. [事件监听与数据更新机制](#事件监听与数据更新机制)
|
||||
3. [关卡数据获取与格式化](#关卡数据获取与格式化)
|
||||
4. [生命周期与初始化逻辑](#生命周期与初始化逻辑)
|
||||
5. [UI更新与数据流分析](#ui更新与数据流分析)
|
||||
6. [组件交互与系统集成](#组件交互与系统集成)
|
||||
|
||||
## 怪物信息显示功能概述
|
||||
|
||||
怪物信息显示组件(MInfoComp)负责在游戏界面中动态展示当前关卡信息。该组件通过监听游戏事件系统中的关卡更新事件,实时响应游戏进度变化,并将当前关卡数据格式化为"第 X 关"的文本形式显示在UI界面上。此功能作为游戏状态可视化的重要组成部分,为玩家提供清晰的进度反馈。
|
||||
|
||||
**Section sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L1-L27)
|
||||
|
||||
## 事件监听与数据更新机制
|
||||
|
||||
MInfoComp组件通过oops消息系统订阅GameEvent.MISSION_UPDATE事件,建立事件驱动的更新机制。当游戏中的关卡状态发生变化时,系统会广播该事件,触发MInfoComp组件的onMissionUpdate回调函数。这种事件监听模式实现了组件间的松耦合,确保UI更新仅在相关数据发生变化时才执行,提高了系统性能和响应效率。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 系统 as 游戏系统
|
||||
participant MInfoComp as MInfoComp组件
|
||||
participant SMC as SingletonModuleComp
|
||||
系统->>SMC : 更新smc.data.mission
|
||||
SMC->>系统 : dispatchEvent(GameEvent.MISSION_UPDATE)
|
||||
系统->>MInfoComp : onMissionUpdate回调
|
||||
MInfoComp->>SMC : 获取smc.data.mission
|
||||
MInfoComp->>自身 : update_mission更新UI
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L9-L13)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L67)
|
||||
|
||||
**Section sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L9-L13)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L67)
|
||||
|
||||
## 关卡数据获取与格式化
|
||||
|
||||
组件通过全局单例smc.data.mission属性获取当前关卡数据。该数据存储在SingletonModuleComp的data对象中,初始值为1,表示游戏从第一关开始。在update_mission方法中,组件将数字类型的关卡号转换为字符串,并格式化为"第 X 关"的显示格式。这种格式化处理增强了用户界面的可读性和友好性,符合中文用户的阅读习惯。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始] --> B{获取关卡数据}
|
||||
B --> C[smc.data.mission]
|
||||
C --> D[转换为字符串]
|
||||
D --> E[格式化为"第 X 关"]
|
||||
E --> F[更新Label组件]
|
||||
F --> G[结束]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L20-L23)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L40)
|
||||
|
||||
**Section sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L20-L23)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L40)
|
||||
|
||||
## 生命周期与初始化逻辑
|
||||
|
||||
在onLoad生命周期方法中,组件注册事件监听器并立即执行一次初始更新,确保UI在加载时显示正确的关卡信息。start方法中再次调用update_mission,形成双重保障机制,防止因事件订阅时机问题导致的显示延迟。这种设计模式确保了组件在不同加载场景下都能正确初始化,提高了代码的健壮性和可靠性。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class MInfoComp {
|
||||
+onLoad()
|
||||
+start()
|
||||
+onMissionUpdate(event, data)
|
||||
+update_mission(mission)
|
||||
}
|
||||
MInfoComp --> GameEvent : "监听"
|
||||
MInfoComp --> SingletonModuleComp : "读取数据"
|
||||
MInfoComp --> Label : "更新文本"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L8-L15)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L37-L40)
|
||||
|
||||
**Section sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L8-L15)
|
||||
|
||||
## UI更新与数据流分析
|
||||
|
||||
组件通过节点查找机制获取名为"mission"的子节点,并获取其Label组件实例,直接更新字符串属性。这种直接的UI操作方式简洁高效,避免了不必要的中间层。数据流从全局单例smc出发,经过事件系统触发,最终更新到UI组件,形成了清晰的数据传递路径。整个过程体现了MVC模式中视图与模型分离的设计思想。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[smc.data.mission] --> B[GameEvent.MISSION_UPDATE]
|
||||
B --> C[MInfoComp.onMissionUpdate]
|
||||
C --> D[MInfoComp.update_mission]
|
||||
D --> E[Label.string更新]
|
||||
E --> F[UI显示变化]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L20-L23)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L37-L40)
|
||||
|
||||
**Section sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L20-L23)
|
||||
|
||||
## 组件交互与系统集成
|
||||
|
||||
MInfoComp与其他游戏组件通过事件系统协同工作。当玩家完成关卡时,VictoryComp组件会触发GameEvent.MissionEnd事件,随后新的关卡开始流程会更新smc.data.mission并广播GameEvent.MISSION_UPDATE事件。这种基于事件的通信机制使得各个功能模块能够独立开发和测试,同时保持良好的系统集成性,体现了高内聚低耦合的设计原则。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant VictoryComp as VictoryComp
|
||||
participant MissionComp as MissionComp
|
||||
participant MInfoComp as MInfoComp
|
||||
VictoryComp->>MissionComp : 触发新关卡
|
||||
MissionComp->>SMC : 更新关卡数据
|
||||
SMC->>系统 : 广播MISSION_UPDATE
|
||||
系统->>MInfoComp : 更新显示
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L9)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L60)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L85)
|
||||
|
||||
**Section sources**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L9)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L60)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L85)
|
||||
414
.qoder/repowiki/zh/content/用户界面系统/技能图标组件.md
Normal file
414
.qoder/repowiki/zh/content/用户界面系统/技能图标组件.md
Normal file
@@ -0,0 +1,414 @@
|
||||
# 技能图标组件详细实现文档
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [CCComp.ts](file://extensions/oops-plugin-framework/assets/module/common/CCComp.ts)
|
||||
- [loader.md](file://doc/core/common/loader.md)
|
||||
- [ecs.md](file://doc/ecs/ecs.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [组件架构概览](#组件架构概览)
|
||||
3. [核心功能实现](#核心功能实现)
|
||||
4. [资源管理系统集成](#资源管理系统集成)
|
||||
5. [ECS系统组件生命周期](#ecs系统组件生命周期)
|
||||
6. [使用示例与最佳实践](#使用示例与最佳实践)
|
||||
7. [性能优化考虑](#性能优化考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
SIconCompComp是一个专门用于显示技能图标的通用UI组件,它通过Cocos Creator的游戏引擎与Oops框架的结合,实现了技能图标资源的动态加载和显示功能。该组件采用ECMAScript组件模式设计,具有良好的可复用性和扩展性。
|
||||
|
||||
该组件的核心价值在于:
|
||||
- 提供统一的技能图标显示接口
|
||||
- 实现资源的按需加载和智能管理
|
||||
- 支持多种UI上下文环境的适配
|
||||
- 集成完整的ECS系统组件生命周期管理
|
||||
|
||||
## 组件架构概览
|
||||
|
||||
SIconCompComp组件采用了分层架构设计,将业务逻辑、资源管理和UI渲染进行了清晰的分离:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CCComp {
|
||||
<<abstract>>
|
||||
+canRecycle : boolean
|
||||
+ent : ecs.Entity
|
||||
+reset() : void
|
||||
}
|
||||
class SIconCompComp {
|
||||
+start() : void
|
||||
+update_data(s_uuid : number) : void
|
||||
+reset() : void
|
||||
}
|
||||
class SkillSet {
|
||||
+Record~number, SkillConfig~
|
||||
+SkillConfig : interface
|
||||
}
|
||||
class Sprite {
|
||||
+spriteFrame : SpriteFrame
|
||||
}
|
||||
class oopsRes {
|
||||
+get(path : string, type : Constructor) : Asset
|
||||
}
|
||||
CCComp <|-- SIconCompComp : 继承
|
||||
SIconCompComp --> SkillSet : 读取配置
|
||||
SIconCompComp --> Sprite : 更新纹理
|
||||
SIconCompComp --> oopsRes : 资源加载
|
||||
SkillSet --> Sprite : 提供路径
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L1-L28)
|
||||
- [CCComp.ts](file://extensions/oops-plugin-framework/assets/module/common/CCComp.ts#L36-L45)
|
||||
|
||||
**章节来源**
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L1-L28)
|
||||
- [CCComp.ts](file://extensions/oops-plugin-framework/assets/module/common/CCComp.ts#L1-L46)
|
||||
|
||||
## 核心功能实现
|
||||
|
||||
### update_data方法详解
|
||||
|
||||
`update_data`方法是组件的核心功能入口,负责接收技能UUID并加载对应的图标资源:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 客户端代码
|
||||
participant SIconComp as SIconCompComp
|
||||
participant SkillSet as SkillSet配置
|
||||
participant oopsRes as 资源管理系统
|
||||
participant Sprite as Sprite组件
|
||||
Client->>SIconComp : update_data(skillUUID)
|
||||
SIconComp->>SkillSet : 查找技能配置
|
||||
SkillSet-->>SIconComp : 返回SkillConfig
|
||||
SIconComp->>SIconComp : 构建资源路径
|
||||
SIconComp->>oopsRes : oops.res.get(path, SpriteFrame)
|
||||
oopsRes-->>SIconComp : 返回SpriteFrame
|
||||
SIconComp->>Sprite : 设置spriteFrame
|
||||
Sprite-->>Client : 图标显示更新
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L18-L20)
|
||||
|
||||
该方法的工作流程包括:
|
||||
1. **技能配置查询**:通过传入的技能UUID从SkillSet配置表中获取对应的技能信息
|
||||
2. **路径构建**:根据技能配置中的`path`字段构建资源加载路径
|
||||
3. **资源加载**:调用oops.res.get方法异步加载SpriteFrame资源
|
||||
4. **纹理更新**:将加载的SpriteFrame赋值给Sprite组件的spriteFrame属性
|
||||
|
||||
### reset方法的节点销毁逻辑
|
||||
|
||||
reset方法实现了组件的清理和销毁功能:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([组件销毁开始]) --> CheckNode{"节点是否有效?"}
|
||||
CheckNode --> |是| DestroyNode["调用node.destroy()"]
|
||||
CheckNode --> |否| Skip["跳过销毁"]
|
||||
DestroyNode --> ReleaseMemory["释放内存资源"]
|
||||
ReleaseMemory --> CleanupComplete["清理完成"]
|
||||
Skip --> CleanupComplete
|
||||
CleanupComplete --> End([销毁结束])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L22-L24)
|
||||
|
||||
reset方法的设计考虑了以下因素:
|
||||
- **内存管理**:确保节点被正确销毁,避免内存泄漏
|
||||
- **ECS系统集成**:与ECS系统的组件回收机制保持一致
|
||||
- **生命周期管理**:在组件被移除时执行必要的清理工作
|
||||
|
||||
**章节来源**
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L18-L24)
|
||||
|
||||
## 资源管理系统集成
|
||||
|
||||
### SkillSet配置系统
|
||||
|
||||
SkillSet配置系统提供了技能的基础信息和资源路径映射:
|
||||
|
||||
| 配置项 | 类型 | 描述 | 示例值 |
|
||||
|--------|------|------|--------|
|
||||
| uuid | number | 技能唯一标识符 | 6001 |
|
||||
| name | string | 技能显示名称 | "挥击" |
|
||||
| path | string | 图标资源路径 | "3036" |
|
||||
| sp_name | string | 特效名称 | "atk_s1" |
|
||||
| TGroup | TGroup | 目标群体类型 | TGroup.Enemy |
|
||||
|
||||
### oops.res.get资源加载机制
|
||||
|
||||
oops.res.get方法提供了统一的资源加载接口:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Request[资源请求] --> Cache{缓存检查}
|
||||
Cache --> |命中| ReturnCached[返回缓存资源]
|
||||
Cache --> |未命中| LoadResource[加载资源]
|
||||
LoadResource --> ParsePath[解析资源路径]
|
||||
ParsePath --> LoadFromDisk[从磁盘加载]
|
||||
LoadFromDisk --> CreateAsset[创建资源对象]
|
||||
CreateAsset --> StoreCache[存储到缓存]
|
||||
StoreCache --> ReturnAsset[返回资源]
|
||||
ReturnCached --> End[完成]
|
||||
ReturnAsset --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [loader.md](file://doc/core/common/loader.md#L1-L66)
|
||||
|
||||
资源加载过程的关键特性:
|
||||
- **异步加载**:支持异步资源加载,避免阻塞主线程
|
||||
- **缓存机制**:自动缓存已加载的资源,提高重复访问效率
|
||||
- **类型安全**:通过泛型参数确保资源类型的一致性
|
||||
- **错误处理**:提供完善的错误处理和回退机制
|
||||
|
||||
**章节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L1-L148)
|
||||
- [loader.md](file://doc/core/common/loader.md#L1-L66)
|
||||
|
||||
## ECS系统组件生命周期
|
||||
|
||||
### 组件注册与管理
|
||||
|
||||
SIconCompComp通过ecs.register装饰器注册到ECS系统中:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 创建实例
|
||||
创建实例 --> 注册组件 : @ecs.register('SIconComp', false)
|
||||
注册组件 --> 初始化 : start()
|
||||
初始化 --> 运行中 : update_data()
|
||||
运行中 --> 更新数据 : update_data()
|
||||
更新数据 --> 运行中 : 继续处理
|
||||
运行中 --> 销毁 : reset()
|
||||
销毁 --> 回收组件 : 组件池管理
|
||||
回收组件 --> [*]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L9-L10)
|
||||
|
||||
### 生命周期方法详解
|
||||
|
||||
组件的生命周期管理遵循ECS系统的设计原则:
|
||||
|
||||
| 方法 | 调用时机 | 主要功能 | 注意事项 |
|
||||
|------|----------|----------|----------|
|
||||
| start() | 组件激活时 | 初始化基础逻辑 | 可选重写 |
|
||||
| update_data() | 外部调用 | 更新技能图标 | 必须实现 |
|
||||
| reset() | 组件销毁时 | 清理资源 | 必须实现 |
|
||||
|
||||
### 与ECS系统的集成优势
|
||||
|
||||
1. **组件复用**:支持多个实体共享同一组件实例
|
||||
2. **性能优化**:通过组件池减少对象创建开销
|
||||
3. **解耦设计**:业务逻辑与渲染逻辑完全分离
|
||||
4. **生命周期管理**:自动化的资源管理和清理
|
||||
|
||||
**章节来源**
|
||||
- [ecs.md](file://doc/ecs/ecs.md#L1-L87)
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L9-L10)
|
||||
|
||||
## 使用示例与最佳实践
|
||||
|
||||
### 基础使用示例
|
||||
|
||||
以下展示了SIconCompComp在不同UI上下文中的典型使用方式:
|
||||
|
||||
#### 技能面板中的应用
|
||||
|
||||
```typescript
|
||||
// 在技能面板中显示技能图标
|
||||
const iconNode = instantiate(iconPrefab);
|
||||
const iconComp = iconNode.getComponent(SIconCompComp);
|
||||
iconComp.update_data(6001); // 显示挥击技能图标
|
||||
panelNode.addChild(iconNode);
|
||||
```
|
||||
|
||||
#### 技能快捷栏中的应用
|
||||
|
||||
```typescript
|
||||
// 在技能快捷栏中动态更新图标
|
||||
skillBar.updateIcon = function(skillUUID: number) {
|
||||
const iconNode = this.iconNode;
|
||||
const iconComp = iconNode.getComponent(SIconCompComp);
|
||||
iconComp.update_data(skillUUID);
|
||||
};
|
||||
```
|
||||
|
||||
### 复用示例集合
|
||||
|
||||
#### 1. 技能详情窗口
|
||||
|
||||
```typescript
|
||||
class SkillDetailPanel {
|
||||
private iconComp: SIconCompComp;
|
||||
|
||||
showSkillDetails(skillUUID: number) {
|
||||
// 更新技能图标
|
||||
this.iconComp.update_data(skillUUID);
|
||||
|
||||
// 更新其他UI元素
|
||||
const skillConfig = SkillSet[skillUUID];
|
||||
this.nameLabel.string = skillConfig.name;
|
||||
this.descriptionLabel.string = skillConfig.info;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 英雄技能槽位
|
||||
|
||||
```typescript
|
||||
class HeroSkillSlot {
|
||||
private iconNode: Node;
|
||||
private slotIndex: number;
|
||||
|
||||
equipSkill(skillUUID: number) {
|
||||
if (!this.iconNode) {
|
||||
this.createIconNode();
|
||||
}
|
||||
|
||||
const iconComp = this.iconNode.getComponent(SIconCompComp);
|
||||
iconComp.update_data(skillUUID);
|
||||
}
|
||||
|
||||
unequipSkill() {
|
||||
if (this.iconNode) {
|
||||
this.iconNode.destroy();
|
||||
this.iconNode = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 战斗技能指示器
|
||||
|
||||
```typescript
|
||||
class CombatSkillIndicator {
|
||||
private indicators: SIconCompComp[];
|
||||
|
||||
updateSkillIndicators(skillUUIDs: number[]) {
|
||||
skillUUIDs.forEach((skillUUID, index) => {
|
||||
const indicator = this.indicators[index];
|
||||
indicator.update_data(skillUUID);
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 最佳实践建议
|
||||
|
||||
1. **资源预加载**:对于频繁使用的技能图标,建议在游戏启动时进行预加载
|
||||
2. **错误处理**:在update_data方法中添加异常处理,防止资源加载失败导致程序崩溃
|
||||
3. **内存监控**:定期检查组件的内存使用情况,及时清理不需要的图标
|
||||
4. **缓存策略**:合理设置资源缓存策略,平衡内存使用和加载性能
|
||||
|
||||
## 性能优化考虑
|
||||
|
||||
### 资源加载优化
|
||||
|
||||
1. **延迟加载**:只在需要时才加载技能图标资源
|
||||
2. **批量加载**:对于一组相关的技能图标,可以考虑批量加载
|
||||
3. **压缩优化**:使用适当的图片压缩格式减少资源体积
|
||||
4. **CDN加速**:对于大型游戏,可以考虑使用CDN加速资源加载
|
||||
|
||||
### 内存管理优化
|
||||
|
||||
1. **组件池化**:利用ECS系统的组件池机制减少对象创建开销
|
||||
2. **及时清理**:在reset方法中确保所有资源都被正确释放
|
||||
3. **弱引用**:对于长期持有的资源引用,考虑使用弱引用避免内存泄漏
|
||||
|
||||
### 渲染性能优化
|
||||
|
||||
1. **纹理合并**:将多个小图标合并到一个大纹理中
|
||||
2. **批处理**:利用Cocos Creator的自动批处理功能
|
||||
3. **LOD系统**:对于远距离显示的图标,使用较低分辨率的版本
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 1. 技能图标无法显示
|
||||
|
||||
**可能原因**:
|
||||
- 技能UUID不存在于SkillSet配置中
|
||||
- 资源路径配置错误
|
||||
- 资源加载失败
|
||||
|
||||
**解决步骤**:
|
||||
```typescript
|
||||
// 添加调试信息
|
||||
update_data(s_uuid: number) {
|
||||
console.log(`尝试加载技能 ${s_uuid} 的图标`);
|
||||
let skill_data = SkillSet[s_uuid];
|
||||
|
||||
if (!skill_data) {
|
||||
console.error(`技能 ${s_uuid} 配置不存在`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`技能 ${s_uuid} 路径: game/heros/cards/${skill_data.path}`);
|
||||
// 继续原有逻辑...
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 内存泄漏问题
|
||||
|
||||
**诊断方法**:
|
||||
- 监控组件的reset方法调用频率
|
||||
- 检查节点是否被正确销毁
|
||||
- 使用内存分析工具检查资源占用
|
||||
|
||||
**预防措施**:
|
||||
```typescript
|
||||
reset() {
|
||||
// 确保节点被正确销毁
|
||||
if (this.node && this.node.isValid) {
|
||||
this.node.destroy();
|
||||
}
|
||||
|
||||
// 清理其他可能的引用
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 资源加载超时
|
||||
|
||||
**解决方案**:
|
||||
- 添加加载超时机制
|
||||
- 提供默认图标作为后备
|
||||
- 实现重试逻辑
|
||||
|
||||
**章节来源**
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L18-L24)
|
||||
|
||||
## 总结
|
||||
|
||||
SIconCompComp技能图标组件是一个设计精良的通用UI组件,它成功地将资源管理、UI渲染和ECS系统生命周期管理进行了有机结合。通过本文档的详细分析,我们可以看到:
|
||||
|
||||
### 核心优势
|
||||
|
||||
1. **架构清晰**:采用分层架构设计,职责分明
|
||||
2. **易于复用**:支持多种UI上下文的适配
|
||||
3. **性能优秀**:集成资源管理系统,支持按需加载
|
||||
4. **生命周期完善**:与ECS系统深度集成,自动化资源管理
|
||||
|
||||
### 设计亮点
|
||||
|
||||
- **update_data方法**:简洁高效的技能图标更新接口
|
||||
- **reset方法**:完善的资源清理和节点销毁逻辑
|
||||
- **SkillSet集成**:标准化的技能配置管理
|
||||
- **oops.res.get**:统一的资源加载机制
|
||||
|
||||
### 应用价值
|
||||
|
||||
该组件不仅解决了技能图标显示的技术难题,更为游戏开发提供了一个可复用的UI组件模板,展示了现代游戏开发中组件化、模块化的设计思想。通过合理的抽象和封装,它大大提高了开发效率,降低了维护成本,是游戏UI组件设计的优秀范例。
|
||||
607
.qoder/repowiki/zh/content/用户界面系统/用户界面系统.md
Normal file
607
.qoder/repowiki/zh/content/用户界面系统/用户界面系统.md
Normal file
@@ -0,0 +1,607 @@
|
||||
# 用户界面系统
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts)
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts)
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts)
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md)
|
||||
- [VMBase.md](file://doc/mvvm/VMBase.md)
|
||||
- [gui.md](file://doc/core/gui/gui.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [UI层级架构](#ui层级架构)
|
||||
4. [核心组件分析](#核心组件分析)
|
||||
5. [MVVM框架集成](#mvvm框架集成)
|
||||
6. [事件系统与数据绑定](#事件系统与数据绑定)
|
||||
7. [使用示例](#使用示例)
|
||||
8. [性能优化考虑](#性能优化考虑)
|
||||
9. [故障排除指南](#故障排除指南)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
本游戏采用基于Oops Framework的现代化UI系统架构,集成了MVVM设计模式和事件驱动的组件化开发方式。系统通过GameUIConfig.ts统一管理界面配置,支持多种UI层级和预制体路径配置,并通过MVVM框架实现数据与视图的自动绑定。
|
||||
|
||||
## 项目结构
|
||||
|
||||
UI系统的核心文件组织结构如下:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "UI配置层"
|
||||
A[GameUIConfig.ts] --> B[UIID枚举]
|
||||
A --> C[UIConfigData配置]
|
||||
end
|
||||
subgraph "组件层"
|
||||
D[HInfoComp.ts] --> E[英雄信息面板]
|
||||
F[MInfoComp.ts] --> G[怪物信息组件]
|
||||
H[TopComp.ts] --> I[顶部状态栏]
|
||||
J[VictoryComp.ts] --> K[胜利界面]
|
||||
L[SIconComp.ts] --> M[技能图标组件]
|
||||
end
|
||||
subgraph "框架层"
|
||||
N[MVVM框架] --> O[ViewModel]
|
||||
N --> P[VMBase组件]
|
||||
Q[事件系统] --> R[GameEvent]
|
||||
end
|
||||
A --> D
|
||||
A --> F
|
||||
A --> H
|
||||
A --> J
|
||||
A --> L
|
||||
N --> D
|
||||
N --> F
|
||||
N --> H
|
||||
N --> J
|
||||
N --> L
|
||||
Q --> D
|
||||
Q --> F
|
||||
Q --> H
|
||||
Q --> J
|
||||
Q --> L
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L36)
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L344)
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L1-L28)
|
||||
|
||||
**章节来源**
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L36)
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L344)
|
||||
|
||||
## UI层级架构
|
||||
|
||||
### 层级类型定义
|
||||
|
||||
系统采用分层的UI管理架构,通过LayerType枚举定义不同的界面层级:
|
||||
|
||||
| 层级类型 | 描述 | 使用场景 |
|
||||
|---------|------|----------|
|
||||
| UI层 | 主界面层级,常驻显示 | 英雄信息面板、顶部状态栏 |
|
||||
| PopUp层 | 弹出式界面 | 网络不稳定提示、Toast消息 |
|
||||
| Dialog层 | 模态对话框 | 弹窗界面、确认对话框 |
|
||||
|
||||
### 配置数据结构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class UIConfig {
|
||||
+LayerType layer
|
||||
+string prefab
|
||||
+string bundle
|
||||
}
|
||||
class UIID {
|
||||
<<enumeration>>
|
||||
Loading
|
||||
Netinstable
|
||||
Role_Controller
|
||||
Victory
|
||||
Guide
|
||||
}
|
||||
class GameUIConfig {
|
||||
+UIConfigData : {[key : number] : UIConfig}
|
||||
+registerUI(id : number, config : UIConfig) : void
|
||||
+getUIConfig(id : number) : UIConfig
|
||||
}
|
||||
UIID --> GameUIConfig : "配置"
|
||||
UIConfig --> GameUIConfig : "管理"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L10-L35)
|
||||
|
||||
**章节来源**
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L36)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### HInfoComp - 英雄信息面板
|
||||
|
||||
英雄信息面板是最复杂的UI组件,负责展示和管理英雄选择、属性显示和交互功能。
|
||||
|
||||
#### 组件架构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class HInfoComp {
|
||||
+number h_uuid
|
||||
+Node[] heroNodes
|
||||
+Vec3 hero_pos
|
||||
+boolean isMoving
|
||||
+any moveTimeoutId
|
||||
+update_data(uuid : number) : void
|
||||
+load_all_hero(uuid : number) : void
|
||||
+load_hui(uuid : number, pos_index : number) : Node
|
||||
+next_hero() : void
|
||||
+prev_hero() : void
|
||||
+buy_hero() : void
|
||||
+start_mission() : void
|
||||
+moveHeroesLeft() : void
|
||||
+moveHeroesRight() : void
|
||||
+show_lock() : void
|
||||
+claear_hero() : void
|
||||
}
|
||||
class CCComp {
|
||||
+onLoad() : void
|
||||
+start() : void
|
||||
+update(deltaTime : number) : void
|
||||
+reset() : void
|
||||
}
|
||||
HInfoComp --|> CCComp : "继承"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L10-L344)
|
||||
|
||||
#### 英雄选择动画系统
|
||||
|
||||
组件实现了复杂的英雄选择动画系统,包括:
|
||||
|
||||
- **循环滚动算法**:支持无限循环的英雄选择
|
||||
- **平滑动画过渡**:使用Tween实现流畅的移动效果
|
||||
- **视觉焦点效果**:3号位置英雄显示1.5倍放大效果
|
||||
- **动画锁定机制**:防止快速点击导致的动画冲突
|
||||
|
||||
#### 数据绑定与更新
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User as 用户
|
||||
participant HInfo as HInfoComp
|
||||
participant SM as SingletonModule
|
||||
participant VM as ViewModel
|
||||
User->>HInfo : 点击英雄选择
|
||||
HInfo->>HInfo : 验证动画状态
|
||||
HInfo->>HInfo : 计算下一个英雄
|
||||
HInfo->>SM : updateFihgtHero(uuid)
|
||||
SM->>VM : 更新战斗英雄
|
||||
VM->>HInfo : 通知数据变更
|
||||
HInfo->>HInfo : update_data(uuid)
|
||||
HInfo->>HInfo : 执行动画过渡
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L200-L344)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L120-L140)
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L344)
|
||||
|
||||
### MInfoComp - 怪物信息组件
|
||||
|
||||
怪物信息组件负责显示当前关卡信息,采用简洁的设计模式。
|
||||
|
||||
#### 组件特性
|
||||
|
||||
- **事件驱动更新**:监听MISSION_UPDATE事件自动更新关卡信息
|
||||
- **文本绑定**:直接绑定到Label组件的字符串属性
|
||||
- **生命周期管理**:在onLoad中注册事件监听器,在start中初始化数据
|
||||
|
||||
**章节来源**
|
||||
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L1-L28)
|
||||
|
||||
### TopComp - 顶部状态栏
|
||||
|
||||
顶部状态栏组件专注于显示玩家资源信息,特别是金币数量的动画效果。
|
||||
|
||||
#### 特色功能
|
||||
|
||||
- **资源动画效果**:金币数量变化时触发缩放动画
|
||||
- **事件响应**:监听GOLD_UPDATE事件执行动画
|
||||
- **轻量级设计**:专注于单一功能,避免过度复杂化
|
||||
|
||||
**章节来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L1-L30)
|
||||
|
||||
### VictoryComp - 胜利界面
|
||||
|
||||
胜利界面组件处理战斗结算和奖励展示,包含复杂的奖励系统和动画效果。
|
||||
|
||||
#### 界面流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[战斗胜利] --> B[显示胜利界面]
|
||||
B --> C[展示奖励信息]
|
||||
C --> D{玩家选择}
|
||||
D --> |继续| E[下一关卡]
|
||||
D --> |重新开始| F[重置关卡]
|
||||
D --> |双倍奖励| G[观看广告]
|
||||
E --> H[清理数据]
|
||||
F --> H
|
||||
G --> I[验证广告]
|
||||
I --> J{验证结果}
|
||||
J --> |成功| K[获得双倍奖励]
|
||||
J --> |失败| L[显示错误]
|
||||
K --> H
|
||||
H --> M[返回主界面]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L30-L75)
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L75)
|
||||
|
||||
### SIconComp - 技能图标组件
|
||||
|
||||
技能图标组件负责显示技能的视觉图标,采用简单的数据绑定模式。
|
||||
|
||||
#### 组件特点
|
||||
|
||||
- **资源动态加载**:根据技能UUID动态加载对应的图标资源
|
||||
- **路径配置**:通过SkillSet配置技能的资源路径
|
||||
- **轻量级实现**:专注于单一职责,易于维护和扩展
|
||||
|
||||
**章节来源**
|
||||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L1-L28)
|
||||
|
||||
## MVVM框架集成
|
||||
|
||||
### 架构概览
|
||||
|
||||
系统采用MVVM(Model-View-ViewModel)架构模式,通过Oops Framework的ViewModel模块实现数据与视图的自动绑定。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "Model层"
|
||||
A[数据模型] --> B[SingletonModuleComp]
|
||||
B --> C[vmdata对象]
|
||||
end
|
||||
subgraph "ViewModel层"
|
||||
D[ViewModel] --> E[VMManager]
|
||||
E --> F[数据监听]
|
||||
end
|
||||
subgraph "View层"
|
||||
G[UI组件] --> H[VMBase组件]
|
||||
H --> I[数据绑定]
|
||||
end
|
||||
C --> D
|
||||
F --> H
|
||||
I --> G
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L50-L70)
|
||||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L10-L15)
|
||||
|
||||
### 数据模型管理
|
||||
|
||||
系统通过SingletonModuleComp统一管理游戏数据,特别是VM数据模型:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SingletonModuleComp {
|
||||
+vmdata : any
|
||||
+vmAdd() : void
|
||||
+updateGold(gold : number) : void
|
||||
+updateFihgtHero(heroId : number) : void
|
||||
+addHero(hero_uuid : number) : void
|
||||
}
|
||||
class ViewModel {
|
||||
+add(data : any, tag : string) : void
|
||||
+get(tag : string) : ViewModel
|
||||
+setValue(path : string, value : any) : void
|
||||
+getValue(path : string) : any
|
||||
}
|
||||
SingletonModuleComp --> ViewModel : "管理"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L50-L70)
|
||||
|
||||
### VMBase组件基类
|
||||
|
||||
所有UI组件都继承自VMBase组件,实现自动的数据绑定功能:
|
||||
|
||||
| 属性 | 类型 | 描述 |
|
||||
|------|------|------|
|
||||
| watchPath | string | 需要监听的数据路径 |
|
||||
| watchPathArr | string[] | 多路径监听数组 |
|
||||
| templateMode | boolean | 启用模板模式 |
|
||||
| VM | VMManager | ViewModel管理器引用 |
|
||||
|
||||
**章节来源**
|
||||
- [VMBase.md](file://doc/mvvm/VMBase.md#L1-L39)
|
||||
|
||||
## 事件系统与数据绑定
|
||||
|
||||
### 事件类型定义
|
||||
|
||||
系统通过GameEvent枚举定义了完整的游戏事件体系:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "战斗事件"
|
||||
A[FightStart] --> B[FightEnd]
|
||||
C[FightPause] --> D[FightResume]
|
||||
end
|
||||
subgraph "关卡事件"
|
||||
E[MissionStart] --> F[MissionEnd]
|
||||
G[MissionWin] --> H[MissionLoss]
|
||||
end
|
||||
subgraph "资源事件"
|
||||
I[GOLD_UPDATE] --> J[DIAMOND_UPDATE]
|
||||
K[MEAT_UPDATE] --> L[MISSION_UPDATE]
|
||||
end
|
||||
subgraph "选择事件"
|
||||
M[HeroSelect] --> N[EnhancementSelect]
|
||||
O[TalentSelect] --> P[FuncSelect]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L10-L70)
|
||||
|
||||
### 数据绑定流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Model as 数据模型
|
||||
participant VM as ViewModel
|
||||
participant View as UI组件
|
||||
participant Event as 事件系统
|
||||
Model->>VM : 数据变更
|
||||
VM->>VM : 触发监听器
|
||||
VM->>Event : 发送事件通知
|
||||
Event->>View : 分发事件
|
||||
View->>View : 更新UI显示
|
||||
View->>Model : 响应用户交互
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L150-L195)
|
||||
|
||||
**章节来源**
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L150-L195)
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 注册新UI界面
|
||||
|
||||
以下是如何注册和使用新UI界面的完整示例:
|
||||
|
||||
```typescript
|
||||
// 1. 在GameUIConfig.ts中添加UI配置
|
||||
export enum UIID {
|
||||
// ... 现有UI ID
|
||||
CustomPanel = 2001,
|
||||
}
|
||||
|
||||
export var UIConfigData: { [key: number]: UIConfig } = {
|
||||
// ... 现有UI配置
|
||||
[UIID.CustomPanel]: {
|
||||
layer: LayerType.UI,
|
||||
prefab: "custom/prefab/panel"
|
||||
},
|
||||
};
|
||||
|
||||
// 2. 创建UI组件
|
||||
@ccclass('CustomPanelComp')
|
||||
export class CustomPanelComp extends CCComp {
|
||||
protected onLoad(): void {
|
||||
// 注册事件监听
|
||||
oops.message.on(GameEvent.CustomEvent, this.onCustomEvent, this);
|
||||
}
|
||||
|
||||
onCustomEvent(event: string, data: any): void {
|
||||
// 处理自定义事件
|
||||
this.updateDisplay(data);
|
||||
}
|
||||
|
||||
updateDisplay(data: any): void {
|
||||
// 更新UI显示
|
||||
const label = this.node.getChildByName("content")
|
||||
.getComponent(Label);
|
||||
label.string = data.message;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 打开UI界面
|
||||
const callbacks: UICallbacks = {
|
||||
onAdded: (node: Node, params: any) => {
|
||||
const comp = node.getComponent(CustomPanelComp);
|
||||
// 初始化界面
|
||||
},
|
||||
onRemoved: (node: Node | null, params: any) => {
|
||||
// 清理资源
|
||||
}
|
||||
};
|
||||
|
||||
oops.gui.open(UIID.CustomPanel, null, callbacks);
|
||||
```
|
||||
|
||||
### 处理按钮点击事件
|
||||
|
||||
```typescript
|
||||
// 在UI组件中处理按钮点击
|
||||
@ccclass('ButtonHandler')
|
||||
export class ButtonHandler extends Component {
|
||||
start(): void {
|
||||
// 获取按钮节点
|
||||
const button = this.node.getChildByName("action_button");
|
||||
if (button) {
|
||||
// 添加点击事件监听
|
||||
button.on(Node.EventType.TOUCH_END, this.onButtonClick, this);
|
||||
}
|
||||
}
|
||||
|
||||
onButtonClick(event: EventTouch): void {
|
||||
// 触发游戏事件
|
||||
oops.message.dispatchEvent(GameEvent.ButtonClicked, {
|
||||
buttonId: "action_button",
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
// 执行业务逻辑
|
||||
this.performAction();
|
||||
}
|
||||
|
||||
performAction(): void {
|
||||
// 实现具体业务逻辑
|
||||
console.log("按钮被点击");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 实现动态数据刷新
|
||||
|
||||
```typescript
|
||||
// 使用MVVM框架实现自动数据刷新
|
||||
@ccclass('DynamicDataComp')
|
||||
export class DynamicDataComp extends VMBase {
|
||||
@property({ type: Label })
|
||||
public displayLabel: Label = null!;
|
||||
|
||||
@property(String)
|
||||
public watchPath: string = "global.player.health";
|
||||
|
||||
onValueChanged(newValue: any, oldValue: any, pathArray: string[]): void {
|
||||
// 自动更新UI显示
|
||||
this.displayLabel.string = `生命值: ${newValue}`;
|
||||
|
||||
// 可选:添加视觉反馈
|
||||
if (newValue < oldValue) {
|
||||
this.showDamageEffect();
|
||||
}
|
||||
}
|
||||
|
||||
showDamageEffect(): void {
|
||||
// 显示伤害特效
|
||||
tween(this.node)
|
||||
.to(0.1, { color: Color.RED })
|
||||
.to(0.1, { color: Color.WHITE })
|
||||
.start();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 性能优化考虑
|
||||
|
||||
### 组件复用策略
|
||||
|
||||
1. **预制体池化**:对于频繁创建销毁的UI组件,实现预制体池化机制
|
||||
2. **延迟加载**:非关键UI组件采用延迟加载策略
|
||||
3. **内存管理**:及时清理事件监听器和定时器
|
||||
|
||||
### 动画性能优化
|
||||
|
||||
1. **批量动画**:将多个动画合并为批量操作
|
||||
2. **硬件加速**:利用CSS3变换实现硬件加速
|
||||
3. **帧率控制**:限制动画帧率避免过度消耗CPU
|
||||
|
||||
### 数据绑定优化
|
||||
|
||||
1. **路径简化**:避免过深的数据绑定路径
|
||||
2. **防抖处理**:对高频数据更新实施防抖机制
|
||||
3. **选择性更新**:只更新发生变化的UI部分
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### UI组件无法显示
|
||||
|
||||
**问题症状**:UI组件创建后不显示或显示异常
|
||||
|
||||
**排查步骤**:
|
||||
1. 检查预制体路径配置是否正确
|
||||
2. 验证UI层级设置是否符合预期
|
||||
3. 确认组件脚本是否正确注册
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 检查UI配置
|
||||
console.log("UI配置:", UIConfigData[UIID.CustomPanel]);
|
||||
|
||||
// 验证预制体加载
|
||||
oops.res.get(UIConfigData[UIID.CustomPanel].prefab, Prefab, (err, prefab) => {
|
||||
if (err) {
|
||||
console.error("预制体加载失败:", err);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 数据绑定失效
|
||||
|
||||
**问题症状**:数据更新后UI不自动刷新
|
||||
|
||||
**排查步骤**:
|
||||
1. 检查watchPath路径是否正确
|
||||
2. 验证ViewModel是否正常工作
|
||||
3. 确认事件系统是否正常
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 手动测试数据绑定
|
||||
VM.setValue("global.test.value", "测试数据");
|
||||
console.log("当前值:", VM.getValue("global.test.value"));
|
||||
```
|
||||
|
||||
#### 动画卡顿
|
||||
|
||||
**问题症状**:UI动画播放不流畅
|
||||
|
||||
**排查步骤**:
|
||||
1. 检查动画复杂度
|
||||
2. 验证硬件性能
|
||||
3. 确认动画队列管理
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 优化动画实现
|
||||
tween(target)
|
||||
.to(0.2, { position: newPosition })
|
||||
.call(() => {
|
||||
// 动画完成后清理
|
||||
this.cleanupAnimation();
|
||||
})
|
||||
.start();
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L200-L344)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L150-L195)
|
||||
|
||||
## 总结
|
||||
|
||||
本UI系统通过模块化的架构设计,实现了高度可维护和可扩展的界面管理方案。系统的主要优势包括:
|
||||
|
||||
1. **统一的配置管理**:通过GameUIConfig.ts集中管理所有UI配置
|
||||
2. **MVVM架构**:实现数据与视图的自动绑定,减少手动DOM操作
|
||||
3. **事件驱动**:基于事件系统实现松耦合的组件通信
|
||||
4. **性能优化**:通过合理的架构设计和优化策略保证良好的性能表现
|
||||
5. **易于扩展**:模块化的设计使得添加新UI组件变得简单直观
|
||||
|
||||
该系统为游戏提供了稳定可靠的UI基础设施,支持复杂的交互逻辑和动态内容更新,是现代游戏开发中UI系统设计的优秀实践案例。
|
||||
467
.qoder/repowiki/zh/content/用户界面系统/胜利界面.md
Normal file
467
.qoder/repowiki/zh/content/用户界面系统/胜利界面.md
Normal file
@@ -0,0 +1,467 @@
|
||||
# 胜利界面
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
- [gui.md](file://doc/core/gui/gui.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
VictoryComp.ts是游戏胜利界面的核心组件,负责展示战斗胜利后的奖励界面,包括经验值、金币和钻石奖励的展示。该组件采用基于ECS(Entity-Component-System)架构设计,实现了视图层与业务逻辑的分离,提供了完整的胜利后交互功能,包括继续游戏、重新开始、观看广告双倍奖励等操作。
|
||||
|
||||
## 项目结构
|
||||
|
||||
胜利界面组件位于游戏的地图模块中,与其他战斗相关组件协同工作:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "游戏模块结构"
|
||||
A[地图模块] --> B[VictoryComp.ts]
|
||||
A --> C[MissionComp.ts]
|
||||
A --> D[MissionMonComp.ts]
|
||||
A --> E[MissionHeroComp.ts]
|
||||
end
|
||||
subgraph "配置文件"
|
||||
F[GameUIConfig.ts] --> G[UIID.Victory]
|
||||
H[GameEvent.ts] --> I[MissionEnd]
|
||||
H --> J[MissionStart]
|
||||
end
|
||||
subgraph "框架支持"
|
||||
K[Oops Framework] --> L[ECS系统]
|
||||
K --> M[GUI管理]
|
||||
K --> N[消息系统]
|
||||
end
|
||||
B --> F
|
||||
B --> H
|
||||
B --> K
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L75)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L35)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L75)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L35)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 主要数据结构
|
||||
|
||||
胜利界面维护以下核心数据结构:
|
||||
|
||||
| 属性名称 | 类型 | 默认值 | 描述 |
|
||||
|---------|------|--------|------|
|
||||
| reward_lv | number | 1 | 奖励等级 |
|
||||
| reward_num | number | 2 | 奖励数量 |
|
||||
| rewards | any[] | [] | 奖励物品列表 |
|
||||
| game_data | object | {exp:0,gold:0,diamond:0} | 游戏数据奖励 |
|
||||
|
||||
### 组件注册与生命周期
|
||||
|
||||
组件通过ECS系统注册,具有完整的生命周期管理:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 初始化
|
||||
初始化 --> onAdded : 接收参数
|
||||
onAdded --> 显示界面 : 设置游戏数据
|
||||
显示界面 --> 等待交互 : 按钮延迟显示
|
||||
等待交互 --> 继续游戏 : victory_end()
|
||||
等待交互 --> 重新开始 : restart()
|
||||
等待交互 --> 广告双倍 : watch_ad()
|
||||
继续游戏 --> 清理资源 : clear_data()
|
||||
重新开始 --> 清理资源 : clear_data()
|
||||
广告双倍 --> 清理资源 : clear_data()
|
||||
清理资源 --> 销毁界面 : removeByNode()
|
||||
销毁界面 --> [*]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L18-L75)
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L18-L75)
|
||||
|
||||
## 架构概览
|
||||
|
||||
胜利界面采用模块化架构设计,与游戏的ECS系统深度集成:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class VictoryComp {
|
||||
+number reward_lv
|
||||
+number reward_num
|
||||
+any[] rewards
|
||||
+object game_data
|
||||
+onAdded(args : any) void
|
||||
+victory_end() void
|
||||
+restart() void
|
||||
+watch_ad() boolean
|
||||
+double_reward() void
|
||||
+clear_data() void
|
||||
+reset() void
|
||||
}
|
||||
class CCComp {
|
||||
<<abstract>>
|
||||
+onLoad() void
|
||||
+onDestroy() void
|
||||
}
|
||||
class ecs {
|
||||
+register(name : string, persistent : boolean) decorator
|
||||
}
|
||||
class oops {
|
||||
+message MessageManager
|
||||
+gui GUIManager
|
||||
}
|
||||
class GameEvent {
|
||||
+MissionEnd string
|
||||
+MissionStart string
|
||||
}
|
||||
VictoryComp --|> CCComp
|
||||
VictoryComp ..> ecs : 注册到ECS
|
||||
VictoryComp ..> oops : 使用GUI和消息系统
|
||||
VictoryComp ..> GameEvent : 触发游戏事件
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L10-L75)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L10-L70)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### onAdded方法:界面初始化
|
||||
|
||||
onAdded方法是胜利界面的主要初始化入口,负责接收游戏数据并设置界面状态:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Mission as MissionComp
|
||||
participant GUI as GUI系统
|
||||
participant Victory as VictoryComp
|
||||
participant SM as SingletonModuleComp
|
||||
participant Game as 游戏事件系统
|
||||
Mission->>GUI : open(UIID.Victory, args)
|
||||
GUI->>Victory : 实例化组件
|
||||
Victory->>Victory : onAdded(args)
|
||||
Victory->>Victory : 检查并设置game_data
|
||||
Victory->>Victory : 显示胜利标题
|
||||
Victory->>Victory : 隐藏继续按钮
|
||||
Victory->>Victory : scheduleOnce延迟显示按钮
|
||||
Victory->>SM : 初始化界面状态
|
||||
Victory-->>GUI : 初始化完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L28-L40)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L65-L108)
|
||||
|
||||
#### 参数处理逻辑
|
||||
|
||||
onAdded方法接收包含游戏数据的参数对象,主要处理以下内容:
|
||||
|
||||
1. **游戏数据验证**:检查args.game_data是否存在并有效
|
||||
2. **数据赋值**:将传入的游戏数据赋值给组件的game_data属性
|
||||
3. **界面元素激活**:显示胜利标题文本
|
||||
4. **按钮状态管理**:隐藏继续按钮,设置延迟显示
|
||||
|
||||
#### 定时器应用
|
||||
|
||||
组件使用scheduleOnce实现按钮的延迟显示,这是优化用户体验的重要设计:
|
||||
|
||||
- **延迟时间**:0.2秒
|
||||
- **目的**:避免界面元素同时出现造成的视觉冲击
|
||||
- **实现方式**:通过Cocos Creator的定时器系统
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L28-L40)
|
||||
|
||||
### 交互功能分析
|
||||
|
||||
#### 继续游戏功能(victory_end)
|
||||
|
||||
继续游戏功能负责结束当前关卡并返回主界面:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[victory_end调用] --> B[clear_data清理数据]
|
||||
B --> C[dispatchEvent MissionEnd]
|
||||
C --> D[removeByNode销毁界面]
|
||||
D --> E[释放内存资源]
|
||||
E --> F[返回主界面]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L42-L46)
|
||||
|
||||
#### 重新开始功能(restart)
|
||||
|
||||
重新开始功能允许玩家重新挑战当前关卡:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[restart调用] --> B[clear_data清理数据]
|
||||
B --> C[dispatchEvent MissionStart]
|
||||
C --> D[removeByNode销毁界面]
|
||||
D --> E[重新初始化关卡]
|
||||
E --> F[开始新游戏]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L54-L58)
|
||||
|
||||
#### 广告双倍奖励机制
|
||||
|
||||
虽然当前实现较为简单,但预留了完整的双倍奖励机制:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[watch_ad调用] --> B{return true}
|
||||
B --> C[触发double_reward]
|
||||
C --> D[处理奖励翻倍逻辑]
|
||||
D --> E[更新游戏数据]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L50-L52)
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L42-L60)
|
||||
|
||||
### 资源管理策略
|
||||
|
||||
#### clear_data方法
|
||||
|
||||
clear_data方法目前为空实现,但作为资源清理的占位符,为未来的扩展预留空间:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[clear_data调用] --> B[当前为空实现]
|
||||
B --> C[预留扩展点]
|
||||
C --> D[未来可添加资源清理逻辑]
|
||||
```
|
||||
|
||||
#### reset方法与界面销毁
|
||||
|
||||
reset方法实现了组件的完整销毁流程:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant ECS as ECS系统
|
||||
participant Victory as VictoryComp
|
||||
participant Node as Cocos节点
|
||||
participant Memory as 内存管理
|
||||
ECS->>Victory : 调用reset()
|
||||
Victory->>Node : node.destroy()
|
||||
Node->>Memory : 释放节点内存
|
||||
Memory-->>Victory : 内存释放完成
|
||||
Victory-->>ECS : 销毁完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L70-L74)
|
||||
|
||||
#### oops.gui.removeByNode的应用
|
||||
|
||||
组件使用oops.gui.removeByNode进行界面销毁,这是框架推荐的标准做法:
|
||||
|
||||
- **优势**:确保资源正确释放
|
||||
- **安全性**:只有通过GUI系统打开的节点才能被正确移除
|
||||
- **一致性**:与整个框架的资源管理模式保持一致
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L42-L74)
|
||||
|
||||
### ECS系统集成
|
||||
|
||||
#### 组件注册机制
|
||||
|
||||
VictoryComp通过@ecs.register装饰器注册到ECS系统:
|
||||
|
||||
```typescript
|
||||
@ecs.register('Victory', false)
|
||||
export class VictoryComp extends CCComp
|
||||
```
|
||||
|
||||
注册参数说明:
|
||||
- **第一个参数**:组件名称'Victory'
|
||||
- **第二个参数**:持久化标志false(表示非持久化组件)
|
||||
|
||||
#### 在游戏状态流转中的作用
|
||||
|
||||
胜利界面在游戏状态流转中扮演关键角色:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 战斗中
|
||||
战斗中 --> 战斗胜利 : 敌人全部死亡
|
||||
战斗胜利 --> 胜利界面 : open(UIID.Victory)
|
||||
胜利界面 --> 继续游戏 : 用户选择
|
||||
胜利界面 --> 重新开始 : 用户选择
|
||||
继续游戏 --> 主界面 : MissionEnd事件
|
||||
重新开始 --> 新关卡 : MissionStart事件
|
||||
主界面 --> [*]
|
||||
新关卡 --> [*]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L30-L35)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L65-L108)
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L13-L14)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L30-L35)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
### 外部依赖
|
||||
|
||||
胜利界面组件依赖以下外部模块:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[VictoryComp] --> B[Cocos Creator引擎]
|
||||
A --> C[Oops Framework]
|
||||
A --> D[ECS系统]
|
||||
A --> E[SingletonModuleComp]
|
||||
A --> F[GameEvent枚举]
|
||||
B --> G[_decorator, instantiate, Label, Prefab, Node]
|
||||
C --> H[GUI管理, 消息系统]
|
||||
D --> I[组件注册, 生命周期管理]
|
||||
E --> J[全局游戏状态]
|
||||
F --> K[游戏事件定义]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L10)
|
||||
|
||||
### 内部依赖
|
||||
|
||||
组件内部的相互依赖关系:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[VictoryComp] --> B[游戏数据处理]
|
||||
A --> C[界面交互逻辑]
|
||||
A --> D[资源管理]
|
||||
A --> E[ECS系统集成]
|
||||
B --> F[game_data对象]
|
||||
C --> G[按钮事件处理]
|
||||
D --> H[clear_data & reset]
|
||||
E --> I[组件注册 & 生命周期]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L18-L75)
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L10)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 内存管理
|
||||
|
||||
胜利界面采用了多层次的内存管理策略:
|
||||
|
||||
1. **组件级销毁**:通过reset方法确保组件完全销毁
|
||||
2. **节点级清理**:使用destroy方法释放Cocos节点
|
||||
3. **引用清理**:避免循环引用导致的内存泄漏
|
||||
|
||||
### 渲染优化
|
||||
|
||||
- **延迟显示**:使用scheduleOnce避免界面元素同时渲染
|
||||
- **条件激活**:根据游戏状态动态控制界面元素的显示
|
||||
- **资源预加载**:通过GUI系统管理界面资源的生命周期
|
||||
|
||||
### 事件处理优化
|
||||
|
||||
- **事件解耦**:通过消息系统实现松耦合的事件通信
|
||||
- **批量处理**:在合适的时机批量处理界面更新
|
||||
- **防重复**:确保相同事件不会被重复处理
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 界面无法正常显示
|
||||
|
||||
**可能原因**:
|
||||
- 参数传递错误
|
||||
- 游戏数据格式不正确
|
||||
- GUI系统配置问题
|
||||
|
||||
**解决方案**:
|
||||
1. 检查args.game_data的结构和内容
|
||||
2. 验证UIID.Victory的配置
|
||||
3. 确认ECS系统注册正常
|
||||
|
||||
#### 按钮点击无响应
|
||||
|
||||
**可能原因**:
|
||||
- 事件绑定失败
|
||||
- 组件生命周期问题
|
||||
- GUI系统状态异常
|
||||
|
||||
**解决方案**:
|
||||
1. 检查onAdded方法的执行情况
|
||||
2. 验证组件的生命周期管理
|
||||
3. 确认GUI系统的正常运行
|
||||
|
||||
#### 内存泄漏问题
|
||||
|
||||
**可能原因**:
|
||||
- 资源未正确释放
|
||||
- 循环引用存在
|
||||
- 事件监听器未清理
|
||||
|
||||
**解决方案**:
|
||||
1. 确保调用clear_data和reset方法
|
||||
2. 检查组件间的引用关系
|
||||
3. 验证事件监听器的正确清理
|
||||
|
||||
**章节来源**
|
||||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L42-L74)
|
||||
|
||||
## 结论
|
||||
|
||||
VictoryComp.ts作为游戏胜利界面的核心组件,展现了现代游戏开发中优秀的架构设计原则:
|
||||
|
||||
### 设计亮点
|
||||
|
||||
1. **模块化架构**:通过ECS系统实现组件化开发
|
||||
2. **生命周期管理**:完善的资源管理和销毁机制
|
||||
3. **事件驱动**:基于消息系统的松耦合设计
|
||||
4. **扩展性**:预留的接口和占位符便于功能扩展
|
||||
|
||||
### 技术特点
|
||||
|
||||
1. **类型安全**:充分利用TypeScript的类型系统
|
||||
2. **性能优化**:合理的内存管理和渲染优化
|
||||
3. **用户体验**:精心设计的界面交互流程
|
||||
4. **框架集成**:与Oops Framework的深度集成
|
||||
|
||||
### 改进建议
|
||||
|
||||
1. **增强功能**:完善双倍奖励机制的具体实现
|
||||
2. **错误处理**:添加更健壮的错误处理逻辑
|
||||
3. **测试覆盖**:建立完整的单元测试和集成测试
|
||||
4. **文档完善**:补充详细的API文档和使用示例
|
||||
|
||||
该组件为游戏胜利界面提供了坚实的技术基础,其设计理念和实现方式值得在类似项目中借鉴和应用。
|
||||
511
.qoder/repowiki/zh/content/用户界面系统/英雄信息面板.md
Normal file
511
.qoder/repowiki/zh/content/用户界面系统/英雄信息面板.md
Normal file
@@ -0,0 +1,511 @@
|
||||
# 英雄信息面板功能详细文档
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [BezierMove.ts](file://assets/script/game/BezierMove/BezierMove.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 概述
|
||||
|
||||
HInfoComp.ts是Cocos Creator游戏引擎中英雄信息面板的核心组件,负责展示英雄属性、实现英雄切换动画以及处理用户交互。该组件采用MVVM架构模式,通过Tween动画系统实现流畅的英雄切换效果,并与全局状态管理系统smc紧密集成。
|
||||
|
||||
## 项目结构
|
||||
|
||||
英雄信息面板位于游戏的地图模块中,其文件组织结构如下:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "英雄信息面板模块"
|
||||
HInfoComp[HInfoComp.ts<br/>主控制器]
|
||||
HeroSet[heroSet.ts<br/>英雄配置]
|
||||
Singleton[SingletonModuleComp.ts<br/>全局状态管理]
|
||||
end
|
||||
subgraph "动画系统"
|
||||
Tween[Tween动画系统]
|
||||
AnimClip[AnimationClip<br/>动画剪辑]
|
||||
end
|
||||
subgraph "UI组件"
|
||||
Label[Label组件<br/>文本显示]
|
||||
ProgressBar[ProgressBar组件<br/>进度条显示]
|
||||
Button[Button组件<br/>交互按钮]
|
||||
end
|
||||
HInfoComp --> Tween
|
||||
HInfoComp --> HeroSet
|
||||
HInfoComp --> Singleton
|
||||
HInfoComp --> Label
|
||||
HInfoComp --> ProgressBar
|
||||
HInfoComp --> Button
|
||||
Tween --> AnimClip
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L50)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L30)
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L344)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L152)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 主控制器组件(HInfoComp)
|
||||
|
||||
HInfoComp是英雄信息面板的主要控制器,负责:
|
||||
- 管理英雄节点的生命周期
|
||||
- 处理英雄切换动画逻辑
|
||||
- 更新UI数据绑定
|
||||
- 响应用户交互事件
|
||||
|
||||
### 英雄配置系统
|
||||
|
||||
英雄配置系统提供了完整的英雄数据结构和过滤逻辑:
|
||||
- `getHeroList()`函数实现英雄列表的智能过滤
|
||||
- 支持拥有的英雄优先显示
|
||||
- 提供英雄属性计算和归一化功能
|
||||
|
||||
### 全局状态管理系统
|
||||
|
||||
smc(SingletonModuleComp)作为全局状态管理器,维护:
|
||||
- 当前出战英雄信息
|
||||
- 用户拥有的英雄列表
|
||||
- 游戏金币和其他资源数据
|
||||
- 与云端数据的同步机制
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L10-L50)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L20-L40)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L40-L80)
|
||||
|
||||
## 架构概览
|
||||
|
||||
英雄信息面板采用分层架构设计,从底层到顶层依次为:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "表现层"
|
||||
UI[UI组件层<br/>Label, ProgressBar, Button]
|
||||
Anim[动画层<br/>Tween动画]
|
||||
end
|
||||
subgraph "业务逻辑层"
|
||||
Controller[控制器层<br/>HInfoComp]
|
||||
EventMgr[事件管理器<br/>GameEvent]
|
||||
end
|
||||
subgraph "数据层"
|
||||
Config[配置层<br/>HeroInfo, HeroSet]
|
||||
State[状态层<br/>smc全局状态]
|
||||
end
|
||||
subgraph "引擎层"
|
||||
CCEngine[Cocos引擎]
|
||||
ECS[ECS系统]
|
||||
end
|
||||
UI --> Controller
|
||||
Anim --> Controller
|
||||
Controller --> EventMgr
|
||||
Controller --> Config
|
||||
Controller --> State
|
||||
EventMgr --> State
|
||||
Config --> ECS
|
||||
State --> ECS
|
||||
Controller --> CCEngine
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L20)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L30)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 英雄属性展示系统
|
||||
|
||||
#### 属性数据绑定机制
|
||||
|
||||
英雄信息面板通过精确的UI数据绑定系统展示英雄属性:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User as 用户界面
|
||||
participant HInfo as HInfoComp
|
||||
participant HeroInfo as HeroInfo配置
|
||||
participant UI as UI组件
|
||||
User->>HInfo : 请求更新英雄属性
|
||||
HInfo->>HeroInfo : 查询英雄数据
|
||||
HeroInfo-->>HInfo : 返回英雄属性数据
|
||||
HInfo->>HInfo : 计算属性进度值
|
||||
HInfo->>UI : 更新Label组件
|
||||
HInfo->>UI : 更新ProgressBar组件
|
||||
UI-->>User : 显示更新后的属性
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L55-L76)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L60-L70)
|
||||
|
||||
#### 英雄属性结构
|
||||
|
||||
| 属性类别 | 组件名称 | 数据来源 | 显示格式 |
|
||||
|---------|----------|----------|----------|
|
||||
| 基础属性 | 名称 | HeroInfo[uuid].name | 文本显示 |
|
||||
| 类型标识 | 类型 | HTypeName[HeroInfo[uuid].type] | 文本显示 |
|
||||
| 攻击力 | ap_node | HeroInfo[uuid].ap | 数字+进度条 |
|
||||
| 生命值 | hp_node | HeroInfo[uuid].hp | 数字+进度条 |
|
||||
| 物理防御 | def_node | HeroInfo[uuid].def | 数字+进度条 |
|
||||
| 魔法防御 | mdef_node | HeroInfo[uuid].mdef | 数字+进度条 |
|
||||
| 魔法值 | mp_node | HeroInfo[uuid].mp | 数字+进度条 |
|
||||
| 魔法攻击力 | map_node | HeroInfo[uuid].map | 数字+进度条 |
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L55-L76)
|
||||
|
||||
### 英雄切换动画系统
|
||||
|
||||
#### 动画冲突防止机制
|
||||
|
||||
系统实现了完善的动画冲突防止机制,确保用户交互的流畅性:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([用户点击切换]) --> CheckMoving{是否正在动画?}
|
||||
CheckMoving --> |是| Return([直接返回])
|
||||
CheckMoving --> |否| GetList[获取英雄列表]
|
||||
GetList --> CalcIndex[计算目标索引]
|
||||
CalcIndex --> UpdateUUID[更新英雄UUID]
|
||||
UpdateUUID --> UpdateData[更新UI数据]
|
||||
UpdateData --> StartAnim[启动切换动画]
|
||||
StartAnim --> SetFlag[设置动画标志]
|
||||
SetFlag --> WaitComplete[等待动画完成]
|
||||
WaitComplete --> ClearFlag[清除动画标志]
|
||||
ClearFlag --> End([完成])
|
||||
Return --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L169-L185)
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L189-L205)
|
||||
|
||||
#### 平滑滚动机制
|
||||
|
||||
英雄切换采用基于Tween的平滑滚动动画:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Comp as HInfoComp
|
||||
participant Tween as Tween系统
|
||||
participant Node as 英雄节点
|
||||
participant Timer as 定时器
|
||||
Comp->>Comp : 检查动画状态
|
||||
Comp->>Comp : 销毁边界节点
|
||||
Comp->>Node : 获取所有现有节点
|
||||
loop 对每个节点
|
||||
Comp->>Tween : 创建移动动画
|
||||
Tween->>Node : 执行位置变换
|
||||
Tween->>Node : 执行缩放动画
|
||||
end
|
||||
Comp->>Timer : 设置延迟回调
|
||||
Timer->>Comp : 执行节点重排
|
||||
Comp->>Comp : 创建新节点
|
||||
Comp->>Comp : 清除动画标志
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L220-L344)
|
||||
|
||||
#### 中心位置缩放特效
|
||||
|
||||
系统为英雄信息面板的中心位置(pos_index=3)实现了独特的缩放特效:
|
||||
|
||||
| 位置索引 | 缩放比例 | 动画时长 | 特效说明 |
|
||||
|---------|----------|----------|----------|
|
||||
| 0, 6 | 1.0倍 | 0.2秒 | 标准大小显示 |
|
||||
| 1, 5 | 1.0倍 | 0.2秒 | 标准大小显示 |
|
||||
| 2, 4 | 1.0倍 | 0.2秒 | 标准大小显示 |
|
||||
| 3 | 1.5倍 | 0.2秒 | 中心放大特效 |
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L289-L344)
|
||||
|
||||
### 英雄列表获取与过滤
|
||||
|
||||
#### getHeroList()函数实现
|
||||
|
||||
getHeroList()函数实现了智能的英雄列表过滤逻辑:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始获取英雄列表]) --> FilterByFac[按阵营过滤英雄]
|
||||
FilterByFac --> SplitOwned[分离拥有的英雄]
|
||||
SplitOwned --> SplitUnowned[分离未拥有的英雄]
|
||||
SplitUnowned --> MergeLists[合并列表]
|
||||
MergeLists --> MapUUID[提取UUID数组]
|
||||
MapUUID --> Return([返回英雄列表])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L20-L35)
|
||||
|
||||
#### 英雄列表排序策略
|
||||
|
||||
英雄列表采用以下排序策略:
|
||||
1. **拥有的英雄优先**:用户已解锁的英雄排在前面
|
||||
2. **未拥有的英雄在后**:显示可购买的英雄
|
||||
3. **保持循环访问**:支持首尾循环切换
|
||||
|
||||
**章节来源**
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L20-L40)
|
||||
|
||||
### UI数据绑定系统
|
||||
|
||||
#### MVVM架构实现
|
||||
|
||||
英雄信息面板采用MVVM架构模式,实现数据与视图的自动同步:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class HInfoComp {
|
||||
+update_data(uuid : number)
|
||||
+show_lock()
|
||||
+is_own() boolean
|
||||
-name_node : any
|
||||
-type_node : any
|
||||
-ap_node : any
|
||||
-hp_node : any
|
||||
-def_node : any
|
||||
-mp_node : any
|
||||
-map_node : any
|
||||
-mdef_node : any
|
||||
}
|
||||
class HeroInfo {
|
||||
+uuid : number
|
||||
+name : string
|
||||
+type : HType
|
||||
+ap : number
|
||||
+hp : number
|
||||
+def : number
|
||||
+mp : number
|
||||
+map : number
|
||||
+mdef : number
|
||||
}
|
||||
class SingletonModuleComp {
|
||||
+fight_hero : number
|
||||
+heros : any[]
|
||||
+vmdata : any
|
||||
+updateFihgtHero(heroId : number)
|
||||
+addHero(hero_uuid : number)
|
||||
}
|
||||
HInfoComp --> HeroInfo : "读取数据"
|
||||
HInfoComp --> SingletonModuleComp : "状态管理"
|
||||
SingletonModuleComp --> HeroInfo : "共享数据"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L10-L50)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L40-L80)
|
||||
|
||||
#### ProgressBar和Label响应机制
|
||||
|
||||
系统通过以下机制响应smc.fight_hero的变化:
|
||||
|
||||
| 组件类型 | 响应方式 | 更新内容 | 触发条件 |
|
||||
|---------|----------|----------|----------|
|
||||
| Label | 直接赋值 | 文本内容 | UUID变化 |
|
||||
| ProgressBar | 进度赋值 | 进度条显示 | 属性值变化 |
|
||||
| Lock状态 | 可见性切换 | 锁定图标显示 | 拥有状态变化 |
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L55-L76)
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L145-L155)
|
||||
|
||||
### 英雄购买逻辑
|
||||
|
||||
#### buy_hero()函数实现
|
||||
|
||||
英雄购买功能实现了完整的购买流程:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([点击购买]) --> CheckGold{金币充足?}
|
||||
CheckGold --> |否| ShowToast[显示提示:"金币不足"]
|
||||
CheckGold --> |是| AddHero[添加英雄到列表]
|
||||
AddHero --> UpdateUI[更新UI显示]
|
||||
UpdateUI --> ShowLock[刷新锁定状态]
|
||||
ShowToast --> End([结束])
|
||||
ShowLock --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L207-L215)
|
||||
|
||||
#### 购买成本与验证
|
||||
|
||||
| 参数 | 值 | 说明 |
|
||||
|------|----|----- |
|
||||
| 购买成本 | 1500金币 | HeroConf.COST常量 |
|
||||
| 验证方式 | smc.vmdata.gold | 全局金币余额 |
|
||||
| 失败处理 | 显示Toast提示 | 用户友好反馈 |
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L207-L215)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L54-L56)
|
||||
|
||||
### 战斗启动流程
|
||||
|
||||
#### start_mission()函数实现
|
||||
|
||||
战斗启动流程负责初始化战斗准备:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User as 用户
|
||||
participant HInfo as HInfoComp
|
||||
participant Event as GameEvent
|
||||
participant Scene as 游戏场景
|
||||
User->>HInfo : 点击开始战斗
|
||||
HInfo->>Event : 分发MissionStart事件
|
||||
Event->>Scene : 触发战斗准备
|
||||
HInfo->>HInfo : 隐藏面板
|
||||
Scene-->>User : 进入战斗场景
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L216-L219)
|
||||
|
||||
#### 与全局状态管理的交互
|
||||
|
||||
战斗启动过程中,HInfoComp与smc的交互包括:
|
||||
- 触发GameEvent.MissionStart事件
|
||||
- 隐藏英雄信息面板
|
||||
- 准备战斗所需的英雄数据
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L216-L219)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L20)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
### 组件间依赖关系
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "外部依赖"
|
||||
CCEngine[Cocos引擎]
|
||||
OopsFramework[Oops框架]
|
||||
end
|
||||
subgraph "内部模块"
|
||||
HInfoComp[HInfoComp]
|
||||
HeroSet[heroSet]
|
||||
Singleton[SingletonModuleComp]
|
||||
GameEvent[GameEvent]
|
||||
end
|
||||
subgraph "动画系统"
|
||||
Tween[Tween动画]
|
||||
AnimClip[AnimationClip]
|
||||
end
|
||||
HInfoComp --> CCEngine
|
||||
HInfoComp --> OopsFramework
|
||||
HInfoComp --> HeroSet
|
||||
HInfoComp --> Singleton
|
||||
HInfoComp --> GameEvent
|
||||
HInfoComp --> Tween
|
||||
Tween --> AnimClip
|
||||
Singleton --> GameEvent
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L10)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L15)
|
||||
|
||||
### 数据流依赖
|
||||
|
||||
英雄信息面板的数据流遵循单向数据流原则:
|
||||
|
||||
| 数据流向 | 源组件 | 目标组件 | 数据类型 | 更新机制 |
|
||||
|---------|--------|----------|----------|----------|
|
||||
| 配置数据 | HeroInfo | HInfoComp | 静态配置 | 静态加载 |
|
||||
| 状态数据 | smc | HInfoComp | 动态状态 | 事件驱动 |
|
||||
| 用户输入 | UI交互 | HInfoComp | 用户指令 | 事件响应 |
|
||||
| 动画状态 | Tween | HInfoComp | 动画进度 | 回调通知 |
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L20)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L40-L80)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 内存管理优化
|
||||
|
||||
英雄信息面板实现了多项内存管理优化措施:
|
||||
|
||||
1. **节点池化**:通过`claear_hero()`方法及时销毁不再使用的英雄节点
|
||||
2. **定时器清理**:使用`moveTimeoutId`避免内存泄漏
|
||||
3. **动画状态控制**:通过`isMoving`标志防止重复动画
|
||||
|
||||
### 动画性能优化
|
||||
|
||||
- **批量动画**:使用Tween系统批量处理多个节点的动画
|
||||
- **延迟执行**:通过setTimeout实现动画与逻辑的解耦
|
||||
- **缩放优化**:中心位置使用预设缩放值,减少计算开销
|
||||
|
||||
### 数据访问优化
|
||||
|
||||
- **静态数据缓存**:HeroInfo配置数据在编译时确定
|
||||
- **索引查找优化**:使用indexOf快速定位英雄位置
|
||||
- **循环边界处理**:预计算边界条件,减少运行时计算
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题与解决方案
|
||||
|
||||
#### 动画冲突问题
|
||||
|
||||
**症状**:快速点击英雄切换按钮导致动画混乱
|
||||
**原因**:多个动画同时执行
|
||||
**解决方案**:系统通过`isMoving`标志和`moveTimeoutId`实现动画冲突防止
|
||||
|
||||
#### 英雄节点显示异常
|
||||
|
||||
**症状**:英雄节点位置错乱或不显示
|
||||
**原因**:hero_pos配置错误或节点销毁不完全
|
||||
**解决方案**:检查HeroPos配置,确保`claear_hero()`正确执行
|
||||
|
||||
#### UI数据不同步
|
||||
|
||||
**症状**:英雄属性显示与实际不符
|
||||
**原因**:smc状态未正确更新
|
||||
**解决方案**:验证smc.updateFihgtHero()调用,检查事件分发机制
|
||||
|
||||
#### 购买功能失效
|
||||
|
||||
**症状**:点击购买按钮无响应
|
||||
**原因**:金币不足检测或smc.addHero()调用失败
|
||||
**解决方案**:检查smc.vmdata.gold值,验证全局状态同步
|
||||
|
||||
**章节来源**
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L169-L185)
|
||||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L207-L215)
|
||||
|
||||
## 结论
|
||||
|
||||
HInfoComp.ts英雄信息面板组件展现了现代游戏开发中的最佳实践:
|
||||
|
||||
1. **架构设计**:采用分层架构和MVVM模式,实现了良好的代码组织和数据管理
|
||||
2. **用户体验**:通过流畅的动画和直观的界面,提供了优秀的用户体验
|
||||
3. **性能优化**:实现了内存管理和动画优化,确保了良好的运行性能
|
||||
4. **扩展性**:模块化设计便于功能扩展和维护
|
||||
|
||||
该组件的成功实现为游戏开发提供了宝贵的参考经验,特别是在动画系统集成、状态管理和用户交互方面。通过深入理解其实现原理,开发者可以更好地构建类似的复杂UI组件。
|
||||
333
.qoder/repowiki/zh/content/用户界面系统/顶部状态栏.md
Normal file
333
.qoder/repowiki/zh/content/用户界面系统/顶部状态栏.md
Normal file
@@ -0,0 +1,333 @@
|
||||
# 顶部状态栏组件详细文档
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构概述](#项目结构概述)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
TopComp.ts是游戏主界面中的顶部状态栏组件,负责显示玩家的金币数量并提供视觉反馈动画。该组件采用Cocos Creator框架开发,集成了Oops框架的消息系统,实现了对金币更新事件的响应式处理。
|
||||
|
||||
## 项目结构概述
|
||||
|
||||
TopComp组件位于游戏的地图模块中,属于游戏主界面的重要组成部分。其文件结构如下:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "游戏模块结构"
|
||||
A[assets/script/game/map/] --> B[TopComp.ts]
|
||||
A --> C[GameEvent.ts]
|
||||
A --> D[BoxSet.ts]
|
||||
A --> E[SingletonModuleComp.ts]
|
||||
end
|
||||
subgraph "Oops框架集成"
|
||||
F[Oops Framework] --> G[Message System]
|
||||
F --> H[Global Events]
|
||||
end
|
||||
B --> F
|
||||
C --> G
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L1-L30)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
|
||||
**章节来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L1-L30)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
TopComp组件是一个继承自Cocos Creator Component类的UI组件,具有以下核心特性:
|
||||
|
||||
### 组件基本信息
|
||||
- **类名**: topComp
|
||||
- **装饰器**: @ccclass('topComp')
|
||||
- **继承关系**: Component
|
||||
- **事件监听**: GameEvent.GOLD_UPDATE
|
||||
|
||||
### 主要功能模块
|
||||
1. **事件监听机制**: 监听金币更新事件
|
||||
2. **动画效果**: 实现金币数字的缩放脉冲动画
|
||||
3. **节点路径查找**: 定位金币显示节点
|
||||
4. **全局消息集成**: 与Oops框架消息系统协作
|
||||
|
||||
**章节来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L8-L30)
|
||||
|
||||
## 架构概览
|
||||
|
||||
TopComp组件在整个游戏架构中扮演着重要的UI状态同步角色:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Game as "游戏逻辑"
|
||||
participant Event as "GameEvent"
|
||||
participant TopComp as "TopComp组件"
|
||||
participant Tween as "Tween动画系统"
|
||||
participant UI as "UI显示层"
|
||||
Game->>Event : 触发GOLD_UPDATE事件
|
||||
Event->>TopComp : onGoldUpdate回调
|
||||
TopComp->>TopComp : 查找节点路径
|
||||
TopComp->>Tween : 创建缩放动画
|
||||
Tween->>UI : 执行1.2倍放大
|
||||
Tween->>UI : 执行恢复动画
|
||||
UI-->>Game : 显示视觉反馈
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L12-L20)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L68-L69)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 事件监听机制
|
||||
|
||||
TopComp组件通过Oops框架的消息系统实现事件监听:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class topComp {
|
||||
+onLoad() void
|
||||
+onGoldUpdate(event, data) void
|
||||
+start() void
|
||||
+update(deltaTime) void
|
||||
}
|
||||
class GameEvent {
|
||||
<<enumeration>>
|
||||
GOLD_UPDATE
|
||||
DIAMOND_UPDATE
|
||||
MEAT_UPDATE
|
||||
MISSION_UPDATE
|
||||
}
|
||||
class OopsMessage {
|
||||
+on(event, callback, target) void
|
||||
+once(event, callback, target) void
|
||||
}
|
||||
topComp --> GameEvent : "监听"
|
||||
topComp --> OopsMessage : "使用"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L10-L12)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L68-L69)
|
||||
|
||||
#### 监听机制实现细节
|
||||
|
||||
组件在`onLoad`生命周期中注册事件监听器,当GameEvent.GOLD_UPDATE事件被触发时,会调用`onGoldUpdate`回调函数。
|
||||
|
||||
**章节来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L10-L12)
|
||||
|
||||
### 金币数字缩放动画
|
||||
|
||||
TopComp的核心功能是实现金币数字的视觉反馈动画:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["接收GOLD_UPDATE事件"] --> B["查找节点路径"]
|
||||
B --> C["获取Label组件"]
|
||||
C --> D["创建Tween动画"]
|
||||
D --> E["执行1.2倍放大(0.1秒)"]
|
||||
E --> F["执行恢复原大小(0.1秒)"]
|
||||
F --> G["动画完成"]
|
||||
B1["this.node.getChildByName('bar')"] --> B2["getChildByName('gold')"]
|
||||
B2 --> B3["getChildByName('num')"]
|
||||
B3 --> B4["getComponent(Label)"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L14-L19)
|
||||
|
||||
#### 动画参数配置
|
||||
|
||||
动画系统使用以下参数:
|
||||
- **持续时间**: 每阶段0.1秒,总时长0.2秒
|
||||
- **缩放比例**: 从1.0倍放大到1.2倍
|
||||
- **恢复比例**: 从1.2倍恢复到1.0倍
|
||||
- **缓动类型**: 默认缓动(未指定具体类型)
|
||||
|
||||
**章节来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L14-L19)
|
||||
|
||||
### 节点路径查找机制
|
||||
|
||||
组件通过层级化的节点查找方式定位金币显示元素:
|
||||
|
||||
#### 路径解析
|
||||
1. **根节点**: `this.node`
|
||||
2. **第一层**: `"bar"` - 状态栏容器
|
||||
3. **第二层**: `"gold"` - 金币区域
|
||||
4. **第三层**: `"num"` - 数字显示区域
|
||||
5. **目标组件**: `Label` - 文本显示组件
|
||||
|
||||
这种设计允许开发者灵活调整UI布局,只需修改节点名称即可适应不同的界面设计。
|
||||
|
||||
**章节来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L14-L19)
|
||||
|
||||
### 与全局消息系统的集成
|
||||
|
||||
TopComp与Oops框架的消息系统深度集成:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A["Oops Message System"] --> B["事件发布"]
|
||||
B --> C["TopComp监听"]
|
||||
C --> D["回调执行"]
|
||||
D --> E["动画触发"]
|
||||
F["GameEvent枚举"] --> G["GOLD_UPDATE"]
|
||||
G --> C
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L10-L12)
|
||||
|
||||
#### 集成优势
|
||||
1. **解耦设计**: 组件间通过事件通信,降低耦合度
|
||||
2. **可扩展性**: 支持多个组件监听同一事件
|
||||
3. **内存安全**: 自动清理事件监听器
|
||||
4. **类型安全**: 通过枚举确保事件名称正确性
|
||||
|
||||
**章节来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L10-L12)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
TopComp组件的依赖关系展现了清晰的分层架构:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "外部依赖"
|
||||
A[Cocos Creator Engine]
|
||||
B[Oops Framework]
|
||||
end
|
||||
subgraph "内部依赖"
|
||||
C[GameEvent枚举]
|
||||
D[SingletonModuleComp]
|
||||
E[BoxSet工具类]
|
||||
end
|
||||
subgraph "TopComp组件"
|
||||
F[topComp类]
|
||||
end
|
||||
A --> F
|
||||
B --> F
|
||||
C --> F
|
||||
D --> F
|
||||
E --> F
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L1-L6)
|
||||
|
||||
### 依赖项说明
|
||||
|
||||
| 依赖项 | 类型 | 用途 | 版本要求 |
|
||||
|--------|------|------|----------|
|
||||
| Cocos Creator | 引擎 | UI渲染和动画系统 | 最新稳定版 |
|
||||
| Oops Framework | 框架 | 消息系统和全局管理 | 1.x版本 |
|
||||
| GameEvent | 枚举 | 事件类型定义 | 内部定义 |
|
||||
| SingletonModuleComp | 单例 | 全局状态管理 | 内部实现 |
|
||||
|
||||
**章节来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L1-L6)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
TopComp组件在设计时充分考虑了性能优化:
|
||||
|
||||
### 动画性能优化
|
||||
- **短时动画**: 0.2秒的动画周期不会造成明显的性能负担
|
||||
- **局部更新**: 只更新金币显示区域,不影响其他UI元素
|
||||
- **硬件加速**: 利用Cocos Creator的GPU加速能力
|
||||
|
||||
### 内存管理
|
||||
- **事件监听**: 使用Oops框架的自动清理机制
|
||||
- **节点查找**: 缓存节点引用,避免重复查找
|
||||
- **组件卸载**: 遵循Cocos Creator的组件生命周期
|
||||
|
||||
### 最佳实践建议
|
||||
1. **避免频繁触发**: 控制GOLD_UPDATE事件的触发频率
|
||||
2. **批量更新**: 如果需要同时更新多个状态,考虑合并事件
|
||||
3. **性能监控**: 在复杂场景下监控动画帧率
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 问题1: 动画不显示
|
||||
**症状**: 金币更新时没有视觉反馈
|
||||
**可能原因**:
|
||||
- 节点路径错误
|
||||
- Label组件未正确绑定
|
||||
- Tween系统异常
|
||||
|
||||
**解决方案**:
|
||||
1. 检查节点层次结构是否符合预期
|
||||
2. 验证"bar/gold/num"路径是否存在
|
||||
3. 确认Label组件已正确添加到目标节点
|
||||
|
||||
#### 问题2: 事件监听失效
|
||||
**症状**: 金币更新事件无法触发动画
|
||||
**可能原因**:
|
||||
- 事件名称不匹配
|
||||
- 组件未正确初始化
|
||||
- Oops消息系统异常
|
||||
|
||||
**解决方案**:
|
||||
1. 确认使用的是`GameEvent.GOLD_UPDATE`
|
||||
2. 检查组件是否已正确添加到场景
|
||||
3. 验证Oops框架是否正常加载
|
||||
|
||||
#### 问题3: 动画卡顿
|
||||
**症状**: 动画播放不流畅
|
||||
**可能原因**:
|
||||
- 系统资源不足
|
||||
- 同时运行过多动画
|
||||
- GPU性能限制
|
||||
|
||||
**解决方案**:
|
||||
1. 减少同时播放的动画数量
|
||||
2. 优化动画参数
|
||||
3. 监控系统资源使用情况
|
||||
|
||||
**章节来源**
|
||||
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L14-L19)
|
||||
|
||||
## 结论
|
||||
|
||||
TopComp组件是一个设计精良的UI状态栏组件,具有以下特点:
|
||||
|
||||
### 技术优势
|
||||
1. **事件驱动架构**: 通过Oops框架实现松耦合的事件通信
|
||||
2. **响应式设计**: 对金币变化提供即时的视觉反馈
|
||||
3. **易于维护**: 清晰的代码结构和明确的职责分工
|
||||
4. **性能友好**: 短时动画和局部更新策略
|
||||
|
||||
### 设计亮点
|
||||
- **模块化**: 事件监听与动画执行分离
|
||||
- **可扩展**: 支持多种状态栏元素的扩展
|
||||
- **健壮性**: 完善的错误处理和边界检查
|
||||
- **用户体验**: 流畅的动画效果提升用户感知
|
||||
|
||||
### 改进建议
|
||||
1. **动画参数化**: 提供可配置的动画参数
|
||||
2. **状态管理**: 集成更完整的UI状态管理系统
|
||||
3. **测试覆盖**: 增加单元测试和集成测试
|
||||
4. **文档完善**: 补充详细的API文档和使用示例
|
||||
|
||||
TopComp组件展现了现代游戏UI开发的最佳实践,为游戏提供了良好的用户体验基础。
|
||||
492
.qoder/repowiki/zh/content/英雄系统/增益_减益状态系统.md
Normal file
492
.qoder/repowiki/zh/content/英雄系统/增益_减益状态系统.md
Normal file
@@ -0,0 +1,492 @@
|
||||
# 增益/减益状态系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [timedCom.ts](file://assets/script/game/skill/timedCom.ts)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [系统概述](#系统概述)
|
||||
2. [核心组件架构](#核心组件架构)
|
||||
3. [状态系统设计](#状态系统设计)
|
||||
4. [状态持续时间管理](#状态持续时间管理)
|
||||
5. [视觉反馈机制](#视觉反馈机制)
|
||||
6. [状态叠加与刷新策略](#状态叠加与刷新策略)
|
||||
7. [状态特效节点管理](#状态特效节点管理)
|
||||
8. [生命周期管理](#生命周期管理)
|
||||
9. [性能优化措施](#性能优化措施)
|
||||
10. [使用示例与最佳实践](#使用示例与最佳实践)
|
||||
|
||||
## 系统概述
|
||||
|
||||
增益/减益状态系统是一个复杂的状态管理框架,负责管理英雄的各种状态效果,包括攻击提升、防御增强、灼烧、冰冻、眩晕等多种状态。该系统采用ECS架构设计,通过分离的状态管理组件和视觉反馈组件协同工作,实现了高效的状态管理和实时的视觉反馈。
|
||||
|
||||
### 主要特性
|
||||
|
||||
- **多重叠加支持**:同一属性允许多个增益/减益效果同时存在
|
||||
- **持久与临时状态**:支持永久buff和限时debuff的统一管理
|
||||
- **类型化属性系统**:区分数值型和百分比型属性的不同计算方式
|
||||
- **实时视觉反馈**:状态变化时的即时视觉效果展示
|
||||
- **性能优化**:通过对象池和定时器复用提升系统效率
|
||||
|
||||
## 核心组件架构
|
||||
|
||||
系统由三个核心组件构成,每个组件承担不同的职责:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class HeroViewComp {
|
||||
+Record~number,Array~ BUFFS
|
||||
+Record~number,Array~ BUFFS_TEMP
|
||||
+Object NeAttrs
|
||||
+addBuff(buffConf)
|
||||
+removeBuff(attrIndex, value, isPermanent)
|
||||
+clearBuffs(attrIndex, isBuff)
|
||||
+recalculateSingleAttr(attrIndex)
|
||||
+updateTemporaryBuffsDebuffs(dt)
|
||||
}
|
||||
class BuffComp {
|
||||
+Node top_node
|
||||
+Node ap_node
|
||||
+Node cd_node
|
||||
+Node def_node
|
||||
+Node hp_node
|
||||
+Node crit_node
|
||||
+number ap_cd
|
||||
+number cd_cd
|
||||
+number def_cd
|
||||
+number hp_cd
|
||||
+number crit_cd
|
||||
+Timer timer
|
||||
+hp_show(hp, hp_max)
|
||||
+mp_show(mp, mp_max)
|
||||
+show_shield(shield, shield_max)
|
||||
+show_do_buff(name)
|
||||
+in_iced(t, ap)
|
||||
+in_fired(t, ap)
|
||||
+in_yun(t, ap)
|
||||
}
|
||||
class timedCom {
|
||||
+number time
|
||||
+number cd
|
||||
+number ap
|
||||
+update(deltaTime)
|
||||
}
|
||||
HeroViewComp --> BuffComp : "管理视觉反馈"
|
||||
HeroViewComp --> timedCom : "创建临时状态"
|
||||
BuffComp --> timedCom : "管理特效节点"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L44-L84)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L0-L46)
|
||||
- [timedCom.ts](file://assets/script/game/skill/timedCom.ts#L0-L24)
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L44-L84)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L0-L46)
|
||||
|
||||
## 状态系统设计
|
||||
|
||||
### 数据结构设计
|
||||
|
||||
系统采用统一的数组设计模式,支持多种类型的状态管理:
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
HeroViewComp {
|
||||
Record BUFFS
|
||||
Record BUFFS_TEMP
|
||||
Object NeAttrs
|
||||
}
|
||||
BuffConf {
|
||||
Attrs buff
|
||||
BType BType
|
||||
number value
|
||||
number time
|
||||
number chance
|
||||
}
|
||||
BuffInstance {
|
||||
number value
|
||||
BType BType
|
||||
number remainTime
|
||||
}
|
||||
NeAttrInstance {
|
||||
number value
|
||||
number time
|
||||
}
|
||||
HeroViewComp ||--o{ BuffInstance : "管理"
|
||||
BuffConf ||--|| BuffInstance : "转换为"
|
||||
HeroViewComp ||--o{ NeAttrInstance : "管理负面状态"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L20-L47)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L80-L90)
|
||||
|
||||
### 属性类型系统
|
||||
|
||||
系统定义了两种属性类型,每种类型采用不同的计算方式:
|
||||
|
||||
| 属性类型 | 描述 | 计算公式 | 示例 |
|
||||
|---------|------|----------|------|
|
||||
| 数值型 (VALUE) | 直接加减绝对数值 | `(基础值 + 所有数值型buff之和) × (1 + 所有百分比buff之和/100)` | 攻击力、防御力、生命值 |
|
||||
| 百分比型 (RATIO) | 按百分比计算 | 基础值 + 所有数值型buff之和 + 所有百分比buff之和 | 暴击率、闪避率、伤害加成 |
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L142-L226)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L251-L320)
|
||||
|
||||
## 状态持续时间管理
|
||||
|
||||
### cd字段族系统
|
||||
|
||||
系统通过专门的cd字段族来管理各种状态的持续时间:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[状态触发] --> B{判断状态类型}
|
||||
B --> |增益状态| C[设置ap_cd字段]
|
||||
B --> |减益状态| D[设置deap_cd字段]
|
||||
C --> E[启动计时器]
|
||||
D --> F[启动计时器]
|
||||
E --> G[更新视觉反馈]
|
||||
F --> G
|
||||
G --> H{计时结束?}
|
||||
H --> |否| I[继续监控]
|
||||
H --> |是| J[清除状态]
|
||||
I --> G
|
||||
J --> K[更新属性计算]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L15-L30)
|
||||
|
||||
### 定时器更新机制
|
||||
|
||||
系统采用帧更新的方式管理状态持续时间:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Game as "游戏主循环"
|
||||
participant Hero as "HeroViewComp"
|
||||
participant Timer as "updateTemporaryBuffsDebuffs"
|
||||
participant Buff as "状态容器"
|
||||
Game->>Hero : update(deltaTime)
|
||||
Hero->>Timer : 调用定时器更新
|
||||
Timer->>Buff : 遍历BUFFS_TEMP
|
||||
loop 每个临时buff
|
||||
Buff->>Buff : remainTime -= deltaTime
|
||||
alt remainTime <= 0
|
||||
Buff->>Buff : 从数组移除
|
||||
Buff->>Hero : 标记属性受影响
|
||||
end
|
||||
end
|
||||
Timer->>Hero : 重新计算受影响属性
|
||||
Hero->>Game : 状态更新完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L350-L400)
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L350-L400)
|
||||
|
||||
## 视觉反馈机制
|
||||
|
||||
### UI同步逻辑
|
||||
|
||||
系统通过专门的方法管理UI元素的显示状态:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[状态变化] --> B[调用相应显示方法]
|
||||
B --> C{状态类型}
|
||||
C --> |生命值| D[hp_show方法]
|
||||
C --> |魔法值| E[mp_show方法]
|
||||
C --> |护盾| F[show_shield方法]
|
||||
C --> |特殊效果| G[show_do_buff方法]
|
||||
D --> H[更新进度条]
|
||||
E --> H
|
||||
F --> H
|
||||
G --> I[创建特效节点]
|
||||
H --> J[延迟更新确保同步]
|
||||
I --> K[设置位置和时间]
|
||||
J --> L[视觉反馈完成]
|
||||
K --> L
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L60-L120)
|
||||
|
||||
### 特效节点管理
|
||||
|
||||
系统支持动态创建和销毁状态特效节点:
|
||||
|
||||
| 方法名 | 功能 | 参数 | 创建的节点类型 |
|
||||
|--------|------|------|---------------|
|
||||
| `show_do_buff` | 显示通用状态特效 | `name: string` | buff_xxx.prefab |
|
||||
| `in_iced` | 显示冰冻状态特效 | `t: number, ap: number` | buff_iced.prefab |
|
||||
| `in_fired` | 显示燃烧状态特效 | `t: number, ap: number` | buff_fired.prefab |
|
||||
| `in_yun` | 显示眩晕状态特效 | `t: number, ap: number` | buff_yun.prefab |
|
||||
| `dead` | 显示死亡特效 | 无 | dead.prefab |
|
||||
|
||||
**章节来源**
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L120-L200)
|
||||
|
||||
## 状态叠加与刷新策略
|
||||
|
||||
### 叠加规则
|
||||
|
||||
系统支持同属性多实例叠加,每种状态实例保持独立:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[添加新状态] --> B{检查属性是否存在}
|
||||
B --> |不存在| C[创建新数组]
|
||||
B --> |存在| D[添加到现有数组]
|
||||
C --> E[设置状态实例]
|
||||
D --> E
|
||||
E --> F{状态类型判断}
|
||||
F --> |持久| G[BUFFS数组]
|
||||
F --> |临时| H[BUFFS_TEMP数组]
|
||||
G --> I[直接添加]
|
||||
H --> J[添加remainTime字段]
|
||||
I --> K[重新计算属性]
|
||||
J --> K
|
||||
K --> L[触发视觉更新]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L217-L251)
|
||||
|
||||
### 刷新与清除策略
|
||||
|
||||
系统提供了多种状态清除机制:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[状态清除请求] --> B{清除范围}
|
||||
B --> |单属性| C[clearBuffsForAttr]
|
||||
B --> |全属性| D[遍历所有属性]
|
||||
C --> E{过滤条件}
|
||||
E --> |增益| F[value > 0]
|
||||
E --> |减益| G[value < 0]
|
||||
E --> |全部| H[无条件清除]
|
||||
F --> I[过滤并保留符合条件的buff]
|
||||
G --> I
|
||||
H --> I
|
||||
I --> J{数组是否为空}
|
||||
J --> |是| K[删除属性条目]
|
||||
J --> |否| L[保留数组]
|
||||
K --> M[重新计算属性]
|
||||
L --> M
|
||||
M --> N[更新视觉反馈]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L421-L459)
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L217-L251)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L421-L459)
|
||||
|
||||
## 状态特效节点管理
|
||||
|
||||
### 动态创建流程
|
||||
|
||||
状态特效节点的创建遵循统一的流程:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant System as "状态系统"
|
||||
participant Manager as "BuffComp"
|
||||
participant Resource as "资源管理器"
|
||||
participant Scene as "场景节点"
|
||||
participant Timed as "timedCom组件"
|
||||
System->>Manager : 请求创建特效
|
||||
Manager->>Resource : 获取预制体资源
|
||||
Resource-->>Manager : 返回Prefab对象
|
||||
Manager->>Manager : instantiate(prefab)
|
||||
Manager->>Scene : 设置父节点
|
||||
Manager->>Manager : setPosition(position)
|
||||
alt 临时状态特效
|
||||
Manager->>Timed : 设置时间参数
|
||||
Timed->>Timed : 启动定时器
|
||||
Timed->>Scene : 自动销毁
|
||||
end
|
||||
Manager-->>System : 特效创建完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L120-L180)
|
||||
- [timedCom.ts](file://assets/script/game/skill/timedCom.ts#L0-L24)
|
||||
|
||||
### 销毁机制
|
||||
|
||||
临时状态特效通过定时器组件自动销毁:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Created : instantiate()
|
||||
Created --> Active : setPosition()
|
||||
Active --> Updating : update(deltaTime)
|
||||
Updating --> Active : remainTime > 0
|
||||
Updating --> Destroyed : remainTime <= 0
|
||||
Destroyed --> [*] : node.destroy()
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [timedCom.ts](file://assets/script/game/skill/timedCom.ts#L15-L24)
|
||||
|
||||
**章节来源**
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L120-L180)
|
||||
- [timedCom.ts](file://assets/script/game/skill/timedCom.ts#L0-L24)
|
||||
|
||||
## 生命周期管理
|
||||
|
||||
### 完整生命周期示例
|
||||
|
||||
以冰冻状态为例,展示状态的完整生命周期:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Skill as "技能系统"
|
||||
participant Hero as "HeroViewComp"
|
||||
participant Buff as "BuffComp"
|
||||
participant Effect as "特效系统"
|
||||
participant UI as "UI系统"
|
||||
Note over Skill,UI : 冰冻状态触发
|
||||
Skill->>Hero : addBuff(冰冻配置)
|
||||
Hero->>Hero : 添加到BUFFS_TEMP
|
||||
Hero->>Hero : recalculateSingleAttr(DEF)
|
||||
Hero->>Buff : in_iced(duration, ap)
|
||||
Buff->>Effect : 创建buff_iced特效
|
||||
Effect->>Effect : 设置remainTime
|
||||
Buff->>UI : 更新防御显示
|
||||
UI-->>Buff : 视觉反馈确认
|
||||
loop 每帧更新
|
||||
Hero->>Hero : updateTemporaryBuffsDebuffs(dt)
|
||||
Hero->>Hero : 减少remainTime
|
||||
alt remainTime <= 0
|
||||
Hero->>Hero : 从BUFFS_TEMP移除
|
||||
Hero->>Hero : recalculateSingleAttr(DEF)
|
||||
Hero->>Buff : 清除特效
|
||||
Hero->>UI : 更新防御显示
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L217-L251)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L150-L170)
|
||||
|
||||
### 状态移除流程
|
||||
|
||||
系统提供了多种状态移除方式:
|
||||
|
||||
| 移除方式 | 触发条件 | 影响范围 | 性能影响 |
|
||||
|----------|----------|----------|----------|
|
||||
| 自然消失 | remainTime <= 0 | 单个状态 | 低 |
|
||||
| 主动清除 | clearBuffs() | 指定属性 | 中等 |
|
||||
| 类型过滤清除 | clearBuffs(attrIndex, isBuff) | 指定属性和类型 | 中等 |
|
||||
| 全部清除 | clearAllNeAttrs() | 所有负面状态 | 高 |
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L385-L425)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L457-L500)
|
||||
|
||||
## 性能优化措施
|
||||
|
||||
### 对象池应用
|
||||
|
||||
虽然当前实现中没有显式的对象池,但系统设计考虑了以下优化点:
|
||||
|
||||
1. **定时器复用**:使用统一的Timer实例管理多个状态的计时
|
||||
2. **数组操作优化**:采用splice而非filter进行状态移除
|
||||
3. **批量属性计算**:通过Set记录受影响属性,避免重复计算
|
||||
|
||||
### 内存管理策略
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[状态添加] --> B[检查内存使用]
|
||||
B --> C{超出阈值?}
|
||||
C --> |否| D[正常添加]
|
||||
C --> |是| E[触发垃圾回收]
|
||||
E --> F[清理无效状态]
|
||||
F --> G[压缩数组结构]
|
||||
G --> D
|
||||
D --> H[更新统计信息]
|
||||
H --> I[监控内存使用]
|
||||
```
|
||||
|
||||
### 更新频率优化
|
||||
|
||||
系统采用智能更新策略:
|
||||
|
||||
- **暂停检测**:在游戏暂停时跳过状态更新
|
||||
- **属性变更追踪**:只重新计算受影响的属性
|
||||
- **延迟更新**:使用scheduleOnce确保UI同步
|
||||
|
||||
**章节来源**
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L40-L50)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L470-L490)
|
||||
|
||||
## 使用示例与最佳实践
|
||||
|
||||
### 基本使用模式
|
||||
|
||||
```typescript
|
||||
// 添加攻击提升buff
|
||||
const attackBuff: BuffConf = {
|
||||
buff: Attrs.AP,
|
||||
BType: BType.VALUE,
|
||||
value: 50,
|
||||
time: 10,
|
||||
chance: 100
|
||||
};
|
||||
hero.addBuff(attackBuff);
|
||||
|
||||
// 添加百分比伤害加成
|
||||
const damageBuff: BuffConf = {
|
||||
buff: Attrs.AP,
|
||||
BType: BType.RATIO,
|
||||
value: 20,
|
||||
time: 5,
|
||||
chance: 80
|
||||
};
|
||||
hero.addBuff(damageBuff);
|
||||
|
||||
// 清除特定属性的所有增益
|
||||
hero.clearBuffs(Attrs.AP, true);
|
||||
|
||||
// 清除所有负面状态
|
||||
hero.clearAllNeAttrs();
|
||||
```
|
||||
|
||||
### 最佳实践建议
|
||||
|
||||
1. **状态优先级管理**:合理安排状态的添加顺序
|
||||
2. **性能监控**:定期检查状态数量,避免过多叠加
|
||||
3. **视觉反馈同步**:确保状态变化时UI及时更新
|
||||
4. **内存泄漏预防**:及时清理不再需要的状态
|
||||
5. **状态冲突处理**:避免相同属性的相互抵消
|
||||
|
||||
### 常见问题解决
|
||||
|
||||
| 问题 | 原因 | 解决方案 |
|
||||
|------|------|----------|
|
||||
| 状态不消失 | remainTime未正确更新 | 检查updateTemporaryBuffsDebuffs调用 |
|
||||
| UI显示异常 | 视觉反馈未触发 | 确认BuffComp相关方法被调用 |
|
||||
| 性能下降 | 状态数量过多 | 实施状态数量限制和定期清理 |
|
||||
| 内存泄漏 | 特效节点未销毁 | 检查timedCom组件的自动销毁机制 |
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L44-L84)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L80-L90)
|
||||
581
.qoder/repowiki/zh/content/英雄系统/天赋系统.md
Normal file
581
.qoder/repowiki/zh/content/英雄系统/天赋系统.md
Normal file
@@ -0,0 +1,581 @@
|
||||
# 天赋系统
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [系统架构](#系统架构)
|
||||
3. [天赋配置结构](#天赋配置结构)
|
||||
4. [天赋组件系统](#天赋组件系统)
|
||||
5. [天赋触发机制](#天赋触发机制)
|
||||
6. [天赋与系统交互](#天赋与系统交互)
|
||||
7. [扩展新天赋类型](#扩展新天赋类型)
|
||||
8. [实现示例](#实现示例)
|
||||
9. [性能优化](#性能优化)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
天赋系统是游戏中的核心成长机制之一,为英雄提供独特的特殊能力和特性。该系统采用配置驱动的方式,通过精心设计的数据结构和组件架构,实现了灵活的天赋配置、智能的触发机制和高效的性能表现。
|
||||
|
||||
天赋系统的主要特点包括:
|
||||
- **多样化触发条件**:支持等级、行为计数、受伤次数等多种触发方式
|
||||
- **丰富的效果类型**:涵盖属性修改、技能触发、天赋增强等多重效果
|
||||
- **智能堆叠机制**:支持效果堆叠和最大层数限制
|
||||
- **无缝集成**:与属性系统、技能系统深度集成,形成完整的成长体系
|
||||
|
||||
## 系统架构
|
||||
|
||||
天赋系统采用模块化的架构设计,主要由以下几个核心组件构成:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
TalSet[TalSet.ts<br/>天赋配置文件]
|
||||
HeroSet[heroSet.ts<br/>英雄配置]
|
||||
SkillSet[SkillSet.ts<br/>技能配置]
|
||||
end
|
||||
subgraph "组件层"
|
||||
TalComp[TalComp.ts<br/>天赋组件]
|
||||
HeroView[HeroViewComp.ts<br/>英雄视图组件]
|
||||
SkillCon[SkillConComp.ts<br/>技能控制组件]
|
||||
end
|
||||
subgraph "系统层"
|
||||
AttrSys[属性系统]
|
||||
BuffSys[Buff系统]
|
||||
ECS[ECS架构]
|
||||
end
|
||||
TalSet --> TalComp
|
||||
HeroSet --> TalComp
|
||||
SkillSet --> TalComp
|
||||
TalComp --> HeroView
|
||||
TalComp --> SkillCon
|
||||
HeroView --> AttrSys
|
||||
HeroView --> BuffSys
|
||||
ECS --> TalComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts#L1-L116)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L1-L171)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L140-L160)
|
||||
|
||||
**章节来源**
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts#L1-L116)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L1-L171)
|
||||
|
||||
## 天赋配置结构
|
||||
|
||||
### 天赋类型枚举
|
||||
|
||||
天赋系统定义了七种基本触发类型,每种类型对应不同的触发条件:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class TalType {
|
||||
+LEVEL : 1
|
||||
+LEVEL_UP : 2
|
||||
+ACTION_COUNT : 3
|
||||
+SKILL_COUNT : 4
|
||||
+DAMAGE_COUNT : 5
|
||||
+INIT : 6
|
||||
+DEAD : 7
|
||||
}
|
||||
class TalEType {
|
||||
+ATTRS : 1
|
||||
+SKILL : 2
|
||||
+SKILL_MORE : 3
|
||||
}
|
||||
class ItalConf {
|
||||
+uuid : number
|
||||
+name : string
|
||||
+desc : string
|
||||
+type : TalType
|
||||
+triggerType : TalEType
|
||||
+chance : number
|
||||
+t_value : number
|
||||
+e_value : number
|
||||
+e_name : number
|
||||
+e_type : BType
|
||||
+e_scaling : number
|
||||
+e_count : number
|
||||
+stackable : boolean
|
||||
+maxStack : number
|
||||
}
|
||||
TalType --> ItalConf
|
||||
TalEType --> ItalConf
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts#L10-L35)
|
||||
|
||||
### 天赋配置表结构
|
||||
|
||||
天赋配置采用紧凑的二维表格式,每行包含注释和配置对象:
|
||||
|
||||
| 配置项 | 类型 | 描述 | 示例 |
|
||||
|--------|------|------|------|
|
||||
| uuid | number | 天赋唯一标识符 | 7001 |
|
||||
| name | string | 天赋名称 | "剑意提升" |
|
||||
| desc | string | 天赋描述 | "每升5级,攻击力增加10%" |
|
||||
| type | TalType | 触发类型 | LEVEL_UP |
|
||||
| triggerType | TalEType | 效果类型 | ATTRS |
|
||||
| chance | number | 触发概率 | 100 |
|
||||
| t_value | number | 触发阈值 | 5 |
|
||||
| e_value | number | 效果值 | 0.10 |
|
||||
| e_name | number | 效果属性类型 | Attrs.AP |
|
||||
| e_type | BType | 效果类型 | RATIO |
|
||||
| e_scaling | number | 缩放系数 | 1 |
|
||||
| e_count | number | 触发次数 | 1 |
|
||||
| stackable | boolean | 是否可堆叠 | true |
|
||||
| maxStack | number | 最大堆叠层数 | 10 |
|
||||
|
||||
### 天赋树结构
|
||||
|
||||
天赋树按照英雄类型进行分类,每个英雄可以拥有多个天赋:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "刘邦 - 战士"
|
||||
L1[剑意提升<br/>每5级+10%攻击力]
|
||||
L2[霸王之威<br/>初始+100生命值]
|
||||
L3[离骚诗韵<br/>每8次攻击触发技能]
|
||||
end
|
||||
subgraph "赵武灵王 - 远程"
|
||||
Z1[胡服骑射<br/>每3级+5%攻击速度]
|
||||
end
|
||||
subgraph "张良 - 法师"
|
||||
Z2[运筹帷幄<br/>每4级+8%魔法攻击力]
|
||||
end
|
||||
subgraph "萧何 - 辅助"
|
||||
X1[后勤保障<br/>每6级+3生命回复]
|
||||
end
|
||||
L1 --> L2
|
||||
L1 --> L3
|
||||
Z1 --> Z2
|
||||
Z2 --> X1
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L60-L120)
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts#L75-L115)
|
||||
|
||||
**章节来源**
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts#L10-L116)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L60-L120)
|
||||
|
||||
## 天赋组件系统
|
||||
|
||||
### 组件架构设计
|
||||
|
||||
天赋组件采用ECS架构模式,继承自CCComp基类,负责管理英雄的天赋系统:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class TalComp {
|
||||
-heroView : any
|
||||
-skillCon : any
|
||||
-heroUuid : number
|
||||
-FStats : FightStats
|
||||
-activeTals : TalEffect[]
|
||||
-talEffects : ItalConf[]
|
||||
-isInitialized : boolean
|
||||
+start()
|
||||
+initializeTalents()
|
||||
+getHeroTalents()
|
||||
+doTalEffect(tal)
|
||||
+checkTrigger(tal)
|
||||
+checkHasTal(type)
|
||||
+onAction()
|
||||
+onSkillUse()
|
||||
+onDamageTaken()
|
||||
+onLevelUp(level)
|
||||
+onDeath()
|
||||
+reset()
|
||||
}
|
||||
class FightStats {
|
||||
+aCount : number
|
||||
+sCount : number
|
||||
+dCount : number
|
||||
+level : number
|
||||
}
|
||||
class TalEffect {
|
||||
+uuid : number
|
||||
+stack : number
|
||||
+lTTime : number
|
||||
}
|
||||
TalComp --> FightStats
|
||||
TalComp --> TalEffect
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L28-L171)
|
||||
|
||||
### 组件生命周期
|
||||
|
||||
天赋组件的生命周期管理确保了正确的初始化和状态维护:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Node as 节点
|
||||
participant TalComp as 天赋组件
|
||||
participant HeroView as 英雄视图
|
||||
participant HeroInfo as 英雄配置
|
||||
Node->>TalComp : start()
|
||||
TalComp->>HeroView : 获取组件引用
|
||||
TalComp->>HeroView : 获取英雄UUID
|
||||
TalComp->>HeroInfo : 查询英雄天赋
|
||||
HeroInfo-->>TalComp : 返回天赋配置
|
||||
TalComp->>TalComp : 初始化触发统计
|
||||
TalComp->>TalComp : 设置初始化标志
|
||||
TalComp-->>Node : 初始化完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L59-L75)
|
||||
|
||||
**章节来源**
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L28-L171)
|
||||
|
||||
## 天赋触发机制
|
||||
|
||||
### 触发条件检测
|
||||
|
||||
天赋系统实现了智能的触发条件检测机制,支持多种触发类型的精确匹配:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始触发检测]) --> GetType{获取天赋类型}
|
||||
GetType --> Level{LEVEL?}
|
||||
GetType --> LevelUp{LEVEL_UP?}
|
||||
GetType --> Action{ACTION_COUNT?}
|
||||
GetType --> Skill{SKILL_COUNT?}
|
||||
GetType --> Damage{DAMAGE_COUNT?}
|
||||
GetType --> Init{INIT?}
|
||||
GetType --> Dead{DEAD?}
|
||||
Level --> LevelCheck{等级 >= 阈值?}
|
||||
LevelUp --> LevelUpCheck{等级 % 阈值 == 0?}
|
||||
Action --> ActionCheck{攻击次数 >= 阈值?}
|
||||
Skill --> SkillCheck{技能使用次数 >= 阈值?}
|
||||
Damage --> DamageCheck{受伤次数 >= 阈值?}
|
||||
Init --> True[返回true]
|
||||
Dead --> False[返回false]
|
||||
LevelCheck --> |是| Trigger[触发天赋]
|
||||
LevelCheck --> |否| NoTrigger[不触发]
|
||||
LevelUpCheck --> |是| Trigger
|
||||
LevelUpCheck --> |否| NoTrigger
|
||||
ActionCheck --> |是| Trigger
|
||||
ActionCheck --> |否| NoTrigger
|
||||
SkillCheck --> |是| Trigger
|
||||
SkillCheck --> |否| NoTrigger
|
||||
DamageCheck --> |是| Trigger
|
||||
DamageCheck --> |否| NoTrigger
|
||||
Trigger --> Effect[执行天赋效果]
|
||||
NoTrigger --> End([结束])
|
||||
Effect --> End
|
||||
True --> End
|
||||
False --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L105-L125)
|
||||
|
||||
### 效果执行机制
|
||||
|
||||
天赋效果的执行遵循统一的处理流程,根据效果类型调用相应的处理函数:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant TalComp as 天赋组件
|
||||
participant HeroView as 英雄视图
|
||||
participant SkillCon as 技能控制
|
||||
participant BuffSys as Buff系统
|
||||
TalComp->>TalComp : 检查天赋效果类型
|
||||
alt 属性修改 (ATTRS)
|
||||
TalComp->>BuffSys : 创建Buff配置
|
||||
TalComp->>HeroView : addBuff(buffConf)
|
||||
HeroView->>HeroView : 应用属性加成
|
||||
else 技能触发 (SKILL)
|
||||
TalComp->>SkillCon : doSkill(skill, false, 0)
|
||||
SkillCon->>SkillCon : 执行技能逻辑
|
||||
else 天赋增强 (SKILL_MORE)
|
||||
TalComp->>HeroView : 添加新技能
|
||||
HeroView->>HeroView : 更新技能列表
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L85-L105)
|
||||
|
||||
**章节来源**
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L105-L171)
|
||||
|
||||
## 天赋与系统交互
|
||||
|
||||
### 与属性系统的集成
|
||||
|
||||
天赋系统与属性系统深度集成,通过Buff机制实现属性加成:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "天赋系统"
|
||||
TalConf[天赋配置]
|
||||
TalEffect[天赋效果]
|
||||
end
|
||||
subgraph "属性系统"
|
||||
AttrCalc[属性计算]
|
||||
BuffMgmt[Buff管理]
|
||||
AttrApply[属性应用]
|
||||
end
|
||||
subgraph "英雄实体"
|
||||
HeroAttrs[英雄属性]
|
||||
BaseAttrs[基础属性]
|
||||
end
|
||||
TalConf --> TalEffect
|
||||
TalEffect --> BuffMgmt
|
||||
BuffMgmt --> AttrCalc
|
||||
AttrCalc --> AttrApply
|
||||
AttrApply --> HeroAttrs
|
||||
HeroAttrs --> BaseAttrs
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L180-L220)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L85-L95)
|
||||
|
||||
### 与技能系统的交互
|
||||
|
||||
天赋系统与技能系统协同工作,支持技能触发和技能增强:
|
||||
|
||||
| 交互类型 | 天赋效果 | 技能系统响应 | 实现方式 |
|
||||
|----------|----------|--------------|----------|
|
||||
| 技能触发 | 触发指定技能 | 执行技能逻辑 | SkillCon.doSkill() |
|
||||
| 技能增强 | 增加额外技能 | 更新技能列表 | HeroView.skills.push() |
|
||||
| 技能冷却 | 影响技能冷却 | 调整CD计算 | 技能系统集成 |
|
||||
|
||||
**章节来源**
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L95-L105)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L28-L40)
|
||||
|
||||
## 扩展新天赋类型
|
||||
|
||||
### 新增触发类型
|
||||
|
||||
要扩展新的触发类型,需要修改以下部分:
|
||||
|
||||
1. **添加新的触发类型枚举**:
|
||||
```typescript
|
||||
export enum TalType {
|
||||
// 现有类型...
|
||||
CUSTOM_TRIGGER = 8, // 新增自定义触发类型
|
||||
}
|
||||
```
|
||||
|
||||
2. **更新触发检测逻辑**:
|
||||
```typescript
|
||||
case TalType.CUSTOM_TRIGGER:
|
||||
return this.customTriggerCondition();
|
||||
```
|
||||
|
||||
3. **实现自定义触发条件**:
|
||||
```typescript
|
||||
private customTriggerCondition(): boolean {
|
||||
// 实现自定义触发逻辑
|
||||
return customConditionMet;
|
||||
}
|
||||
```
|
||||
|
||||
### 新增效果类型
|
||||
|
||||
扩展新的效果类型需要:
|
||||
|
||||
1. **添加效果类型枚举**:
|
||||
```typescript
|
||||
export enum TalEType {
|
||||
// 现有效果类型...
|
||||
NEW_EFFECT = 4, // 新增效果类型
|
||||
}
|
||||
```
|
||||
|
||||
2. **更新效果处理逻辑**:
|
||||
```typescript
|
||||
if (tal.triggerType == TalEType.NEW_EFFECT) {
|
||||
this.handleNewEffect(tal);
|
||||
}
|
||||
```
|
||||
|
||||
3. **实现效果处理函数**:
|
||||
```typescript
|
||||
private handleNewEffect(tal: ItalConf): void {
|
||||
// 实现新效果处理逻辑
|
||||
}
|
||||
```
|
||||
|
||||
### 配置新天赋
|
||||
|
||||
新增天赋的配置格式保持一致:
|
||||
|
||||
```typescript
|
||||
// 新天赋 - 英雄名称 | 触发条件 | 效果描述
|
||||
newTalentId: {uuid: newTalentId, name: "新天赋名称", desc: "效果描述",
|
||||
type: TalType.CUSTOM_TRIGGER, triggerType: TalEType.NEW_EFFECT,
|
||||
chance: 100, t_value: threshold, e_value: effectValue,
|
||||
e_name: specialValue, e_type: BType.VALUE, e_scaling: 1,
|
||||
e_count: 1, stackable: true, maxStack: 5},
|
||||
```
|
||||
|
||||
## 实现示例
|
||||
|
||||
### 天赋选择界面实现
|
||||
|
||||
天赋选择界面需要与后端逻辑紧密配合:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant UI as 界面组件
|
||||
participant TalentMgr as 天赋管理器
|
||||
participant Backend as 后端服务
|
||||
participant Hero as 英雄实体
|
||||
UI->>TalentMgr : 请求可用天赋
|
||||
TalentMgr->>Backend : 查询天赋数据
|
||||
Backend-->>TalentMgr : 返回天赋列表
|
||||
TalentMgr-->>UI : 显示天赋选项
|
||||
UI->>TalentMgr : 选择天赋
|
||||
TalentMgr->>Backend : 提交天赋选择
|
||||
Backend->>Backend : 验证选择合法性
|
||||
Backend->>Hero : 应用天赋效果
|
||||
Hero->>Hero : 更新属性和状态
|
||||
Backend-->>TalentMgr : 确认选择成功
|
||||
TalentMgr-->>UI : 更新界面状态
|
||||
```
|
||||
|
||||
### 天赋点分配系统
|
||||
|
||||
天赋点分配系统的核心实现:
|
||||
|
||||
```typescript
|
||||
// 天赋点分配接口
|
||||
interface TalentPointAllocation {
|
||||
heroUuid: number;
|
||||
selectedTalents: number[];
|
||||
pointsSpent: number;
|
||||
validateAllocation(): boolean;
|
||||
applyAllocation(): void;
|
||||
}
|
||||
|
||||
// 天赋点分配验证逻辑
|
||||
class TalentValidator {
|
||||
private validateTalentCompatibility(talents: number[]): boolean {
|
||||
// 验证天赋兼容性
|
||||
return this.checkMutualExclusivity(talents) &&
|
||||
this.validatePrerequisites(talents);
|
||||
}
|
||||
|
||||
private checkMutualExclusivity(talents: number[]): boolean {
|
||||
// 检查互斥天赋冲突
|
||||
return !this.hasConflictingTalents(talents);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 状态持久化
|
||||
|
||||
天赋系统的状态持久化确保玩家进度的安全存储:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "客户端"
|
||||
LocalStorage[本地存储]
|
||||
Cache[内存缓存]
|
||||
end
|
||||
subgraph "服务器"
|
||||
Database[(数据库)]
|
||||
API[后端API]
|
||||
end
|
||||
subgraph "同步机制"
|
||||
SyncLogic[同步逻辑]
|
||||
ConflictResolve[冲突解决]
|
||||
end
|
||||
Cache --> SyncLogic
|
||||
SyncLogic --> API
|
||||
API --> Database
|
||||
Database --> API
|
||||
API --> SyncLogic
|
||||
SyncLogic --> ConflictResolve
|
||||
ConflictResolve --> Cache
|
||||
LocalStorage --> Cache
|
||||
Cache --> LocalStorage
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 触发检测优化
|
||||
|
||||
天赋系统采用多种优化策略提升性能:
|
||||
|
||||
1. **延迟初始化**:只在需要时初始化天赋组件
|
||||
2. **触发条件缓存**:缓存频繁检查的触发条件
|
||||
3. **批量处理**:将多个天赋效果合并处理
|
||||
|
||||
### 内存管理
|
||||
|
||||
```typescript
|
||||
// 内存优化策略
|
||||
class TalentMemoryManager {
|
||||
private static readonly MAX_ACTIVE_TALENTS = 20;
|
||||
|
||||
cleanupInactiveTalents(): void {
|
||||
if (this.activeTals.length > TalentMemoryManager.MAX_ACTIVE_TALENTS) {
|
||||
this.activeTals.sort((a, b) => b.lTTime - a.lTTime);
|
||||
this.activeTals = this.activeTals.slice(0, TalentMemoryManager.MAX_ACTIVE_TALENTS);
|
||||
}
|
||||
}
|
||||
|
||||
recycleTalentInstances(): void {
|
||||
// 回收不再使用的天赋实例
|
||||
this.activeTals = this.activeTals.filter(tal => tal.stack > 0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 计算优化
|
||||
|
||||
天赋系统的计算优化主要体现在属性重计算的频率控制上:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
AttrChange[属性变化] --> CheckFreq{检查计算频率}
|
||||
CheckFreq --> |高频变化| BatchCalc[批量计算]
|
||||
CheckFreq --> |低频变化| ImmediateCalc[立即计算]
|
||||
BatchCalc --> DelayedRecalc[延迟重计算]
|
||||
ImmediateCalc --> DirectUpdate[直接更新]
|
||||
DelayedRecalc --> FinalAttr[最终属性值]
|
||||
DirectUpdate --> FinalAttr
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
天赋系统作为游戏成长机制的核心组成部分,通过精心设计的架构和灵活的配置系统,为玩家提供了丰富而深入的游戏体验。系统的主要优势包括:
|
||||
|
||||
1. **高度可配置性**:通过配置文件实现天赋的灵活定义和调整
|
||||
2. **智能触发机制**:支持多种触发条件和精确的效果执行
|
||||
3. **系统集成度高**:与属性系统、技能系统无缝协作
|
||||
4. **良好的扩展性**:易于添加新的天赋类型和效果
|
||||
5. **优秀的性能表现**:通过多种优化策略确保流畅的游戏体验
|
||||
|
||||
未来的改进方向包括:
|
||||
- 增强天赋树的可视化展示
|
||||
- 实现天赋组合的动态平衡
|
||||
- 添加天赋效果的实时预览功能
|
||||
- 优化大量天赋场景下的性能表现
|
||||
|
||||
天赋系统的设计理念体现了游戏开发中的模块化思维和配置驱动开发的优势,为构建复杂的游戏成长体系提供了可靠的技术基础。
|
||||
390
.qoder/repowiki/zh/content/英雄系统/技能系统/技能执行机制/多段连发技能执行.md
Normal file
390
.qoder/repowiki/zh/content/英雄系统/技能系统/技能执行机制/多段连发技能执行.md
Normal file
@@ -0,0 +1,390 @@
|
||||
# 多段连发技能执行机制深度解析
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [WFUNY属性机制概述](#wfuny属性机制概述)
|
||||
3. [核心组件架构](#核心组件架构)
|
||||
4. [check_wfuny概率触发机制](#check_wfuny概率触发机制)
|
||||
5. [递归调度执行模型](#递归调度执行模型)
|
||||
6. [技能执行链路分析](#技能执行链路分析)
|
||||
7. [ECS实体生成与管理](#ecs实体生成与管理)
|
||||
8. [定时器延迟加载机制](#定时器延迟加载机制)
|
||||
9. [节点有效性检查机制](#节点有效性检查机制)
|
||||
10. [性能优化与风险控制](#性能优化与风险控制)
|
||||
11. [总结](#总结)
|
||||
|
||||
## 引言
|
||||
|
||||
本系统实现了一套基于WFUNY属性的概率性多段技能连发机制,通过随机数与英雄属性的比较实现技能触发概率控制,配合递归调度和ECS实体管理,构建了一个完整的技能执行流水线。该机制不仅支持技能连续释放效果,还通过多重验证确保异步执行的安全性。
|
||||
|
||||
## WFUNY属性机制概述
|
||||
|
||||
WFUNY属性作为系统的核心概率控制因子,定义了技能连发的基础触发概率。该属性属于百分比型属性,其数值直接影响技能连发的成功概率。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class HeroAttrs {
|
||||
+WFUNY : number
|
||||
+check_wfuny() boolean
|
||||
+calculateAttributeGains() object
|
||||
}
|
||||
class SkillConComp {
|
||||
+check_wfuny() boolean
|
||||
+castSkill() void
|
||||
+doSkill() void
|
||||
-_timers : object
|
||||
}
|
||||
class SkillEnt {
|
||||
+load() void
|
||||
+destroy() void
|
||||
}
|
||||
HeroAttrs --> SkillConComp : "提供WFUNY属性"
|
||||
SkillConComp --> SkillEnt : "创建技能实体"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L40-L45)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L95-L104)
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L40-L45)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L95-L104)
|
||||
|
||||
## 核心组件架构
|
||||
|
||||
系统采用ECS架构模式,主要包含以下核心组件:
|
||||
|
||||
### 技能控制器组件 (SkillConComp)
|
||||
负责技能的整体调度和生命周期管理,维护定时器集合和技能状态。
|
||||
|
||||
### 技能实体 (SkillEnt)
|
||||
作为ECS实体,封装技能的完整生命周期,包括特效加载、参数传递和资源管理。
|
||||
|
||||
### 技能视图组件 (SkillViewCom)
|
||||
处理技能的视觉表现和动画控制,协调技能的执行时机和效果展示。
|
||||
|
||||
### 攻击组件 (AtkConCom)
|
||||
实现具体的伤害计算和碰撞检测逻辑,支持多种攻击模式和伤害类型。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "技能执行流水线"
|
||||
A[技能触发] --> B[check_wfuny概率检查]
|
||||
B --> C{是否满足连发条件}
|
||||
C --> |是| D[scheduleOnce递归调度]
|
||||
C --> |否| E[doSkill执行]
|
||||
D --> F[doSkill递归调用]
|
||||
F --> G[技能实体创建]
|
||||
G --> H[特效播放]
|
||||
H --> I[伤害计算]
|
||||
end
|
||||
subgraph "ECS实体管理"
|
||||
J[SkillEnt实体] --> K[SkillViewCom组件]
|
||||
K --> L[AtkConCom组件]
|
||||
L --> M[碰撞检测]
|
||||
end
|
||||
E --> G
|
||||
I --> N[目标伤害处理]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L58-L110)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L13-L77)
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L35)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L33)
|
||||
|
||||
## check_wfuny概率触发机制
|
||||
|
||||
`check_wfuny`方法实现了基于随机数的概率触发逻辑,这是整个连发机制的核心判断点。
|
||||
|
||||
### 概率计算算法
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始check_wfuny] --> B[生成0-100的随机数]
|
||||
B --> C[获取WFUNY属性值]
|
||||
C --> D{random < WFUNY?}
|
||||
D --> |是| E[返回true - 触发连发]
|
||||
D --> |否| F[返回false - 不触发连发]
|
||||
E --> G[继续技能连发]
|
||||
F --> H[结束当前技能]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L95-L104)
|
||||
|
||||
### 实现细节分析
|
||||
|
||||
该方法采用简单的概率判断逻辑:
|
||||
1. 生成0-100范围内的随机浮点数
|
||||
2. 获取英雄的WFUNY属性值
|
||||
3. 比较随机数与WFUNY值
|
||||
4. 当随机数小于WFUNY时返回true,否则返回false
|
||||
|
||||
这种设计确保了技能连发的概率可控,且与英雄属性紧密关联。
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L95-L104)
|
||||
|
||||
## 递归调度执行模型
|
||||
|
||||
系统采用`scheduleOnce`方法实现递归调度,每次调度间隔为0.1秒,形成稳定的技能连发节奏。
|
||||
|
||||
### 调度机制流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant SC as SkillConComp
|
||||
participant Timer as scheduleOnce
|
||||
participant DS as doSkill
|
||||
participant SE as SkillEnt
|
||||
participant SV as SkillViewCom
|
||||
SC->>SC : castSkill触发
|
||||
SC->>SC : check_wfuny判断
|
||||
alt WFUNY触发成功
|
||||
SC->>Timer : scheduleOnce(doSkill, 0.1)
|
||||
Timer->>DS : 0.1秒后回调
|
||||
DS->>SC : 递归调用doSkill
|
||||
SC->>SE : 创建技能实体
|
||||
SE->>SV : 初始化技能组件
|
||||
SV->>SV : 执行技能逻辑
|
||||
else WFUNY触发失败
|
||||
SC->>DS : 直接执行doSkill
|
||||
DS->>SE : 创建技能实体
|
||||
SE->>SV : 初始化技能组件
|
||||
SV->>SV : 执行技能逻辑
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L110)
|
||||
|
||||
### 递归安全机制
|
||||
|
||||
系统通过以下机制避免无限递归:
|
||||
|
||||
1. **概率控制**:WFUNY属性限制了连发的概率
|
||||
2. **条件检查**:每次递归都进行节点有效性验证
|
||||
3. **状态管理**:通过定时器ID管理和清理机制
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L110)
|
||||
|
||||
## 技能执行链路分析
|
||||
|
||||
技能执行遵循严格的调用链路,确保各组件间的协调工作。
|
||||
|
||||
### 主要执行路径
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[castSkill] --> B[check_wfuny]
|
||||
B --> C{WFUNY检查}
|
||||
C --> |成功| D[doSkill + 递归调度]
|
||||
C --> |失败| E[doSkill + 直接执行]
|
||||
D --> F[技能实体创建]
|
||||
E --> F
|
||||
F --> G[特效播放]
|
||||
G --> H[目标选择]
|
||||
H --> I[伤害计算]
|
||||
I --> J[效果应用]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L58-L110)
|
||||
|
||||
### 关键执行步骤
|
||||
|
||||
1. **技能触发阶段**:`castSkill`方法启动技能执行
|
||||
2. **概率验证阶段**:`check_wfuny`验证连发条件
|
||||
3. **实体创建阶段**:通过ECS框架创建技能实体
|
||||
4. **特效播放阶段**:播放技能视觉效果
|
||||
5. **目标选择阶段**:根据技能配置选择目标
|
||||
6. **伤害计算阶段**:计算并应用伤害效果
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L58-L110)
|
||||
|
||||
## ECS实体生成与管理
|
||||
|
||||
系统采用ECS架构模式,通过SkillEnt实体统一管理技能的生命周期。
|
||||
|
||||
### 实体创建流程
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SkillEnt {
|
||||
+load(startPos, parent, uuid, targetPos, caster, dmg) void
|
||||
+destroy() void
|
||||
-init() void
|
||||
}
|
||||
class SkillViewCom {
|
||||
+s_uuid : number
|
||||
+caster : HeroViewComp
|
||||
+Attrs : object
|
||||
+doSkill() void
|
||||
+move() void
|
||||
}
|
||||
class AtkConCom {
|
||||
+single_damage() void
|
||||
+onBeginContact() void
|
||||
+update() void
|
||||
}
|
||||
SkillEnt --> SkillViewCom : "添加组件"
|
||||
SkillViewCom --> AtkConCom : "协作处理"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L13-L77)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L13-L155)
|
||||
|
||||
### 实体参数传递
|
||||
|
||||
SkillEnt.load方法负责将所有必要的参数传递给技能实体:
|
||||
|
||||
| 参数 | 类型 | 描述 | 用途 |
|
||||
|------|------|------|------|
|
||||
| startPos | Vec3 | 技能起始位置 | 确定技能发射点 |
|
||||
| parent | Node | 父节点 | 设置技能层级关系 |
|
||||
| uuid | number | 技能唯一标识 | 查找技能配置 |
|
||||
| targetPos | any[] | 目标位置数组 | 多目标技能支持 |
|
||||
| caster | HeroViewComp | 施法者组件 | 获取施法者属性 |
|
||||
| dmg | number | 伤害值 | 支持伤害倍率计算 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L13-L77)
|
||||
|
||||
## 定时器延迟加载机制
|
||||
|
||||
系统采用setTimeout实现300毫秒的延迟加载,确保技能特效完全播放后再开始执行。
|
||||
|
||||
### 延迟加载流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant SC as SkillConComp
|
||||
participant Timer as setTimeout
|
||||
participant SE as SkillEnt
|
||||
participant SV as SkillViewCom
|
||||
SC->>SC : doSkill执行
|
||||
SC->>SC : playSkillEffect播放特效
|
||||
SC->>Timer : setTimeout(300ms)
|
||||
Timer->>SC : 300ms后回调
|
||||
SC->>SE : ecs.getEntity<SkillEnt>()
|
||||
SC->>SE : load()加载技能
|
||||
SE->>SV : 初始化技能组件
|
||||
SV->>SV : 开始技能逻辑
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L110)
|
||||
|
||||
### 定时器管理策略
|
||||
|
||||
系统维护一个定时器字典,每个技能UUID对应一个定时器ID:
|
||||
|
||||
```typescript
|
||||
private _timers: { [key: string]: any } = {};
|
||||
```
|
||||
|
||||
这种设计允许:
|
||||
- 单独管理每个技能的定时器
|
||||
- 支持技能中断和清理
|
||||
- 避免定时器泄漏
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L20-L25)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L177)
|
||||
|
||||
## 节点有效性检查机制
|
||||
|
||||
为了确保异步执行的安全性,系统在多个关键节点实施有效性检查。
|
||||
|
||||
### 检查层次结构
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[技能开始] --> B{this.node有效?}
|
||||
B --> |否| C[直接返回]
|
||||
B --> |是| D{this.HeroView有效?}
|
||||
D --> |否| C
|
||||
D --> |是| E{HeroView.node有效?}
|
||||
E --> |否| C
|
||||
E --> |是| F[继续执行]
|
||||
F --> G[技能实体创建]
|
||||
G --> H{再次检查节点}
|
||||
H --> |否| I[清理资源]
|
||||
H --> |是| J[执行技能逻辑]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L75-L85)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L78-L85)
|
||||
|
||||
### 检查时机分布
|
||||
|
||||
1. **技能触发前检查**:验证调用者的有效性
|
||||
2. **定时器回调检查**:确保延迟执行时对象仍然存在
|
||||
3. **技能实体创建检查**:验证目标节点的有效性
|
||||
4. **组件更新检查**:防止已销毁对象的访问
|
||||
|
||||
这种多层次的检查机制有效防止了内存泄漏和空指针异常。
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L75-L85)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L78-L85)
|
||||
|
||||
## 性能优化与风险控制
|
||||
|
||||
### 性能优化策略
|
||||
|
||||
1. **ECS架构优势**:组件化设计提高内存利用率
|
||||
2. **延迟加载**:300ms延迟避免立即创建大量对象
|
||||
3. **定时器复用**:统一管理定时器资源
|
||||
4. **条件检查**:及时退出无效执行路径
|
||||
|
||||
### 风险控制机制
|
||||
|
||||
1. **概率限制**:WFUNY属性控制连发频率
|
||||
2. **超时保护**:0.1秒间隔避免CPU占用过高
|
||||
3. **内存管理**:自动清理定时器和销毁实体
|
||||
4. **异常捕获**:节点有效性检查防止崩溃
|
||||
|
||||
### 安全边界设计
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[输入验证] --> B[概率控制]
|
||||
B --> C[定时器管理]
|
||||
C --> D[节点检查]
|
||||
D --> E[资源清理]
|
||||
E --> F[异常处理]
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L95-L104)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L177)
|
||||
|
||||
## 总结
|
||||
|
||||
这套基于WFUNY属性的多段技能连发机制展现了现代游戏开发中复杂系统的设计精髓:
|
||||
|
||||
1. **概率驱动的动态行为**:通过WFUNY属性实现技能连发的概率控制,使战斗更具策略性和不确定性
|
||||
2. **异步执行的安全保障**:多重节点有效性检查确保了异步操作的稳定性
|
||||
3. **ECS架构的高效利用**:组件化设计提供了良好的扩展性和维护性
|
||||
4. **资源管理的精细化**:定时器管理和实体生命周期控制体现了对性能的关注
|
||||
5. **递归调度的巧妙运用**:0.1秒间隔的递归调度既保证了流畅性,又避免了性能问题
|
||||
|
||||
这套机制不仅实现了技能连发功能,更为复杂的技能系统扩展奠定了坚实基础,是游戏开发中概率性技能系统设计的优秀范例。
|
||||
440
.qoder/repowiki/zh/content/英雄系统/技能系统/技能执行机制/技能冷却管理.md
Normal file
440
.qoder/repowiki/zh/content/英雄系统/技能系统/技能执行机制/技能冷却管理.md
Normal file
@@ -0,0 +1,440 @@
|
||||
# 技能冷却管理系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [系统架构概览](#系统架构概览)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [冷却机制实现](#冷却机制实现)
|
||||
5. [状态管理与控制流](#状态管理与控制流)
|
||||
6. [定时器资源管理](#定时器资源管理)
|
||||
7. [最佳实践指南](#最佳实践指南)
|
||||
8. [故障排除](#故障排除)
|
||||
9. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
SkillConComp是游戏技能冷却管理系统的核心组件,负责维护和管理角色技能的冷却状态。该系统采用基于update循环的帧累加机制,通过精确的时间累积和多重条件判断来实现智能的技能触发逻辑。系统不仅处理技能冷却计算,还集成状态检测、资源管理和生命周期控制等功能。
|
||||
|
||||
## 系统架构概览
|
||||
|
||||
技能冷却管理系统采用分层架构设计,主要由以下层次组成:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "技能冷却系统架构"
|
||||
A[SkillConComp] --> B[HeroViewComp]
|
||||
A --> C[SkillSet配置]
|
||||
A --> D[GameEvent事件]
|
||||
A --> E[定时器管理]
|
||||
B --> F[技能列表]
|
||||
B --> G[状态检测]
|
||||
B --> H[属性计算]
|
||||
C --> I[技能配置]
|
||||
C --> J[冷却参数]
|
||||
D --> K[战斗结束事件]
|
||||
D --> L[暂停事件]
|
||||
E --> M[setTimeout管理]
|
||||
E --> N[cleanup机制]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L780)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### SkillConComp组件
|
||||
|
||||
SkillConComp是技能冷却管理的主要控制器,继承自CCComp基类,实现了完整的冷却逻辑和生命周期管理。
|
||||
|
||||
#### 主要属性和方法
|
||||
|
||||
| 属性/方法 | 类型 | 描述 | 默认值 |
|
||||
|-----------|------|------|--------|
|
||||
| HeroView | any | 关联的HeroView组件 | null |
|
||||
| HeroEntity | any | 关联的实体对象 | null |
|
||||
| TALCOMP | any | 技能组件 | null |
|
||||
| skill_cd | number | 全局技能冷却 | 0 |
|
||||
| _timers | object | 定时器集合 | {} |
|
||||
|
||||
#### 生命周期管理
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Init as 初始化阶段
|
||||
participant Load as 加载阶段
|
||||
participant Start as 启动阶段
|
||||
participant Update as 更新循环
|
||||
participant Destroy as 销毁阶段
|
||||
Init->>Load : init()
|
||||
Load->>Start : onLoad()
|
||||
Start->>Update : start()
|
||||
Update->>Update : update(dt)
|
||||
Update->>Destroy : onDestroy()
|
||||
Destroy->>Init : clear_timer()
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L20-L35)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L160-L177)
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
|
||||
### HeroViewComp组件
|
||||
|
||||
HeroViewComp作为技能状态的承载者,提供了技能列表管理和状态查询功能。
|
||||
|
||||
#### 技能状态管理
|
||||
|
||||
| 状态属性 | 类型 | 描述 | 用途 |
|
||||
|----------|------|------|------|
|
||||
| skills | array | 当前技能列表 | 存储技能配置和冷却状态 |
|
||||
| mp | number | 当前魔法值 | 冷却触发条件之一 |
|
||||
| is_atking | boolean | 是否处于攻击状态 | 影响技能触发时机 |
|
||||
|
||||
**节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L80-L90)
|
||||
|
||||
## 冷却机制实现
|
||||
|
||||
### 帧累加冷却计算
|
||||
|
||||
技能冷却采用基于update循环的帧累加机制,每帧将deltaTime累加到技能的当前冷却时间上。
|
||||
|
||||
#### 冷却计算流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([update循环开始]) --> CheckState{检查游戏状态}
|
||||
CheckState --> |非战斗状态| Skip[跳过冷却计算]
|
||||
CheckState --> |战斗状态| CheckStun{检查眩晕状态}
|
||||
CheckStun --> |眩晕中| Skip
|
||||
CheckStun --> |清醒状态| GetSkills[获取技能列表]
|
||||
GetSkills --> LoopSkills[遍历技能数组]
|
||||
LoopSkills --> AddDeltaTime[累加dt到cd]
|
||||
AddDeltaTime --> CheckConditions{检查触发条件}
|
||||
CheckConditions --> |cd > cd_max且mp充足| TriggerSkill[触发技能]
|
||||
CheckConditions --> |不满足条件| NextSkill[下一个技能]
|
||||
TriggerSkill --> ResetCD[重置冷却时间]
|
||||
ResetCD --> DeductMP[扣除魔法值]
|
||||
DeductMP --> NextSkill
|
||||
NextSkill --> MoreSkills{还有更多技能?}
|
||||
MoreSkills --> |是| LoopSkills
|
||||
MoreSkills --> |否| End([循环结束])
|
||||
Skip --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L37-L55)
|
||||
|
||||
#### 双重条件判断逻辑
|
||||
|
||||
冷却触发采用严格的双重条件判断机制:
|
||||
|
||||
1. **冷却时间条件**:`skills[i].cd > skills[i].cd_max`
|
||||
2. **魔法值条件**:`this.HeroView.mp >= skills[i].cost`
|
||||
|
||||
只有当这两个条件同时满足时,技能才会被触发。
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L42-L50)
|
||||
|
||||
### 技能触发机制
|
||||
|
||||
#### 触发条件详解
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[技能触发检查] --> B{cd > cd_max?}
|
||||
B --> |否| C[继续冷却]
|
||||
B --> |是| D{mp >= cost?}
|
||||
D --> |否| C
|
||||
D --> |是| E{技能类型检查}
|
||||
E --> |伤害技能| F{is_atking?}
|
||||
E --> |其他技能| G[直接触发]
|
||||
F --> |是| H{SType.damage?}
|
||||
F --> |否| C
|
||||
H --> |是| I[触发技能]
|
||||
H --> |否| C
|
||||
G --> I
|
||||
I --> J[重置cd=0]
|
||||
J --> K[扣除mp]
|
||||
K --> L[播放特效]
|
||||
L --> M[执行技能逻辑]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L42-L50)
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L57-L65)
|
||||
|
||||
## 状态管理与控制流
|
||||
|
||||
### 游戏状态检测
|
||||
|
||||
系统通过多个层面的状态检测来决定是否进行冷却计算:
|
||||
|
||||
#### 状态检查层次
|
||||
|
||||
| 检查层级 | 检查内容 | 实现位置 | 作用 |
|
||||
|----------|----------|----------|------|
|
||||
| Mission状态 | `smc.mission.play` | update方法 | 检查整体游戏状态 |
|
||||
| Pause状态 | `smc.mission.pause` | update方法 | 检查暂停状态 |
|
||||
| 状态异常 | `this.HeroView.isStun()` | update方法 | 检查眩晕状态 |
|
||||
| 状态异常 | `this.HeroView.isFrost()` | update方法 | 检查冰冻状态 |
|
||||
|
||||
#### 状态检测流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Update as update循环
|
||||
participant SM as smc.mission
|
||||
participant HeroView as HeroView
|
||||
participant Skills as 技能列表
|
||||
Update->>SM : 检查play状态
|
||||
SM-->>Update : 返回状态
|
||||
Update->>SM : 检查pause状态
|
||||
SM-->>Update : 返回状态
|
||||
Update->>HeroView : 检查眩晕状态
|
||||
HeroView-->>Update : 返回状态
|
||||
Update->>HeroView : 检查冰冻状态
|
||||
HeroView-->>Update : 返回状态
|
||||
Update->>Skills : 获取技能列表
|
||||
Skills-->>Update : 返回技能数组
|
||||
Update->>Update : 执行冷却计算
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L37-L40)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L465-L470)
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L37-L40)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L465-L470)
|
||||
|
||||
### 非战斗状态处理
|
||||
|
||||
在非战斗状态下,系统会完全跳过冷却计算,确保资源的有效利用:
|
||||
|
||||
#### 非战斗状态判断
|
||||
|
||||
```typescript
|
||||
// 非战斗状态检查逻辑
|
||||
if(!smc.mission.play || smc.mission.pause) return
|
||||
```
|
||||
|
||||
这种设计避免了在菜单界面、加载画面等非战斗状态下进行不必要的计算开销。
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L37-L40)
|
||||
|
||||
## 定时器资源管理
|
||||
|
||||
### 定时器生命周期
|
||||
|
||||
SkillConComp实现了完整的定时器生命周期管理,包括创建、使用和清理三个阶段。
|
||||
|
||||
#### 定时器管理架构
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "定时器生命周期"
|
||||
A[创建定时器] --> B[存储到_timers]
|
||||
B --> C[技能执行]
|
||||
C --> D[定时器回调]
|
||||
D --> E[清理定时器]
|
||||
E --> F[内存释放]
|
||||
end
|
||||
subgraph "清理策略"
|
||||
G[战斗结束] --> H[clear_timer]
|
||||
I[组件销毁] --> J[onDestroy]
|
||||
K[手动重置] --> L[reset]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L15-L16)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L155)
|
||||
|
||||
#### 定时器清理机制
|
||||
|
||||
系统提供了多种定时器清理机制:
|
||||
|
||||
| 清理方式 | 触发条件 | 实现方法 | 作用范围 |
|
||||
|----------|----------|----------|----------|
|
||||
| 战斗结束清理 | GameEvent.FightEnd | clear_timer() | 所有定时器 |
|
||||
| 组件销毁清理 | onDestroy() | onDestroy() | 当前组件 |
|
||||
| 手动重置清理 | reset() | reset() | 当前组件 |
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L155)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L160-L177)
|
||||
|
||||
### 资源释放过程
|
||||
|
||||
#### 定时器释放流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Event as 战斗结束事件
|
||||
participant Comp as SkillConComp
|
||||
participant Timer as 定时器系统
|
||||
participant Memory as 内存管理
|
||||
Event->>Comp : GameEvent.FightEnd
|
||||
Comp->>Comp : clear_timer()
|
||||
Comp->>Timer : Object.values(_timers).forEach(clearTimeout)
|
||||
Timer->>Memory : 释放定时器资源
|
||||
Memory-->>Timer : 确认释放
|
||||
Timer-->>Comp : 清理完成
|
||||
Comp->>Comp : _timers = {}
|
||||
Note over Comp,Memory : 组件销毁时自动清理
|
||||
Comp->>Comp : onDestroy()
|
||||
Comp->>Timer : 再次清理所有定时器
|
||||
Comp->>Comp : 重置_timers对象
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L155)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L160-L177)
|
||||
|
||||
**节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L177)
|
||||
|
||||
## 最佳实践指南
|
||||
|
||||
### 暂停状态下的冷却处理
|
||||
|
||||
在游戏暂停状态下,系统会完全跳过冷却计算,这是推荐的最佳实践:
|
||||
|
||||
#### 暂停状态处理
|
||||
|
||||
```typescript
|
||||
// 推荐的暂停状态处理
|
||||
update(dt: number) {
|
||||
if(!smc.mission.play || smc.mission.pause) return
|
||||
// 冷却计算逻辑
|
||||
}
|
||||
```
|
||||
|
||||
这种方式确保了在暂停状态下不会产生额外的计算开销,同时保持了冷却状态的准确性。
|
||||
|
||||
### 战斗结束后的清理
|
||||
|
||||
战斗结束后必须及时清理定时器资源,避免内存泄漏:
|
||||
|
||||
#### 战斗结束清理
|
||||
|
||||
```typescript
|
||||
// 战斗结束事件监听
|
||||
init(): void {
|
||||
this.on(GameEvent.FightEnd, this.clear_timer, this);
|
||||
}
|
||||
|
||||
// 清理方法实现
|
||||
public clear_timer() {
|
||||
Object.values(this._timers).forEach(clearTimeout);
|
||||
}
|
||||
```
|
||||
|
||||
### 非play状态的处理
|
||||
|
||||
在非战斗状态(如菜单界面)下,系统会自动跳过冷却计算:
|
||||
|
||||
#### 非play状态检查
|
||||
|
||||
```typescript
|
||||
// 非play状态检查
|
||||
if(!smc.mission.play || smc.mission.pause) return
|
||||
```
|
||||
|
||||
这种设计确保了系统只在需要的时候进行计算,提高了整体性能。
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 问题1:技能冷却不准确
|
||||
|
||||
**症状**:技能冷却时间显示不正确
|
||||
**原因**:update循环被中断或dt值异常
|
||||
**解决方案**:
|
||||
- 检查smc.mission.play状态
|
||||
- 验证dt参数的有效性
|
||||
- 确保update方法正常执行
|
||||
|
||||
#### 问题2:定时器泄漏
|
||||
|
||||
**症状**:内存使用持续增长
|
||||
**原因**:定时器未正确清理
|
||||
**解决方案**:
|
||||
- 在onDestroy中清理定时器
|
||||
- 确保GameEvent.FightEnd事件正确触发
|
||||
- 检查定时器ID的唯一性
|
||||
|
||||
#### 问题3:技能无法触发
|
||||
|
||||
**症状**:技能达到冷却时间但不触发
|
||||
**原因**:多重条件判断失败
|
||||
**解决方案**:
|
||||
- 检查mp值是否足够
|
||||
- 验证is_atking状态
|
||||
- 确认技能配置正确
|
||||
|
||||
### 调试技巧
|
||||
|
||||
#### 冷却状态监控
|
||||
|
||||
```typescript
|
||||
// 添加调试日志
|
||||
update(dt: number) {
|
||||
console.log(`冷却状态 - play: ${smc.mission.play}, pause: ${smc.mission.pause}`);
|
||||
console.log(`技能冷却 - 当前mp: ${this.HeroView.mp}`);
|
||||
}
|
||||
```
|
||||
|
||||
#### 定时器状态检查
|
||||
|
||||
```typescript
|
||||
// 定时器状态监控
|
||||
public debugTimers() {
|
||||
console.log('当前定时器:', Object.keys(this._timers));
|
||||
console.log('定时器数量:', Object.values(this._timers).length);
|
||||
}
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
SkillConComp技能冷却管理系统是一个设计精良的组件,具有以下特点:
|
||||
|
||||
### 核心优势
|
||||
|
||||
1. **精确的帧累加机制**:基于update循环的冷却计算确保了时间精度
|
||||
2. **多重条件判断**:双条件触发机制保证了技能使用的合理性
|
||||
3. **完善的生命周期管理**:从创建到销毁的完整资源管理
|
||||
4. **灵活的状态控制**:支持各种游戏状态下的冷却处理
|
||||
|
||||
### 设计亮点
|
||||
|
||||
- **模块化架构**:清晰的职责分离和组件交互
|
||||
- **资源优化**:智能的状态检查避免不必要的计算
|
||||
- **错误处理**:完善的异常情况处理机制
|
||||
- **扩展性**:良好的接口设计支持功能扩展
|
||||
|
||||
### 性能考虑
|
||||
|
||||
系统通过智能的状态检查和条件判断,有效减少了不必要的计算开销,在保证功能完整性的同时维持了良好的性能表现。
|
||||
|
||||
这个技能冷却管理系统为游戏提供了稳定可靠的技能控制机制,是游戏战斗系统的重要组成部分。
|
||||
359
.qoder/repowiki/zh/content/英雄系统/技能系统/技能执行机制/技能执行机制.md
Normal file
359
.qoder/repowiki/zh/content/英雄系统/技能系统/技能执行机制/技能执行机制.md
Normal file
@@ -0,0 +1,359 @@
|
||||
# 技能执行机制
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [核心组件架构](#核心组件架构)
|
||||
3. [技能冷却检测机制](#技能冷却检测机制)
|
||||
4. [技能施放流程](#技能施放流程)
|
||||
5. [多段连发技能机制](#多段连发技能机制)
|
||||
6. [目标选择策略](#目标选择策略)
|
||||
7. [异常处理与资源清理](#异常处理与资源清理)
|
||||
8. [性能优化考虑](#性能优化考虑)
|
||||
9. [最佳实践总结](#最佳实践总结)
|
||||
|
||||
## 概述
|
||||
|
||||
SkillConComp类是游戏技能控制系统的核心组件,负责管理英雄的技能冷却、自动施放条件判断以及技能执行流程。该系统采用ECS架构模式,结合定时器机制和节点有效性检查,实现了复杂的技能逻辑控制。
|
||||
|
||||
## 核心组件架构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SkillConComp {
|
||||
+HeroView : HeroViewComp
|
||||
+HeroEntity : any
|
||||
+TALCOMP : TalComp
|
||||
+skill_cd : number
|
||||
-_timers : object
|
||||
+init() void
|
||||
+onLoad() void
|
||||
+start() void
|
||||
+update(dt : number) void
|
||||
+castSkill(config : SkillConfig) void
|
||||
-doSkill(config : SkillConfig, is_wfuny : boolean, dmg : number) void
|
||||
+check_wfuny() boolean
|
||||
+selectTargets(t_num : number) Vec3[]
|
||||
+clear_timer() void
|
||||
+reset() void
|
||||
+onDestroy() void
|
||||
}
|
||||
class SkillEnt {
|
||||
+load(startPos : Vec3, parent : Node, uuid : number, targetPos : any[], caster : HeroViewComp, dmg : number) void
|
||||
+destroy() void
|
||||
+init() void
|
||||
}
|
||||
class HeroViewComp {
|
||||
+playSkillEffect(skill_id : number) void
|
||||
+skills : any[]
|
||||
+mp : number
|
||||
+is_atking : boolean
|
||||
+isStun() boolean
|
||||
+isFrost() boolean
|
||||
}
|
||||
class SkillSet {
|
||||
+SType : enum
|
||||
+TGroup : enum
|
||||
+SkillConfig : interface
|
||||
}
|
||||
SkillConComp --> HeroViewComp : "控制"
|
||||
SkillConComp --> SkillEnt : "创建"
|
||||
SkillConComp --> SkillSet : "使用配置"
|
||||
SkillEnt --> SkillViewCom : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L17-L177)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L14-L78)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L70-L780)
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
|
||||
## 技能冷却检测机制
|
||||
|
||||
### update循环中的冷却检测
|
||||
|
||||
SkillConComp的update方法实现了精确的技能冷却管理系统:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([update循环开始]) --> CheckMission{"检查游戏状态<br/>smc.mission.play && !pause"}
|
||||
CheckMission --> |否| End([结束])
|
||||
CheckMission --> |是| CheckStatus{"检查状态<br/>!isStun && !isFrost"}
|
||||
CheckStatus --> |否| End
|
||||
CheckStatus --> |是| LoopSkills["遍历技能列表"]
|
||||
LoopSkills --> AddCD["累积冷却时间<br/>skills[i].cd += dt"]
|
||||
AddCD --> CheckCD{"冷却完成<br/>cd > cd_max?"}
|
||||
CheckCD --> |否| NextSkill["下一技能"]
|
||||
CheckCD --> |是| CheckMP{"检查魔法值<br/>mp >= cost?"}
|
||||
CheckMP --> |否| NextSkill
|
||||
CheckMP --> |是| CheckType{"技能类型<br/>SType.damage?"}
|
||||
CheckType --> |否| NextSkill
|
||||
CheckType --> |是| CheckAttack{"正在攻击<br/>is_atking?"}
|
||||
CheckAttack --> |否| NextSkill
|
||||
CheckAttack --> |是| CastSkill["调用castSkill"]
|
||||
CastSkill --> ResetCD["重置冷却<br/>skills[i].cd = 0"]
|
||||
ResetCD --> ConsumeMP["消耗魔法值<br/>mp -= cost"]
|
||||
ConsumeMP --> NextSkill
|
||||
NextSkill --> MoreSkills{"还有技能?"}
|
||||
MoreSkills --> |是| LoopSkills
|
||||
MoreSkills --> |否| End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L35-L52)
|
||||
|
||||
### 冷却检测的关键要素
|
||||
|
||||
1. **时间累积机制**:每个技能的冷却时间通过`skills[i].cd += dt`逐步累积
|
||||
2. **阈值判断**:当冷却时间超过最大冷却时间`cd_max`时触发
|
||||
3. **资源检查**:确保魔法值充足`this.HeroView.mp >= skills[i].cost`
|
||||
4. **状态验证**:排除眩晕和冰冻状态影响
|
||||
5. **攻击状态检查**:只有在攻击状态下才允许施放伤害技能
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L35-L52)
|
||||
|
||||
## 技能施放流程
|
||||
|
||||
### castSkill与doSkill方法调用链
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as "玩家输入/自动触发"
|
||||
participant SkillCon as "SkillConComp"
|
||||
participant HeroView as "HeroViewComp"
|
||||
participant SkillEnt as "SkillEnt"
|
||||
participant ECS as "ECS系统"
|
||||
Player->>SkillCon : castSkill(config)
|
||||
SkillCon->>SkillCon : check_wfuny()
|
||||
SkillCon->>SkillCon : doSkill(config, wfuny, dmg)
|
||||
Note over SkillCon : 节点有效性检查
|
||||
SkillCon->>SkillCon : 检查节点有效性
|
||||
alt 目标组为Self
|
||||
SkillCon->>SkillCon : targets = [this.node.position]
|
||||
else 目标组为Enemy
|
||||
SkillCon->>SkillCon : selectTargets(config.t_num)
|
||||
end
|
||||
SkillCon->>HeroView : playSkillEffect(config.uuid)
|
||||
HeroView->>HeroView : 播放技能特效
|
||||
SkillCon->>ECS : ecs.getEntity<SkillEnt>(SkillEnt)
|
||||
SkillCon->>SkillCon : 创建setTimeout定时器
|
||||
Note over SkillCon : 延迟执行300ms
|
||||
SkillCon->>SkillCon : 定时器回调函数
|
||||
SkillCon->>SkillCon : 再次检查节点有效性
|
||||
SkillCon->>SkillEnt : sEnt.load(...)
|
||||
SkillCon->>SkillEnt : load方法
|
||||
SkillEnt->>SkillEnt : 加载技能预制体
|
||||
SkillEnt->>SkillEnt : 设置节点属性
|
||||
SkillEnt->>SkillEnt : 添加SkillViewCom组件
|
||||
alt wfuny机制启用
|
||||
SkillCon->>SkillCon : scheduleOnce(doSkill, 0.1)
|
||||
end
|
||||
Note over SkillCon : 保存定时器ID
|
||||
SkillCon->>SkillCon : this._timers[`skill_${config.uuid}`] = timerId
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L54-L85)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L77)
|
||||
|
||||
### 节点有效性检查机制
|
||||
|
||||
系统实现了双重节点有效性检查:
|
||||
|
||||
1. **初始检查**:在`doSkill`方法开头进行基础节点有效性验证
|
||||
2. **延迟检查**:在定时器回调函数中再次确认节点状态
|
||||
|
||||
这种设计确保了即使在技能施放过程中节点被销毁,也不会导致错误操作。
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L54-L85)
|
||||
|
||||
## 多段连发技能机制
|
||||
|
||||
### wfuny机制实现原理
|
||||
|
||||
wfuny机制是一种基于概率的技能连发系统:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([doSkill开始]) --> CheckWfuny{"检查wfuny<br/>check_wfuny()"}
|
||||
CheckWfuny --> |false| NormalSkill["正常技能执行"]
|
||||
CheckWfuny --> |true| ScheduleOnce["scheduleOnce(doSkill, 0.1)"]
|
||||
ScheduleOnce --> RecursiveCall["递归调用doSkill<br/>is_wfuny=false"]
|
||||
RecursiveCall --> CheckWfuny2{"再次检查wfuny"}
|
||||
CheckWfuny2 --> |false| FinalExecution["最终技能执行"]
|
||||
CheckWfuny2 --> |true| ContinueRecursion["继续递归"]
|
||||
ContinueRecursion --> ScheduleOnce
|
||||
NormalSkill --> SaveTimer["保存定时器ID"]
|
||||
FinalExecution --> SaveTimer
|
||||
SaveTimer --> End([结束])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L82-L87)
|
||||
|
||||
### wfuny概率计算
|
||||
|
||||
```typescript
|
||||
check_wfuny() {
|
||||
let random = Math.random() * 100
|
||||
if (random < this.HeroView.Attrs[Attrs.WFUNY]) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
```
|
||||
|
||||
该方法:
|
||||
1. 生成0-100之间的随机数
|
||||
2. 与英雄的WFUNY属性值比较
|
||||
3. 当随机数小于WFUNY值时返回true,触发连发
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L89-L95)
|
||||
|
||||
## 目标选择策略
|
||||
|
||||
### selectTargets方法实现
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([selectTargets开始]) --> GetEntities["获取目标实体<br/>check_target()"]
|
||||
GetEntities --> CheckEmpty{"实体列表为空?"}
|
||||
CheckEmpty --> |是| DefaultPos["返回默认位置<br/>t_num个相同坐标"]
|
||||
DefaultPos --> Return([返回目标坐标数组])
|
||||
CheckEmpty --> |否| FindFront["找到最前排目标<br/>get_front(entities)"]
|
||||
FindFront --> PushFront["targets.push(frontPos)"]
|
||||
PushFront --> LoopOthers["循环处理剩余目标<br/>i=1 to t_num-1"]
|
||||
LoopOthers --> SelectRandom["随机选择实体<br/>Math.floor(Math.random() * entities.length)"]
|
||||
SelectRandom --> GetRandomPos["获取随机实体位置"]
|
||||
GetRandomPos --> PushRandom["targets.push(randomPos)"]
|
||||
PushRandom --> MoreTargets{"还有目标?"}
|
||||
MoreTargets --> |是| LoopOthers
|
||||
MoreTargets --> |否| Return
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L112-L155)
|
||||
|
||||
### 目标选择算法详解
|
||||
|
||||
1. **实体获取**:通过`check_target()`方法获取敌方实体列表
|
||||
2. **前排优先**:第一个目标总是最前排的实体
|
||||
3. **随机分布**:后续目标从所有可用实体中随机选择
|
||||
4. **重复可能**:由于随机选择,可能出现重复目标
|
||||
5. **默认处理**:当没有可用目标时,返回预设的默认位置
|
||||
|
||||
### 默认位置处理逻辑
|
||||
|
||||
```typescript
|
||||
const defaultPos = this.HeroView.fac === FacSet.HERO ? v3(400, 0, 0) : v3(-400, 0, 0)
|
||||
```
|
||||
|
||||
系统根据施法者阵营确定默认位置:
|
||||
- 英雄阵营:x=400
|
||||
- 敌人阵营:x=-400
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L112-L155)
|
||||
|
||||
## 异常处理与资源清理
|
||||
|
||||
### 定时器管理机制
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class TimerManagement {
|
||||
-_timers : object
|
||||
+clear_timer() void
|
||||
+reset() void
|
||||
+onDestroy() void
|
||||
}
|
||||
class TimerOperations {
|
||||
+Object.values(this._timers).forEach(clearTimeout)
|
||||
+this._timers = {}
|
||||
+this.off(GameEvent.CastHeroSkill)
|
||||
}
|
||||
TimerManagement --> TimerOperations : "执行"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L157-L177)
|
||||
|
||||
### 异常处理策略
|
||||
|
||||
1. **节点有效性检查**:在关键操作前后检查节点状态
|
||||
2. **定时器清理**:确保技能执行完成后清理相关定时器
|
||||
3. **事件监听移除**:在组件销毁时移除事件监听器
|
||||
4. **资源释放**:在组件销毁时释放ECS实体资源
|
||||
|
||||
### 资源清理最佳实践
|
||||
|
||||
```typescript
|
||||
public clear_timer() {
|
||||
Object.values(this._timers).forEach(clearTimeout);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.clear_timer();
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
Object.values(this._timers).forEach(clearTimeout);
|
||||
this._timers = {};
|
||||
this.off(GameEvent.CastHeroSkill);
|
||||
}
|
||||
```
|
||||
|
||||
这些方法确保:
|
||||
- 防止内存泄漏
|
||||
- 避免僵尸定时器
|
||||
- 清理事件监听器
|
||||
- 正确释放ECS资源
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L157-L177)
|
||||
|
||||
## 性能优化考虑
|
||||
|
||||
### 定时器优化策略
|
||||
|
||||
1. **延迟执行**:技能实体创建延迟300ms,避免立即创建大量对象
|
||||
2. **条件检查**:在每次操作前进行有效性检查,防止无效操作
|
||||
3. **批量清理**:使用`Object.values`一次性清理所有定时器
|
||||
|
||||
### 内存管理优化
|
||||
|
||||
1. **及时清理**:在组件销毁时立即清理所有资源
|
||||
2. **弱引用**:避免循环引用导致的内存泄漏
|
||||
3. **对象池**:利用ECS系统提供的实体池机制
|
||||
|
||||
## 最佳实践总结
|
||||
|
||||
### 技能系统设计原则
|
||||
|
||||
1. **模块化设计**:SkillConComp专注于控制逻辑,SkillEnt负责实体管理
|
||||
2. **事件驱动**:通过ECS系统实现松耦合的组件通信
|
||||
3. **容错机制**:多重节点有效性检查确保系统稳定性
|
||||
4. **资源管理**:完善的定时器和事件监听器清理机制
|
||||
|
||||
### 开发建议
|
||||
|
||||
1. **扩展性考虑**:为新的技能类型预留接口
|
||||
2. **性能监控**:定期检查定时器数量和内存使用情况
|
||||
3. **调试支持**:保留必要的日志输出便于问题排查
|
||||
4. **测试覆盖**:确保各种边界情况都有相应的测试用例
|
||||
|
||||
这个技能执行机制展现了现代游戏开发中复杂系统的设计精髓,通过合理的架构设计和完善的异常处理,实现了稳定可靠的技能控制系统。
|
||||
506
.qoder/repowiki/zh/content/英雄系统/技能系统/技能执行机制/技能执行资源管理.md
Normal file
506
.qoder/repowiki/zh/content/英雄系统/技能系统/技能执行机制/技能执行资源管理.md
Normal file
@@ -0,0 +1,506 @@
|
||||
# 技能执行资源管理
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [HeroConComp.ts](file://assets/script/game/hero/HeroConComp.ts)
|
||||
- [timer.md](file://doc/core/common/timer.md)
|
||||
- [MapView.ts](file://assets/script/game/map/MapView.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构概述](#项目结构概述)
|
||||
3. [核心组件分析](#核心组件分析)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
|
||||
在Cocos游戏引擎的战斗系统中,技能执行过程中的定时器资源管理是一个关键的系统级问题。本文档深入分析了技能执行过程中定时器资源的创建、存储、清理和生命周期管理策略,重点关注`_doSkill`方法中`setTimeout`创建的timerId如何被存储于`_timers`对象中,并通过`clear_timer`方法统一清除的完整流程。
|
||||
|
||||
## 项目结构概述
|
||||
|
||||
该项目采用基于组件的架构设计,技能系统的核心组件分布在以下目录结构中:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "技能系统架构"
|
||||
SkillConComp["SkillConComp<br/>技能控制器组件"]
|
||||
SkillEnt["SkillEnt<br/>技能实体管理"]
|
||||
HeroViewComp["HeroViewComp<br/>英雄视图组件"]
|
||||
MissionComp["MissionComp<br/>任务管理组件"]
|
||||
end
|
||||
subgraph "事件系统"
|
||||
GameEvent["GameEvent<br/>游戏事件枚举"]
|
||||
MessageSystem["消息系统<br/>事件分发"]
|
||||
end
|
||||
subgraph "定时器管理"
|
||||
TimerModule["定时器模块<br/>Oops Framework"]
|
||||
LocalTimers["_timers对象<br/>本地定时器存储"]
|
||||
end
|
||||
SkillConComp --> SkillEnt
|
||||
SkillConComp --> HeroViewComp
|
||||
MissionComp --> GameEvent
|
||||
GameEvent --> MessageSystem
|
||||
SkillConComp --> LocalTimers
|
||||
TimerModule --> LocalTimers
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L50)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L30)
|
||||
|
||||
## 核心组件分析
|
||||
|
||||
### SkillConComp - 技能控制器组件
|
||||
|
||||
`SkillConComp`是技能系统的核心控制器,负责技能的施放、定时器管理和生命周期控制。该组件维护了一个私有的`_timers`对象,用于存储所有技能执行过程中创建的定时器ID。
|
||||
|
||||
#### 主要特性:
|
||||
- **定时器存储管理**:使用`_timers: { [key: string]: any } = {}`对象存储定时器
|
||||
- **生命周期钩子**:实现了`onDestroy`和`reset`方法进行资源清理
|
||||
- **事件监听**:订阅`FightEnd`事件进行自动清理
|
||||
- **节点有效性检查**:在多个关键点进行节点有效性验证
|
||||
|
||||
#### 定时器管理流程:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as "玩家输入"
|
||||
participant SkillCon as "SkillConComp"
|
||||
participant Timer as "setTimeout"
|
||||
participant TimersObj as "_timers对象"
|
||||
participant EventSys as "事件系统"
|
||||
participant Cleanup as "清理机制"
|
||||
Player->>SkillCon : castSkill()
|
||||
SkillCon->>SkillCon : doSkill()
|
||||
SkillCon->>Timer : setTimeout(callback, delay)
|
||||
Timer-->>SkillCon : timerId
|
||||
SkillCon->>TimersObj : this._timers[key] = timerId
|
||||
Note over SkillCon,TimersObj : 定时器创建完成
|
||||
alt 战斗结束事件触发
|
||||
EventSys->>SkillCon : FightEnd事件
|
||||
SkillCon->>Cleanup : clear_timer()
|
||||
Cleanup->>TimersObj : Object.values(_timers).forEach(clearTimeout)
|
||||
TimersObj-->>Cleanup : 清理所有定时器
|
||||
else 组件销毁
|
||||
SkillCon->>Cleanup : onDestroy()
|
||||
Cleanup->>TimersObj : Object.values(_timers).forEach(clearTimeout)
|
||||
Cleanup->>TimersObj : this._timers = {}
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L110)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L177)
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L18-L35)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L110)
|
||||
|
||||
## 架构概览
|
||||
|
||||
技能执行资源管理系统采用多层次的清理策略,确保定时器资源得到妥善管理:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([技能施放开始]) --> ValidateNode["节点有效性检查"]
|
||||
ValidateNode --> CreateTimer["创建setTimeout定时器"]
|
||||
CreateTimer --> StoreTimer["存储到_timers对象"]
|
||||
StoreTimer --> ExecuteSkill["执行技能逻辑"]
|
||||
ExecuteSkill --> CheckEvent{"战斗结束事件?"}
|
||||
CheckEvent --> |是| AutoCleanup["自动清理机制"]
|
||||
CheckEvent --> |否| ContinueExecution["继续执行"]
|
||||
ContinueExecution --> CheckDestroy{"组件销毁?"}
|
||||
CheckDestroy --> |是| ManualCleanup["手动清理机制"]
|
||||
CheckDestroy --> |否| WaitNextFrame["等待下一帧"]
|
||||
AutoCleanup --> ClearAllTimers["clear_timer()清理所有定时器"]
|
||||
ManualCleanup --> ClearAllTimers
|
||||
ClearAllTimers --> ResetTimersObj["重置_timers对象"]
|
||||
ResetTimersObj --> RemoveListeners["移除事件监听器"]
|
||||
WaitNextFrame --> CheckEvent
|
||||
RemoveListeners --> End([资源清理完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L177)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L80-L95)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 定时器创建与存储机制
|
||||
|
||||
#### doSkill方法中的定时器创建
|
||||
|
||||
在`doSkill`方法中,技能执行采用了延迟执行模式,通过`setTimeout`创建定时器来延迟技能的实际执行:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SkillConComp {
|
||||
-_timers : { [key : string] : any }
|
||||
+doSkill(config, is_wfuny, dmg)
|
||||
+clear_timer()
|
||||
+onDestroy()
|
||||
+reset()
|
||||
}
|
||||
class TimerStorage {
|
||||
+storeTimer(key, timerId)
|
||||
+clearAllTimers()
|
||||
+resetObject()
|
||||
}
|
||||
class NodeValidation {
|
||||
+checkNodeValidity()
|
||||
+checkHeroViewValidity()
|
||||
}
|
||||
SkillConComp --> TimerStorage : "管理"
|
||||
SkillConComp --> NodeValidation : "验证"
|
||||
TimerStorage --> NodeValidation : "依赖"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L110)
|
||||
|
||||
#### 定时器存储策略
|
||||
|
||||
定时器ID通过键值对形式存储在`_timers`对象中,键名采用`skill_{uuid}`格式,确保唯一性和可追溯性:
|
||||
|
||||
| 存储策略 | 优势 | 应用场景 |
|
||||
|---------|------|----------|
|
||||
| 键值对存储 | 支持按技能UUID快速查找和清理 | 单个技能的精确清理 |
|
||||
| 对象引用 | 集合操作支持批量清理 | 批量资源清理 |
|
||||
| 类型安全 | TypeScript类型约束 | 编译时错误预防 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L110)
|
||||
|
||||
### 生命周期钩子中的定时器清理
|
||||
|
||||
#### onDestroy方法的清理策略
|
||||
|
||||
`onDestroy`方法实现了组件销毁时的资源清理,这是防止内存泄漏的最后一道防线:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
OnDestroy[onDestroy触发] --> ClearTimers["Object.values(_timers).forEach(clearTimeout)"]
|
||||
ClearTimers --> ResetObject["this._timers = {}"]
|
||||
ResetObject --> RemoveListeners["this.off(GameEvent.CastHeroSkill)"]
|
||||
RemoveListeners --> Complete[清理完成]
|
||||
subgraph "清理保护机制"
|
||||
SafetyCheck["节点有效性检查"]
|
||||
NullCheck["空值检查"]
|
||||
TypeGuard["类型守卫"]
|
||||
end
|
||||
ClearTimers -.-> SafetyCheck
|
||||
ClearTimers -.-> NullCheck
|
||||
ClearTimers -.-> TypeGuard
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L177)
|
||||
|
||||
#### reset方法的资源重置
|
||||
|
||||
`reset`方法提供了组件重置时的资源清理功能,主要用于组件池化场景:
|
||||
|
||||
| 清理阶段 | 操作内容 | 目的 |
|
||||
|---------|----------|------|
|
||||
| 定时器清理 | 调用`clear_timer()`方法 | 防止定时器残留 |
|
||||
| 状态重置 | 重置内部状态变量 | 准备组件复用 |
|
||||
| 事件解绑 | 解除事件监听器 | 避免内存泄漏 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L140-L150)
|
||||
|
||||
### FightEnd事件监听机制
|
||||
|
||||
#### 战斗结束自动清理触发路径
|
||||
|
||||
战斗结束时的自动清理通过事件驱动机制实现,确保所有技能定时器得到及时清理:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Hero as "英雄死亡"
|
||||
participant MissionComp as "MissionComp"
|
||||
participant MessageSys as "消息系统"
|
||||
participant SkillCon as "SkillConComp"
|
||||
participant TimerMgr as "定时器管理器"
|
||||
Hero->>MissionComp : do_hero_dead()
|
||||
MissionComp->>MissionComp : 检查英雄数量
|
||||
alt 英雄全部死亡
|
||||
MissionComp->>MessageSys : dispatchEvent(FightEnd)
|
||||
MessageSys->>SkillCon : 触发FightEnd事件
|
||||
SkillCon->>TimerMgr : clear_timer()
|
||||
TimerMgr->>TimerMgr : 清理所有定时器
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L55-L65)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L20-L25)
|
||||
|
||||
#### 事件监听器的注册与管理
|
||||
|
||||
`init`方法中注册了`FightEnd`事件监听器,确保战斗结束时能够触发自动清理:
|
||||
|
||||
| 监听器类型 | 事件名称 | 回调函数 | 清理时机 |
|
||||
|-----------|----------|----------|----------|
|
||||
| 单次监听 | FightEnd | clear_timer | 战斗结束时 |
|
||||
| 生命周期监听 | onDestroy | 清理所有定时器 | 组件销毁时 |
|
||||
| 事件解绑 | CastHeroSkill | 移除特定事件监听 | 组件销毁时 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L20-L25)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L55-L65)
|
||||
|
||||
### 异常场景下的安全性检查
|
||||
|
||||
#### 节点有效性检查实践
|
||||
|
||||
在技能执行的关键路径上,实施了多层节点有效性检查,防止因节点被提前销毁而导致的异常:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
EnterMethod[进入方法] --> FirstCheck["首次节点检查"]
|
||||
FirstCheck --> IsValid1{"节点有效?"}
|
||||
IsValid1 --> |否| EarlyReturn["提前返回"]
|
||||
IsValid1 --> |是| ExecuteLogic["执行业务逻辑"]
|
||||
ExecuteLogic --> SecondCheck["二次节点检查"]
|
||||
SecondCheck --> IsValid2{"节点仍然有效?"}
|
||||
IsValid2 --> |否| SafeExit["安全退出"]
|
||||
IsValid2 --> |是| ContinueExecution["继续执行"]
|
||||
ContinueExecution --> ThirdCheck["英雄视图检查"]
|
||||
ThirdCheck --> IsValid3{"英雄视图有效?"}
|
||||
IsValid3 --> |否| GracefulFail["优雅失败"]
|
||||
IsValid3 --> |是| FinalExecution["最终执行"]
|
||||
EarlyReturn --> End[方法结束]
|
||||
SafeExit --> End
|
||||
GracefulFail --> End
|
||||
FinalExecution --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L70-L75)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L80-L85)
|
||||
|
||||
#### 异常处理策略
|
||||
|
||||
| 异常类型 | 检查点 | 处理策略 | 预防措施 |
|
||||
|---------|--------|----------|----------|
|
||||
| 节点被销毁 | 每次关键操作前 | 提前返回,避免操作 | 定期检查节点有效性 |
|
||||
| 英雄视图丢失 | 技能执行前 | 日志记录,跳过执行 | 保持对英雄状态的监控 |
|
||||
| 定时器失效 | 定时器回调中 | 检查上下文有效性 | 使用闭包保护上下文 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L70-L75)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L80-L85)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
### 组件间依赖关系
|
||||
|
||||
技能执行资源管理系统涉及多个组件间的复杂依赖关系:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "核心组件"
|
||||
SkillConComp["SkillConComp<br/>技能控制器"]
|
||||
SkillEnt["SkillEnt<br/>技能实体"]
|
||||
HeroViewComp["HeroViewComp<br/>英雄视图"]
|
||||
end
|
||||
subgraph "事件系统"
|
||||
GameEvent["GameEvent<br/>事件枚举"]
|
||||
MessageSystem["消息系统"]
|
||||
end
|
||||
subgraph "资源管理"
|
||||
TimerModule["定时器模块"]
|
||||
ComponentPool["组件池"]
|
||||
end
|
||||
subgraph "战斗系统"
|
||||
MissionComp["MissionComp<br/>任务管理"]
|
||||
BattleManager["战斗管理器"]
|
||||
end
|
||||
SkillConComp --> SkillEnt
|
||||
SkillConComp --> HeroViewComp
|
||||
SkillConComp --> TimerModule
|
||||
SkillConComp --> GameEvent
|
||||
GameEvent --> MessageSystem
|
||||
MessageSystem --> SkillConComp
|
||||
MissionComp --> BattleManager
|
||||
BattleManager --> MessageSystem
|
||||
SkillConComp -.-> ComponentPool
|
||||
HeroViewComp -.-> ComponentPool
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L15)
|
||||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L20)
|
||||
|
||||
### 外部依赖分析
|
||||
|
||||
| 依赖类型 | 组件名称 | 作用 | 影响范围 |
|
||||
|---------|----------|------|----------|
|
||||
| 框架依赖 | Oops Framework | 定时器管理、消息系统 | 全局功能 |
|
||||
| 引擎依赖 | Cocos Creator | 节点管理、组件系统 | 渲染层 |
|
||||
| 配置依赖 | SkillSet | 技能配置数据 | 业务逻辑 |
|
||||
| 事件依赖 | GameEvent | 事件通信机制 | 系统集成 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L15)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
|
||||
## 性能考量
|
||||
|
||||
### 定时器性能优化
|
||||
|
||||
技能系统的定时器管理采用了多项性能优化策略:
|
||||
|
||||
#### 定时器池化管理
|
||||
- **批量清理**:使用`Object.values().forEach()`进行批量定时器清理
|
||||
- **内存复用**:通过`_timers`对象实现定时器ID的集中管理
|
||||
- **延迟清理**:在合适的时机(如`onDestroy`或`FightEnd`事件)进行清理
|
||||
|
||||
#### 性能监控指标
|
||||
|
||||
| 性能指标 | 目标值 | 监控方法 | 优化策略 |
|
||||
|---------|--------|----------|----------|
|
||||
| 定时器数量 | < 100个 | 运行时统计 | 实施清理阈值 |
|
||||
| 清理耗时 | < 16ms | 时间测量 | 异步清理 |
|
||||
| 内存占用 | < 10MB | 内存分析 | 对象池化 |
|
||||
|
||||
### 内存泄漏防护
|
||||
|
||||
系统通过多重防护机制防止内存泄漏:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph "防护层次"
|
||||
Level1["第一层:节点检查"]
|
||||
Level2["第二层:事件解绑"]
|
||||
Level3["第三层:组件销毁"]
|
||||
Level4["第四层:框架清理"]
|
||||
end
|
||||
Level1 --> Level2
|
||||
Level2 --> Level3
|
||||
Level3 --> Level4
|
||||
subgraph "检测机制"
|
||||
LeakDetection["泄漏检测"]
|
||||
MemoryProfiling["内存分析"]
|
||||
ResourceTracking["资源追踪"]
|
||||
end
|
||||
Level4 --> LeakDetection
|
||||
LeakDetection --> MemoryProfiling
|
||||
MemoryProfiling --> ResourceTracking
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L177)
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题诊断
|
||||
|
||||
#### 定时器未清理问题
|
||||
|
||||
**症状表现**:
|
||||
- 浏览器内存持续增长
|
||||
- 控制台出现定时器警告
|
||||
- 技能执行异常延迟
|
||||
|
||||
**诊断步骤**:
|
||||
1. 检查`_timers`对象是否正确初始化
|
||||
2. 验证`onDestroy`方法是否被调用
|
||||
3. 确认`FightEnd`事件是否正常触发
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 修复方案示例
|
||||
public onDestroy() {
|
||||
// 确保清理所有定时器
|
||||
Object.values(this._timers).forEach(clearTimeout);
|
||||
this._timers = {};
|
||||
|
||||
// 移除事件监听器
|
||||
this.off(GameEvent.FightEnd);
|
||||
|
||||
// 调用父类销毁方法
|
||||
super.onDestroy();
|
||||
}
|
||||
```
|
||||
|
||||
#### 节点无效异常
|
||||
|
||||
**症状表现**:
|
||||
- 技能执行过程中抛出null引用异常
|
||||
- 控制台出现"node is not valid"错误
|
||||
|
||||
**诊断方法**:
|
||||
- 在关键位置添加节点有效性检查
|
||||
- 监控节点销毁时机
|
||||
- 分析组件生命周期
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L70-L75)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L80-L85)
|
||||
|
||||
### 调试工具和技巧
|
||||
|
||||
#### 定时器状态监控
|
||||
|
||||
开发环境下可以通过以下方式监控定时器状态:
|
||||
|
||||
| 监控项 | 检查方法 | 正常状态 | 异常状态 |
|
||||
|-------|----------|----------|----------|
|
||||
| 定时器数量 | `Object.keys(this._timers).length` | < 10 | > 100 |
|
||||
| 清理完整性 | `this._timers`对象状态 | `{}` | 包含未清理的定时器ID |
|
||||
| 事件监听器 | `this.has(GameEvent.FightEnd)` | `false` | `true` |
|
||||
|
||||
#### 性能分析工具
|
||||
|
||||
推荐使用以下工具进行性能分析:
|
||||
- Chrome DevTools Memory面板
|
||||
- Cocos Creator Profiler
|
||||
- 自定义定时器监控日志
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L177)
|
||||
|
||||
## 结论
|
||||
|
||||
技能执行资源管理系统通过多层次的定时器管理策略,实现了高效、安全的资源控制。系统的核心优势包括:
|
||||
|
||||
### 主要成就
|
||||
|
||||
1. **完善的生命周期管理**:通过`onDestroy`和`reset`方法确保组件销毁时的资源清理
|
||||
2. **事件驱动的自动清理**:利用`FightEnd`事件实现战斗结束时的自动资源回收
|
||||
3. **多重安全性检查**:在关键路径实施节点有效性检查,防止异常情况
|
||||
4. **灵活的清理策略**:支持单个定时器清理和批量清理两种模式
|
||||
|
||||
### 最佳实践总结
|
||||
|
||||
- **及时清理**:在组件销毁和战斗结束时立即清理定时器
|
||||
- **安全性优先**:在每次关键操作前进行节点有效性检查
|
||||
- **事件驱动**:利用事件系统实现自动化资源管理
|
||||
- **异常处理**:在定时器回调中实施完善的异常处理机制
|
||||
|
||||
### 未来改进方向
|
||||
|
||||
1. **异步清理优化**:考虑将大量定时器的清理操作异步化
|
||||
2. **资源使用统计**:增加定时器使用情况的统计和分析功能
|
||||
3. **自动泄漏检测**:实现定时器泄漏的自动检测和报告机制
|
||||
4. **性能监控增强**:集成更详细的性能监控和告警系统
|
||||
|
||||
通过这套完整的技能执行资源管理策略,系统能够在保证功能完整性的同时,有效防止内存泄漏和资源浪费,为游戏的稳定运行提供坚实保障。
|
||||
474
.qoder/repowiki/zh/content/英雄系统/技能系统/技能执行机制/目标选择策略.md
Normal file
474
.qoder/repowiki/zh/content/英雄系统/技能系统/技能执行机制/目标选择策略.md
Normal file
@@ -0,0 +1,474 @@
|
||||
# 目标选择策略
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/hero/HeroViewComp.ts)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [Hero.ts](file://assets/script/hero/Hero.ts)
|
||||
- [Mon.ts](file://assets/script/hero/Mon.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 概述
|
||||
|
||||
本文档深入分析了《英雄传说》游戏中目标选择算法的核心实现,重点关注`selectTargets`方法的策略设计。该算法采用智能的目标分配机制,确保战斗系统的公平性和策略性。
|
||||
|
||||
目标选择算法的核心特点:
|
||||
- **优先级策略**:第一个目标总是最前排的单位
|
||||
- **随机性机制**:后续目标通过随机选择确保多样性
|
||||
- **重复允许**:支持同一目标被多次选中
|
||||
- **边界处理**:当无可用目标时返回默认位置
|
||||
- **阵营感知**:基于FacSet判断左右方向
|
||||
|
||||
## 项目结构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "技能系统"
|
||||
SkillConComp["SkillConComp<br/>技能控制器"]
|
||||
SkillEnt["SkillEnt<br/>技能实体"]
|
||||
end
|
||||
subgraph "阵营系统"
|
||||
FacSet["FacSet<br/>阵营枚举"]
|
||||
HeroViewComp["HeroViewComp<br/>英雄视图组件"]
|
||||
end
|
||||
subgraph "ECS系统"
|
||||
ECS["ECS框架"]
|
||||
BattleMoveSystem["BattleMoveSystem<br/>战斗移动系统"]
|
||||
end
|
||||
subgraph "目标检测"
|
||||
check_target["check_target()<br/>目标检测"]
|
||||
get_front["get_front()<br/>前排检测"]
|
||||
selectTargets["selectTargets()<br/>目标选择"]
|
||||
end
|
||||
SkillConComp --> check_target
|
||||
SkillConComp --> get_front
|
||||
SkillConComp --> selectTargets
|
||||
check_target --> ECS
|
||||
get_front --> ECS
|
||||
BattleMoveSystem --> ECS
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L109-L122)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L165-L200)
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L1-L109)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### SkillConComp - 技能控制器
|
||||
|
||||
`SkillConComp`是目标选择算法的核心控制器,负责协调整个目标选择流程。该组件继承自`CCComp`,实现了ECS注册功能。
|
||||
|
||||
主要职责:
|
||||
- **技能施放管理**:控制技能的触发时机和目标选择
|
||||
- **目标选择协调**:调用`selectTargets`方法获取目标坐标
|
||||
- **异常处理**:确保节点有效性检查和资源清理
|
||||
|
||||
### FacSet - 阵营系统
|
||||
|
||||
`FacSet`定义了游戏中的阵营概念,是目标选择算法的重要输入参数。
|
||||
|
||||
阵营常量:
|
||||
- `HERO = 0`:英雄阵营,位于战场左侧
|
||||
- `MON = 1`:怪物阵营,位于战场右侧
|
||||
|
||||
阵营决定了目标选择的方向性逻辑,英雄会选择右侧的怪物作为目标,而怪物会选择左侧的英雄作为目标。
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L50)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L48-L50)
|
||||
|
||||
## 架构概览
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant SkillCon as "SkillConComp"
|
||||
participant ECS as "ECS查询系统"
|
||||
participant BattleMove as "BattleMoveSystem"
|
||||
participant HeroView as "HeroViewComp"
|
||||
SkillCon->>SkillCon : check_target()
|
||||
SkillCon->>ECS : ecs.query(allOf(MonModelComp))
|
||||
ECS-->>SkillCon : 目标实体列表
|
||||
alt 有可用目标
|
||||
SkillCon->>SkillCon : get_front(entities)
|
||||
SkillCon->>SkillCon : selectTargets(t_num)
|
||||
SkillCon->>SkillCon : 返回目标坐标数组
|
||||
else 无可用目标
|
||||
SkillCon->>SkillCon : 返回默认位置
|
||||
end
|
||||
Note over SkillCon,BattleMove : 目标选择完成,准备施放技能
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L109-L154)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L198-L235)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### selectTargets 方法详解
|
||||
|
||||
`selectTargets`方法是目标选择算法的核心实现,采用了精心设计的策略来确保战斗的公平性和策略性。
|
||||
|
||||
#### 算法流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始目标选择]) --> CheckEntities["检查可用实体"]
|
||||
CheckEntities --> HasEntities{"是否有可用实体?"}
|
||||
HasEntities --> |否| DefaultPos["返回默认位置"]
|
||||
DefaultPos --> CloneDefault["克隆默认位置"]
|
||||
CloneDefault --> ReturnDefault["返回t_num个默认位置"]
|
||||
HasEntities --> |是| GetFront["获取最前排目标"]
|
||||
GetFront --> PushFront["添加最前排坐标到targets"]
|
||||
PushFront --> LoopTargets["循环添加后续目标"]
|
||||
LoopTargets --> RandomSelect["随机选择实体"]
|
||||
RandomSelect --> AddRandom["添加随机坐标到targets"]
|
||||
AddRandom --> MoreTargets{"还有更多目标?"}
|
||||
MoreTargets --> |是| LoopTargets
|
||||
MoreTargets --> |否| ReturnTargets["返回目标坐标数组"]
|
||||
ReturnDefault --> End([结束])
|
||||
ReturnTargets --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L128-L154)
|
||||
|
||||
#### 第一个目标:最前排单位
|
||||
|
||||
算法的第一个目标总是最前排的单位,这是基于以下设计原则:
|
||||
|
||||
1. **战略优先级**:最前排单位通常是敌方的主力或关键目标
|
||||
2. **视觉反馈**:玩家能够直观看到技能的主要目标
|
||||
3. **战斗节奏**:确保技能施放具有明确的战略意义
|
||||
|
||||
**实现细节**:
|
||||
- 使用`get_front`方法确定最前排位置
|
||||
- 根据阵营方向选择最小或最大X坐标
|
||||
- 确保第一个目标始终是最接近施法者的前排单位
|
||||
|
||||
#### 后续目标:随机选择机制
|
||||
|
||||
从第二个目标开始,算法采用随机选择机制:
|
||||
|
||||
1. **随机性保证**:每个目标都有平等的选择机会
|
||||
2. **重复允许**:同一个实体可能被多次选中
|
||||
3. **性能优化**:避免复杂的排序和去重操作
|
||||
|
||||
**实现原理**:
|
||||
- 使用`Math.random()`生成随机索引
|
||||
- 直接从实体列表中选择对应实体
|
||||
- 确保算法复杂度为O(n),其中n为目标数量
|
||||
|
||||
#### 默认位置处理
|
||||
|
||||
当没有可用目标时,算法返回预定义的默认位置:
|
||||
|
||||
```typescript
|
||||
const defaultPos = this.HeroView.fac === FacSet.HERO ? v3(400, 0, 0) : v3(-400, 0, 0);
|
||||
```
|
||||
|
||||
**设计意图**:
|
||||
- **战场定位**:默认位置位于战场边缘,不影响战斗区域
|
||||
- **视觉平衡**:确保技能效果在视觉上仍然有意义
|
||||
- **战术灵活性**:为玩家提供策略选择的空间
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L128-L154)
|
||||
|
||||
### check_target 方法分析
|
||||
|
||||
`check_target`方法负责根据阵营确定目标实体集合:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SkillConComp {
|
||||
+HeroView : any
|
||||
+check_target() Entity[]
|
||||
+get_front(entities) Vec3
|
||||
+selectTargets(t_num) Vec3[]
|
||||
}
|
||||
class FacSet {
|
||||
<<enumeration>>
|
||||
HERO = 0
|
||||
MON = 1
|
||||
}
|
||||
class ECS {
|
||||
+query(filter) Entity[]
|
||||
+allOf(component) Filter
|
||||
}
|
||||
SkillConComp --> FacSet : "使用"
|
||||
SkillConComp --> ECS : "查询"
|
||||
note for SkillConComp "根据阵营决定查询英雄还是怪物"
|
||||
note for FacSet "定义阵营常量"
|
||||
note for ECS "提供实体查询功能"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L109-L115)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L48-L50)
|
||||
|
||||
**实现逻辑**:
|
||||
- 英雄阵营(FacSet.HERO)查询怪物实体(MonModelComp)
|
||||
- 怪物阵营(FacSet.MON)查询英雄实体(HeroModelComp)
|
||||
|
||||
这种设计确保了目标选择的阵营对立性,符合游戏的战斗机制。
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L109-L115)
|
||||
|
||||
### get_front 方法详解
|
||||
|
||||
`get_front`方法实现了前排单位的智能识别:
|
||||
|
||||
#### X坐标比较逻辑
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph "英雄阵营 (FacSet.HERO)"
|
||||
MinX["Math.min(...entities.map(e => e.get(HeroViewComp).node.position.x))"]
|
||||
MinX --> Leftmost["找到最左侧的X坐标"]
|
||||
end
|
||||
subgraph "怪物阵营 (FacSet.MON)"
|
||||
MaxX["Math.max(...entities.map(e => e.get(HeroViewComp).node.position.x))"]
|
||||
MaxX --> Rightmost["找到最右侧的X坐标"]
|
||||
end
|
||||
Leftmost --> KeyEntity["查找对应实体"]
|
||||
Rightmost --> KeyEntity
|
||||
KeyEntity --> FrontPos["返回前排坐标"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L116-L122)
|
||||
|
||||
#### 方向性判断
|
||||
|
||||
算法根据阵营自动判断左右方向:
|
||||
|
||||
1. **英雄阵营**:寻找最小X坐标,即最左侧的单位
|
||||
2. **怪物阵营**:寻找最大X坐标,即最右侧的单位
|
||||
|
||||
这种设计符合战场布局的直觉认知,英雄在左侧,怪物在右侧。
|
||||
|
||||
#### 实体匹配过程
|
||||
|
||||
```typescript
|
||||
let keyPos = this.HeroView.fac == FacSet.HERO ?
|
||||
Math.min(...entities.map(e => e.get(HeroViewComp).node.position.x)) :
|
||||
Math.max(...entities.map(e => e.get(HeroViewComp).node.position.x));
|
||||
|
||||
let keyEntity = entities.find(e => e.get(HeroViewComp).node.position.x === keyPos);
|
||||
return keyEntity.get(HeroViewComp).node.position;
|
||||
```
|
||||
|
||||
这个过程确保了:
|
||||
- 正确的前排单位被识别
|
||||
- 坐标信息准确返回
|
||||
- 异常情况下的稳定性
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L116-L122)
|
||||
|
||||
### ECS查询与坐标比较整合
|
||||
|
||||
目标选择算法与ECS系统的深度集成体现在以下几个方面:
|
||||
|
||||
#### 查询优化
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[ECS查询] --> B[allOf过滤]
|
||||
B --> C[实体列表]
|
||||
C --> D[坐标提取]
|
||||
D --> E[X坐标数组]
|
||||
E --> F[Math.min/max计算]
|
||||
F --> G[前排坐标]
|
||||
G --> H[实体匹配]
|
||||
H --> I[最终目标]
|
||||
style A fill:#e1f5fe
|
||||
style F fill:#f3e5f5
|
||||
style I fill:#e8f5e8
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L198-L235)
|
||||
|
||||
#### 性能考量
|
||||
|
||||
1. **批量查询**:一次性获取所有符合条件的实体
|
||||
2. **延迟计算**:只在需要时进行坐标比较
|
||||
3. **内存优化**:避免不必要的对象创建
|
||||
|
||||
#### 异常处理
|
||||
|
||||
算法包含了多层异常保护:
|
||||
|
||||
1. **空实体检查**:防止空列表访问
|
||||
2. **坐标有效性验证**:确保坐标数据正确
|
||||
3. **实体状态检查**:排除无效或死亡的实体
|
||||
|
||||
**章节来源**
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L198-L235)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "外部依赖"
|
||||
ECS["ECS框架"]
|
||||
Vec3["Vec3类"]
|
||||
FacSet["FacSet枚举"]
|
||||
end
|
||||
subgraph "内部组件"
|
||||
SkillConComp["SkillConComp"]
|
||||
HeroViewComp["HeroViewComp"]
|
||||
BattleMoveSystem["BattleMoveSystem"]
|
||||
end
|
||||
subgraph "配置文件"
|
||||
BoxSet["BoxSet.ts"]
|
||||
heroSet["heroSet.ts"]
|
||||
end
|
||||
SkillConComp --> ECS
|
||||
SkillConComp --> Vec3
|
||||
SkillConComp --> FacSet
|
||||
SkillConComp --> HeroViewComp
|
||||
BattleMoveSystem --> ECS
|
||||
BattleMoveSystem --> HeroViewComp
|
||||
BoxSet --> FacSet
|
||||
heroSet --> HeroViewComp
|
||||
style SkillConComp fill:#ffeb3b
|
||||
style ECS fill:#2196f3
|
||||
style FacSet fill:#4caf50
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L15)
|
||||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L1-L10)
|
||||
|
||||
### 核心依赖关系
|
||||
|
||||
1. **ECS框架依赖**:`ecs.query()`用于实体查询
|
||||
2. **数学运算依赖**:`Math.min()`和`Math.max()`用于坐标比较
|
||||
3. **类型系统依赖**:`Vec3`和`Entity`类型定义
|
||||
4. **配置系统依赖**:`FacSet`提供阵营常量
|
||||
|
||||
### 松耦合设计
|
||||
|
||||
算法采用松耦合设计,便于维护和扩展:
|
||||
|
||||
- **接口隔离**:通过ECS查询接口与具体实体解耦
|
||||
- **配置驱动**:阵营逻辑通过配置文件管理
|
||||
- **模块化组织**:各功能模块职责单一
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L270)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 时间复杂度分析
|
||||
|
||||
目标选择算法的时间复杂度为O(n),其中n为目标数量:
|
||||
|
||||
1. **ECS查询**:O(m),m为实体总数
|
||||
2. **坐标提取**:O(m)
|
||||
3. **前排计算**:O(m)
|
||||
4. **目标生成**:O(n)
|
||||
|
||||
### 空间复杂度分析
|
||||
|
||||
空间复杂度为O(m+n),主要用于存储实体列表和目标坐标:
|
||||
|
||||
1. **实体缓存**:存储查询结果
|
||||
2. **目标数组**:存储最终目标坐标
|
||||
3. **临时变量**:坐标计算过程中的中间值
|
||||
|
||||
### 性能优化策略
|
||||
|
||||
1. **查询复用**:一次查询结果供多个目标选择使用
|
||||
2. **延迟计算**:只在需要时进行坐标比较
|
||||
3. **内存池化**:重用Vec3对象减少GC压力
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见异常情况
|
||||
|
||||
#### 空实体列表
|
||||
|
||||
**问题描述**:当没有可用目标时,算法返回默认位置。
|
||||
|
||||
**解决方案**:
|
||||
- 检查ECS查询条件是否正确
|
||||
- 验证实体是否正确添加到场景中
|
||||
- 确认实体组件是否完整
|
||||
|
||||
#### 坐标计算错误
|
||||
|
||||
**问题描述**:前排单位识别不准确。
|
||||
|
||||
**解决方案**:
|
||||
- 验证`HeroViewComp`组件是否正确挂载
|
||||
- 检查实体位置是否正确初始化
|
||||
- 确认坐标系统的一致性
|
||||
|
||||
#### 随机选择偏差
|
||||
|
||||
**问题描述**:随机选择结果不均匀。
|
||||
|
||||
**解决方案**:
|
||||
- 检查`Math.random()`的分布特性
|
||||
- 验证实体列表的完整性
|
||||
- 确认索引计算的正确性
|
||||
|
||||
### 调试技巧
|
||||
|
||||
1. **日志记录**:在关键步骤添加调试信息
|
||||
2. **可视化**:绘制目标选择路径
|
||||
3. **单元测试**:为每个方法编写测试用例
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L128-L154)
|
||||
|
||||
## 结论
|
||||
|
||||
目标选择算法展现了优秀的工程设计原则:
|
||||
|
||||
### 设计优势
|
||||
|
||||
1. **清晰的职责分离**:每个方法专注于特定功能
|
||||
2. **灵活的扩展性**:易于适应新的需求变化
|
||||
3. **稳定的性能表现**:O(n)时间复杂度确保高效运行
|
||||
4. **健壮的异常处理**:多层次保护机制
|
||||
|
||||
### 战术价值
|
||||
|
||||
算法的设计充分考虑了战斗策略的需求:
|
||||
- **优先级策略**:确保关键目标优先被选中
|
||||
- **随机性机制**:增加战斗的不确定性和趣味性
|
||||
- **边界处理**:优雅处理异常情况
|
||||
- **阵营感知**:符合游戏世界的逻辑设定
|
||||
|
||||
### 未来改进方向
|
||||
|
||||
1. **智能预测**:基于历史数据预测目标偏好
|
||||
2. **动态权重**:根据战斗状态调整目标选择权重
|
||||
3. **机器学习**:利用AI技术优化目标选择策略
|
||||
4. **实时反馈**:提供更直观的目标选择反馈
|
||||
|
||||
该算法为游戏战斗系统提供了坚实的基础,其设计理念和实现方式值得在类似项目中借鉴和应用。
|
||||
769
.qoder/repowiki/zh/content/英雄系统/技能系统/技能系统.md
Normal file
769
.qoder/repowiki/zh/content/英雄系统/技能系统/技能系统.md
Normal file
@@ -0,0 +1,769 @@
|
||||
# 技能系统
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts)
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [Tooltip.ts](file://assets/script/game/skill/Tooltip.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [技能配置系统](#技能配置系统)
|
||||
7. [技能控制机制](#技能控制机制)
|
||||
8. [技能释放流程](#技能释放流程)
|
||||
9. [异常处理与最佳实践](#异常处理与最佳实践)
|
||||
10. [性能考虑](#性能考虑)
|
||||
11. [故障排除指南](#故障排除指南)
|
||||
12. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
技能系统是游戏战斗的核心机制,负责管理角色的技能释放、冷却时间、目标选择、特效播放等关键功能。本系统采用ECS架构设计,通过模块化的方式实现了技能的完整生命周期管理,包括技能配置、控制、执行和特效展示。
|
||||
|
||||
## 项目结构
|
||||
|
||||
技能系统的文件组织遵循模块化原则,主要分为以下几个部分:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
A[SkillSet.ts<br/>技能配置表]
|
||||
end
|
||||
subgraph "控制层"
|
||||
B[SkillConComp.ts<br/>技能控制组件]
|
||||
end
|
||||
subgraph "执行层"
|
||||
C[SkillEnt.ts<br/>技能实体]
|
||||
D[SkillViewCom.ts<br/>技能视图组件]
|
||||
E[AtkConCom.ts<br/>攻击控制组件]
|
||||
end
|
||||
subgraph "支持层"
|
||||
F[HeroViewComp.ts<br/>英雄视图组件]
|
||||
G[Tooltip.ts<br/>提示系统]
|
||||
end
|
||||
A --> B
|
||||
B --> C
|
||||
C --> D
|
||||
D --> E
|
||||
B --> F
|
||||
E --> G
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L1-L148)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
|
||||
**章节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L1-L148)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
|
||||
## 核心组件
|
||||
|
||||
技能系统由以下核心组件构成:
|
||||
|
||||
### 技能配置表 (SkillSet)
|
||||
负责定义技能的所有属性和行为规则,包括技能类型、目标群体、伤害类型、冷却时间等关键字段。
|
||||
|
||||
### 技能控制组件 (SkillConComp)
|
||||
管理技能的触发逻辑、冷却时间计算、目标选择和定时器资源管理。
|
||||
|
||||
### 技能实体 (SkillEnt)
|
||||
负责技能的实例化、特效加载和生命周期管理。
|
||||
|
||||
### 技能视图组件 (SkillViewCom)
|
||||
处理技能的视觉表现、动画播放和位置计算。
|
||||
|
||||
### 攻击控制组件 (AtkConCom)
|
||||
实现具体的攻击逻辑、碰撞检测和伤害计算。
|
||||
|
||||
**章节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L1-L148)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
|
||||
## 架构概览
|
||||
|
||||
技能系统采用分层架构设计,确保各组件职责清晰、耦合度低:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "表现层"
|
||||
A[技能视图组件<br/>SkillViewCom]
|
||||
B[特效播放<br/>Animation/Particle]
|
||||
end
|
||||
subgraph "控制层"
|
||||
C[技能控制组件<br/>SkillConComp]
|
||||
D[攻击控制组件<br/>AtkConCom]
|
||||
end
|
||||
subgraph "数据层"
|
||||
E[技能实体<br/>SkillEnt]
|
||||
F[技能配置<br/>SkillSet]
|
||||
end
|
||||
subgraph "业务层"
|
||||
G[英雄视图组件<br/>HeroViewComp]
|
||||
H[目标选择<br/>selectTargets]
|
||||
end
|
||||
A --> C
|
||||
C --> E
|
||||
E --> F
|
||||
C --> G
|
||||
D --> A
|
||||
G --> H
|
||||
B --> D
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L1-L156)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L1-L236)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 技能配置系统 (SkillSet)
|
||||
|
||||
技能配置系统是整个技能体系的基础,定义了技能的所有属性和行为规则。
|
||||
|
||||
#### 技能类型枚举 (SType)
|
||||
|
||||
| 类型 | 值 | 描述 | 用途 |
|
||||
|------|----|----- |----- |
|
||||
| damage | 0 | 伤害技能 | 对目标造成物理/魔法伤害 |
|
||||
| heal | 1 | 治疗技能 | 恢复目标生命值 |
|
||||
| shield | 2 | 护盾技能 | 为目标添加护盾 |
|
||||
| atk_speed | 3 | 攻击速度提升 | 提升攻击速度 |
|
||||
| power_up | 4 | 力量提升 | 提升攻击力 |
|
||||
| ap_up | 5 | 法术强度提升 | 提升法术伤害 |
|
||||
| dod_up | 6 | 闪避提升 | 提升闪避率 |
|
||||
| crit_up | 7 | 暴击率提升 | 提升暴击率 |
|
||||
| crit_dmg_up | 8 | 暴击伤害提升 | 提升暴击伤害 |
|
||||
| wfuny_up | 9 | 连击率提升 | 提升连击触发概率 |
|
||||
| zhaohuan | 10 | 召唤技能 | 召唤生物协助战斗 |
|
||||
| buff | 11 | 增益技能 | 为目标添加增益效果 |
|
||||
|
||||
#### 目标群体枚举 (TGroup)
|
||||
|
||||
| 群体 | 值 | 描述 | 适用场景 |
|
||||
|------|----|----- |---------|
|
||||
| Self | 0 | 自身 | 自身增益、治疗技能 |
|
||||
| Ally | 1 | 所有敌人 | 团队治疗、辅助技能 |
|
||||
| Team | 2 | 所有友方 | 团队增益、保护技能 |
|
||||
| Enemy | 3 | 敌方单位 | 输出技能、控制技能 |
|
||||
| All | 4 | 所有单位 | 全局效果、范围伤害 |
|
||||
|
||||
#### 伤害类型枚举 (DTType)
|
||||
|
||||
| 类型 | 值 | 描述 | 特点 |
|
||||
|------|----|----- |------|
|
||||
| single | 0 | 单体伤害 | 针对单一目标 |
|
||||
| range | 1 | 范围伤害 | 对多个目标造成伤害 |
|
||||
|
||||
#### 关键字段说明
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SkillConfig {
|
||||
+number uuid
|
||||
+string name
|
||||
+string sp_name
|
||||
+AtkedName AtkedName
|
||||
+string path
|
||||
+TGroup TGroup
|
||||
+SType SType
|
||||
+string act
|
||||
+DTType DTType
|
||||
+DType DType
|
||||
+number ap
|
||||
+number cd
|
||||
+number t_num
|
||||
+number hit_num
|
||||
+number hit
|
||||
+number hitcd
|
||||
+number speed
|
||||
+number cost
|
||||
+number with
|
||||
+BuffConf[] buffs
|
||||
+NeAttrsConf[] neAttrs
|
||||
+string info
|
||||
+number hero
|
||||
}
|
||||
class BuffConf {
|
||||
+Attrs buff
|
||||
+BType BType
|
||||
+number value
|
||||
+number time
|
||||
+number chance
|
||||
}
|
||||
class NeAttrsConf {
|
||||
+NeAttrs neAttrs
|
||||
+number value
|
||||
+number time
|
||||
}
|
||||
SkillConfig --> BuffConf : "包含"
|
||||
SkillConfig --> NeAttrsConf : "包含"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L118-L148)
|
||||
|
||||
**章节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L1-L148)
|
||||
|
||||
### 技能控制组件 (SkillConComp)
|
||||
|
||||
技能控制组件负责技能的整体管理和触发逻辑,是技能系统的核心控制器。
|
||||
|
||||
#### 主要功能
|
||||
|
||||
1. **冷却时间管理**
|
||||
- 监控技能冷却进度
|
||||
- 自动重置冷却时间
|
||||
- 处理技能消耗检查
|
||||
|
||||
2. **自动施法条件判断**
|
||||
- 检查角色状态(眩晕、冰冻等)
|
||||
- 验证魔法值充足
|
||||
- 判断攻击状态冲突
|
||||
|
||||
3. **多段技能连发机制**
|
||||
- 实现wfuny连击系统
|
||||
- 控制技能释放间隔
|
||||
- 管理连击计数器
|
||||
|
||||
4. **目标选择策略**
|
||||
- 基于阵营的目标查询
|
||||
- 前排/后排目标优先级
|
||||
- 随机目标选择算法
|
||||
|
||||
#### 核心方法分析
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家输入
|
||||
participant SkillCon as 技能控制组件
|
||||
participant HeroView as 英雄视图
|
||||
participant SkillEnt as 技能实体
|
||||
participant AtkCon as 攻击控制
|
||||
Player->>SkillCon : 更新技能冷却
|
||||
SkillCon->>SkillCon : 检查冷却时间
|
||||
SkillCon->>HeroView : 检查角色状态
|
||||
HeroView-->>SkillCon : 状态验证结果
|
||||
SkillCon->>SkillCon : 选择目标
|
||||
SkillCon->>HeroView : 播放技能特效
|
||||
SkillCon->>SkillEnt : 创建技能实体
|
||||
SkillEnt->>AtkCon : 初始化攻击组件
|
||||
AtkCon->>AtkCon : 执行攻击逻辑
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L35-L177)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L78)
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
|
||||
### 技能实体 (SkillEnt)
|
||||
|
||||
技能实体负责技能的实例化和生命周期管理,确保技能能够正确地在游戏中表现。
|
||||
|
||||
#### 实体创建流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[技能触发] --> B[加载技能配置]
|
||||
B --> C{配置是否存在?}
|
||||
C --> |否| D[输出错误日志]
|
||||
C --> |是| E[检查施法者]
|
||||
E --> F{施法者是否存在?}
|
||||
F --> |否| D
|
||||
F --> |是| G[加载特效预制体]
|
||||
G --> H{预制体加载成功?}
|
||||
H --> |否| D
|
||||
H --> |是| I[实例化特效节点]
|
||||
I --> J[设置节点属性]
|
||||
J --> K[添加技能组件]
|
||||
K --> L[技能实体就绪]
|
||||
D --> M[结束]
|
||||
L --> N[等待执行时机]
|
||||
N --> O[执行技能逻辑]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L78)
|
||||
|
||||
**章节来源**
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
|
||||
### 技能视图组件 (SkillViewCom)
|
||||
|
||||
技能视图组件处理技能的视觉表现和动画播放,是技能外观效果的主要控制者。
|
||||
|
||||
#### 动画类型支持
|
||||
|
||||
| 类型 | 值 | 描述 | 实现方式 |
|
||||
|------|----|----- |---------|
|
||||
| linear | 0 | 直线运动 | 线性插值移动 |
|
||||
| bezier | 1 | 贝塞尔曲线 | 贝塞尔曲线轨迹 |
|
||||
| fixed | 2 | 固定起点 | 起点固定,终点动态 |
|
||||
| fixedEnd | 3 | 固定终点 | 终点固定,起点动态 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L1-L156)
|
||||
|
||||
### 攻击控制组件 (AtkConCom)
|
||||
|
||||
攻击控制组件实现具体的攻击逻辑,包括碰撞检测、伤害计算和效果应用。
|
||||
|
||||
#### 碰撞检测机制
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[技能移动] --> B[检测碰撞]
|
||||
B --> C{是否接触敌方}
|
||||
C --> |否| D[继续移动]
|
||||
C --> |是| E[检查穿透次数]
|
||||
E --> F{达到最大穿透?}
|
||||
F --> |是| G[销毁技能]
|
||||
F --> |否| H[计算伤害]
|
||||
H --> I[应用伤害效果]
|
||||
I --> J[增加穿透计数]
|
||||
J --> K{范围伤害?}
|
||||
K --> |是| L[对范围内所有目标]
|
||||
K --> |否| M[仅对当前目标]
|
||||
L --> N[继续移动]
|
||||
M --> N
|
||||
D --> N
|
||||
G --> O[结束]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L120-L180)
|
||||
|
||||
**章节来源**
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L1-L236)
|
||||
|
||||
## 技能配置系统
|
||||
|
||||
技能配置系统是技能系统的基础,通过SkillSet.ts定义了所有技能的属性和行为规则。
|
||||
|
||||
### 配置表结构
|
||||
|
||||
技能配置表采用Record结构,以技能UUID作为键,SkillConfig接口作为值:
|
||||
|
||||
```typescript
|
||||
export const SkillSet: Record<number, SkillConfig> = {
|
||||
6001: {
|
||||
uuid: 6001,
|
||||
name: "挥击",
|
||||
sp_name: "atk_s1",
|
||||
AtkedName: AtkedName.atked,
|
||||
path: "3036",
|
||||
TGroup: TGroup.Enemy,
|
||||
SType: SType.damage,
|
||||
act: "atk",
|
||||
DTType: DTType.single,
|
||||
DType: DType.ATK,
|
||||
ap: 100,
|
||||
cd: 1,
|
||||
t_num: 1,
|
||||
hit_num: 1,
|
||||
hit: 1,
|
||||
hitcd: 0.2,
|
||||
speed: 720,
|
||||
cost: 0,
|
||||
with: 0,
|
||||
buffs: [],
|
||||
neAttrs: [],
|
||||
info: "向最前方敌人扔出石斧,造成100%攻击的伤害"
|
||||
},
|
||||
// 更多技能配置...
|
||||
}
|
||||
```
|
||||
|
||||
### 关键配置字段详解
|
||||
|
||||
| 字段 | 类型 | 描述 | 默认值 | 说明 |
|
||||
|------|------|------|--------|------|
|
||||
| uuid | number | 技能唯一标识符 | - | 必需,用于技能识别 |
|
||||
| name | string | 技能名称 | - | 显示用名称 |
|
||||
| sp_name | string | 特效名称 | - | 对应特效资源文件名 |
|
||||
| TGroup | TGroup | 目标群体 | - | 技能作用目标类型 |
|
||||
| SType | SType | 技能类型 | - | 技能效果类型 |
|
||||
| cd | number | 冷却时间 | - | 技能冷却秒数 |
|
||||
| cost | number | 消耗值 | - | 魔法值或能量消耗 |
|
||||
| ap | number | 伤害倍率 | - | 伤害相对于攻击力的百分比 |
|
||||
| hit | number | 穿透次数 | 0 | 攻击可穿透的目标数量 |
|
||||
| hitcd | number | 持续伤害间隔 | 0 | 持续伤害的触发间隔 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L118-L148)
|
||||
|
||||
## 技能控制机制
|
||||
|
||||
技能控制机制是技能系统的核心,负责技能的触发、冷却管理和执行逻辑。
|
||||
|
||||
### 冷却时间管理系统
|
||||
|
||||
冷却时间管理采用增量式计算,每帧更新技能的冷却进度:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[技能冷却开始] --> B[dt累积]
|
||||
B --> C[检查冷却时间]
|
||||
C --> D{是否达到冷却?}
|
||||
D --> |否| E[继续累积]
|
||||
D --> |是| F[检查魔法值]
|
||||
F --> G{魔法值充足?}
|
||||
G --> |否| H[等待补充]
|
||||
G --> |是| I[触发技能]
|
||||
E --> B
|
||||
H --> F
|
||||
I --> J[重置冷却时间]
|
||||
J --> K[扣除魔法值]
|
||||
K --> L[技能准备就绪]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L35-L50)
|
||||
|
||||
### 自动施法条件判断
|
||||
|
||||
系统在每次更新时检查多个条件:
|
||||
|
||||
1. **战斗状态检查**
|
||||
- 检查mission.play状态
|
||||
- 验证mission.pause状态
|
||||
|
||||
2. **角色状态检查**
|
||||
- 检查眩晕状态 (isStun())
|
||||
- 检查冰冻状态 (isFrost())
|
||||
|
||||
3. **技能状态检查**
|
||||
- 验证冷却时间是否完成
|
||||
- 检查魔法值是否足够
|
||||
- 确认攻击状态不冲突
|
||||
|
||||
### 多段技能连发机制
|
||||
|
||||
系统支持wfuny连击机制,通过check_wfuny方法判断是否触发连击:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant SkillCon as 技能控制
|
||||
participant HeroView as 英雄视图
|
||||
participant Timer as 定时器系统
|
||||
SkillCon->>HeroView : 检查wfuny属性
|
||||
HeroView-->>SkillCon : 返回连击概率
|
||||
SkillCon->>SkillCon : 随机数生成
|
||||
alt 触发连击
|
||||
SkillCon->>Timer : 设置延迟执行
|
||||
Timer->>SkillCon : 延迟后再次执行
|
||||
SkillCon->>SkillCon : 递归调用doSkill
|
||||
else 未触发连击
|
||||
SkillCon->>SkillCon : 正常结束
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L85-L105)
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L35-L177)
|
||||
|
||||
## 技能释放流程
|
||||
|
||||
技能释放是一个复杂的多阶段过程,涉及预判、特效播放、实体生成等多个环节。
|
||||
|
||||
### 技能释放全过程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家操作
|
||||
participant SkillCon as 技能控制
|
||||
participant HeroView as 英雄视图
|
||||
participant SkillEnt as 技能实体
|
||||
participant AtkCon as 攻击控制
|
||||
participant Target as 目标对象
|
||||
Player->>SkillCon : 发起技能请求
|
||||
SkillCon->>SkillCon : 验证技能可用性
|
||||
SkillCon->>HeroView : 播放技能动画
|
||||
HeroView-->>SkillCon : 动画播放完成
|
||||
SkillCon->>SkillCon : 创建技能实体
|
||||
SkillCon->>SkillEnt : 加载技能配置
|
||||
SkillEnt->>SkillEnt : 实例化特效节点
|
||||
SkillEnt->>AtkCon : 添加攻击组件
|
||||
AtkCon->>AtkCon : 初始化技能参数
|
||||
AtkCon->>Target : 开始攻击逻辑
|
||||
Target-->>AtkCon : 碰撞检测结果
|
||||
AtkCon->>AtkCon : 计算伤害效果
|
||||
AtkCon->>Target : 应用伤害效果
|
||||
AtkCon->>AtkCon : 检查技能结束条件
|
||||
alt 技能需要多段
|
||||
AtkCon->>AtkCon : 继续下一段攻击
|
||||
else 技能结束
|
||||
AtkCon->>AtkCon : 销毁技能实体
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L60-L105)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L78)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L120-L180)
|
||||
|
||||
### 目标选择策略
|
||||
|
||||
目标选择是技能系统的重要组成部分,采用智能算法确定技能目标:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始目标选择] --> B[查询目标实体]
|
||||
B --> C{是否有目标?}
|
||||
C --> |否| D[返回默认位置]
|
||||
C --> |是| E[确定前排目标]
|
||||
E --> F[添加前排目标到列表]
|
||||
F --> G{还需要更多目标?}
|
||||
G --> |否| H[返回目标列表]
|
||||
G --> |是| I[随机选择剩余目标]
|
||||
I --> J[添加到目标列表]
|
||||
J --> K{达到目标数量?}
|
||||
K --> |否| G
|
||||
K --> |是| H
|
||||
D --> L[填充默认位置]
|
||||
L --> H
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L120-L175)
|
||||
|
||||
### 定时器资源管理
|
||||
|
||||
系统使用定时器管理技能的延迟执行,确保技能释放的精确控制:
|
||||
|
||||
| 定时器类型 | 用途 | 生命周期 | 清理方式 |
|
||||
|------------|------|----------|----------|
|
||||
| 技能延迟定时器 | 技能特效延迟播放 | 技能生命周期内 | 技能结束后清理 |
|
||||
| 连击延迟定时器 | 多段技能间隔 | 连击期间 | 连击结束时清理 |
|
||||
| 冷却定时器 | 技能冷却倒计时 | 技能冷却期间 | 冷却完成时清理 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L60-L177)
|
||||
|
||||
## 异常处理与最佳实践
|
||||
|
||||
技能系统在设计时充分考虑了各种异常情况,提供了完善的错误处理机制。
|
||||
|
||||
### 节点有效性检查
|
||||
|
||||
系统在关键操作前进行节点有效性检查,防止因节点被销毁导致的异常:
|
||||
|
||||
```typescript
|
||||
private doSkill(config: typeof SkillSet[keyof typeof SkillSet], is_wfuny: boolean = false, dmg: number = 0) {
|
||||
// 添加节点有效性检查
|
||||
if (!this.node || !this.node.isValid || !this.HeroView || !this.HeroView.node || !this.HeroView.node.isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 技能执行逻辑
|
||||
|
||||
// 再次检查节点有效性
|
||||
if (!this.node || !this.node.isValid || !this.HeroView || !this.HeroView.node || !this.HeroView.node.isValid) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 异常处理策略
|
||||
|
||||
1. **技能配置缺失处理**
|
||||
```typescript
|
||||
load(startPos: Vec3, parent: Node, uuid: number, targetPos: any[], caster: HeroViewComp = null, dmg: number = 0) {
|
||||
const config = SkillSet[uuid];
|
||||
if (!config) {
|
||||
console.error("[Skill] 技能配置不存在:", uuid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **资源加载失败处理**
|
||||
```typescript
|
||||
const prefab: Prefab = oops.res.get(path, Prefab);
|
||||
if (!prefab) {
|
||||
console.error("[Skill] 预制体加载失败:", path);
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
3. **战斗状态异常处理**
|
||||
```typescript
|
||||
update(dt: number) {
|
||||
if (!smc.mission.play || smc.mission.pause) return;
|
||||
// 技能逻辑执行
|
||||
}
|
||||
```
|
||||
|
||||
### 最佳实践建议
|
||||
|
||||
1. **资源管理**
|
||||
- 及时清理定时器资源
|
||||
- 正确释放技能实体
|
||||
- 避免内存泄漏
|
||||
|
||||
2. **性能优化**
|
||||
- 使用对象池管理技能实体
|
||||
- 减少不必要的对象创建
|
||||
- 优化碰撞检测频率
|
||||
|
||||
3. **错误恢复**
|
||||
- 提供默认行为处理异常
|
||||
- 记录详细的错误日志
|
||||
- 实现优雅降级机制
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L105)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L40)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
技能系统在设计时充分考虑了性能优化,采用了多种策略确保流畅的游戏体验。
|
||||
|
||||
### 对象池管理
|
||||
|
||||
技能实体采用对象池模式,避免频繁的对象创建和销毁:
|
||||
|
||||
```typescript
|
||||
// 在SkillConComp中维护定时器映射
|
||||
private _timers: { [key: string]: any } = {};
|
||||
|
||||
// 定时器资源管理
|
||||
public clear_timer() {
|
||||
Object.values(this._timers).forEach(clearTimeout);
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
// 清理所有定时器
|
||||
Object.values(this._timers).forEach(clearTimeout);
|
||||
this._timers = {};
|
||||
}
|
||||
```
|
||||
|
||||
### 内存优化策略
|
||||
|
||||
1. **延迟加载**
|
||||
- 技能特效按需加载
|
||||
- 避免一次性加载所有技能资源
|
||||
|
||||
2. **引用管理**
|
||||
- 使用浅拷贝传递技能属性
|
||||
- 避免深层复制造成的性能开销
|
||||
|
||||
3. **生命周期管理**
|
||||
- 及时销毁不需要的技能实体
|
||||
- 清理事件监听器和定时器
|
||||
|
||||
### 碰撞检测优化
|
||||
|
||||
攻击控制组件采用高效的碰撞检测算法:
|
||||
|
||||
```typescript
|
||||
// 范围伤害优化
|
||||
public atk(args: any) {
|
||||
let targetsInRange: HeroViewComp[] = [];
|
||||
|
||||
// 使用ECS查询优化目标查找
|
||||
ecs.query(ecs.allOf(HeroViewComp)).some(e => {
|
||||
const view = e.get(HeroViewComp);
|
||||
if (view.fac != this.fac) {
|
||||
const distance = Math.abs(this.node.position.x - view.node.position.x);
|
||||
if (distance <= dis) {
|
||||
targetsInRange.push(view);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 技能无法触发
|
||||
|
||||
**症状**: 技能按下后没有反应
|
||||
**可能原因**:
|
||||
1. 冷却时间未完成
|
||||
2. 魔法值不足
|
||||
3. 角色处于异常状态
|
||||
4. 技能配置缺失
|
||||
|
||||
**解决步骤**:
|
||||
1. 检查技能冷却时间
|
||||
2. 验证角色魔法值
|
||||
3. 确认角色状态正常
|
||||
4. 检查SkillSet配置
|
||||
|
||||
#### 特效播放异常
|
||||
|
||||
**症状**: 技能释放但没有特效
|
||||
**可能原因**:
|
||||
1. 特效资源加载失败
|
||||
2. 节点被提前销毁
|
||||
3. 动画组件配置错误
|
||||
|
||||
**解决步骤**:
|
||||
1. 检查资源路径和文件名
|
||||
2. 验证节点有效性
|
||||
3. 确认动画组件正确绑定
|
||||
|
||||
#### 目标选择错误
|
||||
|
||||
**症状**: 技能攻击了错误的目标
|
||||
**可能原因**:
|
||||
1. 目标查询逻辑错误
|
||||
2. 阵营判断失误
|
||||
3. 前排/后排判定错误
|
||||
|
||||
**解决步骤**:
|
||||
1. 检查阵营判断逻辑
|
||||
2. 验证目标位置计算
|
||||
3. 确认优先级设置
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L170-L177)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L25-L40)
|
||||
|
||||
## 总结
|
||||
|
||||
技能系统是一个复杂而精密的战斗机制,通过合理的架构设计和完善的异常处理,实现了高效、稳定的技能管理功能。
|
||||
|
||||
### 系统优势
|
||||
|
||||
1. **模块化设计**: 各组件职责清晰,易于维护和扩展
|
||||
2. **性能优化**: 采用对象池和延迟加载策略,确保流畅运行
|
||||
3. **异常处理**: 完善的错误检查和恢复机制
|
||||
4. **灵活性**: 支持多种技能类型和效果组合
|
||||
|
||||
### 技术特点
|
||||
|
||||
1. **ECS架构**: 基于组件式设计,提高代码复用性
|
||||
2. **事件驱动**: 通过事件系统实现组件间的松耦合通信
|
||||
3. **配置驱动**: 技能行为完全由配置文件控制
|
||||
4. **资源管理**: 完善的资源加载和释放机制
|
||||
|
||||
### 扩展建议
|
||||
|
||||
1. **技能树系统**: 可以在此基础上扩展技能升级和解锁机制
|
||||
2. **连携技能**: 支持多个角色协同释放的组合技能
|
||||
3. **动态平衡**: 根据玩家表现动态调整技能效果
|
||||
4. **AI适配**: 为AI敌人提供专门的技能释放策略
|
||||
|
||||
技能系统作为游戏战斗的核心,其设计理念和实现方式为类似项目的开发提供了宝贵的参考价值。
|
||||
524
.qoder/repowiki/zh/content/英雄系统/技能系统/技能配置表结构.md
Normal file
524
.qoder/repowiki/zh/content/英雄系统/技能系统/技能配置表结构.md
Normal file
@@ -0,0 +1,524 @@
|
||||
# 技能配置表结构
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构概览](#项目结构概览)
|
||||
3. [核心接口定义](#核心接口定义)
|
||||
4. [枚举类型详解](#枚举类型详解)
|
||||
5. [技能配置实例分析](#技能配置实例分析)
|
||||
6. [技能系统架构](#技能系统架构)
|
||||
7. [战斗系统集成](#战斗系统集成)
|
||||
8. [新增技能配置流程](#新增技能配置流程)
|
||||
9. [验证方法与最佳实践](#验证方法与最佳实践)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
SkillSet.ts是游戏技能系统的核心配置文件,定义了完整的技能配置表结构和相关的枚举类型。该系统采用ECS架构模式,支持多种技能类型、目标群体、伤害类型和效果配置,为游戏战斗系统提供了灵活而强大的技能管理框架。
|
||||
|
||||
## 项目结构概览
|
||||
|
||||
技能系统在项目中的组织结构如下:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
SkillSet["SkillSet.ts<br/>技能配置表"]
|
||||
HeroAttrs["HeroAttrs.ts<br/>属性系统"]
|
||||
end
|
||||
subgraph "技能实体层"
|
||||
SkillEnt["SkillEnt.ts<br/>技能实体"]
|
||||
SkillViewCom["SkillViewCom.ts<br/>技能视图组件"]
|
||||
end
|
||||
subgraph "控制层"
|
||||
SkillConComp["SkillConComp.ts<br/>技能控制器"]
|
||||
AtkConCom["AtkConCom.ts<br/>攻击控制器"]
|
||||
end
|
||||
subgraph "战斗层"
|
||||
HeroViewComp["HeroViewComp.ts<br/>英雄视图组件"]
|
||||
BuffComp["BuffComp.ts<br/>Buff组件"]
|
||||
end
|
||||
SkillSet --> SkillEnt
|
||||
SkillEnt --> SkillViewCom
|
||||
SkillConComp --> SkillEnt
|
||||
AtkConCom --> SkillEnt
|
||||
HeroViewComp --> BuffComp
|
||||
SkillSet --> HeroViewComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L1-L148)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
|
||||
## 核心接口定义
|
||||
|
||||
### SkillConfig接口结构
|
||||
|
||||
SkillConfig是技能配置的核心接口,包含了技能的所有属性定义:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SkillConfig {
|
||||
+number uuid
|
||||
+string name
|
||||
+string sp_name
|
||||
+AtkedName AtkedName
|
||||
+string path
|
||||
+TGroup TGroup
|
||||
+SType SType
|
||||
+string act
|
||||
+DTType DTType
|
||||
+DType DType
|
||||
+number ap
|
||||
+number cd
|
||||
+number t_num
|
||||
+number hit_num
|
||||
+number hit
|
||||
+number hitcd
|
||||
+number speed
|
||||
+number cost
|
||||
+number with
|
||||
+BuffConf[] buffs
|
||||
+NeAttrsConf[] neAttrs
|
||||
+string info
|
||||
+number hero
|
||||
}
|
||||
class BuffConf {
|
||||
+Attrs buff
|
||||
+BType BType
|
||||
+number value
|
||||
+number time
|
||||
+number chance
|
||||
}
|
||||
class NeAttrsConf {
|
||||
+NeAttrs neAttrs
|
||||
+number value
|
||||
+number time
|
||||
}
|
||||
SkillConfig --> BuffConf : "包含多个"
|
||||
SkillConfig --> NeAttrsConf : "包含多个"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L127-L148)
|
||||
|
||||
### 字段详细说明
|
||||
|
||||
| 字段名 | 类型 | 描述 | 默认值 |
|
||||
|--------|------|------|--------|
|
||||
| uuid | number | 技能唯一标识符 | - |
|
||||
| name | string | 技能显示名称 | - |
|
||||
| sp_name | string | 特效资源名称 | - |
|
||||
| AtkedName | AtkedName | 受伤动画类型 | - |
|
||||
| path | string | 图片资源路径 | - |
|
||||
| TGroup | TGroup | 目标群体类型 | - |
|
||||
| SType | SType | 技能效果类型 | - |
|
||||
| act | string | 角色执行动画 | - |
|
||||
| DTType | DTType | 伤害类型 | - |
|
||||
| DType | DType | 伤害属性类型 | - |
|
||||
| ap | number | 攻击力百分比 | - |
|
||||
| cd | number | 冷却时间(秒) | - |
|
||||
| t_num | number | 目标数量 | - |
|
||||
| hit_num | number | 范围攻击伤害敌人数量 | - |
|
||||
| hit | number | 穿刺次数 | - |
|
||||
| hitcd | number | 持续伤害间隔 | - |
|
||||
| speed | number | 移动速度 | - |
|
||||
| cost | number | 资源消耗 | - |
|
||||
| with | number | 暂时无用 | - |
|
||||
| buffs | BuffConf[] | 附加效果列表 | [] |
|
||||
| neAttrs | NeAttrsConf[] | 负面状态列表 | [] |
|
||||
| info | string | 技能描述信息 | - |
|
||||
| hero | number | 关联英雄ID | - |
|
||||
|
||||
**章节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L127-L148)
|
||||
|
||||
## 枚举类型详解
|
||||
|
||||
### TGroup - 目标群体枚举
|
||||
|
||||
目标群体决定了技能的作用范围和目标选择策略:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
TGroup --> Self["Self<br/>自身"]
|
||||
TGroup --> Ally["Ally<br/>所有友方"]
|
||||
TGroup --> Team["Team<br/>所有友方"]
|
||||
TGroup --> Enemy["Enemy<br/>敌方单位"]
|
||||
TGroup --> All["All<br/>所有单位"]
|
||||
Self --> SelfDesc["对自己生效<br/>如:治疗技能"]
|
||||
Ally --> AllyDesc["对所有友方单位<br/>如:增益技能"]
|
||||
Team --> TeamDesc["同Ally,历史遗留"]
|
||||
Enemy --> EnemyDesc["对敌方单位<br/>如:攻击技能"]
|
||||
All --> AllDesc["对所有单位<br/>如:全地图技能"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L2-L7)
|
||||
|
||||
### SType - 技能类型枚举
|
||||
|
||||
技能类型定义了技能的主要效果分类:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
SType --> Damage["damage<br/>伤害型"]
|
||||
SType --> Heal["heal<br/>治疗型"]
|
||||
SType --> Shield["shield<br/>护盾型"]
|
||||
SType --> AtkSpeed["atk_speed<br/>攻速型"]
|
||||
SType --> PowerUp["power_up<br/>力量型"]
|
||||
SType --> ApUp["ap_up<br/>攻击型"]
|
||||
SType --> DodUp["dod_up<br/>闪避型"]
|
||||
SType --> CritUp["crit_up<br/>暴击型"]
|
||||
SType --> CritDmgUp["crit_dmg_up<br/>暴击伤害型"]
|
||||
SType --> WfunyUp["wfuny_up<br/>风怒型"]
|
||||
SType --> Zhaohuan["zhaohuan<br/>召唤型"]
|
||||
SType --> Buff["buff<br/>增益型"]
|
||||
Damage --> DamageDesc["造成物理/魔法伤害"]
|
||||
Heal --> HealDesc["恢复生命值"]
|
||||
Shield --> ShieldDesc["生成护盾保护"]
|
||||
AtkSpeed --> AtkSpeedDesc["提升攻击速度"]
|
||||
PowerUp --> PowerUpDesc["提升基础属性"]
|
||||
ApUp --> ApUpDesc["提升攻击力"]
|
||||
DodUp --> DodUpDesc["提升闪避率"]
|
||||
CritUp --> CritUpDesc["提升暴击率"]
|
||||
CritDmgUp --> CritDmgUpDesc["提升暴击伤害"]
|
||||
WfunyUp --> WfunyUpDesc["提升风怒效果"]
|
||||
Zhaohuan --> ZhaohuanDesc["召唤单位"]
|
||||
Buff --> BuffDesc["提供各种增益效果"]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L34-L43)
|
||||
|
||||
### DType - 伤害类型枚举
|
||||
|
||||
伤害类型决定了技能的属性分类:
|
||||
|
||||
| 枚举值 | 数值 | 描述 | 应用场景 |
|
||||
|--------|------|------|----------|
|
||||
| ATK | 0 | 物理伤害 | 物理攻击技能 |
|
||||
| MAGE | 1 | 魔法伤害 | 法术攻击技能 |
|
||||
|
||||
### AtkedName - 受伤动画枚举
|
||||
|
||||
定义了不同类型的受伤动画效果:
|
||||
|
||||
| 枚举值 | 动画名称 | 效果描述 |
|
||||
|--------|----------|----------|
|
||||
| atked | atked | 普通受伤动画 |
|
||||
| ice | atked_ice | 冰冻受伤动画 |
|
||||
| fire | atked_fire | 火焰受伤动画 |
|
||||
| wind | atked_wind | 风元素受伤动画 |
|
||||
| crit | atked_crit | 暴击受伤动画 |
|
||||
|
||||
**章节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L45-L52)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L106-L110)
|
||||
|
||||
## 技能配置实例分析
|
||||
|
||||
### 代码示例6001 - 挥击
|
||||
|
||||
挥击是最基础的物理攻击技能,展示了技能配置的基本要素:
|
||||
|
||||
**配置特点:**
|
||||
- **目标群体**: Enemy(敌方单位)
|
||||
- **技能类型**: damage(伤害型)
|
||||
- **伤害属性**: ATK(物理伤害)
|
||||
- **攻击力百分比**: 100%
|
||||
- **冷却时间**: 1秒
|
||||
- **资源消耗**: 0
|
||||
- **特效名称**: atk_s1
|
||||
|
||||
**应用场景**:
|
||||
- 单体物理攻击
|
||||
- 最基础的普攻技能
|
||||
- 无附加效果
|
||||
|
||||
### 代码示例6005 - 火球术
|
||||
|
||||
火球术是一个典型的魔法攻击技能,具有更复杂的配置:
|
||||
|
||||
**配置特点:**
|
||||
- **目标群体**: Enemy(敌方单位)
|
||||
- **技能类型**: damage(伤害型)
|
||||
- **伤害属性**: MAGE(魔法伤害)
|
||||
- **攻击力百分比**: 100%
|
||||
- **冷却时间**: 5秒
|
||||
- **资源消耗**: 20
|
||||
- **特效名称**: atk_fires
|
||||
- **特殊效果**: 有一定几率施加灼烧状态
|
||||
|
||||
**应用场景**:
|
||||
- 单体魔法攻击
|
||||
- 高资源消耗的强力技能
|
||||
- 具有附加状态效果
|
||||
|
||||
**章节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L130-L148)
|
||||
|
||||
## 技能系统架构
|
||||
|
||||
### 系统架构图
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家输入
|
||||
participant SkillCon as 技能控制器
|
||||
participant SkillEnt as 技能实体
|
||||
participant SkillView as 技能视图
|
||||
participant HeroView as 英雄视图
|
||||
participant BuffSys as Buff系统
|
||||
Player->>SkillCon : 发起技能请求
|
||||
SkillCon->>SkillCon : 检查冷却时间
|
||||
SkillCon->>SkillCon : 验证资源消耗
|
||||
SkillCon->>SkillEnt : 创建技能实体
|
||||
SkillEnt->>SkillView : 加载特效资源
|
||||
SkillView->>HeroView : 播放技能动画
|
||||
HeroView->>HeroView : 计算伤害效果
|
||||
HeroView->>BuffSys : 应用附加效果
|
||||
BuffSys-->>HeroView : 更新属性状态
|
||||
HeroView-->>Player : 显示技能效果
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L40-L80)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L15-L70)
|
||||
|
||||
### 技能执行流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([技能请求开始]) --> CheckCD["检查冷却时间"]
|
||||
CheckCD --> CDReady{"冷却完成?"}
|
||||
CDReady --> |否| WaitCD["等待冷却"]
|
||||
CDReady --> |是| CheckCost["检查资源消耗"]
|
||||
CheckCost --> CostOK{"资源充足?"}
|
||||
CostOK --> |否| NotEnough["资源不足"]
|
||||
CostOK --> |是| SelectTarget["选择目标"]
|
||||
SelectTarget --> LoadEffect["加载特效"]
|
||||
LoadEffect --> PlayAnim["播放动画"]
|
||||
PlayAnim --> CalcDamage["计算伤害"]
|
||||
CalcDamage --> ApplyEffects["应用附加效果"]
|
||||
ApplyEffects --> UpdateStatus["更新状态"]
|
||||
UpdateStatus --> End([技能执行完成])
|
||||
WaitCD --> CheckCD
|
||||
NotEnough --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L45-L85)
|
||||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts#L147-L186)
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
|
||||
## 战斗系统集成
|
||||
|
||||
### Buff系统集成
|
||||
|
||||
技能系统与Buff系统紧密集成,支持复杂的附加效果:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class HeroViewComp {
|
||||
+Record~number,BuffInfo[]~ BUFFS
|
||||
+Record~number,BuffInfo[]~ BUFFS_TEMP
|
||||
+addBuff(buffConf : BuffConf)
|
||||
+removeBuff(attrIndex : number, value : number, isPermanent : boolean)
|
||||
+recalculateSingleAttr(attrIndex : number)
|
||||
}
|
||||
class BuffConf {
|
||||
+Attrs buff
|
||||
+BType BType
|
||||
+number value
|
||||
+number time
|
||||
+number chance
|
||||
}
|
||||
class SkillConfig {
|
||||
+BuffConf[] buffs
|
||||
+NeAttrsConf[] neAttrs
|
||||
}
|
||||
HeroViewComp --> BuffConf : "管理"
|
||||
SkillConfig --> BuffConf : "定义"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L20-L84)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L112-L126)
|
||||
|
||||
### 属性计算机制
|
||||
|
||||
技能系统支持基于属性的动态计算:
|
||||
|
||||
| 属性类型 | 计算方式 | 示例 |
|
||||
|----------|----------|------|
|
||||
| 数值型属性 | 基础值 + 所有数值型buff之和 | HP = 100 + 20 + 15 = 135 |
|
||||
| 百分比型属性 | 基础值 × (1 + 所有百分比buff之和/100) | AP = 50 × (1 + 0.2) = 60 |
|
||||
| 混合型属性 | (基础值 + 数值型总和) × (1 + 百分比总和/100) | DEF = (100 + 10) × (1 + 0.1) = 121 |
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L217-L251)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L150-L199)
|
||||
|
||||
## 新增技能配置流程
|
||||
|
||||
### 完整配置步骤
|
||||
|
||||
1. **确定技能UUID**
|
||||
- 确保UUID唯一性
|
||||
- 按功能分类分配范围(如6001-6099为基础攻击)
|
||||
|
||||
2. **定义基础属性**
|
||||
```typescript
|
||||
// 示例配置模板
|
||||
const newSkill: SkillConfig = {
|
||||
uuid: 6006,
|
||||
name: "新技能名称",
|
||||
sp_name: "特效名称",
|
||||
AtkedName: AtkedName.atked,
|
||||
path: "图片资源路径",
|
||||
TGroup: TGroup.Enemy,
|
||||
SType: SType.damage,
|
||||
act: "技能动画名称",
|
||||
DTType: DTType.single,
|
||||
DType: DType.ATK,
|
||||
ap: 150,
|
||||
cd: 3,
|
||||
t_num: 1,
|
||||
hit_num: 1,
|
||||
hit: 1,
|
||||
hitcd: 0.2,
|
||||
speed: 720,
|
||||
cost: 15,
|
||||
with: 0,
|
||||
buffs: [],
|
||||
neAttrs: [],
|
||||
info: "技能描述信息",
|
||||
hero: 1001
|
||||
};
|
||||
```
|
||||
|
||||
3. **配置目标群体**
|
||||
- 根据技能效果选择合适的TGroup
|
||||
- 考虑团队协作和平衡性
|
||||
|
||||
4. **设置技能类型**
|
||||
- 选择最符合技能效果的SType
|
||||
- 注意与其他技能的差异化
|
||||
|
||||
5. **定义数值参数**
|
||||
- 攻击力百分比(ap):通常在50-200%之间
|
||||
- 冷却时间(cd):根据技能强度调整
|
||||
- 资源消耗(cost):平衡技能使用频率
|
||||
|
||||
6. **配置附加效果**
|
||||
- 添加BuffConf数组定义增益效果
|
||||
- 添加NeAttrsConf数组定义负面效果
|
||||
- 注意效果的平衡性和独特性
|
||||
|
||||
7. **编写技能描述**
|
||||
- 清晰描述技能效果
|
||||
- 包含关键数值信息
|
||||
- 说明使用策略
|
||||
|
||||
### 验证检查清单
|
||||
|
||||
| 检查项 | 验证内容 | 通过标准 |
|
||||
|--------|----------|----------|
|
||||
| UUID唯一性 | 确保uuid不重复 | 不与其他技能冲突 |
|
||||
| 参数合理性 | 数值在合理范围内 | 符合游戏平衡 |
|
||||
| 效果一致性 | 描述与实际效果一致 | 文字描述准确 |
|
||||
| 性能影响 | 对游戏性能影响最小 | 无明显卡顿 |
|
||||
| 资源完整性 | 所有资源文件存在 | 无缺失资源 |
|
||||
|
||||
## 验证方法与最佳实践
|
||||
|
||||
### 开发阶段验证
|
||||
|
||||
1. **编译时验证**
|
||||
- TypeScript类型检查确保字段完整
|
||||
- 枚举值范围验证
|
||||
- 必填字段检查
|
||||
|
||||
2. **运行时验证**
|
||||
```typescript
|
||||
// 验证函数示例
|
||||
function validateSkillConfig(config: SkillConfig): boolean {
|
||||
// 检查必填字段
|
||||
if (!config.uuid || !config.name || !config.sp_name) return false;
|
||||
|
||||
// 检查数值范围
|
||||
if (config.ap <= 0 || config.cd <= 0) return false;
|
||||
|
||||
// 检查目标群体有效性
|
||||
if (config.TGroup < 0 || config.TGroup > 4) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
3. **单元测试**
|
||||
- 测试各种技能类型的执行
|
||||
- 验证Buff效果的正确应用
|
||||
- 检查目标选择逻辑
|
||||
|
||||
### 平衡性测试
|
||||
|
||||
1. **强度评估**
|
||||
- 与其他同类技能对比
|
||||
- 在不同场景下的表现
|
||||
- 对游戏整体平衡的影响
|
||||
|
||||
2. **使用频率测试**
|
||||
- 冷却时间对玩家体验的影响
|
||||
- 资源消耗的合理性
|
||||
- 技能组合的可行性
|
||||
|
||||
3. **视觉效果验证**
|
||||
- 特效资源的质量
|
||||
- 动画流畅度
|
||||
- 视觉反馈的清晰度
|
||||
|
||||
### 性能优化建议
|
||||
|
||||
1. **资源管理**
|
||||
- 合理控制特效资源大小
|
||||
- 使用对象池减少内存分配
|
||||
- 及时释放不再使用的资源
|
||||
|
||||
2. **算法优化**
|
||||
- 优化目标选择算法
|
||||
- 减少不必要的计算
|
||||
- 使用空间换时间的策略
|
||||
|
||||
3. **网络同步**
|
||||
- 确保技能效果在网络环境下的同步
|
||||
- 处理延迟和丢包情况
|
||||
- 保证客户端和服务端的一致性
|
||||
|
||||
## 总结
|
||||
|
||||
SkillSet.ts定义了一个完整而灵活的技能配置系统,通过精心设计的接口和枚举类型,为游戏战斗系统提供了强大的技能管理能力。该系统的主要优势包括:
|
||||
|
||||
1. **结构化配置**:通过SkillConfig接口实现了技能属性的标准化管理
|
||||
2. **灵活扩展**:枚举类型和接口设计支持未来功能扩展
|
||||
3. **类型安全**:TypeScript类型系统确保配置的正确性
|
||||
4. **性能优化**:ECS架构和组件化设计提高了系统效率
|
||||
5. **易于维护**:清晰的代码结构和完善的注释便于维护
|
||||
|
||||
通过遵循本文档提供的配置流程和最佳实践,开发者可以快速创建高质量的游戏技能,并确保其在游戏系统中的稳定运行。技能系统的持续优化和完善将为玩家带来更加丰富和有趣的游戏体验。
|
||||
501
.qoder/repowiki/zh/content/英雄系统/英雄属性系统.md
Normal file
501
.qoder/repowiki/zh/content/英雄系统/英雄属性系统.md
Normal file
@@ -0,0 +1,501 @@
|
||||
# 英雄属性系统
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts)
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
英雄属性系统是游戏《heroes》的核心战斗机制之一,负责管理英雄的基础属性、成长属性、动态计算以及战斗中的实时更新。该系统采用模块化设计,通过HeroAttrs.ts定义属性枚举和配置,Hero.ts实现英雄实体管理,HeroViewComp.ts处理属性计算和UI更新,形成了完整的属性管理体系。
|
||||
|
||||
系统支持多种属性类型,包括基础生存属性、攻击属性、防御属性、特殊效果属性等,每种属性都有明确的数值型或百分比型分类。通过Buff系统实现属性的动态叠加和计算,确保战斗中的属性变化能够实时反映在UI界面中。
|
||||
|
||||
## 项目结构
|
||||
|
||||
英雄属性系统的核心文件分布在以下目录结构中:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "属性配置层"
|
||||
A[HeroAttrs.ts<br/>属性枚举与配置]
|
||||
B[heroSet.ts<br/>英雄数据配置]
|
||||
C[GameEvent.ts<br/>事件系统]
|
||||
end
|
||||
subgraph "实体管理层"
|
||||
D[Hero.ts<br/>英雄实体]
|
||||
E[HeroViewComp.ts<br/>视图组件]
|
||||
F[BuffComp.ts<br/>缓冲组件]
|
||||
end
|
||||
subgraph "战斗系统"
|
||||
G[Mon.ts<br/>怪物系统]
|
||||
H[BuffComp.ts<br/>UI组件]
|
||||
end
|
||||
A --> D
|
||||
B --> D
|
||||
C --> E
|
||||
D --> E
|
||||
E --> F
|
||||
G --> E
|
||||
H --> F
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L50)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L1-L30)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L50)
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L546)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L1-L100)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 属性枚举系统
|
||||
|
||||
属性系统定义了完整的属性体系,涵盖战斗中的各个方面:
|
||||
|
||||
| 属性类别 | 属性数量 | 主要功能 | 示例属性 |
|
||||
|---------|---------|---------|---------|
|
||||
| 基础生存属性 | 6 | 生命值、魔法值、护盾 | HP_MAX, MP_MAX, SHIELD_MAX |
|
||||
| 攻击属性 | 6 | 输出能力相关 | AP, MAP, AS, AREA_OF_EFFECT |
|
||||
| 防御属性 | 7 | 防御能力相关 | DEF, MDEF, DODGE, BLOCK |
|
||||
| 暴击与命中 | 5 | 命中率与暴击系统 | CRITICAL, CRITICAL_DMG, HIT |
|
||||
| 特殊效果属性 | 10 | 特殊战斗效果 | LIFESTEAL, FREEZE_CHANCE, BURN_CHANCE |
|
||||
| 增益效果属性 | 10 | 状态增强效果 | BUFF_UP, SPEED, EXP_GAIN |
|
||||
|
||||
### 属性类型系统
|
||||
|
||||
系统区分两种属性类型:
|
||||
- **数值型属性(VALUE)**:直接加减的绝对数值,如攻击力、防御力
|
||||
- **百分比型属性(RATIO)**:按百分比计算的相对数值,如暴击率、闪避率
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L142-L226)
|
||||
|
||||
## 架构概览
|
||||
|
||||
英雄属性系统采用分层架构设计,确保职责分离和模块化:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家操作
|
||||
participant Hero as Hero实体
|
||||
participant View as HeroViewComp
|
||||
participant Buff as Buff系统
|
||||
participant UI as UI组件
|
||||
Player->>Hero : 创建英雄
|
||||
Hero->>View : hero_init()
|
||||
View->>View : 初始化基础属性
|
||||
View->>View : 初始化属性配置
|
||||
View->>Buff : initAttrs()
|
||||
Note over Player,UI : 属性计算流程
|
||||
Player->>Buff : 添加Buff
|
||||
Buff->>View : recalculateSingleAttr()
|
||||
View->>View : 计算属性值
|
||||
View->>UI : 更新UI显示
|
||||
Note over Player,UI : 属性更新流程
|
||||
Player->>Buff : 属性变更
|
||||
Buff->>View : 触发重新计算
|
||||
View->>UI : 实时更新显示
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L65-L99)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L165-L250)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### HeroAttrs.ts - 属性配置核心
|
||||
|
||||
HeroAttrs.ts定义了完整的属性体系和配置机制:
|
||||
|
||||
#### 属性枚举设计
|
||||
|
||||
系统定义了105种属性,按逻辑分组排列:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Attrs {
|
||||
+HP_MAX : 0
|
||||
+MP_MAX : 1
|
||||
+SHIELD_MAX : 2
|
||||
+AP : 10
|
||||
+MAP : 11
|
||||
+DEF : 20
|
||||
+MDEF : 21
|
||||
+CRITICAL : 30
|
||||
+CRITICAL_DMG : 31
|
||||
+LIFESTEAL : 50
|
||||
+SPEED : 63
|
||||
+STRENGTH : 90
|
||||
+INTELLIGENCE : 91
|
||||
+AGILITY : 92
|
||||
+SPIRIT : 93
|
||||
+LUCK : 94
|
||||
}
|
||||
class BType {
|
||||
+VALUE : 0
|
||||
+RATIO : 1
|
||||
}
|
||||
class NeAttrs {
|
||||
+IN_FROST : 0
|
||||
+IN_STUN : 1
|
||||
+IN_BURN : 2
|
||||
+IN_POISON : 3
|
||||
}
|
||||
Attrs --> BType : "类型分类"
|
||||
Attrs --> NeAttrs : "负面状态"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L10-L105)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L8-L10)
|
||||
|
||||
#### 属性类型配置
|
||||
|
||||
系统通过AttrsType配置表明确区分属性类型:
|
||||
|
||||
| 属性类型 | 数值型属性 | 百分比型属性 | 混合型属性 |
|
||||
|---------|-----------|-------------|-----------|
|
||||
| 基础生存 | HP_MAX, MP_MAX, SHIELD_MAX | HEAL_EFFECT | - |
|
||||
| 攻击属性 | AP, MAP, DIS, AREA_OF_EFFECT, PIERCE | AS, SKILL_DURATION | - |
|
||||
| 防御属性 | DEF, MDEF | DODGE, BLOCK, DAMAGE_REDUCTION, THORNS | - |
|
||||
| 特殊效果 | - | LIFESTEAL, MANASTEAL, FREEZE_CHANCE | - |
|
||||
|
||||
#### 职业属性成长系统
|
||||
|
||||
系统实现了基于职业的属性成长机制:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[基础属性输入] --> B{职业类型}
|
||||
B --> |战士| C[战士成长配置]
|
||||
B --> |远程| D[远程成长配置]
|
||||
B --> |法师| E[法师成长配置]
|
||||
B --> |辅助| F[辅助成长配置]
|
||||
B --> |刺客| G[刺客成长配置]
|
||||
C --> H[计算属性增长]
|
||||
D --> H
|
||||
E --> H
|
||||
F --> H
|
||||
G --> H
|
||||
H --> I[返回属性增长值]
|
||||
style A fill:#e1f5fe
|
||||
style I fill:#c8e6c9
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L266-L439)
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L106-L226)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L266-L439)
|
||||
|
||||
### Hero.ts - 英雄实体管理
|
||||
|
||||
Hero.ts负责英雄实体的创建和基础属性初始化:
|
||||
|
||||
#### 英雄初始化流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 客户端
|
||||
participant Hero as Hero实体
|
||||
participant Model as HeroModelComp
|
||||
participant View as HeroViewComp
|
||||
Client->>Hero : load(pos, scale, uuid)
|
||||
Hero->>Hero : 查找空闲槽位
|
||||
Hero->>Hero : 加载英雄预制体
|
||||
Hero->>Hero : 设置位置和缩放
|
||||
Hero->>Hero : hero_init(uuid, node)
|
||||
Hero->>View : 初始化属性配置
|
||||
Hero->>View : 设置基础属性值
|
||||
Hero->>View : 初始化属性系统
|
||||
Hero->>Model : 添加模型组件
|
||||
Hero-->>Client : 英雄加载完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L40-L99)
|
||||
|
||||
#### 基础属性设置
|
||||
|
||||
hero_init方法完成了英雄基础属性的初始化:
|
||||
|
||||
| 属性类型 | 设置方式 | 默认值来源 |
|
||||
|---------|---------|-----------|
|
||||
| 基础属性 | 直接赋值 | HeroInfo配置 |
|
||||
| 属性映射 | getAttrs() | 初始化为0 |
|
||||
| 负面状态 | getNeAttrs() | 初始化为0 |
|
||||
| 技能列表 | 循环遍历 | 技能配置表 |
|
||||
|
||||
**章节来源**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L65-L99)
|
||||
|
||||
### HeroViewComp.ts - 属性计算与UI更新
|
||||
|
||||
HeroViewComp.ts是属性系统的核心计算引擎,负责属性的动态计算和UI更新:
|
||||
|
||||
#### 属性计算算法
|
||||
|
||||
系统实现了复杂的属性计算算法:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[属性计算请求] --> B[获取基础值]
|
||||
B --> C[收集数值型Buff]
|
||||
C --> D[收集百分比型Buff]
|
||||
D --> E{属性类型判断}
|
||||
E --> |百分比型| F[直接相加]
|
||||
E --> |数值型| G[基础值×(1+百分比/100)+数值]
|
||||
F --> H[属性值限制检查]
|
||||
G --> H
|
||||
H --> I{属性值验证}
|
||||
I --> |超出范围| J[调整到合理值]
|
||||
I --> |正常范围| K[更新属性值]
|
||||
J --> K
|
||||
K --> L[触发UI更新]
|
||||
L --> M[完成计算]
|
||||
style A fill:#e3f2fd
|
||||
style M fill:#e8f5e8
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L254-L354)
|
||||
|
||||
#### Buff系统设计
|
||||
|
||||
Buff系统支持持久和临时两种类型的Buff叠加:
|
||||
|
||||
| Buff类型 | 存储位置 | 生命周期 | 计算方式 |
|
||||
|---------|---------|---------|---------|
|
||||
| 持久Buff | BUFFS | 手动清除 | 直接累加 |
|
||||
| 临时Buff | BUFFS_TEMP | 时间到期自动清除 | 时间递减计算 |
|
||||
| 增益Buff | 正数值 | - | 属性提升 |
|
||||
| 减益Buff | 负数值 | - | 属性削弱 |
|
||||
|
||||
#### 属性计算公式
|
||||
|
||||
系统根据不同属性类型采用不同的计算公式:
|
||||
|
||||
**百分比型属性公式**:
|
||||
```
|
||||
最终值 = 基础值 + 所有数值型Buff之和 + 所有百分比Buff之和
|
||||
```
|
||||
|
||||
**数值型属性公式**:
|
||||
```
|
||||
最终值 = (基础值 + 所有数值型Buff之和) × (1 + 所有百分比Buff之和/100)
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L165-L354)
|
||||
|
||||
### BuffComp.ts - UI组件集成
|
||||
|
||||
BuffComp.ts负责将属性变化实时反映到UI界面上:
|
||||
|
||||
#### UI更新机制
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Attr as 属性系统
|
||||
participant View as HeroViewComp
|
||||
participant Buff as BuffComp
|
||||
participant UI as UI组件
|
||||
Attr->>View : 属性值变更
|
||||
View->>View : recalculateSingleAttr()
|
||||
View->>Buff : hp_show/hp_mp_show
|
||||
Buff->>UI : 更新进度条
|
||||
Buff->>UI : 更新标签文本
|
||||
UI->>UI : 动画效果展示
|
||||
Note over Attr,UI : 实时更新流程
|
||||
View->>Buff : show_shield
|
||||
Buff->>UI : 更新护盾显示
|
||||
UI->>UI : 护盾动画效果
|
||||
Note over Attr,UI : 护盾更新流程
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L44-L80)
|
||||
|
||||
#### UI组件类型
|
||||
|
||||
BuffComp管理多种UI组件:
|
||||
|
||||
| UI组件 | 功能 | 更新触发 |
|
||||
|-------|------|---------|
|
||||
| 血条 | 显示生命值 | hp_show |
|
||||
| 能量条 | 显示魔法值 | mp_show |
|
||||
| 护盾条 | 显示护盾值 | show_shield |
|
||||
| 提示框 | 显示伤害数字 | tooltip |
|
||||
| 状态图标 | 显示负面状态 | 状态切换 |
|
||||
|
||||
**章节来源**
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L1-L80)
|
||||
|
||||
### Mon.ts - 怪物属性系统
|
||||
|
||||
Mon.ts继承了英雄的属性系统,但针对怪物进行了优化:
|
||||
|
||||
#### 怪物属性特点
|
||||
|
||||
| 属性类型 | 英雄 vs 怪物 | 设计差异 |
|
||||
|---------|-------------|---------|
|
||||
| 基础属性 | 多样化配置 | 固定基础值 |
|
||||
| 成长属性 | 动态计算 | 预设固定值 |
|
||||
| Buff系统 | 复杂计算 | 简化处理 |
|
||||
| UI更新 | 实时同步 | 基础显示 |
|
||||
|
||||
**章节来源**
|
||||
- [Mon.ts](file://assets/script/game/hero/Mon.ts#L87-L108)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
英雄属性系统的依赖关系体现了清晰的分层架构:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
A[HeroAttrs.ts]
|
||||
B[heroSet.ts]
|
||||
C[GameEvent.ts]
|
||||
end
|
||||
subgraph "实体层"
|
||||
D[Hero.ts]
|
||||
E[HeroViewComp.ts]
|
||||
F[BuffComp.ts]
|
||||
end
|
||||
subgraph "战斗层"
|
||||
G[Mon.ts]
|
||||
H[战斗系统]
|
||||
end
|
||||
A --> D
|
||||
A --> E
|
||||
B --> D
|
||||
C --> E
|
||||
D --> E
|
||||
E --> F
|
||||
G --> E
|
||||
H --> E
|
||||
style A fill:#e3f2fd
|
||||
style D fill:#f3e5f5
|
||||
style E fill:#e8f5e8
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L20)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L1-L20)
|
||||
|
||||
### 模块间通信
|
||||
|
||||
系统通过事件机制实现模块间的松耦合通信:
|
||||
|
||||
| 通信方式 | 使用场景 | 实现方式 |
|
||||
|---------|---------|---------|
|
||||
| 直接调用 | 属性计算 | 方法调用 |
|
||||
| 事件分发 | 状态同步 | GameEvent |
|
||||
| UI更新 | 实时反馈 | 组件回调 |
|
||||
| 数据绑定 | 状态管理 | MVVM模式 |
|
||||
|
||||
**章节来源**
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 属性计算优化
|
||||
|
||||
系统采用了多种性能优化策略:
|
||||
|
||||
1. **延迟计算**:只有在属性值发生变化时才重新计算
|
||||
2. **批量更新**:同一帧内的多个属性变更只触发一次UI更新
|
||||
3. **缓存机制**:缓存常用的属性计算结果
|
||||
4. **增量更新**:只更新受影响的属性,而不是全部重新计算
|
||||
|
||||
### 内存管理
|
||||
|
||||
- 使用对象池管理Buff实例
|
||||
- 及时清理过期的临时Buff
|
||||
- 避免频繁的属性值分配和回收
|
||||
|
||||
### UI渲染优化
|
||||
|
||||
- 使用Tween动画实现平滑的属性变化
|
||||
- 批量更新UI组件,减少重绘次数
|
||||
- 使用可视区域裁剪避免不必要的渲染
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题及解决方案
|
||||
|
||||
#### 属性计算异常
|
||||
|
||||
**问题现象**:属性值显示不正确或计算错误
|
||||
**可能原因**:
|
||||
- Buff配置错误
|
||||
- 属性类型判断失误
|
||||
- 基础值设置错误
|
||||
|
||||
**解决步骤**:
|
||||
1. 检查HeroAttrs.ts中的属性类型配置
|
||||
2. 验证Buff的BType设置
|
||||
3. 确认基础属性值的正确性
|
||||
|
||||
#### UI更新延迟
|
||||
|
||||
**问题现象**:属性变化后UI没有及时更新
|
||||
**可能原因**:
|
||||
- UI更新频率不足
|
||||
- 属性变更事件未正确触发
|
||||
- 组件生命周期问题
|
||||
|
||||
**解决步骤**:
|
||||
1. 检查update方法中的UI更新逻辑
|
||||
2. 验证属性变更事件的分发
|
||||
3. 确认组件的生命周期状态
|
||||
|
||||
#### 性能问题
|
||||
|
||||
**问题现象**:大量英雄同时战斗时出现卡顿
|
||||
**可能原因**:
|
||||
- 属性计算过于频繁
|
||||
- UI更新过于密集
|
||||
- 内存泄漏
|
||||
|
||||
**解决步骤**:
|
||||
1. 优化属性计算的频率
|
||||
2. 实施属性变更的批量处理
|
||||
3. 检查内存使用情况
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L385-L425)
|
||||
|
||||
## 结论
|
||||
|
||||
英雄属性系统通过精心设计的分层架构,实现了复杂而高效的属性管理机制。系统的主要优势包括:
|
||||
|
||||
1. **模块化设计**:清晰的职责分离使得系统易于维护和扩展
|
||||
2. **灵活的属性类型**:支持数值型和百分比型属性的混合计算
|
||||
3. **强大的Buff系统**:支持持久和临时Buff的叠加计算
|
||||
4. **实时UI同步**:确保属性变化能够即时反映在用户界面上
|
||||
5. **性能优化**:通过多种优化策略保证系统的流畅运行
|
||||
|
||||
该系统为游戏提供了坚实的战斗基础,支持丰富的角色定制和战斗策略,是整个游戏体验的重要组成部分。随着游戏的发展,这套属性系统已经证明了其良好的扩展性和稳定性,能够适应未来更多的功能需求。
|
||||
594
.qoder/repowiki/zh/content/英雄系统/英雄系统.md
Normal file
594
.qoder/repowiki/zh/content/英雄系统/英雄系统.md
Normal file
@@ -0,0 +1,594 @@
|
||||
# 英雄系统
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts)
|
||||
- [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [系统架构概览](#系统架构概览)
|
||||
3. [英雄属性系统](#英雄属性系统)
|
||||
4. [技能系统](#技能系统)
|
||||
5. [天赋系统](#天赋系统)
|
||||
6. [状态管理系统](#状态管理系统)
|
||||
7. [组件间通信机制](#组件间通信机制)
|
||||
8. [关键功能实现](#关键功能实现)
|
||||
9. [性能优化考虑](#性能优化考虑)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
英雄系统是游戏的核心战斗机制,负责管理英雄的属性、技能、天赋和状态。本系统采用模块化设计,通过ECS架构实现组件间的松耦合通信,支持复杂的战斗逻辑和动态效果管理。
|
||||
|
||||
## 系统架构概览
|
||||
|
||||
英雄系统采用分层架构设计,主要包含以下核心层次:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "表现层"
|
||||
HV[HeroViewComp<br/>英雄视图组件]
|
||||
BC[BuffComp<br/>状态显示组件]
|
||||
end
|
||||
subgraph "控制层"
|
||||
HC[Hero<br/>英雄实体]
|
||||
SC[SkillConComp<br/>技能控制组件]
|
||||
TC[TalComp<br/>天赋控制组件]
|
||||
end
|
||||
subgraph "配置层"
|
||||
HA[HeroAttrs<br/>属性配置]
|
||||
SS[SkillSet<br/>技能配置]
|
||||
TS[TalSet<br/>天赋配置]
|
||||
end
|
||||
subgraph "数据层"
|
||||
HM[HeroModelComp<br/>模型数据]
|
||||
MM[MonModelComp<br/>怪物数据]
|
||||
end
|
||||
HC --> HV
|
||||
HC --> HM
|
||||
SC --> HV
|
||||
TC --> HV
|
||||
HV --> BC
|
||||
HV --> HA
|
||||
SC --> SS
|
||||
TC --> TS
|
||||
HV --> MM
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L1-L100)
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L100)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L50)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L1-L50)
|
||||
|
||||
## 英雄属性系统
|
||||
|
||||
### 属性枚举与分类
|
||||
|
||||
英雄属性系统定义了完整的战斗属性体系,按照功能分为多个类别:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Attrs {
|
||||
<<enumeration>>
|
||||
+HP_MAX : 0
|
||||
+MP_MAX : 1
|
||||
+SHIELD_MAX : 2
|
||||
+HP_REGEN : 3
|
||||
+MP_REGEN : 4
|
||||
+AP : 10
|
||||
+MAP : 11
|
||||
+DEF : 20
|
||||
+MDEF : 21
|
||||
+CRITICAL : 30
|
||||
+CRITICAL_DMG : 31
|
||||
+SPEED : 63
|
||||
+EXP_GAIN : 64
|
||||
+STRENGTH : 90
|
||||
+INTELLIGENCE : 91
|
||||
+AGILITY : 92
|
||||
+SPIRIT : 93
|
||||
+LUCK : 94
|
||||
}
|
||||
class BType {
|
||||
<<enumeration>>
|
||||
+VALUE : 0
|
||||
+RATIO : 1
|
||||
}
|
||||
class HeroAttrs {
|
||||
+getAttrs() Object
|
||||
+isRatioAttr(attrType) boolean
|
||||
+calculateAttributeGains() Object
|
||||
+addStrength() Object
|
||||
+addIntelligence() Object
|
||||
+addAgility() Object
|
||||
+addSpirit() Object
|
||||
+addLuck() Object
|
||||
}
|
||||
HeroAttrs --> Attrs
|
||||
HeroAttrs --> BType
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L15-L100)
|
||||
|
||||
### 属性类型配置
|
||||
|
||||
系统通过 `AttrsType` 配置表区分属性的计算方式:
|
||||
|
||||
| 属性类型 | 计算方式 | 示例属性 |
|
||||
|---------|---------|---------|
|
||||
| 数值型 | 直接相加 | HP_MAX, AP, DEF |
|
||||
| 百分比型 | 基础值×(1+百分比/100) | CRITICAL, SPEED, BUFF_UP |
|
||||
|
||||
### 职业属性成长系统
|
||||
|
||||
不同职业具有独特的属性成长曲线:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[基础属性输入] --> B{职业类型}
|
||||
B --> |战士| C[力量→HP_MAX:3, AP:1.5, DEF:0.8]
|
||||
B --> |远程| D[敏捷→CRITICAL:0.8, DODGE:0.6, AS:0.5]
|
||||
B --> |法师| E[智力→MP_MAX:2, MAP:1.8, MDEF:0.8]
|
||||
B --> |辅助| F[精神→MP_MAX:2, CON_RES:0.5, BUFF_UP:0.6]
|
||||
B --> |刺客| G[敏捷→CRITICAL:1, DODGE:0.8, AS:0.6]
|
||||
C --> H[属性增长计算]
|
||||
D --> H
|
||||
E --> H
|
||||
F --> H
|
||||
G --> H
|
||||
H --> I[最终属性值]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L200-L400)
|
||||
|
||||
**章节来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L1-L546)
|
||||
|
||||
## 技能系统
|
||||
|
||||
### 技能配置结构
|
||||
|
||||
技能系统提供了完整的技能数据定义框架:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SkillConfig {
|
||||
+uuid : number
|
||||
+name : string
|
||||
+TGroup : TGroup
|
||||
+SType : SType
|
||||
+DTType : DTType
|
||||
+DType : DType
|
||||
+ap : number
|
||||
+cd : number
|
||||
+cost : number
|
||||
+speed : number
|
||||
+buffs : BuffConf[]
|
||||
+neAttrs : NeAttrsConf[]
|
||||
+info : string
|
||||
}
|
||||
class TGroup {
|
||||
<<enumeration>>
|
||||
+Self : 0
|
||||
+Ally : 1
|
||||
+Team : 2
|
||||
+Enemy : 3
|
||||
+All : 4
|
||||
}
|
||||
class SType {
|
||||
<<enumeration>>
|
||||
+damage : 0
|
||||
+heal : 1
|
||||
+shield : 2
|
||||
+buff : 11
|
||||
}
|
||||
class BuffConf {
|
||||
+buff : Attrs
|
||||
+BType : BType
|
||||
+value : number
|
||||
+time : number
|
||||
+chance : number
|
||||
}
|
||||
SkillConfig --> TGroup
|
||||
SkillConfig --> SType
|
||||
SkillConfig --> BuffConf
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L80-L148)
|
||||
|
||||
### 技能控制逻辑
|
||||
|
||||
技能释放遵循严格的时序控制:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家输入
|
||||
participant SC as SkillConComp
|
||||
participant HV as HeroViewComp
|
||||
participant SE as SkillEnt
|
||||
participant Target as 目标实体
|
||||
Player->>SC : 技能冷却完成
|
||||
SC->>SC : 检查英雄状态
|
||||
SC->>HV : 选择目标
|
||||
HV-->>SC : 返回目标坐标
|
||||
SC->>HV : 播放技能特效
|
||||
SC->>SE : 创建技能实体
|
||||
SE->>Target : 执行伤害/效果
|
||||
Target-->>SE : 反馈结果
|
||||
SE-->>HV : 更新状态
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L50-L120)
|
||||
|
||||
### 目标选择算法
|
||||
|
||||
系统实现了智能的目标选择机制:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始目标选择] --> B[获取敌方实体列表]
|
||||
B --> C{是否有目标?}
|
||||
C --> |否| D[返回默认位置]
|
||||
C --> |是| E[确定最前排目标]
|
||||
E --> F[添加最前排为目标]
|
||||
F --> G[随机选择剩余目标]
|
||||
G --> H[返回目标坐标数组]
|
||||
D --> I[结束]
|
||||
H --> I
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L130-L170)
|
||||
|
||||
**章节来源**
|
||||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts#L1-L148)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L177)
|
||||
|
||||
## 天赋系统
|
||||
|
||||
### 天赋类型与触发机制
|
||||
|
||||
天赋系统支持多种触发条件和效果类型:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class TalType {
|
||||
<<enumeration>>
|
||||
+LEVEL : 1
|
||||
+LEVEL_UP : 2
|
||||
+ACTION_COUNT : 3
|
||||
+SKILL_COUNT : 4
|
||||
+DAMAGE_COUNT : 5
|
||||
+INIT : 6
|
||||
+DEAD : 7
|
||||
}
|
||||
class TalEType {
|
||||
<<enumeration>>
|
||||
+ATTRS : 1
|
||||
+SKILL : 2
|
||||
+SKILL_MORE : 3
|
||||
}
|
||||
class ItalConf {
|
||||
+uuid : number
|
||||
+name : string
|
||||
+desc : string
|
||||
+type : TalType
|
||||
+triggerType : TalEType
|
||||
+chance : number
|
||||
+t_value : number
|
||||
+e_value : number
|
||||
+e_name : number
|
||||
+e_type : BType
|
||||
+e_scaling : number
|
||||
+e_count : number
|
||||
+stackable : boolean
|
||||
+maxStack : number
|
||||
}
|
||||
class FightStats {
|
||||
+aCount : number
|
||||
+sCount : number
|
||||
+dCount : number
|
||||
+level : number
|
||||
}
|
||||
ItalConf --> TalType
|
||||
ItalConf --> TalEType
|
||||
TalComp --> FightStats
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts#L10-L50)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L15-L40)
|
||||
|
||||
### 天赋触发流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[事件发生] --> B{事件类型}
|
||||
B --> |等级提升| C[更新FStats.level]
|
||||
B --> |普通攻击| D[更新aCount]
|
||||
B --> |技能使用| E[更新sCount]
|
||||
B --> |受到伤害| F[更新dCount]
|
||||
C --> G[检查LEVEL天赋]
|
||||
D --> H[检查ACTION_COUNT天赋]
|
||||
E --> I[检查SKILL_COUNT天赋]
|
||||
F --> J[检查DAMAGE_COUNT天赋]
|
||||
G --> K{满足触发条件?}
|
||||
H --> K
|
||||
I --> K
|
||||
J --> K
|
||||
K --> |是| L[执行天赋效果]
|
||||
K --> |否| M[等待下次检查]
|
||||
L --> N[应用属性增益]
|
||||
L --> O[触发技能]
|
||||
L --> P[增加技能数量]
|
||||
N --> Q[重新计算属性]
|
||||
O --> R[技能释放]
|
||||
P --> S[技能列表更新]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L120-L170)
|
||||
|
||||
**章节来源**
|
||||
- [TalSet.ts](file://assets/script/game/common/config/TalSet.ts#L1-L116)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L1-L171)
|
||||
|
||||
## 状态管理系统
|
||||
|
||||
### Buff/Debuff系统架构
|
||||
|
||||
状态管理系统实现了完整的增益/减益效果管理:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class HeroViewComp {
|
||||
+BUFFS : Record~number, Array~
|
||||
+BUFFS_TEMP : Record~number, Array~
|
||||
+NeAttrs : Record~number, Object~
|
||||
+addBuff(buffConf) void
|
||||
+removeBuff(attrIndex, value, isPermanent) void
|
||||
+clearBuffs(attrIndex, isBuff) void
|
||||
+recalculateSingleAttr(attrIndex) void
|
||||
+updateTemporaryBuffsDebuffs(dt) void
|
||||
}
|
||||
class BuffInfo {
|
||||
+attr : Attrs
|
||||
+value : number
|
||||
+remainTime : number
|
||||
}
|
||||
class NeAttrs {
|
||||
+IN_FROST : 0
|
||||
+IN_STUN : 1
|
||||
+IN_BURN : 2
|
||||
+IN_POISON : 3
|
||||
}
|
||||
HeroViewComp --> BuffInfo
|
||||
HeroViewComp --> NeAttrs
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L80-L120)
|
||||
|
||||
### 属性计算公式
|
||||
|
||||
系统采用复合计算公式处理不同类型的属性:
|
||||
|
||||
| 属性类型 | 计算公式 | 说明 |
|
||||
|---------|---------|------|
|
||||
| 数值型 | `(基础值 + 所有数值型buff之和) × (1 + 所有百分比buff之和/100)` | 攻击力、防御力等 |
|
||||
| 百分比型 | `基础值 + 所有数值型buff之和 + 所有百分比buff之和` | 暴击率、闪避率等 |
|
||||
|
||||
### 状态更新机制
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Game as 游戏循环
|
||||
participant HV as HeroViewComp
|
||||
participant Buff as Buff系统
|
||||
participant Attr as 属性计算
|
||||
Game->>HV : update(dt)
|
||||
HV->>Buff : updateTemporaryBuffsDebuffs(dt)
|
||||
Buff->>Buff : 减少剩余时间
|
||||
Buff->>Buff : 移除过期buff
|
||||
Buff->>Attr : recalculateSingleAttr()
|
||||
Attr->>Attr : 重新计算属性值
|
||||
Attr-->>HV : 更新后的属性
|
||||
HV->>HV : clampSingleAttr()
|
||||
HV-->>Game : 状态更新完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L400-L500)
|
||||
|
||||
**章节来源**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L780)
|
||||
- [BuffComp.ts](file://assets/script/game/hero/BuffComp.ts#L1-L213)
|
||||
|
||||
## 组件间通信机制
|
||||
|
||||
### ECS架构下的组件交互
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "英雄实体"
|
||||
E[Hero实体]
|
||||
HV[HeroViewComp]
|
||||
HC[HeroConComp]
|
||||
BM[BattleMoveComp]
|
||||
end
|
||||
subgraph "技能系统"
|
||||
SC[SkillConComp]
|
||||
SE[SkillEnt]
|
||||
end
|
||||
subgraph "状态系统"
|
||||
BC[BuffComp]
|
||||
TC[TalComp]
|
||||
end
|
||||
E --> HV
|
||||
E --> HC
|
||||
E --> BM
|
||||
HC --> SC
|
||||
SC --> SE
|
||||
HV --> BC
|
||||
HV --> TC
|
||||
TC --> HV
|
||||
SC --> HV
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L15-L35)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L15-L30)
|
||||
|
||||
### 事件驱动通信
|
||||
|
||||
系统通过事件机制实现组件间的解耦通信:
|
||||
|
||||
| 事件类型 | 发送者 | 接收者 | 用途 |
|
||||
|---------|-------|-------|------|
|
||||
| GameEvent.MasterCalled | Hero | Talent系统 | 英雄召唤事件 |
|
||||
| GameEvent.CastHeroSkill | SkillCon | 其他组件 | 技能释放通知 |
|
||||
| GameEvent.FightEnd | Battle | 所有组件 | 战斗结束事件 |
|
||||
| GameEvent.HeroDead | HeroView | Talent系统 | 英雄死亡事件 |
|
||||
|
||||
**章节来源**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L1-L100)
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L50)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L1-L50)
|
||||
|
||||
## 关键功能实现
|
||||
|
||||
### 技能释放流程
|
||||
|
||||
技能释放是英雄系统的核心功能,涉及多个组件的协调工作:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[玩家输入技能] --> B[SkillConComp接收]
|
||||
B --> C{英雄状态检查}
|
||||
C --> |眩晕/冰冻| D[阻止技能释放]
|
||||
C --> |正常状态| E[检查冷却时间]
|
||||
E --> |冷却完成| F[检查魔法值]
|
||||
F --> |魔法值充足| G[选择目标]
|
||||
F --> |魔法值不足| H[显示提示]
|
||||
G --> I[播放技能特效]
|
||||
I --> J[创建技能实体]
|
||||
J --> K[执行伤害计算]
|
||||
K --> L[应用Buff效果]
|
||||
L --> M[更新英雄状态]
|
||||
D --> N[技能释放失败]
|
||||
H --> N
|
||||
M --> O[技能释放成功]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L50-L100)
|
||||
|
||||
### 属性升级系统
|
||||
|
||||
属性升级通过职业成长配置实现:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[属性点分配] --> B{职业类型}
|
||||
B --> |力量| C[addStrength函数]
|
||||
B --> |智力| D[addIntelligence函数]
|
||||
B --> |敏捷| E[addAgility函数]
|
||||
B --> |精神| F[addSpirit函数]
|
||||
B --> |幸运| G[addLuck函数]
|
||||
C --> H[计算力量成长]
|
||||
D --> I[计算智力成长]
|
||||
E --> J[计算敏捷成长]
|
||||
F --> K[计算精神成长]
|
||||
G --> L[计算幸运成长]
|
||||
H --> M[应用到属性]
|
||||
I --> M
|
||||
J --> M
|
||||
K --> M
|
||||
L --> M
|
||||
M --> N[重新计算所有属性]
|
||||
N --> O[更新显示]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L500-L546)
|
||||
|
||||
### 天赋触发机制
|
||||
|
||||
天赋系统实现了复杂的触发逻辑:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[事件触发] --> B[更新统计数据]
|
||||
B --> C[遍历天赋配置]
|
||||
C --> D{检查触发条件}
|
||||
D --> |满足| E[计算触发概率]
|
||||
D --> |不满足| F[跳过此天赋]
|
||||
E --> |触发| G[执行天赋效果]
|
||||
E --> |不触发| F
|
||||
G --> H{效果类型}
|
||||
H --> |属性增益| I[添加Buff]
|
||||
H --> |技能触发| J[释放技能]
|
||||
H --> |技能增加| K[增加技能列表]
|
||||
I --> L[重新计算属性]
|
||||
J --> M[技能执行]
|
||||
K --> N[技能可用]
|
||||
L --> O[更新界面]
|
||||
M --> O
|
||||
N --> O
|
||||
F --> P[检查下一个天赋]
|
||||
P --> C
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L100-L170)
|
||||
|
||||
**章节来源**
|
||||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L50-L177)
|
||||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L500-L546)
|
||||
- [TalComp.ts](file://assets/script/game/hero/TalComp.ts#L100-L171)
|
||||
|
||||
## 性能优化考虑
|
||||
|
||||
### 内存管理优化
|
||||
|
||||
1. **对象池化**: 技能实体和伤害数字使用对象池减少GC压力
|
||||
2. **延迟加载**: 天赋效果按需计算,避免不必要的属性重计算
|
||||
3. **弱引用**: 避免组件间的强引用导致内存泄漏
|
||||
|
||||
### 计算优化
|
||||
|
||||
1. **增量计算**: 只重新计算受影响的属性,而不是全部属性
|
||||
2. **缓存机制**: 缓存属性计算结果,避免重复计算
|
||||
3. **批量更新**: 在同一帧内批量处理多个状态变化
|
||||
|
||||
### 渲染优化
|
||||
|
||||
1. **状态显示**: BuffComp只更新可见的状态信息
|
||||
2. **特效管理**: 技能特效使用预制体池,避免频繁创建销毁
|
||||
3. **层级管理**: 合理管理UI层级,减少渲染开销
|
||||
|
||||
## 总结
|
||||
|
||||
英雄系统通过模块化设计和ECS架构实现了高度可扩展和可维护的战斗机制。系统的主要特点包括:
|
||||
|
||||
1. **完整的属性体系**: 支持数值型和百分比型属性的灵活组合
|
||||
2. **智能技能管理**: 提供丰富的技能配置选项和自动化的目标选择
|
||||
3. **动态天赋系统**: 支持多种触发条件和效果类型的天赋配置
|
||||
4. **高效状态管理**: 实现了完整的Buff/Debuff生命周期管理
|
||||
5. **松耦合架构**: 通过ECS和事件机制实现组件间的解耦通信
|
||||
|
||||
该系统为游戏提供了坚实的战斗基础,支持复杂的游戏玩法和深度的角色养成体验。通过合理的架构设计和性能优化,确保了系统的稳定性和可扩展性。
|
||||
521
.qoder/repowiki/zh/content/辅助系统/新手引导系统.md
Normal file
521
.qoder/repowiki/zh/content/辅助系统/新手引导系统.md
Normal file
@@ -0,0 +1,521 @@
|
||||
# 新手引导系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts)
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts)
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [guide_step.prefab](file://assets/resources/gui/element/guide_step.prefab)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [系统架构](#系统架构)
|
||||
3. [核心数据结构](#核心数据结构)
|
||||
4. [引导配置管理](#引导配置管理)
|
||||
5. [引导流程控制](#引导流程控制)
|
||||
6. [UI高亮与交互](#ui高亮与交互)
|
||||
7. [事件监听与进度管理](#事件监听与进度管理)
|
||||
8. [与Oops GUI系统集成](#与oops-gui系统集成)
|
||||
9. [实际应用示例](#实际应用示例)
|
||||
10. [跳过逻辑与资源清理](#跳过逻辑与资源清理)
|
||||
11. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
新手引导系统是游戏中的重要组成部分,用于指导新玩家了解游戏的基本操作和核心玩法。本系统基于Oops框架构建,采用组件化设计,支持多种引导类型,具备完善的进度管理和事件驱动机制。
|
||||
|
||||
系统的主要特点包括:
|
||||
- 支持点击、拖拽、提示、等待等多种引导类型
|
||||
- 基于事件驱动的触发机制
|
||||
- 完善的进度跟踪和状态管理
|
||||
- 与Oops GUI系统的深度集成
|
||||
- 可扩展的配置化引导方案
|
||||
|
||||
## 系统架构
|
||||
|
||||
新手引导系统采用分层架构设计,包含配置层、控制层和UI层三个主要部分:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
GC[GuideConfig<br/>引导配置]
|
||||
GEC[EndEventToKey<br/>事件映射]
|
||||
GT[GuideTypes<br/>引导类型]
|
||||
end
|
||||
subgraph "控制层"
|
||||
GCC[GuideConComp<br/>引导控制器]
|
||||
SM[SingletonModule<br/>单例模块]
|
||||
GE[GameEvent<br/>游戏事件]
|
||||
end
|
||||
subgraph "UI层"
|
||||
GSC[GuideSetpComp<br/>引导步骤UI]
|
||||
GUI[Oops GUI<br/>界面管理]
|
||||
GS[Guide Step<br/>引导步骤]
|
||||
end
|
||||
subgraph "资源层"
|
||||
PREFAB[guide_step.prefab<br/>引导UI预制体]
|
||||
CONFIG[GameUIConfig<br/>UI配置]
|
||||
end
|
||||
GC --> GCC
|
||||
GEC --> GCC
|
||||
GT --> GCC
|
||||
GCC --> GSC
|
||||
SM --> GCC
|
||||
GE --> GCC
|
||||
GSC --> GUI
|
||||
GUI --> GS
|
||||
PREFAB --> GSC
|
||||
CONFIG --> GUI
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L1-L283)
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L1-L220)
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L1-L268)
|
||||
|
||||
## 核心数据结构
|
||||
|
||||
### 引导步骤类型枚举
|
||||
|
||||
系统定义了四种基本的引导步骤类型:
|
||||
|
||||
| 类型 | 枚举值 | 描述 | 适用场景 |
|
||||
|------|--------|------|----------|
|
||||
| 点击操作 | `CLICK` | 用户需要点击目标节点 | 按钮激活、功能解锁 |
|
||||
| 拖拽操作 | `DRAG` | 用户需要拖拽目标节点 | 物品移动、场景探索 |
|
||||
| 显示提示 | `TIP` | 显示文字提示信息 | 游戏说明、规则介绍 |
|
||||
| 等待操作 | `WAIT` | 等待特定时间或条件 | 动画播放、效果展示 |
|
||||
|
||||
### 引导步骤配置接口
|
||||
|
||||
每个引导步骤都遵循统一的配置接口规范:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class IGuideStep {
|
||||
+string id
|
||||
+GuideStepType type
|
||||
+number key
|
||||
+string targetPath
|
||||
+string tipParent
|
||||
+string tipText
|
||||
+Vec2 tipOffset
|
||||
+Vec2 handOffset
|
||||
+string nextStep
|
||||
+boolean skippable
|
||||
+function condition
|
||||
+UIID uiId
|
||||
+number waitTime
|
||||
+string end_event
|
||||
+boolean noInput
|
||||
}
|
||||
class GuideStepType {
|
||||
<<enumeration>>
|
||||
CLICK
|
||||
DRAG
|
||||
TIP
|
||||
WAIT
|
||||
}
|
||||
class UIID {
|
||||
<<enumeration>>
|
||||
Guide = 1001
|
||||
}
|
||||
IGuideStep --> GuideStepType
|
||||
IGuideStep --> UIID
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L25-L50)
|
||||
|
||||
**章节来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L1-L283)
|
||||
|
||||
## 引导配置管理
|
||||
|
||||
### 引导配置数据结构
|
||||
|
||||
引导系统采用数字ID与字符串ID双重索引的方式管理引导配置:
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
GuideConfig {
|
||||
number key PK
|
||||
string id UK
|
||||
GuideStepType type
|
||||
number target_key
|
||||
string target_path
|
||||
string tip_text
|
||||
vec2 hand_offset
|
||||
string next_step
|
||||
number wait_time
|
||||
string end_event
|
||||
boolean skippable
|
||||
}
|
||||
EndEventToKey {
|
||||
string end_event PK
|
||||
array guide_keys
|
||||
}
|
||||
SingletonModule {
|
||||
array guides
|
||||
number current_guide
|
||||
}
|
||||
GuideConfig ||--o{ EndEventToKey : "maps to"
|
||||
SingletonModule ||--o{ GuideConfig : "tracks progress"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L52-L120)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L35-L40)
|
||||
|
||||
### 引导配置示例
|
||||
|
||||
系统提供了完整的三步引导示例,展示了不同类型引导的实际应用场景:
|
||||
|
||||
| 步骤ID | 类型 | 目标路径 | 提示文本 | 手指偏移 |
|
||||
|--------|------|----------|----------|----------|
|
||||
| welcome | WAIT | root/gui/LayerUI/role_controller/mission_home/start/name | "伟大的勇者,欢迎来到 『像素模拟战』" | {42, -45} |
|
||||
| start_battle | CLICK | root/gui/LayerUI/role_controller/mission_home/start/name | "请带领您的英雄抵御兽人的入侵吧!" | {42, -45} |
|
||||
| hero_page | CLICK | root/gui/LayerUI/role_controller/mission_home/btns/heros | "在酒馆招募更多英雄增强队伍" | {42, -45} |
|
||||
|
||||
**章节来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L52-L120)
|
||||
|
||||
## 引导流程控制
|
||||
|
||||
### 引导控制器架构
|
||||
|
||||
引导控制器负责整个引导流程的协调和管理:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家
|
||||
participant GCC as GuideConComp
|
||||
participant SM as SingletonModule
|
||||
participant GSC as GuideSetpComp
|
||||
participant GUI as Oops GUI
|
||||
Player->>GCC : 触发引导事件
|
||||
GCC->>GCC : 验证引导权限
|
||||
GCC->>GSC : 创建引导步骤UI
|
||||
GSC->>GUI : 打开引导界面
|
||||
GUI-->>GSC : UI加载完成
|
||||
GSC->>GSC : 显示引导内容
|
||||
Player->>GSC : 完成引导操作
|
||||
GSC->>GCC : 步骤完成回调
|
||||
GCC->>GCC : 检查下一步骤
|
||||
GCC->>GSC : 启动下一引导
|
||||
Note over GCC,GSC : 循环直到引导完成
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L40-L80)
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L80-L120)
|
||||
|
||||
### 引导启动机制
|
||||
|
||||
引导系统采用事件驱动的启动方式,支持多种触发条件:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([引导启动请求]) --> CheckPermission{检查权限}
|
||||
CheckPermission --> |权限不足| ReturnError[返回错误]
|
||||
CheckPermission --> |权限充足| GetGuide[获取引导配置]
|
||||
GetGuide --> ValidateConfig{验证配置}
|
||||
ValidateConfig --> |配置无效| ReturnError
|
||||
ValidateConfig --> |配置有效| ClosePrevious[关闭之前引导]
|
||||
ClosePrevious --> OpenUI[打开引导UI]
|
||||
OpenUI --> ShowStep[显示引导步骤]
|
||||
ShowStep --> WaitInput[等待用户输入]
|
||||
WaitInput --> CompleteStep[完成步骤]
|
||||
CompleteStep --> CheckNext{是否有下一步}
|
||||
CheckNext --> |有| StartNext[启动下一引导]
|
||||
CheckNext --> |无| CompleteGuide[完成引导]
|
||||
StartNext --> ShowStep
|
||||
CompleteGuide --> End([引导结束])
|
||||
ReturnError --> End
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L50-L90)
|
||||
|
||||
**章节来源**
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L1-L220)
|
||||
|
||||
## UI高亮与交互
|
||||
|
||||
### 引导步骤UI组件
|
||||
|
||||
引导步骤UI组件负责显示引导内容和处理用户交互:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class GuideSetpComp {
|
||||
+Label tipLabel
|
||||
+Node tipNode
|
||||
+Node handNode
|
||||
+Button skipButton
|
||||
-IGuideStep currentStep
|
||||
-number currentStepIndex
|
||||
-number totalSteps
|
||||
-Node _targetNode
|
||||
-Node _tipParent
|
||||
-boolean _showTip
|
||||
-boolean _showHand
|
||||
-any _callback
|
||||
-boolean _noInput
|
||||
-boolean _hasTouchListener
|
||||
+onAdded(args) void
|
||||
+handleStepInfo(data) void
|
||||
+findTargetNode(path) Node
|
||||
+showStep(step, index, total) void
|
||||
+onTouchStart(event) void
|
||||
+addTouchListener() void
|
||||
+removeTouchListener() void
|
||||
+onSkipButtonClick() void
|
||||
+cleanup() void
|
||||
}
|
||||
class GuideStepType {
|
||||
<<enumeration>>
|
||||
CLICK
|
||||
DRAG
|
||||
TIP
|
||||
WAIT
|
||||
}
|
||||
GuideSetpComp --> GuideStepType
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L10-L50)
|
||||
|
||||
### 目标节点查找机制
|
||||
|
||||
系统提供了灵活的目标节点查找机制,支持相对路径和绝对路径两种方式:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始查找目标节点]) --> SplitPath[分割路径字符串]
|
||||
SplitPath --> GetScene[获取场景根节点]
|
||||
GetScene --> LoopPath{遍历路径段}
|
||||
LoopPath --> |路径段存在| GetChild[获取子节点]
|
||||
LoopPath --> |路径段不存在| NotFound[节点未找到]
|
||||
GetChild --> CheckChild{检查子节点}
|
||||
CheckChild --> |找到| NextSegment[下一段]
|
||||
CheckChild --> |未找到| NotFound
|
||||
NextSegment --> MoreSegments{还有更多段?}
|
||||
MoreSegments --> |是| LoopPath
|
||||
MoreSegments --> |否| Found[节点找到]
|
||||
NotFound --> LogError[记录错误日志]
|
||||
Found --> ReturnNode[返回节点对象]
|
||||
LogError --> ReturnNull[返回null]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L180-L220)
|
||||
|
||||
**章节来源**
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L1-L268)
|
||||
|
||||
## 事件监听与进度管理
|
||||
|
||||
### 事件监听机制
|
||||
|
||||
引导系统实现了完善的事件监听机制,支持多种交互方式:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant GSC as GuideSetpComp
|
||||
participant Node as UI节点
|
||||
participant Touch as 触摸系统
|
||||
participant Callback as 回调函数
|
||||
GSC->>Node : 添加触摸监听器
|
||||
Node->>Touch : 注册事件监听
|
||||
Touch-->>Node : 触摸事件发生
|
||||
Node->>GSC : 触摸事件回调
|
||||
GSC->>GSC : 验证引导类型
|
||||
GSC->>Callback : 调用完成回调
|
||||
Callback->>GSC : 清理资源
|
||||
GSC->>Node : 移除监听器
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L50-L90)
|
||||
|
||||
### 进度管理系统
|
||||
|
||||
系统采用数组形式管理引导进度,每个引导步骤对应数组的一个元素:
|
||||
|
||||
| 状态 | 数值 | 描述 | 影响 |
|
||||
|------|------|------|------|
|
||||
| 未开始 | 0 | 引导尚未执行 | 可以正常启动 |
|
||||
| 进行中 | 0 | 引导正在执行 | 阻止重复启动 |
|
||||
| 已完成 | 1 | 引导已经完成 | 不再显示该引导 |
|
||||
| 已跳过 | 2 | 用户主动跳过 | 标记状态但不影响其他引导 |
|
||||
|
||||
**章节来源**
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L130-L170)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L80-L90)
|
||||
|
||||
## 与Oops GUI系统集成
|
||||
|
||||
### GUI集成架构
|
||||
|
||||
新手引导系统与Oops GUI系统深度集成,利用其强大的界面管理能力:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "Oops GUI系统"
|
||||
GM[GUI Manager]
|
||||
LM[Layer Manager]
|
||||
PM[Prefab Manager]
|
||||
end
|
||||
subgraph "引导系统"
|
||||
GCC[GuideConComp]
|
||||
GSC[GuideSetpComp]
|
||||
UI[UI Config]
|
||||
end
|
||||
subgraph "资源管理"
|
||||
PREFAB[guide_step.prefab]
|
||||
ASSETS[引导资源]
|
||||
end
|
||||
GCC --> GM
|
||||
GSC --> LM
|
||||
UI --> PM
|
||||
PREFAB --> PM
|
||||
ASSETS --> PM
|
||||
GM --> UI
|
||||
LM --> GSC
|
||||
PM --> PREFAB
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L20-L35)
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L170-L200)
|
||||
|
||||
### UI配置管理
|
||||
|
||||
系统通过统一的UI配置管理引导界面的加载和显示:
|
||||
|
||||
| 配置项 | 值 | 说明 |
|
||||
|--------|-----|------|
|
||||
| UIID.Guide | 1001 | 引导界面的唯一标识 |
|
||||
| LayerType | UI | 界面层级类型 |
|
||||
| Prefab路径 | gui/element/guide_step | 引导UI预制体路径 |
|
||||
| Bundle | resources | 资源包名称 |
|
||||
|
||||
**章节来源**
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L36)
|
||||
|
||||
## 实际应用示例
|
||||
|
||||
### 新增三步引导流程
|
||||
|
||||
以下是如何新增一个完整的三步引导流程的完整示例:
|
||||
|
||||
#### 1. 配置引导数据
|
||||
|
||||
```typescript
|
||||
// 在Guide.ts中添加新的引导配置
|
||||
export const GuideConfig: { [key: number]: IGuideStep } = {
|
||||
// ... 现有引导配置 ...
|
||||
|
||||
11: {
|
||||
id: "new_feature_tutorial",
|
||||
type: GuideStepType.CLICK,
|
||||
key: 11,
|
||||
targetPath: "root/gui/LayerUI/new_feature_panel/button",
|
||||
tipText: "点击这里体验新功能!",
|
||||
handOffset: { x: 42, y: -45 },
|
||||
nextStep: "feature_explanation",
|
||||
skippable: true
|
||||
},
|
||||
|
||||
12: {
|
||||
id: "feature_explanation",
|
||||
type: GuideStepType.TIP,
|
||||
key: 12,
|
||||
targetPath: "root/gui/LayerUI/new_feature_panel/explanation",
|
||||
tipText: "这是全新的功能特性,让游戏更加有趣!",
|
||||
tipOffset: { x: 0, y: 100 },
|
||||
waitTime: 3000,
|
||||
nextStep: "feature_usage"
|
||||
},
|
||||
|
||||
13: {
|
||||
id: "feature_usage",
|
||||
type: GuideStepType.CLICK,
|
||||
key: 13,
|
||||
targetPath: "root/gui/LayerUI/new_feature_panel/usage_button",
|
||||
tipText: "现在尝试使用这个功能吧!",
|
||||
handOffset: { x: 42, y: -45 },
|
||||
skippable: true
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
#### 2. 触发引导启动
|
||||
|
||||
```typescript
|
||||
// 在适当的游戏事件中触发引导
|
||||
oops.message.dispatchEvent(GameEvent.GuideStart, 11);
|
||||
```
|
||||
|
||||
#### 3. 处理用户交互
|
||||
|
||||
系统会自动处理用户的点击、拖拽等交互行为,并根据配置自动推进到下一步骤。
|
||||
|
||||
#### 4. 完成回调处理
|
||||
|
||||
当引导完成后,系统会自动更新进度状态并清理相关资源。
|
||||
|
||||
**章节来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L52-L120)
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L50-L90)
|
||||
|
||||
## 跳过逻辑与资源清理
|
||||
|
||||
### 跳过按钮实现
|
||||
|
||||
引导系统提供了完善的跳过功能,允许用户主动终止引导流程:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([用户点击跳过]) --> HideTips[隐藏提示内容]
|
||||
HideTips --> DestroyHands[销毁手势动画]
|
||||
DestroyHands --> RemoveListeners[移除事件监听器]
|
||||
RemoveListeners --> CallCallback[调用完成回调]
|
||||
CallCallback --> CleanupResources[清理资源]
|
||||
CleanupResources --> CloseUI[关闭引导界面]
|
||||
CloseUI --> End([跳过完成])
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L240-L260)
|
||||
|
||||
### 资源清理机制
|
||||
|
||||
系统实现了多层次的资源清理机制,确保内存使用效率:
|
||||
|
||||
| 清理阶段 | 清理内容 | 触发时机 |
|
||||
|----------|----------|----------|
|
||||
| 步骤完成 | 移除触摸监听器 | 每个步骤结束后 |
|
||||
| 引导取消 | 销毁UI组件 | 用户跳过时 |
|
||||
| 组件销毁 | 清理所有资源 | 组件生命周期结束 |
|
||||
| 内存回收 | 释放引用 | 系统垃圾回收 |
|
||||
|
||||
**章节来源**
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L240-L268)
|
||||
|
||||
## 总结
|
||||
|
||||
新手引导系统是一个功能完善、架构清晰的游戏辅助系统。它具有以下核心优势:
|
||||
|
||||
1. **模块化设计**:采用分层架构,职责明确,易于维护和扩展
|
||||
2. **事件驱动**:基于事件的触发机制,灵活性强,适应各种游戏场景
|
||||
3. **配置化管理**:支持通过配置文件管理引导流程,减少代码耦合
|
||||
4. **资源优化**:完善的资源清理机制,确保良好的性能表现
|
||||
5. **用户体验**:直观的UI设计和流畅的交互体验
|
||||
|
||||
开发者可以通过本系统快速实现各种类型的引导功能,为新用户提供良好的游戏体验。系统的可扩展性也确保了随着游戏发展,可以轻松添加新的引导内容和功能。
|
||||
533
.qoder/repowiki/zh/content/辅助系统/日志输出系统.md
Normal file
533
.qoder/repowiki/zh/content/辅助系统/日志输出系统.md
Normal file
@@ -0,0 +1,533 @@
|
||||
# 日志输出系统
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [log.md](file://doc/core/common/log.md)
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts)
|
||||
- [GameConfig.ts](file://extensions/oops-plugin-framework/assets/module/config/GameConfig.ts)
|
||||
- [GUI.ts](file://extensions/oops-plugin-framework/assets/core/gui/GUI.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [日志系统架构](#日志系统架构)
|
||||
3. [日志输出方法详解](#日志输出方法详解)
|
||||
4. [日志格式与结构](#日志格式与结构)
|
||||
5. [性能分析工具](#性能分析工具)
|
||||
6. [日志表格化输出](#日志表格化输出)
|
||||
7. [实际开发示例](#实际开发示例)
|
||||
8. [日志级别与模块分类](#日志级别与模块分类)
|
||||
9. [生产环境日志控制](#生产环境日志控制)
|
||||
10. [最佳实践指南](#最佳实践指南)
|
||||
|
||||
## 简介
|
||||
|
||||
Oops Framework 提供了一套完整而强大的日志管理系统,专门针对复杂的游戏业务逻辑进行优化。该系统不仅提供了多种颜色标识的日志输出方式,还集成了性能分析、表格化展示等高级功能,为开发者提供了全方位的调试支持。
|
||||
|
||||
日志系统的核心设计理念是通过颜色编码和模块分类来区分不同类型的日志信息,使开发者能够快速定位问题所在。同时,系统支持灵活的日志级别控制,可以在生产环境中安全地关闭不必要的日志输出,确保应用性能不受影响。
|
||||
|
||||
## 日志系统架构
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Logger {
|
||||
-tags : number
|
||||
+setTags(tag : LogType) : void
|
||||
+trace(msg : any, color : string) : void
|
||||
+logNet(msg : any, describe? : string) : void
|
||||
+logModel(msg : any, describe? : string) : void
|
||||
+logBusiness(msg : any, describe? : string) : void
|
||||
+logView(msg : any, describe? : string) : void
|
||||
+logConfig(msg : any, describe? : string) : void
|
||||
+start(describe : string) : void
|
||||
+end(describe : string) : void
|
||||
+table(msg : any, describe? : string) : void
|
||||
-isOpen(tag : LogType) : boolean
|
||||
-print(tag : LogType, msg : any, color : string, describe? : string) : void
|
||||
-stack(index : number) : string
|
||||
-getDateString() : string
|
||||
}
|
||||
class LogType {
|
||||
<<enumeration>>
|
||||
Net : 1
|
||||
Model : 2
|
||||
Business : 4
|
||||
View : 8
|
||||
Config : 16
|
||||
Trace : 32
|
||||
}
|
||||
Logger --> LogType : uses
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts#L1-L281)
|
||||
|
||||
**章节来源**
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts#L1-L50)
|
||||
|
||||
## 日志输出方法详解
|
||||
|
||||
### 基础日志输出
|
||||
|
||||
系统提供了六种不同类型的日志输出方法,每种方法对应不同的业务模块和颜色标识:
|
||||
|
||||
| 方法名 | 颜色标识 | 用途描述 | 适用场景 |
|
||||
|--------|----------|----------|----------|
|
||||
| `trace()` | 黑色 | 默认标准日志 | 通用调试信息 |
|
||||
| `logConfig()` | 灰色 | 配置相关日志 | 游戏配置、参数设置 |
|
||||
| `logNet()` | 橙色 | 网络通信日志 | 网络请求、数据传输 |
|
||||
| `logModel()` | 紫色 | 数据模型日志 | 数据结构、状态变更 |
|
||||
| `logBusiness()` | 蓝色 | 业务逻辑日志 | 游戏流程、规则执行 |
|
||||
| `logView()` | 绿色 | 视图界面日志 | UI交互、渲染操作 |
|
||||
|
||||
### 性能分析方法
|
||||
|
||||
#### start() 和 end() 方法
|
||||
|
||||
这两个方法用于性能耗时分析,通过浏览器的 `console.time()` 和 `console.timeEnd()` 实现精确的时间测量:
|
||||
|
||||
```typescript
|
||||
// 性能分析使用示例
|
||||
oops.log.start("数据加载耗时");
|
||||
// 执行耗时操作
|
||||
const result = await loadData();
|
||||
oops.log.end("数据加载耗时");
|
||||
```
|
||||
|
||||
#### 工作原理
|
||||
|
||||
- `start()` 方法启动计时器,记录开始时间
|
||||
- `end()` 方法停止计时器,计算并输出执行时间
|
||||
- 支持自定义描述信息,便于识别不同的性能测量点
|
||||
|
||||
**章节来源**
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts#L45-L85)
|
||||
|
||||
## 日志格式与结构
|
||||
|
||||
### 标准日志格式
|
||||
|
||||
所有日志输出都遵循统一的格式规范:
|
||||
|
||||
```
|
||||
[时间戳][日志类型][文件路径->方法名]:日志内容
|
||||
```
|
||||
|
||||
### 格式组成部分详解
|
||||
|
||||
| 组件 | 格式 | 示例 | 说明 |
|
||||
|------|------|------|------|
|
||||
| 时间戳 | `[HH:mm:ss:SSS]` | `[11:31:07:293]` | 精确到毫秒的时间标记 |
|
||||
| 日志类型 | `[类型名称]` | `[网络日志]` | 通过颜色区分的模块标识 |
|
||||
| 文件路径 | `[文件名.ts]` 或 `[文件名.ts->方法名]` | `[Hero.ts->load]` | 调用位置的精确追踪 |
|
||||
| 日志内容 | `具体内容` | `'英雄加载完成'` | 实际的日志消息内容 |
|
||||
|
||||
### 文件路径解析机制
|
||||
|
||||
系统自动解析调用栈,提取文件名和方法名:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[调用堆栈] --> B[解析错误对象]
|
||||
B --> C[分割堆栈行]
|
||||
C --> D[提取文件信息]
|
||||
D --> E{文件类型判断}
|
||||
E --> |单文件| F[返回文件名]
|
||||
E --> |方法调用| G[返回文件名->方法名]
|
||||
F --> H[格式化输出]
|
||||
G --> H
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts#L150-L200)
|
||||
|
||||
**章节来源**
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts#L150-L281)
|
||||
|
||||
## 性能分析工具
|
||||
|
||||
### 时间测量功能
|
||||
|
||||
系统内置了精确的性能分析工具,支持:
|
||||
|
||||
#### 基本用法
|
||||
```typescript
|
||||
// 开始性能测量
|
||||
oops.log.start("复杂算法执行");
|
||||
|
||||
// 执行需要测量的代码
|
||||
for (let i = 0; i < 1000000; i++) {
|
||||
// 复杂计算
|
||||
Math.sqrt(i);
|
||||
}
|
||||
|
||||
// 结束测量并输出结果
|
||||
oops.log.end("复杂算法执行");
|
||||
```
|
||||
|
||||
#### 多重测量
|
||||
```typescript
|
||||
// 测量多个独立的操作
|
||||
oops.log.start("数据预处理");
|
||||
processData();
|
||||
oops.log.end("数据预处理");
|
||||
|
||||
oops.log.start("算法计算");
|
||||
calculateResults();
|
||||
oops.log.end("算法计算");
|
||||
```
|
||||
|
||||
### 性能监控最佳实践
|
||||
|
||||
1. **合理命名测量点**:使用描述性的名称便于识别
|
||||
2. **避免过度测量**:仅测量关键路径和瓶颈点
|
||||
3. **及时清理**:在生产环境中移除性能测量代码
|
||||
|
||||
**章节来源**
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts#L65-L85)
|
||||
|
||||
## 日志表格化输出
|
||||
|
||||
### table() 方法功能
|
||||
|
||||
`table()` 方法专门用于对象数据的表格化展示,特别适用于调试复杂的数据结构:
|
||||
|
||||
#### 基本用法
|
||||
```typescript
|
||||
// 对象数据表格化输出
|
||||
const playerData = {
|
||||
uid: 1001,
|
||||
name: "勇者",
|
||||
level: 25,
|
||||
hp: 850,
|
||||
mp: 300,
|
||||
attributes: {
|
||||
strength: 120,
|
||||
agility: 95,
|
||||
intelligence: 110
|
||||
}
|
||||
};
|
||||
|
||||
oops.log.table(playerData, "玩家属性详情");
|
||||
```
|
||||
|
||||
#### 输出效果
|
||||
表格化输出会将对象的键值对以表格形式展示,便于快速查看和比较:
|
||||
|
||||
| 键名 | 值 |
|
||||
|------|-----|
|
||||
| uid | 1001 |
|
||||
| name | "勇者" |
|
||||
| level | 25 |
|
||||
| hp | 850 |
|
||||
| mp | 300 |
|
||||
| attributes | {...} |
|
||||
|
||||
### 使用场景
|
||||
|
||||
1. **数据结构调试**:查看复杂对象的内部结构
|
||||
2. **配置参数检查**:验证配置数据的正确性
|
||||
3. **状态监控**:跟踪游戏状态的变化
|
||||
4. **性能分析**:对比不同条件下的数据差异
|
||||
|
||||
**章节来源**
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts#L87-L97)
|
||||
|
||||
## 实际开发示例
|
||||
|
||||
### Hero.ts 中的业务日志
|
||||
|
||||
在英雄系统中,可以使用不同类型的日志来跟踪各种操作:
|
||||
|
||||
```typescript
|
||||
// 英雄加载过程中的日志记录
|
||||
load(pos: Vec3, scale: number, uuid: number = 1001, fight_pos: number = 1) {
|
||||
oops.log.logBusiness("开始加载英雄", { uuid, pos, scale });
|
||||
|
||||
// 加载前的预检查
|
||||
oops.log.logModel("检查英雄槽位可用性");
|
||||
|
||||
// 资源加载
|
||||
oops.log.logNet("从服务器获取英雄资源");
|
||||
|
||||
// 初始化英雄属性
|
||||
oops.log.logBusiness("初始化英雄基础属性");
|
||||
|
||||
// 添加到战斗系统
|
||||
oops.log.logModel("将英雄添加到战斗系统");
|
||||
|
||||
oops.log.logBusiness("英雄加载完成", { uuid, position: pos });
|
||||
}
|
||||
```
|
||||
|
||||
### GameMap.ts 中的地图日志
|
||||
|
||||
地图系统的日志记录示例:
|
||||
|
||||
```typescript
|
||||
load() {
|
||||
oops.log.logView("开始加载地图资源");
|
||||
|
||||
// 资源加载过程
|
||||
oops.log.logNet("加载地图预制体资源");
|
||||
|
||||
// 地图初始化
|
||||
oops.log.logModel("初始化地图数据结构");
|
||||
|
||||
// UI显示
|
||||
oops.log.logView("创建地图显示节点");
|
||||
|
||||
oops.log.logBusiness("地图加载完成");
|
||||
}
|
||||
```
|
||||
|
||||
### Root.ts 中的系统级日志
|
||||
|
||||
全局系统事件的日志记录:
|
||||
|
||||
```typescript
|
||||
// 游戏显示事件
|
||||
game.on(Game.EVENT_SHOW, () => {
|
||||
oops.log.logView("【系统】游戏前台显示");
|
||||
oops.log.logBusiness("恢复游戏运行状态");
|
||||
});
|
||||
|
||||
// 游戏隐藏事件
|
||||
game.on(Game.EVENT_HIDE, () => {
|
||||
oops.log.logView("【系统】游戏切到后台");
|
||||
oops.log.logBusiness("暂停游戏运行状态");
|
||||
});
|
||||
```
|
||||
|
||||
**章节来源**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L40-L80)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L20-L35)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L105-L140)
|
||||
|
||||
## 日志级别与模块分类
|
||||
|
||||
### 日志类型枚举
|
||||
|
||||
系统定义了完整的日志类型体系:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[LogType 枚举] --> B[Net<br/>网络层日志]
|
||||
A --> C[Model<br/>数据层日志]
|
||||
A --> D[Business<br/>业务层日志]
|
||||
A --> E[View<br/>视图层日志]
|
||||
A --> F[Config<br/>配置日志]
|
||||
A --> G[Trace<br/>标准日志]
|
||||
B --> B1[网络请求]
|
||||
B --> B2[数据传输]
|
||||
B --> B3[API调用]
|
||||
C --> C1[数据结构]
|
||||
C --> C2[状态变更]
|
||||
C --> C3[缓存操作]
|
||||
D --> D1[游戏流程]
|
||||
D --> D2[规则执行]
|
||||
D --> D3[事件处理]
|
||||
E --> E1[UI交互]
|
||||
E --> E2[渲染操作]
|
||||
E --> E3[动画播放]
|
||||
F --> F1[配置文件]
|
||||
F --> F2[参数设置]
|
||||
F --> F3[初始化数据]
|
||||
G --> G1[通用调试]
|
||||
G --> G2[错误提示]
|
||||
G --> G3[警告信息]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts#L3-L15)
|
||||
|
||||
### 日志级别控制
|
||||
|
||||
#### setTags() 方法
|
||||
|
||||
通过 `setTags()` 方法可以控制哪些类型的日志会被输出:
|
||||
|
||||
```typescript
|
||||
// 显示所有日志类型
|
||||
oops.log.setTags(
|
||||
LogType.Net | LogType.Model | LogType.Business |
|
||||
LogType.View | LogType.Config | LogType.Trace
|
||||
);
|
||||
|
||||
// 只显示业务和视图日志
|
||||
oops.log.setTags(LogType.Business | LogType.View);
|
||||
|
||||
// 关闭所有日志输出
|
||||
oops.log.setTags(0);
|
||||
```
|
||||
|
||||
#### 默认行为
|
||||
|
||||
系统默认不显示任何日志,需要显式设置日志级别才能看到输出。
|
||||
|
||||
**章节来源**
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts#L25-L45)
|
||||
|
||||
## 生产环境日志控制
|
||||
|
||||
### 性能优化策略
|
||||
|
||||
在生产环境中,合理的日志控制对于应用性能至关重要:
|
||||
|
||||
#### 1. 条件编译控制
|
||||
|
||||
```typescript
|
||||
// 开发环境启用详细日志
|
||||
#if DEBUG
|
||||
oops.log.setTags(
|
||||
LogType.Net | LogType.Model | LogType.Business |
|
||||
LogType.View | LogType.Config | LogType.Trace
|
||||
);
|
||||
#else
|
||||
// 生产环境关闭所有日志
|
||||
oops.log.setTags(0);
|
||||
#endif
|
||||
```
|
||||
|
||||
#### 2. 动态日志级别调整
|
||||
|
||||
```typescript
|
||||
// 运行时动态调整日志级别
|
||||
class LogManager {
|
||||
static enableDebugLogs(enabled: boolean) {
|
||||
if (enabled) {
|
||||
oops.log.setTags(
|
||||
LogType.Net | LogType.Model | LogType.Business |
|
||||
LogType.View | LogType.Config | LogType.Trace
|
||||
);
|
||||
} else {
|
||||
oops.log.setTags(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 模块化日志控制
|
||||
|
||||
```typescript
|
||||
// 针对不同模块设置不同的日志级别
|
||||
class ModuleLogManager {
|
||||
static configureNetworkLogs(enabled: boolean) {
|
||||
const currentTags = oops.log.getTags();
|
||||
const newTags = enabled
|
||||
? currentTags | LogType.Net
|
||||
: currentTags & ~LogType.Net;
|
||||
oops.log.setTags(newTags);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 性能影响评估
|
||||
|
||||
| 日志级别 | 内存占用 | CPU开销 | I/O影响 | 推荐场景 |
|
||||
|----------|----------|---------|---------|----------|
|
||||
| 全部开启 | 高 | 高 | 高 | 开发调试 |
|
||||
| 业务+视图 | 中 | 中 | 中 | 正常测试 |
|
||||
| 仅错误日志 | 低 | 低 | 低 | 生产环境 |
|
||||
|
||||
### 最佳实践建议
|
||||
|
||||
1. **开发阶段**:启用全部日志以便全面调试
|
||||
2. **测试阶段**:启用关键模块日志,减少噪音
|
||||
3. **生产环境**:仅保留错误和关键业务日志
|
||||
4. **定期审查**:定期检查日志输出,移除不必要的日志代码
|
||||
|
||||
**章节来源**
|
||||
- [Logger.ts](file://extensions/oops-plugin-framework/assets/core/common/log/Logger.ts#L25-L45)
|
||||
|
||||
## 最佳实践指南
|
||||
|
||||
### 日志编写原则
|
||||
|
||||
#### 1. 明确目的
|
||||
每次写日志都应该有明确的目的:
|
||||
- 调试特定问题
|
||||
- 监控系统状态
|
||||
- 记录重要事件
|
||||
- 性能分析
|
||||
|
||||
#### 2. 选择合适的日志类型
|
||||
根据日志内容选择最适合的类型:
|
||||
- 网络操作使用 `logNet()`
|
||||
- 数据变更使用 `logModel()`
|
||||
- 用户交互使用 `logView()`
|
||||
- 配置信息使用 `logConfig()`
|
||||
|
||||
#### 3. 提供上下文信息
|
||||
```typescript
|
||||
// 好的做法:提供足够的上下文
|
||||
oops.log.logBusiness("玩家升级", {
|
||||
playerId: player.id,
|
||||
oldLevel: player.level,
|
||||
newLevel: player.level + 1
|
||||
});
|
||||
|
||||
// 避免的做法:缺乏上下文
|
||||
oops.log.logBusiness("玩家升级");
|
||||
```
|
||||
|
||||
### 日志内容组织
|
||||
|
||||
#### 结构化日志
|
||||
```typescript
|
||||
// 使用对象传递复杂信息
|
||||
const logData = {
|
||||
action: "skill_cast",
|
||||
caster: { id: caster.id, name: caster.name },
|
||||
target: { id: target.id, health: target.health },
|
||||
skill: { id: skill.id, name: skill.name },
|
||||
damage: calculatedDamage,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
|
||||
oops.log.logBusiness("技能释放", logData);
|
||||
```
|
||||
|
||||
#### 条件日志记录
|
||||
```typescript
|
||||
// 根据条件决定是否记录详细日志
|
||||
if (DEBUG_MODE) {
|
||||
oops.log.logModel("详细数据状态", gameState);
|
||||
} else {
|
||||
oops.log.logBusiness("游戏状态更新");
|
||||
}
|
||||
```
|
||||
|
||||
### 日志维护策略
|
||||
|
||||
#### 1. 定期清理
|
||||
- 移除不再需要的调试日志
|
||||
- 优化重复的日志输出
|
||||
- 更新过时的日志格式
|
||||
|
||||
#### 2. 日志质量检查
|
||||
- 确保日志信息的准确性
|
||||
- 避免敏感信息泄露
|
||||
- 保持日志格式的一致性
|
||||
|
||||
#### 3. 性能监控
|
||||
- 监控日志输出对性能的影响
|
||||
- 识别高频率的日志输出点
|
||||
- 优化频繁调用的日志方法
|
||||
|
||||
### 团队协作规范
|
||||
|
||||
#### 日志命名约定
|
||||
- 使用描述性的日志描述
|
||||
- 保持术语的一致性
|
||||
- 遵循团队的编码规范
|
||||
|
||||
#### 日志审核流程
|
||||
- 新功能开发时同步添加必要的日志
|
||||
- 代码审查时检查日志的适当性
|
||||
- 定期回顾和优化现有日志
|
||||
|
||||
通过遵循这些最佳实践,可以构建一个高效、可维护的日志系统,既满足开发调试需求,又保证生产环境的性能表现。
|
||||
473
.qoder/repowiki/zh/content/辅助系统/辅助系统.md
Normal file
473
.qoder/repowiki/zh/content/辅助系统/辅助系统.md
Normal file
@@ -0,0 +1,473 @@
|
||||
# 辅助系统
|
||||
|
||||
<cite>
|
||||
**本文档中引用的文件**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts)
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts)
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [log.md](file://doc/core/common/log.md)
|
||||
- [audio.md](file://doc/core/common/audio.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
|
||||
辅助系统是Cocos游戏框架中的重要组成部分,主要负责新手引导、日志输出管理和音效控制三大核心功能。该系统采用模块化设计,通过事件驱动的方式实现各功能模块间的解耦,提供了灵活且可扩展的辅助功能支持。
|
||||
|
||||
系统的核心特点包括:
|
||||
- **新手引导系统**:提供可视化的操作指导,支持多种交互类型的引导步骤
|
||||
- **日志管理系统**:封装了丰富的日志输出功能,支持不同级别的日志分类
|
||||
- **音效控制系统**:管理背景音乐和音效的播放、暂停、音量控制等功能
|
||||
|
||||
## 项目结构
|
||||
|
||||
辅助系统的文件组织结构清晰,按功能模块进行分类:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "配置层"
|
||||
A[Guide.ts<br/>引导配置]
|
||||
B[GameUIConfig.ts<br/>UI配置]
|
||||
C[GameEvent.ts<br/>事件定义]
|
||||
end
|
||||
subgraph "组件层"
|
||||
D[GuideConComp.ts<br/>引导控制器]
|
||||
E[GuideSetpComp.ts<br/>引导步骤组件]
|
||||
F[SingletonModuleComp.ts<br/>单例模块]
|
||||
end
|
||||
subgraph "工具层"
|
||||
G[log.md<br/>日志规范]
|
||||
H[audio.md<br/>音效规范]
|
||||
end
|
||||
A --> D
|
||||
A --> E
|
||||
B --> D
|
||||
C --> D
|
||||
D --> F
|
||||
E --> F
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L1-L50)
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L1-L30)
|
||||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L20)
|
||||
|
||||
**章节来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L1-L283)
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L1-L220)
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 引导系统核心组件
|
||||
|
||||
引导系统包含三个核心组件,每个组件承担不同的职责:
|
||||
|
||||
1. **GuideConfig**:引导配置管理器,负责引导步骤的定义和查找
|
||||
2. **GuideConComp**:引导控制器,负责引导流程的控制和状态管理
|
||||
3. **GuideSetpComp**:引导步骤组件,负责具体的UI显示和用户交互
|
||||
|
||||
### 日志系统核心组件
|
||||
|
||||
日志系统基于Oops Framework的日志管理模块,提供以下功能:
|
||||
- 标准日志输出
|
||||
- 分类日志(配置、网络、数据、业务、视图)
|
||||
- 性能监控(执行时间统计)
|
||||
- 表格格式化输出
|
||||
|
||||
### 音效系统核心组件
|
||||
|
||||
音效系统提供完整的音频管理功能:
|
||||
- 背景音乐播放控制
|
||||
- 音效播放管理
|
||||
- 音量调节和开关控制
|
||||
- 音频资源的异步加载
|
||||
|
||||
**章节来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L1-L100)
|
||||
- [log.md](file://doc/core/common/log.md#L1-L30)
|
||||
- [audio.md](file://doc/core/common/audio.md#L1-L85)
|
||||
|
||||
## 架构概览
|
||||
|
||||
辅助系统采用分层架构设计,确保各功能模块的独立性和可维护性:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "表现层"
|
||||
A[UI界面]
|
||||
B[引导步骤UI]
|
||||
C[日志输出界面]
|
||||
end
|
||||
subgraph "控制层"
|
||||
D[GuideConComp<br/>引导控制器]
|
||||
E[SingletonModuleComp<br/>单例模块]
|
||||
F[事件管理器]
|
||||
end
|
||||
subgraph "服务层"
|
||||
G[引导服务]
|
||||
H[日志服务]
|
||||
I[音效服务]
|
||||
end
|
||||
subgraph "数据层"
|
||||
J[引导配置数据]
|
||||
K[日志配置数据]
|
||||
L[音效配置数据]
|
||||
end
|
||||
A --> D
|
||||
B --> D
|
||||
C --> H
|
||||
D --> G
|
||||
E --> G
|
||||
F --> G
|
||||
G --> J
|
||||
H --> K
|
||||
I --> L
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L15-L35)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L25-L50)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 引导系统详细分析
|
||||
|
||||
#### 引导配置结构
|
||||
|
||||
引导系统的核心是`IGuideStep`接口定义,它描述了引导步骤的所有属性:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class IGuideStep {
|
||||
+string id
|
||||
+GuideStepType type
|
||||
+number key
|
||||
+string targetPath
|
||||
+string tipParent
|
||||
+string tipText
|
||||
+Vector2 tipOffset
|
||||
+Vector2 handOffset
|
||||
+string nextStep
|
||||
+boolean skippable
|
||||
+function condition
|
||||
+UIID uiId
|
||||
+number waitTime
|
||||
+string end_event
|
||||
+boolean noInput
|
||||
}
|
||||
class GuideStepType {
|
||||
<<enumeration>>
|
||||
CLICK
|
||||
DRAG
|
||||
TIP
|
||||
WAIT
|
||||
}
|
||||
class GuideConfig {
|
||||
+IGuideStep[] steps
|
||||
+findGuideById(id) IGuideStep
|
||||
+findGuideByNumberId(id) IGuideStep
|
||||
+findGuideIndexById(id) number
|
||||
}
|
||||
IGuideStep --> GuideStepType
|
||||
GuideConfig --> IGuideStep
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L25-L55)
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L84-L110)
|
||||
|
||||
#### 引导流程执行逻辑
|
||||
|
||||
引导控制器负责管理整个引导流程的执行:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家
|
||||
participant Controller as GuideConComp
|
||||
participant StepComp as GuideSetpComp
|
||||
participant SM as SingletonModuleComp
|
||||
participant UI as UI系统
|
||||
Player->>Controller : 触发引导事件
|
||||
Controller->>Controller : 初始化引导进度
|
||||
Controller->>StepComp : 创建引导步骤UI
|
||||
StepComp->>UI : 显示引导界面
|
||||
UI->>Player : 展示引导提示
|
||||
Player->>StepComp : 完成引导操作
|
||||
StepComp->>Controller : 步骤完成回调
|
||||
Controller->>Controller : 检查下一步骤
|
||||
alt 有下一步骤
|
||||
Controller->>StepComp : 显示下个步骤
|
||||
else 无下一步骤
|
||||
Controller->>SM : 标记引导完成
|
||||
Controller->>UI : 关闭引导界面
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L50-L80)
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L80-L120)
|
||||
|
||||
#### UI高亮机制
|
||||
|
||||
引导步骤组件实现了精确的目标节点定位和高亮显示:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[解析目标路径] --> B{路径有效?}
|
||||
B --> |是| C[查找目标节点]
|
||||
B --> |否| D[使用默认节点]
|
||||
C --> E{找到节点?}
|
||||
E --> |是| F[设置高亮样式]
|
||||
E --> |否| G[记录错误日志]
|
||||
D --> F
|
||||
F --> H[计算手指位置]
|
||||
H --> I[显示引导指示器]
|
||||
G --> J[降级处理]
|
||||
J --> I
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L200-L250)
|
||||
|
||||
**章节来源**
|
||||
- [Guide.ts](file://assets/script/game/common/config/Guide.ts#L25-L85)
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L50-L150)
|
||||
- [GuideSetpComp.ts](file://assets/script/game/map/GuideSetpComp.ts#L150-L200)
|
||||
|
||||
### 日志系统详细分析
|
||||
|
||||
#### 日志输出规范
|
||||
|
||||
日志系统提供了六种不同级别的日志输出:
|
||||
|
||||
| 日志级别 | 方法名 | 颜色标识 | 使用场景 |
|
||||
|---------|--------|----------|----------|
|
||||
| 标准日志 | `oops.log.trace()` | 默认 | 通用调试信息 |
|
||||
| 配置日志 | `oops.log.logConfig()` | 灰色 | 配置相关输出 |
|
||||
| 网络日志 | `oops.log.logNet()` | 橙色 | 网络请求跟踪 |
|
||||
| 数据日志 | `oops.log.logModel()` | 紫色 | 数据模型操作 |
|
||||
| 业务日志 | `oops.log.logBusiness()` | 蓝色 | 业务逻辑执行 |
|
||||
| 视图日志 | `oops.log.logView()` | 绿色 | UI界面交互 |
|
||||
|
||||
#### 性能监控功能
|
||||
|
||||
日志系统还提供了性能监控能力:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[开始计时] --> B[执行代码段]
|
||||
B --> C[结束计时]
|
||||
C --> D[计算执行时间]
|
||||
D --> E[输出性能日志]
|
||||
F[表格数据] --> G[格式化输出]
|
||||
G --> H[结构化日志]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [log.md](file://doc/core/common/log.md#L10-L25)
|
||||
|
||||
**章节来源**
|
||||
- [log.md](file://doc/core/common/log.md#L1-L30)
|
||||
|
||||
### 音效系统详细分析
|
||||
|
||||
#### 音效资源管理
|
||||
|
||||
音效系统采用异步加载策略,确保游戏性能:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 初始化
|
||||
初始化 --> 加载中 : 请求播放
|
||||
加载中 --> 播放就绪 : 资源加载完成
|
||||
加载中 --> 加载失败 : 资源加载失败
|
||||
播放就绪 --> 播放中 : 开始播放
|
||||
播放中 --> 暂停 : 用户暂停
|
||||
暂停 --> 播放中 : 用户继续
|
||||
播放中 --> 停止 : 用户停止
|
||||
停止 --> [*]
|
||||
加载失败 --> [*]
|
||||
```
|
||||
|
||||
#### 音量控制策略
|
||||
|
||||
音效系统提供了精细的音量控制:
|
||||
|
||||
| 功能 | 方法 | 参数范围 | 说明 |
|
||||
|------|------|----------|------|
|
||||
| 背景音乐音量 | `oops.audio.musicVolume` | 0.0 - 1.0 | 全局背景音乐音量 |
|
||||
| 音效音量 | `oops.audio.volumeEffect` | 0.0 - 1.0 | 全局音效音量 |
|
||||
| 音乐开关 | `oops.audio.switchMusic` | true/false | 控制背景音乐播放 |
|
||||
| 音效开关 | `oops.audio.switchEffect` | true/false | 控制音效播放 |
|
||||
|
||||
**章节来源**
|
||||
- [audio.md](file://doc/core/common/audio.md#L1-L85)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
辅助系统的依赖关系体现了良好的模块化设计:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "外部依赖"
|
||||
A[Oops Framework]
|
||||
B[Cocos Creator]
|
||||
end
|
||||
subgraph "核心模块"
|
||||
C[Guide.ts]
|
||||
D[GuideConComp.ts]
|
||||
E[GuideSetpComp.ts]
|
||||
F[SingletonModuleComp.ts]
|
||||
end
|
||||
subgraph "配置模块"
|
||||
G[GameUIConfig.ts]
|
||||
H[GameEvent.ts]
|
||||
end
|
||||
subgraph "工具模块"
|
||||
I[log.md]
|
||||
J[audio.md]
|
||||
end
|
||||
A --> C
|
||||
A --> D
|
||||
A --> E
|
||||
B --> D
|
||||
B --> E
|
||||
C --> D
|
||||
C --> E
|
||||
G --> D
|
||||
H --> D
|
||||
F --> D
|
||||
F --> E
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L1-L10)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L15)
|
||||
|
||||
**章节来源**
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L1-L20)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L25)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
辅助系统在设计时充分考虑了性能优化:
|
||||
|
||||
### 引导系统性能优化
|
||||
|
||||
1. **延迟加载**:引导UI仅在需要时创建和销毁
|
||||
2. **内存管理**:及时清理不再使用的引导资源
|
||||
3. **事件监听**:智能添加和移除触摸监听器
|
||||
4. **节点查找**:缓存常用节点引用,避免重复查找
|
||||
|
||||
### 日志系统性能优化
|
||||
|
||||
1. **条件输出**:根据日志级别决定是否输出
|
||||
2. **批量处理**:支持批量日志输出以减少I/O操作
|
||||
3. **格式化优化**:使用高效的字符串拼接方法
|
||||
|
||||
### 音效系统性能优化
|
||||
|
||||
1. **预加载策略**:关键音效提前加载
|
||||
2. **资源池管理**:复用音频资源减少内存占用
|
||||
3. **异步加载**:避免阻塞主线程
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见引导问题
|
||||
|
||||
#### 引导无法启动
|
||||
**症状**:触发引导事件但没有显示任何提示
|
||||
**原因分析**:
|
||||
- 目标节点路径错误
|
||||
- 引导配置数据缺失
|
||||
- 引导进度状态异常
|
||||
|
||||
**解决方案**:
|
||||
1. 检查`targetPath`是否正确
|
||||
2. 验证`GuideConfig`配置
|
||||
3. 重置引导进度:`smc.guides = []`
|
||||
|
||||
#### 引导步骤不连续
|
||||
**症状**:引导过程中跳过了某些步骤
|
||||
**原因分析**:
|
||||
- `nextStep`配置错误
|
||||
- 引导完成状态未正确更新
|
||||
- 事件触发时机不当
|
||||
|
||||
**解决方案**:
|
||||
1. 检查引导步骤的`nextStep`链接
|
||||
2. 确认`smc.finishGuide()`调用
|
||||
3. 验证事件触发顺序
|
||||
|
||||
### 日志系统问题
|
||||
|
||||
#### 日志输出格式异常
|
||||
**症状**:日志时间戳或类别显示错误
|
||||
**解决方案**:
|
||||
检查日志配置和格式化函数
|
||||
|
||||
#### 性能监控失效
|
||||
**症状**:执行时间统计不准确
|
||||
**解决方案**:
|
||||
确认`oops.log.start()`和`oops.log.end()`配对使用
|
||||
|
||||
### 音效系统问题
|
||||
|
||||
#### 音效无法播放
|
||||
**症状**:音效请求后没有声音输出
|
||||
**解决方案**:
|
||||
1. 检查音效文件路径
|
||||
2. 验证音量设置
|
||||
3. 确认音频开关状态
|
||||
|
||||
#### 背景音乐重复播放
|
||||
**症状**:同一首音乐多次播放
|
||||
**解决方案**:
|
||||
1. 检查音乐播放完成回调
|
||||
2. 确认音乐切换逻辑
|
||||
3. 清理旧的音乐实例
|
||||
|
||||
**章节来源**
|
||||
- [GuideConComp.ts](file://assets/script/game/map/GuideConComp.ts#L180-L220)
|
||||
- [log.md](file://doc/core/common/log.md#L15-L30)
|
||||
- [audio.md](file://doc/core/common/audio.md#L40-L85)
|
||||
|
||||
## 结论
|
||||
|
||||
辅助系统作为游戏开发中的重要基础设施,提供了完整的新手引导、日志管理和音效控制功能。通过模块化的设计和事件驱动的架构,系统实现了高度的可扩展性和可维护性。
|
||||
|
||||
### 主要优势
|
||||
|
||||
1. **模块化设计**:各功能模块职责明确,便于维护和扩展
|
||||
2. **事件驱动**:通过事件系统实现松耦合的组件通信
|
||||
3. **配置灵活**:支持动态配置引导步骤和日志级别
|
||||
4. **性能优化**:采用多种优化策略确保系统流畅运行
|
||||
|
||||
### 最佳实践建议
|
||||
|
||||
1. **引导设计**:合理规划引导步骤,避免过度引导影响用户体验
|
||||
2. **日志管理**:根据环境设置合适的日志级别,生产环境避免过多调试信息
|
||||
3. **音效控制**:注意音效的音量平衡,避免影响游戏体验
|
||||
4. **资源管理**:及时释放不再使用的资源,防止内存泄漏
|
||||
|
||||
### 扩展方向
|
||||
|
||||
1. **多语言支持**:扩展引导文本的国际化功能
|
||||
2. **自定义事件**:支持开发者自定义引导触发事件
|
||||
3. **数据分析**:集成引导完成率等数据分析功能
|
||||
4. **云端配置**:支持引导配置的云端动态更新
|
||||
|
||||
通过持续的优化和功能扩展,辅助系统将继续为游戏开发提供强有力的支持,帮助开发者构建更好的用户体验。
|
||||
301
.qoder/repowiki/zh/content/辅助系统/音效管理系统.md
Normal file
301
.qoder/repowiki/zh/content/辅助系统/音效管理系统.md
Normal file
@@ -0,0 +1,301 @@
|
||||
# 音效管理系统
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [audio.md](file://doc/core/common/audio.md)
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts)
|
||||
- [AudioMusic.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioMusic.ts)
|
||||
- [AudioEffect.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioEffect.ts)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts)
|
||||
- [GameComponent.ts](file://extensions/oops-plugin-framework/assets/module/common/GameComponent.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [核心功能](#核心功能)
|
||||
3. [背景音乐管理](#背景音乐管理)
|
||||
4. [音效管理](#音效管理)
|
||||
5. [播放状态控制](#播放状态控制)
|
||||
6. [用户设置持久化](#用户设置持久化)
|
||||
7. [关键节点集成示例](#关键节点集成示例)
|
||||
8. [性能优化建议](#性能优化建议)
|
||||
9. [系统架构](#系统架构)
|
||||
10. [依赖关系](#依赖关系)
|
||||
|
||||
## 简介
|
||||
Oops Framework 音效管理模块为游戏提供完整的音频解决方案,涵盖背景音乐与音效两大核心功能。该系统在游戏启动时自动初始化,支持异步资源加载、音量控制、播放状态管理及用户偏好设置的本地持久化。通过简洁的接口设计,开发者可轻松在游戏各关键节点集成音效,提升用户体验。
|
||||
|
||||
**Section sources**
|
||||
- [audio.md](file://doc/core/common/audio.md#L1-L10)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L85-L93)
|
||||
|
||||
## 核心功能
|
||||
音效管理系统提供以下核心功能:
|
||||
- 背景音乐与音效的异步加载与播放
|
||||
- 独立的音量控制(musicVolume 与 volumeEffect)
|
||||
- 开关状态管理(switchMusic 与 switchEffect)
|
||||
- 播放进度控制(progressMusic)
|
||||
- 全局播放状态控制(pauseAll/resumeAll/stopAll)
|
||||
- 用户音频设置的本地持久化(save/load)
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[音效管理系统] --> B[背景音乐管理]
|
||||
A --> C[音效管理]
|
||||
A --> D[状态控制]
|
||||
A --> E[数据持久化]
|
||||
B --> F[异步加载]
|
||||
B --> G[音量控制]
|
||||
B --> H[进度控制]
|
||||
C --> I[异步加载]
|
||||
C --> J[音量控制]
|
||||
D --> K[暂停/恢复/停止]
|
||||
E --> L[保存/加载]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts#L10-L201)
|
||||
|
||||
## 背景音乐管理
|
||||
|
||||
### 播放与加载机制
|
||||
通过 `playMusic` 或 `playerMusicLoop` 方法播放背景音乐,系统会异步加载音频资源。播放前会自动释放先前的音乐资源,确保内存高效利用。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 游戏逻辑
|
||||
participant AudioManager
|
||||
participant AudioMusic
|
||||
participant 资源系统
|
||||
游戏逻辑->>AudioManager : playMusic("audios/nocturne")
|
||||
AudioManager->>AudioManager : 检查switchMusic开关
|
||||
AudioManager->>AudioMusic : load(url)
|
||||
AudioMusic->>资源系统 : oops.res.load(url, AudioClip)
|
||||
资源系统-->>AudioMusic : 返回AudioClip
|
||||
AudioMusic->>AudioMusic : 停止当前播放,设置新音频
|
||||
AudioMusic->>AudioMusic : 开始播放
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts#L37-L55)
|
||||
- [AudioMusic.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioMusic.ts#L40-L60)
|
||||
|
||||
### 音量与开关控制
|
||||
提供 `volumeMusic` 属性设置背景音乐音量(范围0-1),`switchMusic` 属性控制开关状态。关闭时会自动停止播放。
|
||||
|
||||
**Section sources**
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts#L65-L85)
|
||||
|
||||
### 进度控制
|
||||
通过 `progressMusic` 属性获取或设置音乐播放进度(0-1)。设置时会自动调整 `currentTime` 实现跳转。
|
||||
|
||||
**Section sources**
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts#L57-L63)
|
||||
|
||||
## 音效管理
|
||||
|
||||
### 播放机制
|
||||
通过 `playEffect` 方法播放音效,系统异步加载音频资源后使用 `playOneShot` 播放。每个音效资源会被缓存,避免重复加载。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 游戏逻辑
|
||||
participant AudioManager
|
||||
participant AudioEffect
|
||||
participant 资源系统
|
||||
游戏逻辑->>AudioManager : playEffect("audios/Gravel")
|
||||
AudioManager->>AudioManager : 检查switchEffect开关
|
||||
AudioManager->>AudioEffect : load(url)
|
||||
AudioEffect->>资源系统 : oops.res.load(url, AudioClip)
|
||||
资源系统-->>AudioEffect : 返回AudioClip
|
||||
AudioEffect->>AudioEffect : 缓存AudioClip
|
||||
AudioEffect->>AudioEffect : playOneShot(data, volume)
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts#L101-L108)
|
||||
- [AudioEffect.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioEffect.ts#L20-L35)
|
||||
|
||||
### 音量与开关控制
|
||||
提供 `volumeEffect` 属性设置音效音量(范围0-1),`switchEffect` 属性控制开关状态。关闭时会停止所有音效播放。
|
||||
|
||||
**Section sources**
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts#L110-L128)
|
||||
|
||||
## 播放状态控制
|
||||
系统提供全局播放状态控制方法:
|
||||
- `pauseAll()`:暂停所有音乐与音效
|
||||
- `resumeAll()`:恢复所有暂停的音乐与音效
|
||||
- `stopAll()`:停止所有音乐与音效播放
|
||||
|
||||
这些方法在游戏切入后台时自动调用,确保良好的用户体验。
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 播放中
|
||||
播放中 --> 暂停 : pauseAll()
|
||||
暂停 --> 播放中 : resumeAll()
|
||||
播放中 --> 停止 : stopAll()
|
||||
暂停 --> 停止 : stopAll()
|
||||
停止 --> 播放中 : playMusic/playEffect
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts#L130-L150)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L109-L119)
|
||||
|
||||
## 用户设置持久化
|
||||
系统使用本地存储保存和加载用户音频设置,包括音量和开关状态。
|
||||
|
||||
### 保存设置
|
||||
`save()` 方法将当前音量和开关状态序列化为JSON字符串并存储到本地。
|
||||
|
||||
### 加载设置
|
||||
`load()` 方法在初始化时自动调用,从本地加载设置并应用到音频系统。如果数据损坏,则使用默认值。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[初始化] --> B[调用load()]
|
||||
B --> C{本地数据存在?}
|
||||
C --> |是| D[解析JSON数据]
|
||||
C --> |否| E[使用默认值]
|
||||
D --> F{解析成功?}
|
||||
F --> |是| G[应用音量和开关设置]
|
||||
F --> |否| H[使用默认值]
|
||||
G --> I[初始化AudioMusic和AudioEffect组件]
|
||||
H --> I
|
||||
I --> J[系统就绪]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts#L152-L198)
|
||||
|
||||
## 关键节点集成示例
|
||||
|
||||
### 游戏启动
|
||||
在游戏启动时,系统自动初始化音频管理器并加载用户设置:
|
||||
|
||||
```typescript
|
||||
// Root.ts 中的初始化代码
|
||||
oops.audio = this.persistRootNode.addComponent(AudioManager);
|
||||
oops.audio.load(); // 加载用户音频设置
|
||||
```
|
||||
|
||||
**Section sources**
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L92-L93)
|
||||
|
||||
### 战斗开始
|
||||
在战斗相关组件中,可通过封装的方法播放音效:
|
||||
|
||||
```typescript
|
||||
// GameComponent.ts 中的封装方法
|
||||
playEffect(url: string) {
|
||||
this.resPaths.set(url, oops.res.defaultBundleName);
|
||||
oops.audio.playEffect(url);
|
||||
}
|
||||
```
|
||||
|
||||
**Section sources**
|
||||
- [GameComponent.ts](file://extensions/oops-plugin-framework/assets/module/common/GameComponent.ts#L180-L196)
|
||||
|
||||
### 技能释放
|
||||
在技能控制组件中,可根据技能类型播放相应音效:
|
||||
|
||||
```typescript
|
||||
// 示例:技能释放时播放音效
|
||||
this.HeroView.playSkillEffect(skill_id);
|
||||
// 内部实现可能调用 oops.audio.playEffect(...)
|
||||
```
|
||||
|
||||
**Section sources**
|
||||
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L720-L746)
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
### 避免频繁创建
|
||||
- 音效资源会被缓存,避免重复加载
|
||||
- 使用 `playOneShot` 而非创建多个 AudioSource 组件
|
||||
- 在对象销毁时调用 `release()` 释放资源
|
||||
|
||||
### 音量层级管理
|
||||
- 合理设置 `volumeMusic` 和 `volumeEffect` 的默认值
|
||||
- 提供用户界面让玩家自定义音量
|
||||
- 背景音乐音量通常低于音效音量,保持平衡
|
||||
|
||||
### 资源管理
|
||||
- 使用资源路径规范,便于管理和加载
|
||||
- 在适当时机预加载常用音效
|
||||
- 定期清理不常用的音效缓存
|
||||
|
||||
**Section sources**
|
||||
- [AudioEffect.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioEffect.ts#L37-L44)
|
||||
- [AudioMusic.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioMusic.ts#L80-L89)
|
||||
|
||||
## 系统架构
|
||||
音效管理系统采用组件化设计,核心类关系如下:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class AudioManager {
|
||||
+local_data : any
|
||||
+music : AudioMusic
|
||||
+effect : AudioEffect
|
||||
+playMusic(url : string)
|
||||
+playEffect(url : string)
|
||||
+pauseAll()
|
||||
+resumeAll()
|
||||
+stopAll()
|
||||
+save()
|
||||
+load()
|
||||
}
|
||||
class AudioMusic {
|
||||
+onComplete : Function | null
|
||||
+progress : number
|
||||
+volume : number
|
||||
+load(url : string)
|
||||
+play()
|
||||
+pause()
|
||||
+stop()
|
||||
}
|
||||
class AudioEffect {
|
||||
+effects : Map~string, AudioClip~
|
||||
+load(url : string)
|
||||
+playOneShot()
|
||||
+release()
|
||||
}
|
||||
AudioManager --> AudioMusic : "包含"
|
||||
AudioManager --> AudioEffect : "包含"
|
||||
AudioMusic --|> AudioSource : "继承"
|
||||
AudioEffect --|> AudioSource : "继承"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts#L10-L201)
|
||||
- [AudioMusic.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioMusic.ts#L10-L90)
|
||||
- [AudioEffect.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioEffect.ts#L10-L45)
|
||||
|
||||
## 依赖关系
|
||||
音效管理系统依赖于框架的其他核心模块:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
AudioManager --> oops.res : "资源加载"
|
||||
AudioManager --> oops.storage : "本地存储"
|
||||
AudioManager --> oops.log : "错误日志"
|
||||
Root --> AudioManager : "初始化"
|
||||
GameComponent --> AudioManager : "使用接口"
|
||||
subgraph "核心依赖"
|
||||
oops.res
|
||||
oops.storage
|
||||
oops.log
|
||||
end
|
||||
subgraph "使用方"
|
||||
Root
|
||||
GameComponent
|
||||
其他游戏组件
|
||||
end
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [AudioManager.ts](file://extensions/oops-plugin-framework/assets/core/common/audio/AudioManager.ts#L1-L201)
|
||||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L85-L143)
|
||||
419
.qoder/repowiki/zh/content/项目概述.md
Normal file
419
.qoder/repowiki/zh/content/项目概述.md
Normal file
@@ -0,0 +1,419 @@
|
||||
# 项目概述
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [heros.md](file://assets/script/heros.md)
|
||||
- [Design.md](file://assets/script/Design.md)
|
||||
- [Main.ts](file://assets/script/Main.ts)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts)
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
|
||||
- [package.json](file://package.json)
|
||||
- [tsconfig.json](file://tsconfig.json)
|
||||
- [config.json](file://assets/resources/config.json)
|
||||
- [NetCode.json](file://assets/resources/config/game/NetCode.json)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [项目简介](#项目简介)
|
||||
2. [核心设计理念](#核心设计理念)
|
||||
3. [技术架构概览](#技术架构概览)
|
||||
4. [项目结构分析](#项目结构分析)
|
||||
5. [核心技术栈](#核心技术栈)
|
||||
6. [核心功能模块](#核心功能模块)
|
||||
7. [游戏机制详解](#游戏机制详解)
|
||||
8. [数据管理系统](#数据管理系统)
|
||||
9. [架构设计亮点](#架构设计亮点)
|
||||
10. [总结](#总结)
|
||||
|
||||
## 项目简介
|
||||
|
||||
Heros是一款基于Cocos Creator开发的微信小游戏,融合了Roguelike塔防玩法与中国历史人物英雄设定的独特设计理念。游戏将传统的塔防策略与肉鸽(Roguelike)元素相结合,创造出既具有深度策略性又充满随机性和重玩价值的游戏体验。
|
||||
|
||||
### 游戏特色
|
||||
- **历史英雄集合**:收录了春秋战国至楚汉争霸时期的34位历史名将,每位英雄都具有独特的背景故事和战斗特性
|
||||
- **创新玩法**:自动战斗系统配合策略性奖励选择,简化操作同时保持深度策略性
|
||||
- **文化传承**:通过游戏形式传播中国传统文化和历史知识
|
||||
- **跨平台支持**:基于Cocos Creator开发,支持微信小程序等多平台部署
|
||||
|
||||
**章节来源**
|
||||
- [heros.md](file://assets/script/heros.md#L1-L374)
|
||||
- [Design.md](file://assets/script/Design.md#L1-L109)
|
||||
|
||||
## 核心设计理念
|
||||
|
||||
### 游戏核心概念
|
||||
Heros采用单局制肉鸽塔防的核心玩法,玩家通过策略性地选择每波怪物清理后的奖励来强化自己的英雄队伍,最终挑战强大的Boss。这种设计实现了以下核心理念:
|
||||
|
||||
1. **策略性与随机性的平衡**:固定关卡结构搭配随机奖励选择,创造既可预测又充满惊喜的游戏体验
|
||||
2. **资源管理深度**:有限的金币资源迫使玩家在短期收益与长期发展之间做出权衡
|
||||
3. **英雄成长多样性**:每个英雄都有三条不同的成长路线,鼓励玩家尝试不同的策略组合
|
||||
|
||||
### 设计哲学
|
||||
- **简化操作复杂性**:所有战斗均为自动进行,玩家只需在关键节点做出选择
|
||||
- **深度策略性保留**:通过奖励系统和英雄特性维持游戏的策略深度
|
||||
- **文化价值传递**:每个英雄都承载着丰富的历史文化内涵
|
||||
|
||||
**章节来源**
|
||||
- [Design.md](file://assets/script/Design.md#L5-L25)
|
||||
|
||||
## 技术架构概览
|
||||
|
||||
### 整体架构设计
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "表现层"
|
||||
UI[用户界面]
|
||||
Scene[场景管理]
|
||||
Animation[动画系统]
|
||||
end
|
||||
subgraph "业务逻辑层"
|
||||
GameLogic[游戏逻辑]
|
||||
BattleSystem[战斗系统]
|
||||
RewardSystem[奖励系统]
|
||||
HeroSystem[英雄系统]
|
||||
end
|
||||
subgraph "数据层"
|
||||
SingletonModule[单例模块]
|
||||
CloudStorage[云端存储]
|
||||
LocalStorage[本地存储]
|
||||
end
|
||||
subgraph "技术框架"
|
||||
CocosEngine[Cocos Creator引擎]
|
||||
OopsFramework[Oops插件框架]
|
||||
ECS[ECS架构]
|
||||
MVVM[MVVM模式]
|
||||
end
|
||||
UI --> GameLogic
|
||||
Scene --> BattleSystem
|
||||
Animation --> HeroSystem
|
||||
GameLogic --> SingletonModule
|
||||
BattleSystem --> CloudStorage
|
||||
RewardSystem --> LocalStorage
|
||||
SingletonModule --> CocosEngine
|
||||
CloudStorage --> OopsFramework
|
||||
LocalStorage --> ECS
|
||||
CocosEngine --> MVVM
|
||||
OopsFramework --> ECS
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L41)
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L195)
|
||||
|
||||
### 架构层次说明
|
||||
|
||||
1. **表现层**:负责用户界面展示、场景管理和动画播放
|
||||
2. **业务逻辑层**:包含游戏核心逻辑、战斗系统、奖励系统和英雄系统
|
||||
3. **数据层**:管理游戏数据、云端存储和本地缓存
|
||||
4. **技术框架**:基于Cocos Creator引擎和Oops插件框架构建
|
||||
|
||||
**章节来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L10-L41)
|
||||
|
||||
## 项目结构分析
|
||||
|
||||
### 目录结构概览
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "assets资源目录"
|
||||
Resources[resources资源]
|
||||
Script[script脚本]
|
||||
Extensions[extensions扩展]
|
||||
end
|
||||
subgraph "核心脚本模块"
|
||||
Game[game游戏模块]
|
||||
Common[common通用模块]
|
||||
Initialize[initialize初始化]
|
||||
end
|
||||
subgraph "功能子模块"
|
||||
Hero[英雄系统]
|
||||
Map[地图系统]
|
||||
Skill[技能系统]
|
||||
WX[微信云开发]
|
||||
end
|
||||
Resources --> Game
|
||||
Script --> Common
|
||||
Extensions --> Initialize
|
||||
Game --> Hero
|
||||
Game --> Map
|
||||
Game --> Skill
|
||||
Game --> WX
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Main.ts](file://assets/script/Main.ts#L1-L10)
|
||||
|
||||
### 主要目录说明
|
||||
|
||||
- **assets/resources**:存放游戏资源配置文件,包括语言包、地图配置和网络代码定义
|
||||
- **assets/script**:核心游戏脚本代码,包含游戏逻辑、英雄系统、地图系统等
|
||||
- **build-templates**:微信小游戏构建模板和云函数配置
|
||||
- **doc**:项目文档,包含ECS架构、MVVM模式等技术文档
|
||||
|
||||
**章节来源**
|
||||
- [config.json](file://assets/resources/config.json#L1-L21)
|
||||
|
||||
## 核心技术栈
|
||||
|
||||
### Cocos Creator引擎
|
||||
- **版本**:3.8.6
|
||||
- **特性**:跨平台游戏开发,支持Web、移动端和小程序
|
||||
- **优势**:成熟的2D/3D游戏开发工具链,丰富的内置组件
|
||||
|
||||
### Oops Plugin Framework
|
||||
基于MVVM架构的插件框架,提供:
|
||||
- **Model-View-ViewModel分离**:清晰的代码组织结构
|
||||
- **数据绑定机制**:自动化的UI更新
|
||||
- **组件化开发**:模块化的功能组织
|
||||
|
||||
### TypeScript技术栈
|
||||
- **编译器配置**:ES2017目标,严格模式
|
||||
- **类型安全**:完整的TypeScript类型系统
|
||||
- **现代语法**:支持最新的JavaScript特性
|
||||
|
||||
### 微信云开发SDK
|
||||
- **云端数据存储**:支持玩家游戏数据的云端同步
|
||||
- **用户认证**:基于微信平台的用户身份验证
|
||||
- **云函数**:后端逻辑处理和数据管理
|
||||
|
||||
**章节来源**
|
||||
- [package.json](file://package.json#L1-L13)
|
||||
- [tsconfig.json](file://tsconfig.json#L1-L12)
|
||||
|
||||
## 核心功能模块
|
||||
|
||||
### 英雄系统
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Hero {
|
||||
+HeroModelComp model
|
||||
+HeroViewComp view
|
||||
+BattleMoveComp move
|
||||
+load(pos, scale, uuid, fight_pos)
|
||||
+hero_init(uuid, node)
|
||||
}
|
||||
class HeroModelComp {
|
||||
+number uuid
|
||||
+string name
|
||||
+HType type
|
||||
+number lv
|
||||
+number hp
|
||||
+number mp
|
||||
+number ap
|
||||
+number def
|
||||
}
|
||||
class HeroViewComp {
|
||||
+number hero_uuid
|
||||
+string hero_name
|
||||
+number lv
|
||||
+number hp
|
||||
+number mp
|
||||
+number[] skills
|
||||
+Attrs attrs
|
||||
+do_atk()
|
||||
+do_dead()
|
||||
}
|
||||
class BattleMoveComp {
|
||||
+number direction
|
||||
+number targetX
|
||||
+boolean moving
|
||||
+update()
|
||||
}
|
||||
Hero --> HeroModelComp
|
||||
Hero --> HeroViewComp
|
||||
Hero --> BattleMoveComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L1-L100)
|
||||
|
||||
英雄系统是游戏的核心组成部分,包含以下关键特性:
|
||||
|
||||
1. **英雄类型系统**:分为战士、远程、法师、辅助、刺客五大职业类型
|
||||
2. **属性成长体系**:每个英雄有三条不同的成长方向
|
||||
3. **自动战斗机制**:英雄根据配置自动释放技能攻击敌人
|
||||
4. **技能系统**:支持普通攻击和大招技能的升级
|
||||
|
||||
**章节来源**
|
||||
- [Hero.ts](file://assets/script/game/hero/Hero.ts#L20-L100)
|
||||
- [heros.md](file://assets/script/heros.md#L300-L374)
|
||||
|
||||
### 地图系统
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class GameMap {
|
||||
+MapModelComp model
|
||||
+MapViewComp view
|
||||
+load()
|
||||
}
|
||||
class MapModelComp {
|
||||
+number id
|
||||
+string resPrefab
|
||||
+reset()
|
||||
}
|
||||
class MapViewComp {
|
||||
+Scene scene
|
||||
+Node entityLayer
|
||||
+Node mapLayer
|
||||
+startBattle()
|
||||
+endBattle()
|
||||
}
|
||||
GameMap --> MapModelComp
|
||||
GameMap --> MapViewComp
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
|
||||
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
|
||||
|
||||
地图系统负责:
|
||||
- **地图加载与渲染**:动态加载地图资源和显示地图场景
|
||||
- **战斗区域管理**:定义战斗发生的具体区域
|
||||
- **实体层管理**:管理英雄、怪物等游戏实体的显示层级
|
||||
|
||||
**章节来源**
|
||||
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L15-L36)
|
||||
|
||||
### 技能系统
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Player as 玩家
|
||||
participant Hero as 英雄
|
||||
participant Skill as 技能实体
|
||||
participant Target as 目标
|
||||
Player->>Hero : 选择技能
|
||||
Hero->>Skill : 创建技能实体
|
||||
Skill->>Skill : 加载预制体
|
||||
Skill->>Target : 执行技能效果
|
||||
Target->>Hero : 反馈伤害结果
|
||||
Hero->>Player : 更新状态显示
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L78)
|
||||
|
||||
技能系统特点:
|
||||
- **技能配置管理**:通过SkillSet统一管理技能配置
|
||||
- **自动施法机制**:技能根据英雄配置自动施放
|
||||
- **特效系统**:支持丰富的技能视觉效果
|
||||
|
||||
**章节来源**
|
||||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L10-L78)
|
||||
|
||||
## 游戏机制详解
|
||||
|
||||
### 自动战斗系统
|
||||
|
||||
游戏采用全自动战斗模式,玩家无需手动操作,战斗过程完全自动化:
|
||||
|
||||
1. **战斗触发**:当英雄进入敌人攻击范围时自动开始战斗
|
||||
2. **技能释放**:英雄根据配置自动释放普通攻击和大招
|
||||
3. **战斗结束**:当一方所有单位死亡时战斗结束
|
||||
|
||||
### 奖励选择系统
|
||||
|
||||
每波怪物清理后提供三种奖励选项:
|
||||
- **弱奖励**:消耗较少金币,提供基础属性提升
|
||||
- **一般奖励**:平衡的属性提升和技能升级
|
||||
- **强奖励**:高额金币消耗,提供强力属性加成
|
||||
|
||||
### 金币经济系统
|
||||
|
||||
- **金币获取**:通过击败怪物固定掉落获得
|
||||
- **金币消耗**:用于购买奖励选项
|
||||
- **策略性消费**:有限的金币总量要求玩家合理分配
|
||||
|
||||
**章节来源**
|
||||
- [Design.md](file://assets/script/Design.md#L10-L35)
|
||||
|
||||
## 数据管理系统
|
||||
|
||||
### 微信云开发集成
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 客户端
|
||||
participant WxCloud as 微信云
|
||||
participant Server as 云函数
|
||||
participant Database as 数据库
|
||||
Client->>WxCloud : 初始化云环境
|
||||
Client->>WxCloud : 用户登录
|
||||
WxCloud->>Server : 调用云函数
|
||||
Server->>Database : 查询/保存数据
|
||||
Database-->>Server : 返回数据
|
||||
Server-->>WxCloud : 返回结果
|
||||
WxCloud-->>Client : 完成操作
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L1-L94)
|
||||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L100-L150)
|
||||
|
||||
### 数据同步机制
|
||||
|
||||
1. **云端数据优先**:微信客户端优先使用云端数据
|
||||
2. **本地调试支持**:非微信客户端使用本地调试数据
|
||||
3. **数据覆盖策略**:云端数据直接覆盖本地数据
|
||||
4. **错误处理机制**:数据同步失败时提供回滚机制
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L80-L150)
|
||||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L20-L94)
|
||||
|
||||
## 架构设计亮点
|
||||
|
||||
### ECS架构应用
|
||||
|
||||
项目采用ECS(Entity-Component-System)架构模式,具有以下优势:
|
||||
|
||||
1. **组件化设计**:每个功能模块独立为组件,便于维护和扩展
|
||||
2. **数据与逻辑分离**:模型、视图、控制器职责明确
|
||||
3. **高性能执行**:系统按需处理相关组件,提高性能
|
||||
|
||||
### MVVM模式实现
|
||||
|
||||
通过Oops插件框架实现MVVM架构:
|
||||
- **Model**:数据模型,管理游戏状态
|
||||
- **View**:视图层,负责界面展示
|
||||
- **ViewModel**:视图模型,连接Model和View
|
||||
|
||||
### 单例模式应用
|
||||
|
||||
SingletonModuleComp作为全局数据管理中心,提供:
|
||||
- **全局状态管理**:统一管理游戏全局状态
|
||||
- **数据持久化**:支持本地和云端数据存储
|
||||
- **事件通信**:提供全局事件分发机制
|
||||
|
||||
**章节来源**
|
||||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L15-L50)
|
||||
|
||||
## 总结
|
||||
|
||||
Heros项目展现了现代游戏开发的最佳实践,通过以下方面体现了优秀的架构设计:
|
||||
|
||||
### 技术创新
|
||||
- **混合架构**:结合ECS和MVVM模式,实现高效的游戏开发
|
||||
- **跨平台支持**:基于Cocos Creator的跨平台解决方案
|
||||
- **云端集成**:充分利用微信云开发的便利性
|
||||
|
||||
### 游戏设计
|
||||
- **策略深度**:通过奖励系统和英雄特性维持游戏深度
|
||||
- **文化价值**:将历史文化融入游戏设计
|
||||
- **用户体验**:简化操作的同时保持策略性
|
||||
|
||||
### 架构优势
|
||||
- **模块化设计**:清晰的功能模块划分,便于维护和扩展
|
||||
- **数据管理**:完善的本地和云端数据管理机制
|
||||
- **性能优化**:合理的架构设计确保良好的游戏性能
|
||||
|
||||
该项目不仅是一个成功的商业游戏案例,也为类似项目提供了宝贵的架构参考和设计思路。通过深入理解其技术架构和设计理念,开发者可以更好地把握现代游戏开发的趋势和最佳实践。
|
||||
1
.qoder/repowiki/zh/meta/repowiki-metadata.json
Normal file
1
.qoder/repowiki/zh/meta/repowiki-metadata.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -345,7 +345,7 @@
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "f87f53f9-2fba-4a5b-968a-79a593311ab2@49762",
|
||||
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73@23c37",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
"_type": 0,
|
||||
@@ -360,7 +360,10 @@
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_useGrayscale": false,
|
||||
"_atlas": null,
|
||||
"_atlas": {
|
||||
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73",
|
||||
"__expectedType__": "cc.SpriteAtlas"
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
|
||||
@@ -22,31 +22,34 @@
|
||||
"__id__": 2
|
||||
},
|
||||
{
|
||||
"__id__": 8
|
||||
"__id__": 25
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 16
|
||||
"__id__": 33
|
||||
},
|
||||
{
|
||||
"__id__": 18
|
||||
"__id__": 35
|
||||
},
|
||||
{
|
||||
"__id__": 20
|
||||
"__id__": 37
|
||||
},
|
||||
{
|
||||
"__id__": 22
|
||||
"__id__": 39
|
||||
},
|
||||
{
|
||||
"__id__": 41
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 24
|
||||
"__id__": 43
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"y": 365,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -74,29 +77,116 @@
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "ToastMessage_Bg_Gray",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_prefab": {
|
||||
"__id__": 3
|
||||
},
|
||||
"__editorExtras__": {}
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 2
|
||||
},
|
||||
"asset": {
|
||||
"__uuid__": "fbbc9ff5-0bcf-4e92-9c71-f9dc27a30158",
|
||||
"__expectedType__": "cc.Prefab"
|
||||
},
|
||||
"fileId": "0bP5AdjVNKbIVXJK2hNWPD",
|
||||
"instance": {
|
||||
"__id__": 4
|
||||
},
|
||||
"targetOverrides": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInstance",
|
||||
"fileId": "58cIYrwIBIUJTPYa+To7Os",
|
||||
"prefabRootNode": {
|
||||
"__id__": 1
|
||||
},
|
||||
"mountedChildren": [
|
||||
{
|
||||
"__id__": 5
|
||||
}
|
||||
],
|
||||
"mountedComponents": [],
|
||||
"propertyOverrides": [
|
||||
{
|
||||
"__id__": 13
|
||||
},
|
||||
{
|
||||
"__id__": 15
|
||||
},
|
||||
{
|
||||
"__id__": 16
|
||||
},
|
||||
{
|
||||
"__id__": 17
|
||||
},
|
||||
{
|
||||
"__id__": 18
|
||||
},
|
||||
{
|
||||
"__id__": 20
|
||||
},
|
||||
{
|
||||
"__id__": 22
|
||||
},
|
||||
{
|
||||
"__id__": 24
|
||||
}
|
||||
],
|
||||
"removedComponents": []
|
||||
},
|
||||
{
|
||||
"__type__": "cc.MountedChildrenInfo",
|
||||
"targetInfo": {
|
||||
"__id__": 6
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"__id__": 7
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"__type__": "cc.TargetInfo",
|
||||
"localID": [
|
||||
"0bP5AdjVNKbIVXJK2hNWPD"
|
||||
]
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "ItemIcon_Scroll_Feather",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {
|
||||
"mountedRoot": {
|
||||
"__id__": 2
|
||||
}
|
||||
},
|
||||
"_parent": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 3
|
||||
"__id__": 8
|
||||
},
|
||||
{
|
||||
"__id__": 5
|
||||
"__id__": 10
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 7
|
||||
"__id__": 12
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"x": -297.311,
|
||||
"y": 40.47700000000009,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -108,8 +198,8 @@
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"x": 0.7,
|
||||
"y": 0.7,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
@@ -128,16 +218,16 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 2
|
||||
"__id__": 7
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 4
|
||||
"__id__": 9
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 800,
|
||||
"height": 60
|
||||
"width": 122,
|
||||
"height": 112
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -148,7 +238,7 @@
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "daWGVMfiBINaoHLXMFGxnx"
|
||||
"fileId": "95euAr+ABP4aTgxKUFnC10"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
@@ -156,29 +246,29 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 2
|
||||
"__id__": 7
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 6
|
||||
"__id__": 11
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
"_dstBlendFactor": 4,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 112,
|
||||
"g": 112,
|
||||
"b": 112,
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "f87f53f9-2fba-4a5b-968a-79a593311ab2@85c63",
|
||||
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73@6a8a9",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
"_type": 1,
|
||||
"_type": 0,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 0,
|
||||
"_sizeMode": 1,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
@@ -187,13 +277,13 @@
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_useGrayscale": true,
|
||||
"_useGrayscale": false,
|
||||
"_atlas": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "3fUgziN35AapBo1Cf9UAoy"
|
||||
"fileId": "87hztWZFVH0L7943RpKfAr"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
@@ -203,11 +293,139 @@
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "249lHuvrpOfrKXv35DvZQA",
|
||||
"fileId": "fbQMFJWSFAgpDKxvWpMcqN",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "CCPropertyOverrideInfo",
|
||||
"targetInfo": {
|
||||
"__id__": 14
|
||||
},
|
||||
"propertyPath": [
|
||||
"_name"
|
||||
],
|
||||
"value": "slist"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.TargetInfo",
|
||||
"localID": [
|
||||
"0bP5AdjVNKbIVXJK2hNWPD"
|
||||
]
|
||||
},
|
||||
{
|
||||
"__type__": "CCPropertyOverrideInfo",
|
||||
"targetInfo": {
|
||||
"__id__": 14
|
||||
},
|
||||
"propertyPath": [
|
||||
"_lpos"
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"__type__": "CCPropertyOverrideInfo",
|
||||
"targetInfo": {
|
||||
"__id__": 14
|
||||
},
|
||||
"propertyPath": [
|
||||
"_lrot"
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"__type__": "CCPropertyOverrideInfo",
|
||||
"targetInfo": {
|
||||
"__id__": 14
|
||||
},
|
||||
"propertyPath": [
|
||||
"_euler"
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"__type__": "CCPropertyOverrideInfo",
|
||||
"targetInfo": {
|
||||
"__id__": 19
|
||||
},
|
||||
"propertyPath": [
|
||||
"_contentSize"
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 680,
|
||||
"height": 120
|
||||
}
|
||||
},
|
||||
{
|
||||
"__type__": "cc.TargetInfo",
|
||||
"localID": [
|
||||
"53s5rNSsdM1rRVM8XF85z1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"__type__": "CCPropertyOverrideInfo",
|
||||
"targetInfo": {
|
||||
"__id__": 21
|
||||
},
|
||||
"propertyPath": [
|
||||
"_contentSize"
|
||||
],
|
||||
"value": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 680,
|
||||
"height": 120
|
||||
}
|
||||
},
|
||||
{
|
||||
"__type__": "cc.TargetInfo",
|
||||
"localID": [
|
||||
"0fDjKrHkFN9YsEzQamA+QJ"
|
||||
]
|
||||
},
|
||||
{
|
||||
"__type__": "CCPropertyOverrideInfo",
|
||||
"targetInfo": {
|
||||
"__id__": 23
|
||||
},
|
||||
"propertyPath": [
|
||||
"_left"
|
||||
],
|
||||
"value": 10
|
||||
},
|
||||
{
|
||||
"__type__": "cc.TargetInfo",
|
||||
"localID": [
|
||||
"88vjsnrkhKvrT5BHQt/TeZ"
|
||||
]
|
||||
},
|
||||
{
|
||||
"__type__": "CCPropertyOverrideInfo",
|
||||
"targetInfo": {
|
||||
"__id__": 23
|
||||
},
|
||||
"propertyPath": [
|
||||
"_right"
|
||||
],
|
||||
"value": 10
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "lab_content",
|
||||
@@ -220,17 +438,17 @@
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 9
|
||||
"__id__": 26
|
||||
},
|
||||
{
|
||||
"__id__": 11
|
||||
"__id__": 28
|
||||
},
|
||||
{
|
||||
"__id__": 13
|
||||
"__id__": 30
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 15
|
||||
"__id__": 32
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -267,16 +485,16 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 8
|
||||
"__id__": 25
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 10
|
||||
"__id__": 27
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 102.408203125,
|
||||
"height": 41.8
|
||||
"width": 600,
|
||||
"height": 54.4
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -295,11 +513,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 8
|
||||
"__id__": 25
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 12
|
||||
"__id__": 29
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
@@ -311,14 +529,14 @@
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_string": "content",
|
||||
"_string": "信息",
|
||||
"_horizontalAlign": 1,
|
||||
"_verticalAlign": 1,
|
||||
"_actualFontSize": 30,
|
||||
"_fontSize": 30,
|
||||
"_actualFontSize": 35,
|
||||
"_fontSize": 35,
|
||||
"_fontFamily": "Arial",
|
||||
"_lineHeight": 30,
|
||||
"_overflow": 0,
|
||||
"_lineHeight": 40,
|
||||
"_overflow": 3,
|
||||
"_enableWrapText": true,
|
||||
"_font": null,
|
||||
"_isSystemFontUsed": true,
|
||||
@@ -363,11 +581,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 8
|
||||
"__id__": 25
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 14
|
||||
"__id__": 31
|
||||
},
|
||||
"_params": [],
|
||||
"_dataID": "",
|
||||
@@ -400,12 +618,12 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 17
|
||||
"__id__": 34
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 539,
|
||||
"height": 90
|
||||
"width": 700,
|
||||
"height": 150
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -428,7 +646,7 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 19
|
||||
"__id__": 36
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
@@ -470,7 +688,7 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 21
|
||||
"__id__": 38
|
||||
},
|
||||
"playOnLoad": true,
|
||||
"_clips": [
|
||||
@@ -499,13 +717,13 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 23
|
||||
"__id__": 40
|
||||
},
|
||||
"lab_content": {
|
||||
"__id__": 11
|
||||
"__id__": 28
|
||||
},
|
||||
"animation": {
|
||||
"__id__": 20
|
||||
"__id__": 37
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
@@ -513,6 +731,42 @@
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "965Ml9gPBIqJ2+GUadTe+K"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 42
|
||||
},
|
||||
"_alignFlags": 1,
|
||||
"_target": null,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 200,
|
||||
"_bottom": 0,
|
||||
"_horizontalCenter": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 0,
|
||||
"_originalHeight": 0,
|
||||
"_alignMode": 2,
|
||||
"_lockFlags": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "a2zw+Or45DsIUs9Ufp1kbN"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
@@ -523,6 +777,11 @@
|
||||
},
|
||||
"fileId": "4fj6jVgO1KzKob1u6D65Ik",
|
||||
"instance": null,
|
||||
"targetOverrides": null
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": [
|
||||
{
|
||||
"__id__": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
Binary file not shown.
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"ver": "1.0.1",
|
||||
"importer": "ttf-font",
|
||||
"imported": true,
|
||||
"uuid": "a8f2a4a3-911f-43d3-9174-f2176554d7d4",
|
||||
"files": [
|
||||
".json",
|
||||
"Anton-Regular.ttf"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "e8fdb73f-0f68-4f2e-b93c-33ad80d67a9e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
@@ -1,134 +0,0 @@
|
||||
{
|
||||
"ver": "1.0.26",
|
||||
"importer": "image",
|
||||
"imported": true,
|
||||
"uuid": "8f6e46a9-2249-44fc-8a3b-324e76e037e7",
|
||||
"files": [
|
||||
".json",
|
||||
".png"
|
||||
],
|
||||
"subMetas": {
|
||||
"6c48a": {
|
||||
"importer": "texture",
|
||||
"uuid": "8f6e46a9-2249-44fc-8a3b-324e76e037e7@6c48a",
|
||||
"displayName": "Layer01",
|
||||
"id": "6c48a",
|
||||
"name": "texture",
|
||||
"userData": {
|
||||
"wrapModeS": "clamp-to-edge",
|
||||
"wrapModeT": "clamp-to-edge",
|
||||
"minfilter": "linear",
|
||||
"magfilter": "linear",
|
||||
"mipfilter": "none",
|
||||
"anisotropy": 0,
|
||||
"isUuid": true,
|
||||
"imageUuidOrDatabaseUri": "8f6e46a9-2249-44fc-8a3b-324e76e037e7",
|
||||
"visible": false
|
||||
},
|
||||
"ver": "1.0.22",
|
||||
"imported": true,
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {}
|
||||
},
|
||||
"f9941": {
|
||||
"importer": "sprite-frame",
|
||||
"uuid": "8f6e46a9-2249-44fc-8a3b-324e76e037e7@f9941",
|
||||
"displayName": "Layer01",
|
||||
"id": "f9941",
|
||||
"name": "spriteFrame",
|
||||
"userData": {
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": -357.5,
|
||||
"trimX": 0,
|
||||
"trimY": 715,
|
||||
"width": 1180,
|
||||
"height": 885,
|
||||
"rawWidth": 1180,
|
||||
"rawHeight": 1600,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"packable": true,
|
||||
"pixelsToUnit": 100,
|
||||
"pivotX": 0.5,
|
||||
"pivotY": 0.5,
|
||||
"meshType": 0,
|
||||
"vertices": {
|
||||
"rawPosition": [
|
||||
-590,
|
||||
-442.5,
|
||||
0,
|
||||
590,
|
||||
-442.5,
|
||||
0,
|
||||
-590,
|
||||
442.5,
|
||||
0,
|
||||
590,
|
||||
442.5,
|
||||
0
|
||||
],
|
||||
"indexes": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
3
|
||||
],
|
||||
"uv": [
|
||||
0,
|
||||
885,
|
||||
1180,
|
||||
885,
|
||||
0,
|
||||
0,
|
||||
1180,
|
||||
0
|
||||
],
|
||||
"nuv": [
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0.553125,
|
||||
1,
|
||||
0.553125
|
||||
],
|
||||
"minPos": [
|
||||
-590,
|
||||
-442.5,
|
||||
0
|
||||
],
|
||||
"maxPos": [
|
||||
590,
|
||||
442.5,
|
||||
0
|
||||
]
|
||||
},
|
||||
"isUuid": true,
|
||||
"imageUuidOrDatabaseUri": "8f6e46a9-2249-44fc-8a3b-324e76e037e7@6c48a",
|
||||
"atlasUuid": ""
|
||||
},
|
||||
"ver": "1.0.12",
|
||||
"imported": true,
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {}
|
||||
}
|
||||
},
|
||||
"userData": {
|
||||
"hasAlpha": true,
|
||||
"type": "sprite-frame",
|
||||
"fixAlphaTransparencyArtifacts": false,
|
||||
"redirect": "8f6e46a9-2249-44fc-8a3b-324e76e037e7@f9941"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,134 +0,0 @@
|
||||
{
|
||||
"ver": "1.0.26",
|
||||
"importer": "image",
|
||||
"imported": true,
|
||||
"uuid": "32133d6d-5ec3-44fe-b8ff-b95f73314284",
|
||||
"files": [
|
||||
".json",
|
||||
".png"
|
||||
],
|
||||
"subMetas": {
|
||||
"6c48a": {
|
||||
"importer": "texture",
|
||||
"uuid": "32133d6d-5ec3-44fe-b8ff-b95f73314284@6c48a",
|
||||
"displayName": "Layer03",
|
||||
"id": "6c48a",
|
||||
"name": "texture",
|
||||
"userData": {
|
||||
"wrapModeS": "clamp-to-edge",
|
||||
"wrapModeT": "clamp-to-edge",
|
||||
"minfilter": "linear",
|
||||
"magfilter": "linear",
|
||||
"mipfilter": "none",
|
||||
"anisotropy": 0,
|
||||
"isUuid": true,
|
||||
"imageUuidOrDatabaseUri": "32133d6d-5ec3-44fe-b8ff-b95f73314284",
|
||||
"visible": false
|
||||
},
|
||||
"ver": "1.0.22",
|
||||
"imported": true,
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {}
|
||||
},
|
||||
"f9941": {
|
||||
"importer": "sprite-frame",
|
||||
"uuid": "32133d6d-5ec3-44fe-b8ff-b95f73314284@f9941",
|
||||
"displayName": "Layer03",
|
||||
"id": "f9941",
|
||||
"name": "spriteFrame",
|
||||
"userData": {
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 87.5,
|
||||
"trimX": 0,
|
||||
"trimY": 653,
|
||||
"width": 1180,
|
||||
"height": 119,
|
||||
"rawWidth": 1180,
|
||||
"rawHeight": 1600,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"packable": true,
|
||||
"pixelsToUnit": 100,
|
||||
"pivotX": 0.5,
|
||||
"pivotY": 0.5,
|
||||
"meshType": 0,
|
||||
"vertices": {
|
||||
"rawPosition": [
|
||||
-590,
|
||||
-59.5,
|
||||
0,
|
||||
590,
|
||||
-59.5,
|
||||
0,
|
||||
-590,
|
||||
59.5,
|
||||
0,
|
||||
590,
|
||||
59.5,
|
||||
0
|
||||
],
|
||||
"indexes": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
3
|
||||
],
|
||||
"uv": [
|
||||
0,
|
||||
947,
|
||||
1180,
|
||||
947,
|
||||
0,
|
||||
828,
|
||||
1180,
|
||||
828
|
||||
],
|
||||
"nuv": [
|
||||
0,
|
||||
0.5175,
|
||||
1,
|
||||
0.5175,
|
||||
0,
|
||||
0.591875,
|
||||
1,
|
||||
0.591875
|
||||
],
|
||||
"minPos": [
|
||||
-590,
|
||||
-59.5,
|
||||
0
|
||||
],
|
||||
"maxPos": [
|
||||
590,
|
||||
59.5,
|
||||
0
|
||||
]
|
||||
},
|
||||
"isUuid": true,
|
||||
"imageUuidOrDatabaseUri": "32133d6d-5ec3-44fe-b8ff-b95f73314284@6c48a",
|
||||
"atlasUuid": ""
|
||||
},
|
||||
"ver": "1.0.12",
|
||||
"imported": true,
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {}
|
||||
}
|
||||
},
|
||||
"userData": {
|
||||
"hasAlpha": true,
|
||||
"type": "sprite-frame",
|
||||
"fixAlphaTransparencyArtifacts": false,
|
||||
"redirect": "32133d6d-5ec3-44fe-b8ff-b95f73314284@f9941"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
@@ -1,134 +0,0 @@
|
||||
{
|
||||
"ver": "1.0.26",
|
||||
"importer": "image",
|
||||
"imported": true,
|
||||
"uuid": "78557b60-f387-4160-b471-5e69d80eb1d8",
|
||||
"files": [
|
||||
".json",
|
||||
".png"
|
||||
],
|
||||
"subMetas": {
|
||||
"6c48a": {
|
||||
"importer": "texture",
|
||||
"uuid": "78557b60-f387-4160-b471-5e69d80eb1d8@6c48a",
|
||||
"displayName": "Layer04",
|
||||
"id": "6c48a",
|
||||
"name": "texture",
|
||||
"userData": {
|
||||
"wrapModeS": "clamp-to-edge",
|
||||
"wrapModeT": "clamp-to-edge",
|
||||
"minfilter": "linear",
|
||||
"magfilter": "linear",
|
||||
"mipfilter": "none",
|
||||
"anisotropy": 0,
|
||||
"isUuid": true,
|
||||
"imageUuidOrDatabaseUri": "78557b60-f387-4160-b471-5e69d80eb1d8",
|
||||
"visible": false
|
||||
},
|
||||
"ver": "1.0.22",
|
||||
"imported": true,
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {}
|
||||
},
|
||||
"f9941": {
|
||||
"importer": "sprite-frame",
|
||||
"uuid": "78557b60-f387-4160-b471-5e69d80eb1d8@f9941",
|
||||
"displayName": "Layer04",
|
||||
"id": "f9941",
|
||||
"name": "spriteFrame",
|
||||
"userData": {
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": -25.5,
|
||||
"offsetY": 513,
|
||||
"trimX": 35,
|
||||
"trimY": 121,
|
||||
"width": 1059,
|
||||
"height": 332,
|
||||
"rawWidth": 1180,
|
||||
"rawHeight": 1600,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"packable": true,
|
||||
"pixelsToUnit": 100,
|
||||
"pivotX": 0.5,
|
||||
"pivotY": 0.5,
|
||||
"meshType": 0,
|
||||
"vertices": {
|
||||
"rawPosition": [
|
||||
-529.5,
|
||||
-166,
|
||||
0,
|
||||
529.5,
|
||||
-166,
|
||||
0,
|
||||
-529.5,
|
||||
166,
|
||||
0,
|
||||
529.5,
|
||||
166,
|
||||
0
|
||||
],
|
||||
"indexes": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
3
|
||||
],
|
||||
"uv": [
|
||||
35,
|
||||
1479,
|
||||
1094,
|
||||
1479,
|
||||
35,
|
||||
1147,
|
||||
1094,
|
||||
1147
|
||||
],
|
||||
"nuv": [
|
||||
0.029661016949152543,
|
||||
0.716875,
|
||||
0.9271186440677966,
|
||||
0.716875,
|
||||
0.029661016949152543,
|
||||
0.924375,
|
||||
0.9271186440677966,
|
||||
0.924375
|
||||
],
|
||||
"minPos": [
|
||||
-529.5,
|
||||
-166,
|
||||
0
|
||||
],
|
||||
"maxPos": [
|
||||
529.5,
|
||||
166,
|
||||
0
|
||||
]
|
||||
},
|
||||
"isUuid": true,
|
||||
"imageUuidOrDatabaseUri": "78557b60-f387-4160-b471-5e69d80eb1d8@6c48a",
|
||||
"atlasUuid": ""
|
||||
},
|
||||
"ver": "1.0.12",
|
||||
"imported": true,
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {}
|
||||
}
|
||||
},
|
||||
"userData": {
|
||||
"hasAlpha": true,
|
||||
"type": "sprite-frame",
|
||||
"fixAlphaTransparencyArtifacts": false,
|
||||
"redirect": "78557b60-f387-4160-b471-5e69d80eb1d8@f9941"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
@@ -1,134 +0,0 @@
|
||||
{
|
||||
"ver": "1.0.26",
|
||||
"importer": "image",
|
||||
"imported": true,
|
||||
"uuid": "a42dc8e2-1334-40a3-8917-7e3953fcc082",
|
||||
"files": [
|
||||
".json",
|
||||
".png"
|
||||
],
|
||||
"subMetas": {
|
||||
"6c48a": {
|
||||
"importer": "texture",
|
||||
"uuid": "a42dc8e2-1334-40a3-8917-7e3953fcc082@6c48a",
|
||||
"displayName": "Layer05",
|
||||
"id": "6c48a",
|
||||
"name": "texture",
|
||||
"userData": {
|
||||
"wrapModeS": "clamp-to-edge",
|
||||
"wrapModeT": "clamp-to-edge",
|
||||
"minfilter": "linear",
|
||||
"magfilter": "linear",
|
||||
"mipfilter": "none",
|
||||
"anisotropy": 0,
|
||||
"isUuid": true,
|
||||
"imageUuidOrDatabaseUri": "a42dc8e2-1334-40a3-8917-7e3953fcc082",
|
||||
"visible": false
|
||||
},
|
||||
"ver": "1.0.22",
|
||||
"imported": true,
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {}
|
||||
},
|
||||
"f9941": {
|
||||
"importer": "sprite-frame",
|
||||
"uuid": "a42dc8e2-1334-40a3-8917-7e3953fcc082@f9941",
|
||||
"displayName": "Layer05",
|
||||
"id": "f9941",
|
||||
"name": "spriteFrame",
|
||||
"userData": {
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 433.5,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 1180,
|
||||
"height": 733,
|
||||
"rawWidth": 1180,
|
||||
"rawHeight": 1600,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"packable": true,
|
||||
"pixelsToUnit": 100,
|
||||
"pivotX": 0.5,
|
||||
"pivotY": 0.5,
|
||||
"meshType": 0,
|
||||
"vertices": {
|
||||
"rawPosition": [
|
||||
-590,
|
||||
-366.5,
|
||||
0,
|
||||
590,
|
||||
-366.5,
|
||||
0,
|
||||
-590,
|
||||
366.5,
|
||||
0,
|
||||
590,
|
||||
366.5,
|
||||
0
|
||||
],
|
||||
"indexes": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
3
|
||||
],
|
||||
"uv": [
|
||||
0,
|
||||
1600,
|
||||
1180,
|
||||
1600,
|
||||
0,
|
||||
867,
|
||||
1180,
|
||||
867
|
||||
],
|
||||
"nuv": [
|
||||
0,
|
||||
0.541875,
|
||||
1,
|
||||
0.541875,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"minPos": [
|
||||
-590,
|
||||
-366.5,
|
||||
0
|
||||
],
|
||||
"maxPos": [
|
||||
590,
|
||||
366.5,
|
||||
0
|
||||
]
|
||||
},
|
||||
"isUuid": true,
|
||||
"imageUuidOrDatabaseUri": "a42dc8e2-1334-40a3-8917-7e3953fcc082@6c48a",
|
||||
"atlasUuid": ""
|
||||
},
|
||||
"ver": "1.0.12",
|
||||
"imported": true,
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {}
|
||||
}
|
||||
},
|
||||
"userData": {
|
||||
"hasAlpha": true,
|
||||
"type": "sprite-frame",
|
||||
"fixAlphaTransparencyArtifacts": false,
|
||||
"redirect": "a42dc8e2-1334-40a3-8917-7e3953fcc082@f9941"
|
||||
}
|
||||
}
|
||||
9
assets/resources/game/05-outline-glow.meta
Normal file
9
assets/resources/game/05-outline-glow.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "af691440-7aca-4cb5-9a78-9bfed9cb70de",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
BIN
assets/resources/game/05-outline-glow/.DS_Store
vendored
Normal file
BIN
assets/resources/game/05-outline-glow/.DS_Store
vendored
Normal file
Binary file not shown.
1
assets/resources/game/05-outline-glow/materials.meta
Normal file
1
assets/resources/game/05-outline-glow/materials.meta
Normal file
@@ -0,0 +1 @@
|
||||
{"ver":"1.2.0","importer":"directory","imported":true,"uuid":"551a2611-69c0-45ae-bfc6-37f056a34b33","files":[],"subMetas":{},"userData":{}}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"__type__": "cc.Material",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_native": "",
|
||||
"_effectAsset": {
|
||||
"__uuid__": "cfeeea4f-db9c-42cd-a0f7-fc5cb37bd3d7",
|
||||
"__expectedType__": "cc.EffectAsset"
|
||||
},
|
||||
"_techIdx": 0,
|
||||
"_defines": [
|
||||
{
|
||||
"USE_TEXTURE": true
|
||||
}
|
||||
],
|
||||
"_states": [
|
||||
{
|
||||
"rasterizerState": {},
|
||||
"depthStencilState": {},
|
||||
"blendState": {
|
||||
"targets": [
|
||||
{}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"_props": [
|
||||
{
|
||||
"glowColor": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 0,
|
||||
"g": 0,
|
||||
"b": 0,
|
||||
"a": 255
|
||||
},
|
||||
"glowWidth": 0.003,
|
||||
"glowThreshold": 0.645
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"ver":"1.0.21","importer":"material","imported":true,"uuid":"2fcd55a9-38ca-45aa-9164-68e48aaf51ce","files":[".json"],"subMetas":{},"userData":{}}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"__type__": "cc.Material",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_native": "",
|
||||
"_effectAsset": {
|
||||
"__uuid__": "40c25c17-db22-4ae7-8d3a-f73cbb6d36ba",
|
||||
"__expectedType__": "cc.EffectAsset"
|
||||
},
|
||||
"_techIdx": 0,
|
||||
"_defines": [
|
||||
{
|
||||
"USE_TEXTURE": true
|
||||
}
|
||||
],
|
||||
"_states": [
|
||||
{
|
||||
"rasterizerState": {},
|
||||
"depthStencilState": {},
|
||||
"blendState": {
|
||||
"targets": [
|
||||
{}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"_props": [
|
||||
{
|
||||
"glowColor": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 235,
|
||||
"b": 0,
|
||||
"a": 255
|
||||
},
|
||||
"glowWidth": 0.002
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"ver":"1.0.21","importer":"material","imported":true,"uuid":"974af3c9-d7ee-449f-a5df-cd8e2dd49188","files":[".json"],"subMetas":{},"userData":{}}
|
||||
1
assets/resources/game/05-outline-glow/shaders.meta
Normal file
1
assets/resources/game/05-outline-glow/shaders.meta
Normal file
@@ -0,0 +1 @@
|
||||
{"ver":"1.2.0","importer":"directory","imported":true,"uuid":"7d369c63-9191-4323-abcc-edda5799a410","files":[],"subMetas":{},"userData":{}}
|
||||
@@ -0,0 +1,169 @@
|
||||
// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
|
||||
CCEffect %{
|
||||
techniques:
|
||||
- passes:
|
||||
- vert: sprite-vs:vert
|
||||
frag: sprite-fs:frag
|
||||
depthStencilState:
|
||||
depthTest: false
|
||||
depthWrite: false
|
||||
blendState:
|
||||
targets:
|
||||
- blend: true
|
||||
blendSrc: src_alpha
|
||||
blendDst: one_minus_src_alpha
|
||||
blendDstAlpha: one_minus_src_alpha
|
||||
rasterizerState:
|
||||
cullMode: none
|
||||
properties:
|
||||
alphaThreshold: { value: 0.5 }
|
||||
|
||||
glowColor: { value: [1, 1, 1, 1], editor: { type: color } }
|
||||
glowWidth: { value: 0.05, editor: { slide: true, range: [0, 0.3], step: 0.001 } }
|
||||
glowThreshold: { value: 1, editor: { slide: true, range: [0, 1], step: 0.001 } }
|
||||
}%
|
||||
|
||||
CCProgram sprite-vs %{
|
||||
precision highp float;
|
||||
#include <builtin/uniforms/cc-global>
|
||||
#if USE_LOCAL
|
||||
#include <builtin/uniforms/cc-local>
|
||||
#endif
|
||||
#if SAMPLE_FROM_RT
|
||||
#include <common/common-define>
|
||||
#endif
|
||||
in vec3 a_position;
|
||||
in vec2 a_texCoord;
|
||||
in vec4 a_color;
|
||||
|
||||
out vec4 color;
|
||||
out vec2 uv0;
|
||||
|
||||
vec4 vert () {
|
||||
vec4 pos = vec4(a_position, 1);
|
||||
|
||||
#if USE_LOCAL
|
||||
pos = cc_matWorld * pos;
|
||||
#endif
|
||||
|
||||
#if USE_PIXEL_ALIGNMENT
|
||||
pos = cc_matView * pos;
|
||||
pos.xyz = floor(pos.xyz);
|
||||
pos = cc_matProj * pos;
|
||||
#else
|
||||
pos = cc_matViewProj * pos;
|
||||
#endif
|
||||
|
||||
uv0 = a_texCoord;
|
||||
#if SAMPLE_FROM_RT
|
||||
CC_HANDLE_RT_SAMPLE_FLIP(uv0);
|
||||
#endif
|
||||
color = a_color;
|
||||
|
||||
return pos;
|
||||
}
|
||||
}%
|
||||
|
||||
CCProgram sprite-fs %{
|
||||
precision highp float;
|
||||
#include <builtin/internal/embedded-alpha>
|
||||
#include <builtin/internal/alpha-test>
|
||||
|
||||
in vec4 color;
|
||||
|
||||
uniform FSConstants {
|
||||
vec4 glowColor;
|
||||
float glowWidth;
|
||||
float glowThreshold;
|
||||
};
|
||||
|
||||
#if USE_TEXTURE
|
||||
in vec2 uv0;
|
||||
#pragma builtin(local)
|
||||
layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture;
|
||||
#endif
|
||||
|
||||
vec4 getTextureColor (sampler2D mainTexture, vec2 uv) {
|
||||
if (uv.x > 1.0 || uv.x < 0.0 || uv.y > 1.0 || uv.y < 0.0) {
|
||||
return vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
return texture(mainTexture, uv);
|
||||
}
|
||||
|
||||
float getColorAlpha (float angle, float dist) {
|
||||
// 角度转弧度,公式为:弧度 = 角度 * (pi / 180)
|
||||
float radian = angle * 3.14 / 180.0;
|
||||
vec2 newUV = uv0 + vec2(dist * cos(radian), dist * sin(radian));
|
||||
vec4 color = getTextureColor(cc_spriteTexture, newUV);
|
||||
return color.a;
|
||||
}
|
||||
|
||||
float getAverageAlpha (float dist) {
|
||||
float totalAlpha = 0.0;
|
||||
|
||||
totalAlpha += getColorAlpha(0.0, dist);
|
||||
totalAlpha += getColorAlpha(30.0, dist);
|
||||
totalAlpha += getColorAlpha(60.0, dist);
|
||||
totalAlpha += getColorAlpha(90.0, dist);
|
||||
totalAlpha += getColorAlpha(120.0, dist);
|
||||
totalAlpha += getColorAlpha(150.0, dist);
|
||||
totalAlpha += getColorAlpha(180.0, dist);
|
||||
totalAlpha += getColorAlpha(210.0, dist);
|
||||
totalAlpha += getColorAlpha(240.0, dist);
|
||||
totalAlpha += getColorAlpha(270.0, dist);
|
||||
totalAlpha += getColorAlpha(300.0, dist);
|
||||
totalAlpha += getColorAlpha(330.0, dist);
|
||||
|
||||
return totalAlpha * 0.0833;
|
||||
}
|
||||
|
||||
float getGlowAlpha () {
|
||||
if (glowWidth == 0.0 ) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float totalAlpha = 0.0;
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.1);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.2);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.3);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.4);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.5);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.6);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.7);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.8);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.9);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 1.0);
|
||||
|
||||
return totalAlpha * 0.1;
|
||||
}
|
||||
|
||||
vec4 frag () {
|
||||
vec4 o = vec4(1, 1, 1, 1);
|
||||
|
||||
#if USE_TEXTURE
|
||||
o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);
|
||||
#if IS_GRAY
|
||||
float gray = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;
|
||||
o.r = o.g = o.b = gray;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float alpha = getGlowAlpha();
|
||||
|
||||
if (alpha <= glowThreshold) {
|
||||
alpha /= glowThreshold;
|
||||
alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0;
|
||||
} else {
|
||||
alpha = 0.0;
|
||||
}
|
||||
|
||||
vec4 dstColor = glowColor * alpha;
|
||||
vec4 scrColor = o;
|
||||
|
||||
o = scrColor * scrColor.a + dstColor * (1.0 - scrColor.a);
|
||||
|
||||
o *= color;
|
||||
ALPHA_TEST(o);
|
||||
return o;
|
||||
}
|
||||
}%
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"ver": "1.7.1",
|
||||
"importer": "effect",
|
||||
"imported": true,
|
||||
"uuid": "cfeeea4f-db9c-42cd-a0f7-fc5cb37bd3d7",
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"combinations": [
|
||||
{}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
|
||||
CCEffect %{
|
||||
techniques:
|
||||
- passes:
|
||||
- vert: sprite-vs:vert
|
||||
frag: sprite-fs:frag
|
||||
depthStencilState:
|
||||
depthTest: false
|
||||
depthWrite: false
|
||||
blendState:
|
||||
targets:
|
||||
- blend: true
|
||||
blendSrc: src_alpha
|
||||
blendDst: one_minus_src_alpha
|
||||
blendDstAlpha: one_minus_src_alpha
|
||||
rasterizerState:
|
||||
cullMode: none
|
||||
properties:
|
||||
alphaThreshold: { value: 0.5 }
|
||||
|
||||
glowColor: { value: [1, 1, 1, 1], editor: { type: color } }
|
||||
glowWidth: { value: 0.05, editor: { slide: true, range: [0, 0.3], step: 0.001 } }
|
||||
glowThreshold: { value: 1, editor: { slide: true, range: [0, 1], step: 0.001 } }
|
||||
}%
|
||||
|
||||
CCProgram sprite-vs %{
|
||||
precision highp float;
|
||||
#include <builtin/uniforms/cc-global>
|
||||
#if USE_LOCAL
|
||||
#include <builtin/uniforms/cc-local>
|
||||
#endif
|
||||
#if SAMPLE_FROM_RT
|
||||
#include <common/common-define>
|
||||
#endif
|
||||
in vec3 a_position;
|
||||
in vec2 a_texCoord;
|
||||
in vec4 a_color;
|
||||
|
||||
out vec4 color;
|
||||
out vec2 uv0;
|
||||
|
||||
vec4 vert () {
|
||||
vec4 pos = vec4(a_position, 1);
|
||||
|
||||
#if USE_LOCAL
|
||||
pos = cc_matWorld * pos;
|
||||
#endif
|
||||
|
||||
#if USE_PIXEL_ALIGNMENT
|
||||
pos = cc_matView * pos;
|
||||
pos.xyz = floor(pos.xyz);
|
||||
pos = cc_matProj * pos;
|
||||
#else
|
||||
pos = cc_matViewProj * pos;
|
||||
#endif
|
||||
|
||||
uv0 = a_texCoord;
|
||||
#if SAMPLE_FROM_RT
|
||||
CC_HANDLE_RT_SAMPLE_FLIP(uv0);
|
||||
#endif
|
||||
color = a_color;
|
||||
|
||||
return pos;
|
||||
}
|
||||
}%
|
||||
|
||||
CCProgram sprite-fs %{
|
||||
precision highp float;
|
||||
#include <builtin/internal/embedded-alpha>
|
||||
#include <builtin/internal/alpha-test>
|
||||
|
||||
in vec4 color;
|
||||
|
||||
uniform FSConstants {
|
||||
vec4 glowColor;
|
||||
float glowWidth;
|
||||
float glowThreshold;
|
||||
};
|
||||
|
||||
#if USE_TEXTURE
|
||||
in vec2 uv0;
|
||||
#pragma builtin(local)
|
||||
layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture;
|
||||
#endif
|
||||
|
||||
vec4 getTextureColor (sampler2D mainTexture, vec2 uv) {
|
||||
if (uv.x > 1.0 || uv.x < 0.0 || uv.y > 1.0 || uv.y < 0.0) {
|
||||
return vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
return texture(mainTexture, uv);
|
||||
}
|
||||
|
||||
float getColorAlpha (float angle, float dist) {
|
||||
// 角度转弧度,公式为:弧度 = 角度 * (pi / 180)
|
||||
float radian = angle * 3.14 / 180.0;
|
||||
vec2 newUV = uv0 + vec2(dist * cos(radian), dist * sin(radian));
|
||||
vec4 color = getTextureColor(cc_spriteTexture, newUV);
|
||||
return color.a;
|
||||
}
|
||||
|
||||
float getAverageAlpha (float dist) {
|
||||
float totalAlpha = 0.0;
|
||||
|
||||
totalAlpha += getColorAlpha(0.0, dist);
|
||||
totalAlpha += getColorAlpha(30.0, dist);
|
||||
totalAlpha += getColorAlpha(60.0, dist);
|
||||
totalAlpha += getColorAlpha(90.0, dist);
|
||||
totalAlpha += getColorAlpha(120.0, dist);
|
||||
totalAlpha += getColorAlpha(150.0, dist);
|
||||
totalAlpha += getColorAlpha(180.0, dist);
|
||||
totalAlpha += getColorAlpha(210.0, dist);
|
||||
totalAlpha += getColorAlpha(240.0, dist);
|
||||
totalAlpha += getColorAlpha(270.0, dist);
|
||||
totalAlpha += getColorAlpha(300.0, dist);
|
||||
totalAlpha += getColorAlpha(330.0, dist);
|
||||
|
||||
return totalAlpha * 0.0833;
|
||||
}
|
||||
|
||||
float getGlowAlpha () {
|
||||
if (glowWidth == 0.0 ) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float totalAlpha = 0.0;
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.1);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.2);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.3);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.4);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.5);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.6);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.7);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.8);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 0.9);
|
||||
totalAlpha += getAverageAlpha(glowWidth * 1.0);
|
||||
|
||||
return totalAlpha * 0.1;
|
||||
}
|
||||
|
||||
vec4 frag () {
|
||||
vec4 o = vec4(1, 1, 1, 1);
|
||||
|
||||
#if USE_TEXTURE
|
||||
o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);
|
||||
#if IS_GRAY
|
||||
float gray = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;
|
||||
o.r = o.g = o.b = gray;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float alpha = getGlowAlpha();
|
||||
|
||||
if (alpha <= glowThreshold) {
|
||||
alpha /= glowThreshold;
|
||||
alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0;
|
||||
} else {
|
||||
alpha = 0.0;
|
||||
}
|
||||
|
||||
vec4 dstColor = glowColor * alpha;
|
||||
vec4 scrColor = o;
|
||||
|
||||
o = scrColor * scrColor.a + dstColor * (1.0 - scrColor.a);
|
||||
|
||||
o *= color;
|
||||
ALPHA_TEST(o);
|
||||
return o;
|
||||
}
|
||||
}%
|
||||
@@ -0,0 +1 @@
|
||||
{"ver":"1.7.1","importer":"effect","imported":true,"uuid":"40c25c17-db22-4ae7-8d3a-f73cbb6d36ba","files":[".json"],"subMetas":{},"userData":{"combinations":[{}]}}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user