2025-09-29 18:15:47 +08:00
|
|
|
|
# 微信小游戏适配器
|
|
|
|
|
|
|
|
|
|
|
|
## 概述
|
|
|
|
|
|
|
|
|
|
|
|
微信小游戏平台适配器专为微信小游戏环境设计,处理微信小游戏的特殊限制和API。
|
|
|
|
|
|
|
|
|
|
|
|
## 特性支持
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
| 特性 | 支持情况 | 说明 |
|
|
|
|
|
|
|------|----------|------|
|
|
|
|
|
|
| **Worker** | ✅ 支持 | 需要使用预编译文件,配置 `workerScriptPath` |
|
|
|
|
|
|
| **SharedArrayBuffer** | ❌ 不支持 | 微信小游戏环境不支持 |
|
|
|
|
|
|
| **Transferable Objects** | ❌ 不支持 | 只支持可序列化对象 |
|
|
|
|
|
|
| **高精度时间** | ✅ 支持 | 使用 `wx.getPerformance()` |
|
|
|
|
|
|
| **设备信息** | ✅ 支持 | 完整的微信小游戏设备信息 |
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
## WorkerEntitySystem 使用方式
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
### 重要:微信小游戏 Worker 限制
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
微信小游戏的 Worker 有以下限制:
|
|
|
|
|
|
- **Worker 脚本必须在代码包内**,不能动态生成
|
|
|
|
|
|
- **必须在 `game.json` 中配置** `workers` 目录
|
|
|
|
|
|
- **最多只能创建 1 个 Worker**
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
因此,使用 `WorkerEntitySystem` 时有两种方式:
|
|
|
|
|
|
1. **推荐:使用 CLI 工具自动生成** Worker 文件
|
|
|
|
|
|
2. 手动创建 Worker 文件
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
### 方式一:使用 CLI 工具自动生成(推荐)
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
我们提供了 `@esengine/worker-generator` 工具,可以自动从你的 TypeScript 代码中提取 `workerProcess` 函数并生成微信小游戏兼容的 Worker 文件。
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
#### 安装
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
```bash
|
|
|
|
|
|
pnpm add -D @esengine/worker-generator
|
|
|
|
|
|
# 或
|
|
|
|
|
|
npm install --save-dev @esengine/worker-generator
|
|
|
|
|
|
```
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
#### 使用
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
```bash
|
|
|
|
|
|
# 扫描 src 目录,生成 Worker 文件到 workers 目录
|
|
|
|
|
|
npx esengine-worker-gen --src ./src --out ./workers --wechat
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
# 查看帮助
|
|
|
|
|
|
npx esengine-worker-gen --help
|
|
|
|
|
|
```
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
#### 参数说明
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
| 参数 | 说明 | 默认值 |
|
|
|
|
|
|
|------|------|--------|
|
|
|
|
|
|
| `-s, --src <dir>` | 源代码目录 | `./src` |
|
|
|
|
|
|
| `-o, --out <dir>` | 输出目录 | `./workers` |
|
|
|
|
|
|
| `-w, --wechat` | 生成微信小游戏兼容代码 | `false` |
|
|
|
|
|
|
| `-m, --mapping` | 生成 worker-mapping.json | `true` |
|
|
|
|
|
|
| `-t, --tsconfig <path>` | TypeScript 配置文件路径 | 自动查找 |
|
|
|
|
|
|
| `-v, --verbose` | 详细输出 | `false` |
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
#### 示例输出
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
```
|
|
|
|
|
|
🔧 ESEngine Worker Generator
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
Source directory: /project/src
|
|
|
|
|
|
Output directory: /project/workers
|
|
|
|
|
|
WeChat mode: Yes
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
Scanning for WorkerEntitySystem classes...
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
✓ Found 1 WorkerEntitySystem class(es):
|
|
|
|
|
|
- PhysicsSystem (src/systems/PhysicsSystem.ts)
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
Generating Worker files...
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
✓ Successfully generated 1 Worker file(s):
|
|
|
|
|
|
- PhysicsSystem -> workers/physics-system-worker.js
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
📝 Usage:
|
|
|
|
|
|
1. Copy the generated files to your project's workers/ directory
|
|
|
|
|
|
2. Configure game.json (WeChat): { "workers": "workers" }
|
|
|
|
|
|
3. In your System constructor, add:
|
|
|
|
|
|
workerScriptPath: 'workers/physics-system-worker.js'
|
|
|
|
|
|
```
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
#### 在构建流程中集成
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
```json
|
|
|
|
|
|
// package.json
|
|
|
|
|
|
{
|
|
|
|
|
|
"scripts": {
|
|
|
|
|
|
"build:workers": "esengine-worker-gen --src ./src --out ./workers --wechat",
|
|
|
|
|
|
"build": "pnpm build:workers && your-build-command"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
### 方式二:手动创建 Worker 文件
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
如果你不想使用 CLI 工具,也可以手动创建 Worker 文件。
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
在项目中创建 `workers/entity-worker.js`:
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
```javascript
|
|
|
|
|
|
// workers/entity-worker.js
|
|
|
|
|
|
// 微信小游戏 WorkerEntitySystem 通用 Worker 模板
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
let sharedFloatArray = null;
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
worker.onMessage(function(e) {
|
|
|
|
|
|
const { type, id, entities, deltaTime, systemConfig, startIndex, endIndex, sharedBuffer } = e.data;
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
try {
|
|
|
|
|
|
// 处理 SharedArrayBuffer 初始化
|
|
|
|
|
|
if (type === 'init' && sharedBuffer) {
|
|
|
|
|
|
sharedFloatArray = new Float32Array(sharedBuffer);
|
|
|
|
|
|
worker.postMessage({ type: 'init', success: true });
|
|
|
|
|
|
return;
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
// 处理 SharedArrayBuffer 数据
|
|
|
|
|
|
if (type === 'shared' && sharedFloatArray) {
|
|
|
|
|
|
processSharedArrayBuffer(startIndex, endIndex, deltaTime, systemConfig);
|
|
|
|
|
|
worker.postMessage({ id, result: null });
|
|
|
|
|
|
return;
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
// 传统处理方式
|
|
|
|
|
|
if (entities) {
|
|
|
|
|
|
const result = workerProcess(entities, deltaTime, systemConfig);
|
|
|
|
|
|
|
|
|
|
|
|
// 处理 Promise 返回值
|
|
|
|
|
|
if (result && typeof result.then === 'function') {
|
|
|
|
|
|
result.then(function(finalResult) {
|
|
|
|
|
|
worker.postMessage({ id, result: finalResult });
|
|
|
|
|
|
}).catch(function(error) {
|
|
|
|
|
|
worker.postMessage({ id, error: error.message });
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
worker.postMessage({ id, result: result });
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-08 17:02:11 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
worker.postMessage({ id, error: error.message });
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
2025-12-08 17:02:11 +08:00
|
|
|
|
});
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 实体处理函数 - 根据你的业务逻辑修改此函数
|
|
|
|
|
|
* @param {Array} entities - 实体数据数组
|
|
|
|
|
|
* @param {number} deltaTime - 帧间隔时间
|
|
|
|
|
|
* @param {Object} systemConfig - 系统配置
|
|
|
|
|
|
* @returns {Array} 处理后的实体数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
function workerProcess(entities, deltaTime, systemConfig) {
|
|
|
|
|
|
// ====== 在这里编写你的处理逻辑 ======
|
|
|
|
|
|
// 示例:物理计算
|
|
|
|
|
|
return entities.map(function(entity) {
|
|
|
|
|
|
// 应用重力
|
|
|
|
|
|
entity.vy += (systemConfig.gravity || 100) * deltaTime;
|
|
|
|
|
|
|
|
|
|
|
|
// 更新位置
|
|
|
|
|
|
entity.x += entity.vx * deltaTime;
|
|
|
|
|
|
entity.y += entity.vy * deltaTime;
|
|
|
|
|
|
|
|
|
|
|
|
// 应用摩擦力
|
|
|
|
|
|
entity.vx *= (systemConfig.friction || 0.95);
|
|
|
|
|
|
entity.vy *= (systemConfig.friction || 0.95);
|
|
|
|
|
|
|
|
|
|
|
|
return entity;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* SharedArrayBuffer 处理函数(可选)
|
|
|
|
|
|
*/
|
|
|
|
|
|
function processSharedArrayBuffer(startIndex, endIndex, deltaTime, systemConfig) {
|
|
|
|
|
|
if (!sharedFloatArray) return;
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
// ====== 根据需要实现 SharedArrayBuffer 处理逻辑 ======
|
|
|
|
|
|
// 注意:微信小游戏不支持 SharedArrayBuffer,此函数通常不会被调用
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
### 步骤 2:配置 game.json
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
在 `game.json` 中添加 workers 配置:
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"deviceOrientation": "portrait",
|
|
|
|
|
|
"showStatusBar": false,
|
|
|
|
|
|
"workers": "workers"
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
### 步骤 3:使用 WorkerEntitySystem
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
|
|
|
|
|
```typescript
|
2025-09-30 09:37:30 +08:00
|
|
|
|
import { WorkerEntitySystem, Matcher, Entity } from '@esengine/ecs-framework';
|
|
|
|
|
|
|
|
|
|
|
|
interface PhysicsData {
|
|
|
|
|
|
id: number;
|
|
|
|
|
|
x: number;
|
|
|
|
|
|
y: number;
|
|
|
|
|
|
vx: number;
|
|
|
|
|
|
vy: number;
|
|
|
|
|
|
mass: number;
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-30 09:37:30 +08:00
|
|
|
|
class PhysicsSystem extends WorkerEntitySystem<PhysicsData> {
|
2025-09-29 18:15:47 +08:00
|
|
|
|
constructor() {
|
|
|
|
|
|
super(Matcher.all(Transform, Velocity), {
|
|
|
|
|
|
enableWorker: true,
|
2025-12-08 17:02:11 +08:00
|
|
|
|
workerCount: 1, // 微信小游戏限制只能创建 1 个 Worker
|
|
|
|
|
|
workerScriptPath: 'workers/entity-worker.js', // 指定预编译的 Worker 文件
|
|
|
|
|
|
systemConfig: {
|
|
|
|
|
|
gravity: 100,
|
|
|
|
|
|
friction: 0.95
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-30 09:37:30 +08:00
|
|
|
|
protected getDefaultEntityDataSize(): number {
|
2025-12-08 17:02:11 +08:00
|
|
|
|
return 6;
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-30 09:37:30 +08:00
|
|
|
|
protected extractEntityData(entity: Entity): PhysicsData {
|
|
|
|
|
|
const transform = entity.getComponent(Transform);
|
|
|
|
|
|
const velocity = entity.getComponent(Velocity);
|
|
|
|
|
|
const physics = entity.getComponent(Physics);
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-09-30 09:37:30 +08:00
|
|
|
|
return {
|
|
|
|
|
|
id: entity.id,
|
|
|
|
|
|
x: transform.x,
|
|
|
|
|
|
y: transform.y,
|
|
|
|
|
|
vx: velocity.x,
|
|
|
|
|
|
vy: velocity.y,
|
|
|
|
|
|
mass: physics.mass
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
// 注意:在微信小游戏中,此方法不会被使用
|
|
|
|
|
|
// Worker 的处理逻辑在 workers/entity-worker.js 中的 workerProcess 函数里
|
2025-09-30 09:37:30 +08:00
|
|
|
|
protected workerProcess(entities: PhysicsData[], deltaTime: number, config: any): PhysicsData[] {
|
2025-09-29 18:15:47 +08:00
|
|
|
|
return entities.map(entity => {
|
|
|
|
|
|
entity.vy += config.gravity * deltaTime;
|
|
|
|
|
|
entity.x += entity.vx * deltaTime;
|
|
|
|
|
|
entity.y += entity.vy * deltaTime;
|
2025-09-30 09:37:30 +08:00
|
|
|
|
entity.vx *= config.friction;
|
|
|
|
|
|
entity.vy *= config.friction;
|
2025-09-29 18:15:47 +08:00
|
|
|
|
return entity;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2025-09-30 09:37:30 +08:00
|
|
|
|
|
|
|
|
|
|
protected applyResult(entity: Entity, result: PhysicsData): void {
|
|
|
|
|
|
const transform = entity.getComponent(Transform);
|
|
|
|
|
|
const velocity = entity.getComponent(Velocity);
|
|
|
|
|
|
|
|
|
|
|
|
transform.x = result.x;
|
|
|
|
|
|
transform.y = result.y;
|
|
|
|
|
|
velocity.x = result.vx;
|
|
|
|
|
|
velocity.y = result.vy;
|
|
|
|
|
|
}
|
2025-12-08 17:02:11 +08:00
|
|
|
|
|
|
|
|
|
|
// SharedArrayBuffer 相关方法(微信小游戏不支持,可省略)
|
|
|
|
|
|
protected writeEntityToBuffer(data: PhysicsData, offset: number): void {}
|
|
|
|
|
|
protected readEntityFromBuffer(offset: number): PhysicsData | null { return null; }
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
2025-09-30 09:37:30 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
### 临时禁用 Worker(降级到同步模式)
|
2025-09-30 09:37:30 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
如果遇到问题,可以临时禁用 Worker:
|
2025-09-30 09:37:30 +08:00
|
|
|
|
|
|
|
|
|
|
```typescript
|
2025-12-08 17:02:11 +08:00
|
|
|
|
class PhysicsSystem extends WorkerEntitySystem<PhysicsData> {
|
|
|
|
|
|
constructor() {
|
|
|
|
|
|
super(Matcher.all(Transform, Velocity), {
|
|
|
|
|
|
enableWorker: false, // 禁用 Worker,使用主线程同步处理
|
|
|
|
|
|
// ... 其他配置
|
2025-09-30 09:37:30 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
## 完整适配器实现
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
```typescript
|
|
|
|
|
|
import type {
|
|
|
|
|
|
IPlatformAdapter,
|
|
|
|
|
|
PlatformWorker,
|
|
|
|
|
|
WorkerCreationOptions,
|
|
|
|
|
|
PlatformConfig
|
|
|
|
|
|
} from '@esengine/ecs-framework';
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 微信小游戏平台适配器
|
|
|
|
|
|
*/
|
|
|
|
|
|
export class WeChatMiniGameAdapter implements IPlatformAdapter {
|
|
|
|
|
|
public readonly name = 'wechat-minigame';
|
|
|
|
|
|
public readonly version: string;
|
|
|
|
|
|
private systemInfo: any;
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
constructor() {
|
|
|
|
|
|
this.systemInfo = this.getSystemInfo();
|
|
|
|
|
|
this.version = this.systemInfo.SDKVersion || 'unknown';
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public isWorkerSupported(): boolean {
|
|
|
|
|
|
return typeof wx !== 'undefined' && typeof wx.createWorker === 'function';
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public isSharedArrayBufferSupported(): boolean {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public getHardwareConcurrency(): number {
|
|
|
|
|
|
return 1; // 微信小游戏最多 1 个 Worker
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public createWorker(scriptPath: string, options: WorkerCreationOptions = {}): PlatformWorker {
|
|
|
|
|
|
if (!this.isWorkerSupported()) {
|
|
|
|
|
|
throw new Error('微信小游戏环境不支持 Worker');
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
// scriptPath 必须是代码包内的文件路径
|
|
|
|
|
|
const worker = wx.createWorker(scriptPath, {
|
|
|
|
|
|
useExperimentalWorker: true
|
|
|
|
|
|
});
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
return new WeChatWorker(worker);
|
|
|
|
|
|
}
|
2025-09-30 09:37:30 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public createSharedArrayBuffer(length: number): SharedArrayBuffer | null {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public getHighResTimestamp(): number {
|
|
|
|
|
|
if (typeof wx !== 'undefined' && wx.getPerformance) {
|
|
|
|
|
|
return wx.getPerformance().now();
|
|
|
|
|
|
}
|
|
|
|
|
|
return Date.now();
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public getPlatformConfig(): PlatformConfig {
|
|
|
|
|
|
return {
|
|
|
|
|
|
maxWorkerCount: 1,
|
|
|
|
|
|
supportsModuleWorker: false,
|
|
|
|
|
|
supportsTransferableObjects: false,
|
|
|
|
|
|
maxSharedArrayBufferSize: 0,
|
|
|
|
|
|
workerScriptPrefix: '',
|
|
|
|
|
|
limitations: {
|
|
|
|
|
|
noEval: true, // 重要:标记不支持动态脚本
|
|
|
|
|
|
requiresWorkerInit: false,
|
|
|
|
|
|
memoryLimit: 512 * 1024 * 1024,
|
|
|
|
|
|
workerNotSupported: false,
|
|
|
|
|
|
workerLimitations: [
|
|
|
|
|
|
'最多只能创建 1 个 Worker',
|
|
|
|
|
|
'Worker 脚本必须在代码包内',
|
|
|
|
|
|
'需要在 game.json 中配置 workers 路径',
|
|
|
|
|
|
'需要使用 workerScriptPath 配置'
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
extensions: {
|
|
|
|
|
|
platform: 'wechat-minigame',
|
|
|
|
|
|
sdkVersion: this.systemInfo.SDKVersion
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
private getSystemInfo(): any {
|
|
|
|
|
|
if (typeof wx !== 'undefined' && wx.getSystemInfoSync) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return wx.getSystemInfoSync();
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.warn('获取微信系统信息失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 微信 Worker 封装
|
|
|
|
|
|
*/
|
|
|
|
|
|
class WeChatWorker implements PlatformWorker {
|
|
|
|
|
|
private _state: 'running' | 'terminated' = 'running';
|
|
|
|
|
|
private worker: any;
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
constructor(worker: any) {
|
|
|
|
|
|
this.worker = worker;
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public get state(): 'running' | 'terminated' {
|
|
|
|
|
|
return this._state;
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public postMessage(message: any, transfer?: Transferable[]): void {
|
|
|
|
|
|
if (this._state === 'terminated') {
|
|
|
|
|
|
throw new Error('Worker 已被终止');
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
2025-12-08 17:02:11 +08:00
|
|
|
|
this.worker.postMessage(message);
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public onMessage(handler: (event: { data: any }) => void): void {
|
|
|
|
|
|
this.worker.onMessage((res: any) => {
|
|
|
|
|
|
handler({ data: res });
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public onError(handler: (error: ErrorEvent) => void): void {
|
|
|
|
|
|
if (this.worker.onError) {
|
|
|
|
|
|
this.worker.onError(handler);
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
2025-12-08 17:02:11 +08:00
|
|
|
|
}
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
public terminate(): void {
|
|
|
|
|
|
if (this._state === 'running') {
|
|
|
|
|
|
this.worker.terminate();
|
|
|
|
|
|
this._state = 'terminated';
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
## 注册适配器
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
|
|
|
|
|
```typescript
|
2025-12-08 17:02:11 +08:00
|
|
|
|
import { PlatformManager } from '@esengine/ecs-framework';
|
|
|
|
|
|
import { WeChatMiniGameAdapter } from './platform/WeChatMiniGameAdapter';
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
// 在游戏启动时注册适配器
|
|
|
|
|
|
if (typeof wx !== 'undefined') {
|
|
|
|
|
|
const adapter = new WeChatMiniGameAdapter();
|
|
|
|
|
|
PlatformManager.getInstance().registerAdapter(adapter);
|
2025-09-29 18:15:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
## 官方文档参考
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
- [wx.createWorker API](https://developers.weixin.qq.com/minigame/dev/api/worker/wx.createWorker.html)
|
|
|
|
|
|
- [Worker.postMessage API](https://developers.weixin.qq.com/minigame/dev/api/worker/Worker.postMessage.html)
|
|
|
|
|
|
- [Worker.onMessage API](https://developers.weixin.qq.com/minigame/dev/api/worker/Worker.onMessage.html)
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
## 重要注意事项
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
### Worker 限制
|
|
|
|
|
|
|
|
|
|
|
|
| 限制项 | 说明 |
|
|
|
|
|
|
|--------|------|
|
|
|
|
|
|
| 数量限制 | 最多只能创建 1 个 Worker |
|
|
|
|
|
|
| 版本要求 | 需要基础库 1.9.90 及以上 |
|
|
|
|
|
|
| 脚本位置 | 必须在代码包内,不支持动态生成 |
|
|
|
|
|
|
| 生命周期 | 创建新 Worker 前必须先 terminate() |
|
|
|
|
|
|
|
|
|
|
|
|
### 内存限制
|
|
|
|
|
|
|
|
|
|
|
|
- 通常限制在 256MB - 512MB
|
|
|
|
|
|
- 需要及时释放不用的资源
|
|
|
|
|
|
- 建议监听内存警告:
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
wx.onMemoryWarning(() => {
|
|
|
|
|
|
console.warn('收到内存警告,开始清理资源');
|
|
|
|
|
|
// 清理不必要的资源
|
|
|
|
|
|
});
|
2025-09-29 18:15:47 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
## 调试技巧
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
|
|
|
|
|
```typescript
|
2025-12-08 17:02:11 +08:00
|
|
|
|
// 检查 Worker 配置
|
|
|
|
|
|
const adapter = PlatformManager.getInstance().getAdapter();
|
|
|
|
|
|
const config = adapter.getPlatformConfig();
|
2025-09-29 18:15:47 +08:00
|
|
|
|
|
2025-12-08 17:02:11 +08:00
|
|
|
|
console.log('Worker 支持:', adapter.isWorkerSupported());
|
|
|
|
|
|
console.log('最大 Worker 数:', config.maxWorkerCount);
|
|
|
|
|
|
console.log('平台限制:', config.limitations);
|
|
|
|
|
|
```
|