更新性能分析器及更改部分注释
This commit is contained in:
@@ -21,6 +21,9 @@
|
||||
},
|
||||
{
|
||||
"__id__": 5
|
||||
},
|
||||
{
|
||||
"__id__": 7
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
@@ -55,7 +58,7 @@
|
||||
},
|
||||
"autoReleaseAssets": false,
|
||||
"_globals": {
|
||||
"__id__": 7
|
||||
"__id__": 9
|
||||
},
|
||||
"_id": "fcbf2917-6d43-4528-8829-7ee089594879"
|
||||
},
|
||||
@@ -246,32 +249,90 @@
|
||||
"_trackingType": 0,
|
||||
"_id": "7dWQTpwS5LrIHnc1zAPUtf"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "ECSManager",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 8
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": "3e7rcS/tZHIY0l6bef0fag"
|
||||
},
|
||||
{
|
||||
"__type__": "b8965bwYyBLbYHNRHv4ESMM",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 7
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": null,
|
||||
"debugMode": true,
|
||||
"_id": "a5SvVlMsZCrIJB1jr083gX"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.SceneGlobals",
|
||||
"ambient": {
|
||||
"__id__": 8
|
||||
},
|
||||
"shadows": {
|
||||
"__id__": 9
|
||||
},
|
||||
"_skybox": {
|
||||
"__id__": 10
|
||||
},
|
||||
"fog": {
|
||||
"shadows": {
|
||||
"__id__": 11
|
||||
},
|
||||
"octree": {
|
||||
"_skybox": {
|
||||
"__id__": 12
|
||||
},
|
||||
"skin": {
|
||||
"fog": {
|
||||
"__id__": 13
|
||||
},
|
||||
"lightProbeInfo": {
|
||||
"octree": {
|
||||
"__id__": 14
|
||||
},
|
||||
"postSettings": {
|
||||
"skin": {
|
||||
"__id__": 15
|
||||
},
|
||||
"lightProbeInfo": {
|
||||
"__id__": 16
|
||||
},
|
||||
"postSettings": {
|
||||
"__id__": 17
|
||||
},
|
||||
"bakedWithStationaryMainLight": false,
|
||||
"bakedWithHighpLightmap": false
|
||||
},
|
||||
|
||||
9
extensions/cocos/cocos-ecs/assets/scripts/ecs.meta
Normal file
9
extensions/cocos/cocos-ecs/assets/scripts/ecs.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "a1f43720-46e1-4d07-b56a-c9307e45726c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
98
extensions/cocos/cocos-ecs/assets/scripts/ecs/ECSManager.ts
Normal file
98
extensions/cocos/cocos-ecs/assets/scripts/ecs/ECSManager.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { Core } from '@esengine/ecs-framework';
|
||||
import { Component, _decorator } from 'cc';
|
||||
import { GameScene } from './scenes/GameScene';
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* ECS管理器 - Cocos Creator组件
|
||||
* 将此组件添加到场景中的任意节点上即可启动ECS框架
|
||||
*
|
||||
* 使用说明:
|
||||
* 1. 在Cocos Creator场景中创建一个空节点
|
||||
* 2. 将此ECSManager组件添加到该节点
|
||||
* 3. 运行场景即可自动启动ECS框架
|
||||
*/
|
||||
@ccclass('ECSManager')
|
||||
export class ECSManager extends Component {
|
||||
|
||||
@property({
|
||||
tooltip: '是否启用调试模式(建议开发阶段开启)'
|
||||
})
|
||||
public debugMode: boolean = true;
|
||||
|
||||
private isInitialized: boolean = false;
|
||||
|
||||
/**
|
||||
* 组件启动时初始化ECS
|
||||
*/
|
||||
start() {
|
||||
this.initializeECS();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化ECS框架
|
||||
*/
|
||||
private initializeECS(): void {
|
||||
if (this.isInitialized) return;
|
||||
|
||||
// ECS框架初始化开始
|
||||
|
||||
try {
|
||||
// 1. 创建Core实例,启用调试功能
|
||||
if (this.debugMode) {
|
||||
Core.create({
|
||||
debugConfig: {
|
||||
enabled: true,
|
||||
websocketUrl: 'ws://localhost:8080',
|
||||
autoReconnect: true,
|
||||
updateInterval: 100,
|
||||
debugFrameRate: 30,
|
||||
channels: {
|
||||
entities: true,
|
||||
systems: true,
|
||||
performance: true,
|
||||
components: true,
|
||||
scenes: true
|
||||
}
|
||||
}
|
||||
});
|
||||
// ECS调试模式已启用
|
||||
} else {
|
||||
Core.create(false);
|
||||
}
|
||||
|
||||
// 2. 创建游戏场景
|
||||
const gameScene = new GameScene();
|
||||
|
||||
// 3. 设置为当前场景(会自动调用scene.begin())
|
||||
Core.scene = gameScene;
|
||||
|
||||
this.isInitialized = true;
|
||||
// ECS框架初始化完成
|
||||
|
||||
} catch (error) {
|
||||
console.error('ECS框架初始化失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 每帧更新ECS框架
|
||||
*/
|
||||
update(deltaTime: number) {
|
||||
if (this.isInitialized) {
|
||||
// 更新ECS核心系统
|
||||
Core.update(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件销毁时清理ECS
|
||||
*/
|
||||
onDestroy() {
|
||||
if (this.isInitialized) {
|
||||
// ECS框架清理
|
||||
this.isInitialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "b89656f0-6320-4b6d-81cd-447bf811230c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
153
extensions/cocos/cocos-ecs/assets/scripts/ecs/README.md
Normal file
153
extensions/cocos/cocos-ecs/assets/scripts/ecs/README.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# ECS框架启动模板
|
||||
|
||||
欢迎使用ECS框架!这是一个最基础的启动模板,帮助您快速开始ECS项目开发。
|
||||
|
||||
## 📁 项目结构
|
||||
|
||||
```
|
||||
ecs/
|
||||
├── components/ # 组件目录(请在此添加您的组件)
|
||||
├── systems/ # 系统目录(请在此添加您的系统)
|
||||
├── scenes/ # 场景目录
|
||||
│ └── GameScene.ts # 主游戏场景
|
||||
├── ECSManager.ts # ECS管理器组件
|
||||
└── README.md # 本文档
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 启动ECS框架
|
||||
|
||||
ECS框架已经配置完成!您只需要:
|
||||
|
||||
1. 在Cocos Creator中打开您的场景
|
||||
2. 创建一个空节点(例如命名为"ECSManager")
|
||||
3. 将 `ECSManager` 组件添加到该节点
|
||||
4. 运行场景,ECS框架将自动启动
|
||||
|
||||
### 2. 查看控制台输出
|
||||
|
||||
如果一切正常,您将在控制台看到:
|
||||
|
||||
```
|
||||
🎮 正在初始化ECS框架...
|
||||
🔧 ECS调试模式已启用,可在Cocos Creator扩展面板中查看调试信息
|
||||
🎯 游戏场景已创建
|
||||
✅ ECS框架初始化成功!
|
||||
🚀 游戏场景已启动
|
||||
```
|
||||
|
||||
### 3. 使用调试面板
|
||||
|
||||
ECS框架已启用调试功能,您可以:
|
||||
|
||||
1. 在Cocos Creator编辑器菜单中选择 "扩展" → "ECS Framework" → "调试面板"
|
||||
2. 调试面板将显示实时的ECS运行状态:
|
||||
- 实体数量和状态
|
||||
- 系统执行信息
|
||||
- 性能监控数据
|
||||
- 组件统计信息
|
||||
|
||||
**注意**:调试功能会消耗一定性能,正式发布时建议关闭调试模式。
|
||||
|
||||
## 📚 下一步开发
|
||||
|
||||
### 创建您的第一个组件
|
||||
|
||||
在 `components/` 目录下创建组件:
|
||||
|
||||
```typescript
|
||||
// components/PositionComponent.ts
|
||||
import { Component } from '@esengine/ecs-framework';
|
||||
import { Vec3 } from 'cc';
|
||||
|
||||
export class PositionComponent extends Component {
|
||||
public position: Vec3 = new Vec3();
|
||||
|
||||
constructor(x: number = 0, y: number = 0, z: number = 0) {
|
||||
super();
|
||||
this.position.set(x, y, z);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 创建您的第一个系统
|
||||
|
||||
在 `systems/` 目录下创建系统:
|
||||
|
||||
```typescript
|
||||
// systems/MovementSystem.ts
|
||||
import { EntitySystem, Entity, Matcher } from '@esengine/ecs-framework';
|
||||
import { PositionComponent } from '../components/PositionComponent';
|
||||
|
||||
export class MovementSystem extends EntitySystem {
|
||||
constructor() {
|
||||
super(Matcher.empty().all(PositionComponent));
|
||||
}
|
||||
|
||||
protected process(entities: Entity[]): void {
|
||||
for (const entity of entities) {
|
||||
const position = entity.getComponent(PositionComponent);
|
||||
if (position) {
|
||||
// TODO: 在这里编写移动逻辑
|
||||
console.log(`实体 ${entity.name} 位置: ${position.position}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 在场景中注册系统
|
||||
|
||||
在 `scenes/GameScene.ts` 的 `initialize()` 方法中添加:
|
||||
|
||||
```typescript
|
||||
import { MovementSystem } from '../systems/MovementSystem';
|
||||
|
||||
public initialize(): void {
|
||||
super.initialize();
|
||||
this.name = "MainGameScene";
|
||||
|
||||
// 添加系统
|
||||
this.addEntityProcessor(new MovementSystem());
|
||||
|
||||
// 创建测试实体
|
||||
const testEntity = this.createEntity("TestEntity");
|
||||
testEntity.addComponent(new PositionComponent(0, 0, 0));
|
||||
}
|
||||
```
|
||||
|
||||
## 🔗 学习资源
|
||||
|
||||
- [ECS框架完整文档](https://github.com/esengine/ecs-framework)
|
||||
- [ECS概念详解](https://github.com/esengine/ecs-framework/blob/master/docs/concepts-explained.md)
|
||||
- [新手教程](https://github.com/esengine/ecs-framework/blob/master/docs/beginner-tutorials.md)
|
||||
- [组件设计指南](https://github.com/esengine/ecs-framework/blob/master/docs/component-design-guide.md)
|
||||
- [系统开发指南](https://github.com/esengine/ecs-framework/blob/master/docs/system-guide.md)
|
||||
|
||||
## 💡 开发提示
|
||||
|
||||
1. **组件只存储数据**:避免在组件中编写复杂逻辑
|
||||
2. **系统处理逻辑**:所有业务逻辑应该在系统中实现
|
||||
3. **使用Matcher过滤实体**:系统通过Matcher指定需要处理的实体类型
|
||||
4. **性能优化**:大量实体时考虑使用位掩码查询和组件索引
|
||||
|
||||
## ❓ 常见问题
|
||||
|
||||
### Q: 如何创建实体?
|
||||
A: 在场景中使用 `this.createEntity("实体名称")`
|
||||
|
||||
### Q: 如何给实体添加组件?
|
||||
A: 使用 `entity.addComponent(new YourComponent())`
|
||||
|
||||
### Q: 如何获取实体的组件?
|
||||
A: 使用 `entity.getComponent(YourComponent)`
|
||||
|
||||
### Q: 如何删除实体?
|
||||
A: 使用 `entity.destroy()` 或 `this.destroyEntity(entity)`
|
||||
|
||||
---
|
||||
|
||||
🎮 **开始您的ECS开发之旅吧!**
|
||||
|
||||
如有问题,请查阅官方文档或提交Issue。
|
||||
11
extensions/cocos/cocos-ecs/assets/scripts/ecs/README.md.meta
Normal file
11
extensions/cocos/cocos-ecs/assets/scripts/ecs/README.md.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "1.0.1",
|
||||
"importer": "text",
|
||||
"imported": true,
|
||||
"uuid": "ca94b460-6c6a-4f72-9ec1-ab5fcd2e0e0a",
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "3c7bd2b3-6781-482c-be41-21f3dde0e2ab",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { Component } from '@esengine/ecs-framework';
|
||||
|
||||
/**
|
||||
* 生命值组件
|
||||
* 管理实体的生命值、最大生命值等
|
||||
*/
|
||||
export class Health extends Component {
|
||||
/** 当前生命值 */
|
||||
public currentHealth: number = 100;
|
||||
|
||||
/** 最大生命值 */
|
||||
public maxHealth: number = 100;
|
||||
|
||||
/** 是否死亡 */
|
||||
public isDead: boolean = false;
|
||||
|
||||
/** 生命值回复速度 (每秒) */
|
||||
public regenRate: number = 0;
|
||||
|
||||
constructor(maxHealth: number = 100) {
|
||||
super();
|
||||
this.maxHealth = maxHealth;
|
||||
this.currentHealth = maxHealth;
|
||||
}
|
||||
|
||||
/**
|
||||
* 受到伤害
|
||||
*/
|
||||
public takeDamage(damage: number): void {
|
||||
this.currentHealth = Math.max(0, this.currentHealth - damage);
|
||||
this.isDead = this.currentHealth <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 治疗
|
||||
*/
|
||||
public heal(amount: number): void {
|
||||
if (!this.isDead) {
|
||||
this.currentHealth = Math.min(this.maxHealth, this.currentHealth + amount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 复活
|
||||
*/
|
||||
public revive(healthPercent: number = 1.0): void {
|
||||
this.isDead = false;
|
||||
this.currentHealth = Math.floor(this.maxHealth * Math.max(0, Math.min(1, healthPercent)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取生命值百分比
|
||||
*/
|
||||
public getHealthPercent(): number {
|
||||
return this.maxHealth > 0 ? this.currentHealth / this.maxHealth : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置组件
|
||||
*/
|
||||
public reset(): void {
|
||||
this.currentHealth = this.maxHealth;
|
||||
this.isDead = false;
|
||||
this.regenRate = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "90369635-a6cb-4313-adf1-64117b50f2bc",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Component } from '@esengine/ecs-framework';
|
||||
import { Color } from 'cc';
|
||||
|
||||
/**
|
||||
* 渲染组件
|
||||
* 存储实体的渲染相关信息
|
||||
*/
|
||||
export class Renderer extends Component {
|
||||
/** 颜色 */
|
||||
public color: Color = new Color(255, 255, 255, 255);
|
||||
|
||||
/** 是否可见 */
|
||||
public visible: boolean = true;
|
||||
|
||||
/** 渲染层级 */
|
||||
public layer: number = 0;
|
||||
|
||||
/** 精灵名称或纹理路径 */
|
||||
public spriteName: string = '';
|
||||
|
||||
/** 大小 */
|
||||
public size: { width: number, height: number } = { width: 32, height: 32 };
|
||||
|
||||
/** 透明度 (0-1) */
|
||||
public alpha: number = 1.0;
|
||||
|
||||
constructor(spriteName: string = '', color?: Color) {
|
||||
super();
|
||||
this.spriteName = spriteName;
|
||||
if (color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置颜色
|
||||
*/
|
||||
public setColor(r: number, g: number, b: number, a: number = 255): void {
|
||||
this.color.set(r, g, b, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置透明度
|
||||
*/
|
||||
public setAlpha(alpha: number): void {
|
||||
this.alpha = Math.max(0, Math.min(1, alpha));
|
||||
this.color.a = Math.floor(this.alpha * 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置大小
|
||||
*/
|
||||
public setSize(width: number, height: number): void {
|
||||
this.size.width = width;
|
||||
this.size.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示/隐藏
|
||||
*/
|
||||
public setVisible(visible: boolean): void {
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置组件
|
||||
*/
|
||||
public reset(): void {
|
||||
this.color.set(255, 255, 255, 255);
|
||||
this.visible = true;
|
||||
this.layer = 0;
|
||||
this.spriteName = '';
|
||||
this.size = { width: 32, height: 32 };
|
||||
this.alpha = 1.0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "bf51f134-6ea5-4a26-8b15-0ed20fe1d605",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { Component } from '@esengine/ecs-framework';
|
||||
import { Vec3 } from 'cc';
|
||||
|
||||
/**
|
||||
* 变换组件
|
||||
* 存储实体的位置、旋转和缩放信息
|
||||
*/
|
||||
export class Transform extends Component {
|
||||
/** 位置 */
|
||||
public position: Vec3 = new Vec3(0, 0, 0);
|
||||
|
||||
/** 旋转 (度数) */
|
||||
public rotation: Vec3 = new Vec3(0, 0, 0);
|
||||
|
||||
/** 缩放 */
|
||||
public scale: Vec3 = new Vec3(1, 1, 1);
|
||||
|
||||
/** 移动速度 */
|
||||
public speed: number = 100;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置位置
|
||||
*/
|
||||
public setPosition(x: number, y: number, z: number = 0): void {
|
||||
this.position.set(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动
|
||||
*/
|
||||
public move(deltaX: number, deltaY: number, deltaZ: number = 0): void {
|
||||
this.position.x += deltaX;
|
||||
this.position.y += deltaY;
|
||||
this.position.z += deltaZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置组件
|
||||
*/
|
||||
public reset(): void {
|
||||
this.position.set(0, 0, 0);
|
||||
this.rotation.set(0, 0, 0);
|
||||
this.scale.set(1, 1, 1);
|
||||
this.speed = 100;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "09de6e5b-7bb7-4de8-8038-67be5ae955bc",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Component } from '@esengine/ecs-framework';
|
||||
import { Vec3 } from 'cc';
|
||||
|
||||
/**
|
||||
* 速度组件
|
||||
* 存储实体的移动速度和方向
|
||||
*/
|
||||
export class Velocity extends Component {
|
||||
/** 速度向量 */
|
||||
public velocity: Vec3 = new Vec3(0, 0, 0);
|
||||
|
||||
/** 最大速度 */
|
||||
public maxSpeed: number = 200;
|
||||
|
||||
/** 摩擦力 (0-1, 1表示无摩擦) */
|
||||
public friction: number = 0.98;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置速度
|
||||
*/
|
||||
public setVelocity(x: number, y: number, z: number = 0): void {
|
||||
this.velocity.set(x, y, z);
|
||||
this.clampToMaxSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加速度
|
||||
*/
|
||||
public addVelocity(x: number, y: number, z: number = 0): void {
|
||||
this.velocity.x += x;
|
||||
this.velocity.y += y;
|
||||
this.velocity.z += z;
|
||||
this.clampToMaxSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用摩擦力
|
||||
*/
|
||||
public applyFriction(): void {
|
||||
this.velocity.multiplyScalar(this.friction);
|
||||
|
||||
// 当速度很小时直接设为0,避免无限减小
|
||||
if (this.velocity.length() < 0.1) {
|
||||
this.velocity.set(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 限制到最大速度
|
||||
*/
|
||||
private clampToMaxSpeed(): void {
|
||||
const currentSpeed = this.velocity.length();
|
||||
if (currentSpeed > this.maxSpeed) {
|
||||
this.velocity.normalize().multiplyScalar(this.maxSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前速度大小
|
||||
*/
|
||||
public getSpeed(): number {
|
||||
return this.velocity.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置组件
|
||||
*/
|
||||
public reset(): void {
|
||||
this.velocity.set(0, 0, 0);
|
||||
this.maxSpeed = 200;
|
||||
this.friction = 0.98;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "10c40371-267a-4016-a8b5-9f803e68e72b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// 导出所有组件
|
||||
export { Transform } from './Transform';
|
||||
export { Health } from './Health';
|
||||
export { Velocity } from './Velocity';
|
||||
export { Renderer } from './Renderer';
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "dfc46d23-7ad6-4a21-914c-35d948185f93",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "39da4804-e61e-440e-b73d-544963bd3901",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
import { Scene } from '@esengine/ecs-framework';
|
||||
import { Color } from 'cc';
|
||||
import { MovementSystem, HealthSystem, RandomMovementSystem } from '../systems';
|
||||
import { Transform, Health, Velocity, Renderer } from '../components';
|
||||
|
||||
/**
|
||||
* 游戏场景
|
||||
*
|
||||
* 这是您的主游戏场景。在这里可以:
|
||||
* - 添加游戏系统
|
||||
* - 创建初始实体
|
||||
* - 设置场景参数
|
||||
*/
|
||||
export class GameScene extends Scene {
|
||||
|
||||
/**
|
||||
* 场景初始化
|
||||
* 在场景创建时调用,用于设置基础配置
|
||||
*/
|
||||
public initialize(): void {
|
||||
super.initialize();
|
||||
|
||||
// 设置场景名称
|
||||
this.name = "MainGameScene";
|
||||
|
||||
console.log('🎯 游戏场景已创建');
|
||||
|
||||
// 添加游戏系统
|
||||
this.addEntityProcessor(new MovementSystem());
|
||||
this.addEntityProcessor(new HealthSystem());
|
||||
this.addEntityProcessor(new RandomMovementSystem());
|
||||
|
||||
// 创建测试实体
|
||||
this.createTestEntities();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建测试实体
|
||||
*/
|
||||
private createTestEntities(): void {
|
||||
console.log('🚀 开始创建测试实体...');
|
||||
|
||||
// 创建玩家实体
|
||||
const player = this.createEntity("Player");
|
||||
player.addComponent(new Transform());
|
||||
player.addComponent(new Health(150));
|
||||
player.addComponent(new Velocity());
|
||||
player.addComponent(new Renderer("player", new Color(0, 255, 0, 255)));
|
||||
|
||||
const playerTransform = player.getComponent(Transform);
|
||||
const playerHealth = player.getComponent(Health);
|
||||
if (playerTransform) {
|
||||
playerTransform.setPosition(0, 0);
|
||||
playerTransform.speed = 120;
|
||||
}
|
||||
if (playerHealth) {
|
||||
playerHealth.regenRate = 5; // 每秒回复5点生命值
|
||||
}
|
||||
|
||||
// 创建一些敌人实体
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const enemy = this.createEntity(`Enemy_${i}`);
|
||||
enemy.addComponent(new Transform());
|
||||
enemy.addComponent(new Health(80));
|
||||
enemy.addComponent(new Velocity());
|
||||
enemy.addComponent(new Renderer("enemy", new Color(255, 0, 0, 255)));
|
||||
|
||||
const enemyTransform = enemy.getComponent(Transform);
|
||||
const enemyVelocity = enemy.getComponent(Velocity);
|
||||
if (enemyTransform) {
|
||||
// 随机位置
|
||||
const x = (Math.random() - 0.5) * 800;
|
||||
const y = (Math.random() - 0.5) * 600;
|
||||
enemyTransform.setPosition(x, y);
|
||||
enemyTransform.speed = 80;
|
||||
}
|
||||
if (enemyVelocity) {
|
||||
enemyVelocity.maxSpeed = 120;
|
||||
enemyVelocity.friction = 0.95;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建一些中性实体(只移动,无生命值)
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const neutral = this.createEntity(`Neutral_${i}`);
|
||||
neutral.addComponent(new Transform());
|
||||
neutral.addComponent(new Velocity());
|
||||
neutral.addComponent(new Renderer("neutral", new Color(255, 255, 0, 255)));
|
||||
|
||||
const neutralTransform = neutral.getComponent(Transform);
|
||||
const neutralVelocity = neutral.getComponent(Velocity);
|
||||
if (neutralTransform) {
|
||||
const x = (Math.random() - 0.5) * 600;
|
||||
const y = (Math.random() - 0.5) * 400;
|
||||
neutralTransform.setPosition(x, y);
|
||||
neutralTransform.speed = 60;
|
||||
}
|
||||
if (neutralVelocity) {
|
||||
neutralVelocity.maxSpeed = 80;
|
||||
neutralVelocity.friction = 0.99;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景开始运行
|
||||
* 在场景开始时调用,用于执行启动逻辑
|
||||
*/
|
||||
public onStart(): void {
|
||||
super.onStart();
|
||||
|
||||
console.log('🚀 游戏场景已启动');
|
||||
|
||||
// TODO: 在这里添加场景启动逻辑
|
||||
// 例如:创建UI、播放音乐、初始化游戏状态等
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景卸载
|
||||
* 在场景结束时调用,用于清理资源
|
||||
*/
|
||||
public unload(): void {
|
||||
console.log('🛑 游戏场景已结束');
|
||||
|
||||
// TODO: 在这里添加清理逻辑
|
||||
// 例如:清理缓存、释放资源等
|
||||
|
||||
super.unload();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "dbf17c21-6f4a-4f87-8568-7ac5a2ec10cd",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "f8f0d97b-46f6-49ff-9fe5-b31eee989963",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import { EntitySystem, Entity, Matcher, Time } from '@esengine/ecs-framework';
|
||||
import { Health } from '../components';
|
||||
|
||||
/**
|
||||
* 生命值系统
|
||||
* 处理生命值回复、死亡检测等逻辑
|
||||
*/
|
||||
export class HealthSystem extends EntitySystem {
|
||||
|
||||
constructor() {
|
||||
// 处理具有Health组件的实体
|
||||
super(Matcher.empty().all(Health));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理所有实体
|
||||
*/
|
||||
protected process(entities: Entity[]): void {
|
||||
const deltaTime = Time.deltaTime;
|
||||
|
||||
for (const entity of entities) {
|
||||
this.processEntity(entity, deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单个实体
|
||||
*/
|
||||
private processEntity(entity: Entity, deltaTime: number): void {
|
||||
const health = entity.getComponent(Health);
|
||||
|
||||
if (!health) return;
|
||||
|
||||
// 如果实体已死亡,跳过处理
|
||||
if (health.isDead) return;
|
||||
|
||||
// 处理生命值回复
|
||||
if (health.regenRate > 0) {
|
||||
const regenAmount = health.regenRate * deltaTime;
|
||||
health.heal(regenAmount);
|
||||
}
|
||||
|
||||
// 检查是否需要标记为死亡
|
||||
if (health.currentHealth <= 0 && !health.isDead) {
|
||||
health.isDead = true;
|
||||
this.onEntityDied(entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当实体死亡时调用
|
||||
*/
|
||||
private onEntityDied(entity: Entity): void {
|
||||
console.log(`💀 实体 ${entity.name} 已死亡`);
|
||||
|
||||
// 这里可以添加死亡相关的逻辑
|
||||
// 比如播放死亡动画、掉落物品等
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统初始化时调用
|
||||
*/
|
||||
public initialize(): void {
|
||||
super.initialize();
|
||||
console.log('❤️ 生命值系统已启动');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "074b3e3a-351e-4d95-b502-5a7dab8efc8d",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import { EntitySystem, Entity, Matcher, Time } from '@esengine/ecs-framework';
|
||||
import { Transform, Velocity } from '../components';
|
||||
|
||||
/**
|
||||
* 移动系统
|
||||
* 处理具有Transform和Velocity组件的实体移动
|
||||
*/
|
||||
export class MovementSystem extends EntitySystem {
|
||||
|
||||
constructor() {
|
||||
// 使用Matcher设置系统处理的组件类型
|
||||
super(Matcher.empty().all(Transform, Velocity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理所有实体
|
||||
*/
|
||||
protected process(entities: Entity[]): void {
|
||||
const deltaTime = Time.deltaTime;
|
||||
|
||||
for (const entity of entities) {
|
||||
this.processEntity(entity, deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单个实体
|
||||
*/
|
||||
private processEntity(entity: Entity, deltaTime: number): void {
|
||||
const transform = entity.getComponent(Transform);
|
||||
const velocity = entity.getComponent(Velocity);
|
||||
|
||||
if (!transform || !velocity) return;
|
||||
|
||||
// 应用摩擦力
|
||||
velocity.applyFriction();
|
||||
|
||||
// 根据速度更新位置
|
||||
const deltaX = velocity.velocity.x * deltaTime;
|
||||
const deltaY = velocity.velocity.y * deltaTime;
|
||||
const deltaZ = velocity.velocity.z * deltaTime;
|
||||
|
||||
transform.move(deltaX, deltaY, deltaZ);
|
||||
|
||||
// 简单的边界检查 (假设游戏世界是 -500 到 500)
|
||||
const bounds = 500;
|
||||
if (transform.position.x > bounds) {
|
||||
transform.position.x = bounds;
|
||||
velocity.velocity.x = -Math.abs(velocity.velocity.x) * 0.5; // 反弹并减速
|
||||
} else if (transform.position.x < -bounds) {
|
||||
transform.position.x = -bounds;
|
||||
velocity.velocity.x = Math.abs(velocity.velocity.x) * 0.5;
|
||||
}
|
||||
|
||||
if (transform.position.y > bounds) {
|
||||
transform.position.y = bounds;
|
||||
velocity.velocity.y = -Math.abs(velocity.velocity.y) * 0.5;
|
||||
} else if (transform.position.y < -bounds) {
|
||||
transform.position.y = -bounds;
|
||||
velocity.velocity.y = Math.abs(velocity.velocity.y) * 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统初始化时调用
|
||||
*/
|
||||
public initialize(): void {
|
||||
super.initialize();
|
||||
console.log('🏃 移动系统已启动');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "5e556e6d-ddd5-415c-b074-3cbdb59ed503",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import { EntitySystem, Entity, Matcher, Time } from '@esengine/ecs-framework';
|
||||
import { Transform, Velocity } from '../components';
|
||||
|
||||
/**
|
||||
* 随机移动系统
|
||||
* 让实体随机改变移动方向
|
||||
*/
|
||||
export class RandomMovementSystem extends EntitySystem {
|
||||
|
||||
/** 每个实体的下次方向改变时间 */
|
||||
private nextDirectionChangeTime: Map<number, number> = new Map();
|
||||
|
||||
constructor() {
|
||||
// 处理具有Transform和Velocity组件的实体
|
||||
super(Matcher.empty().all(Transform, Velocity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理所有实体
|
||||
*/
|
||||
protected process(entities: Entity[]): void {
|
||||
const currentTime = Time.totalTime;
|
||||
|
||||
for (const entity of entities) {
|
||||
this.processEntity(entity, currentTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单个实体
|
||||
*/
|
||||
private processEntity(entity: Entity, currentTime: number): void {
|
||||
const velocity = entity.getComponent(Velocity);
|
||||
|
||||
if (!velocity) return;
|
||||
|
||||
// 检查是否需要改变方向
|
||||
const nextChangeTime = this.nextDirectionChangeTime.get(entity.id) || 0;
|
||||
|
||||
if (currentTime >= nextChangeTime) {
|
||||
// 随机生成新的移动方向
|
||||
const angle = Math.random() * Math.PI * 2; // 0-360度
|
||||
const speed = 50 + Math.random() * 100; // 50-150的随机速度
|
||||
|
||||
const newVelocityX = Math.cos(angle) * speed;
|
||||
const newVelocityY = Math.sin(angle) * speed;
|
||||
|
||||
velocity.setVelocity(newVelocityX, newVelocityY);
|
||||
|
||||
// 设置下次改变方向的时间(1-3秒后)
|
||||
const nextInterval = 1 + Math.random() * 2;
|
||||
this.nextDirectionChangeTime.set(entity.id, currentTime + nextInterval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当实体被添加到系统时
|
||||
*/
|
||||
protected onAdded(entity: Entity): void {
|
||||
// 为新实体设置初始方向改变时间
|
||||
const initialDelay = Math.random() * 2; // 0-2秒的初始延迟
|
||||
this.nextDirectionChangeTime.set(entity.id, Time.totalTime + initialDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当实体从系统中移除时
|
||||
*/
|
||||
protected onRemoved(entity: Entity): void {
|
||||
// 清理实体的时间记录
|
||||
this.nextDirectionChangeTime.delete(entity.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统初始化时调用
|
||||
*/
|
||||
public initialize(): void {
|
||||
super.initialize();
|
||||
console.log('🎲 随机移动系统已启动');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ed1688a1-b44f-4588-ae6a-080a6af38a94",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// 导出所有系统
|
||||
export { MovementSystem } from './MovementSystem';
|
||||
export { HealthSystem } from './HealthSystem';
|
||||
export { RandomMovementSystem } from './RandomMovementSystem';
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "586d2e9b-054b-457b-b44c-dafda0a73b6e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Reference in New Issue
Block a user