355 lines
9.5 KiB
Markdown
355 lines
9.5 KiB
Markdown
# Pinball Bootstrap 使用指南
|
||
|
||
## 概览
|
||
|
||
Pinball Bootstrap 系统提供了一个统一的、配置驱动的方式来启动不同模式的 Pinball 游戏。通过简单的配置对象,你可以启动 Standalone、Client Multiplayer 或 Server Multiplayer 模式。
|
||
|
||
## 核心组件
|
||
|
||
### 1. PinballBootstrap
|
||
主要的启动器类,使用单例模式,负责根据配置启动对应的游戏模式。
|
||
|
||
### 2. PinballBootUtils
|
||
提供常用的便捷启动方法和配置生成器。
|
||
|
||
### 3. 配置类型
|
||
- `PinballBootConfig`: 启动配置接口
|
||
- `PinballBootResult`: 启动结果接口
|
||
- `PinballBootMode`: 启动模式枚举
|
||
|
||
## 使用方法
|
||
|
||
### 基础用法
|
||
|
||
#### 方式一:使用 ClientRunner(推荐)
|
||
```typescript
|
||
// ClientRunner 已经集成了 Bootstrap 系统
|
||
// 只需要设置相应的属性即可
|
||
|
||
@ccclass('MyGameManager')
|
||
export class MyGameManager extends Component {
|
||
|
||
@property(ClientRunner)
|
||
clientRunner: ClientRunner = null;
|
||
|
||
start() {
|
||
// ClientRunner 会自动使用 Bootstrap 启动
|
||
// 无需额外代码
|
||
}
|
||
|
||
async switchToMultiplayer() {
|
||
// 动态切换到多人模式
|
||
await this.clientRunner.switchMode(RunMode.CLIENT_MULTIPLAYER);
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 方式二:直接使用 Bootstrap
|
||
```typescript
|
||
import { PinballBootstrap, PinballBootMode, PinballBootUtils } from 'path/to/Boot';
|
||
|
||
@ccclass('MyBootManager')
|
||
export class MyBootManager extends Component {
|
||
|
||
async start() {
|
||
// 快速启动 Standalone 模式
|
||
const result = await PinballBootUtils.quickStartStandalone(
|
||
this,
|
||
this.cameraNode,
|
||
this.renderContainer
|
||
);
|
||
|
||
if (result.success) {
|
||
console.log('游戏启动成功!');
|
||
} else {
|
||
console.error('启动失败:', result.error);
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 高级配置
|
||
|
||
#### 自定义配置启动
|
||
```typescript
|
||
async customBoot() {
|
||
const config: PinballBootConfig = {
|
||
mode: PinballBootMode.STANDALONE,
|
||
cameraNode: this.mainCamera,
|
||
renderContainer: this.gameContainer,
|
||
debugMode: true,
|
||
autoStart: true,
|
||
|
||
// 自定义物理配置
|
||
physicsConfig: {
|
||
gravity: { x: 0, y: -15 }, // 更强的重力
|
||
timeStep: 1/120 // 更高精度
|
||
},
|
||
|
||
// 自定义渲染配置
|
||
renderConfig: {
|
||
enableEffects: true,
|
||
maxParticles: 800
|
||
},
|
||
|
||
// 自定义 WASM 路径
|
||
wasmPath: 'custom/path/physics.wasm'
|
||
};
|
||
|
||
const bootstrap = PinballBootstrap.getInstance();
|
||
const result = await bootstrap.boot(this, config);
|
||
|
||
return result;
|
||
}
|
||
```
|
||
|
||
#### 平台特定配置
|
||
```typescript
|
||
async bootForPlatform() {
|
||
let config: PinballBootConfig;
|
||
|
||
// 根据平台选择不同配置
|
||
if (this.isMobilePlatform()) {
|
||
config = PinballBootUtils.createMobileConfig(PinballBootMode.STANDALONE);
|
||
} else {
|
||
config = PinballBootUtils.createDesktopConfig(PinballBootMode.STANDALONE);
|
||
}
|
||
|
||
// 设置节点引用
|
||
config.cameraNode = this.cameraNode;
|
||
config.renderContainer = this.renderContainer;
|
||
|
||
const bootstrap = PinballBootstrap.getInstance();
|
||
return await bootstrap.boot(this, config);
|
||
}
|
||
|
||
private isMobilePlatform(): boolean {
|
||
// 检测平台逻辑
|
||
return cc.sys.isMobile;
|
||
}
|
||
```
|
||
|
||
### 多人模式配置
|
||
|
||
#### 客户端多人模式
|
||
```typescript
|
||
async bootClientMultiplayer() {
|
||
const config: PinballBootConfig = {
|
||
mode: PinballBootMode.CLIENT_MULTIPLAYER,
|
||
cameraNode: this.cameraNode,
|
||
renderContainer: this.renderContainer,
|
||
|
||
multiplayerConfig: {
|
||
serverAddress: 'wss://your-server.com:3000',
|
||
playerName: 'Player123',
|
||
roomId: 'room_abc'
|
||
}
|
||
};
|
||
|
||
const bootstrap = PinballBootstrap.getInstance();
|
||
return await bootstrap.boot(this, config);
|
||
}
|
||
```
|
||
|
||
#### 服务器多人模式
|
||
```typescript
|
||
async bootServerMultiplayer() {
|
||
const config: PinballBootConfig = {
|
||
mode: PinballBootMode.SERVER_MULTIPLAYER,
|
||
cameraNode: this.cameraNode,
|
||
renderContainer: this.renderContainer,
|
||
|
||
multiplayerConfig: {
|
||
serverAddress: 'localhost:3000',
|
||
playerName: 'Host',
|
||
roomId: 'main_room'
|
||
},
|
||
|
||
// 服务器模式可能需要更高性能配置
|
||
physicsConfig: {
|
||
gravity: { x: 0, y: -9.81 },
|
||
timeStep: 1/60
|
||
}
|
||
};
|
||
|
||
const bootstrap = PinballBootstrap.getInstance();
|
||
return await bootstrap.boot(this, config);
|
||
}
|
||
```
|
||
|
||
### 工具方法使用
|
||
|
||
#### 批量测试启动
|
||
```typescript
|
||
async testAllModes() {
|
||
const configs = [
|
||
PinballBootUtils.createDebugConfig(PinballBootMode.STANDALONE),
|
||
PinballBootUtils.createDebugConfig(PinballBootMode.CLIENT_MULTIPLAYER),
|
||
PinballBootUtils.createDebugConfig(PinballBootMode.SERVER_MULTIPLAYER)
|
||
];
|
||
|
||
// 为每个配置设置必需的节点引用
|
||
configs.forEach(config => {
|
||
config.cameraNode = this.cameraNode;
|
||
config.renderContainer = this.renderContainer;
|
||
});
|
||
|
||
const results = await PinballBootUtils.batchBoot(this, configs);
|
||
|
||
// 生成报告
|
||
const report = PinballBootUtils.generateBootReport(results);
|
||
console.log(report);
|
||
|
||
return results;
|
||
}
|
||
```
|
||
|
||
#### 性能基准测试
|
||
```typescript
|
||
async benchmarkPerformance() {
|
||
const config = PinballBootUtils.createMobileConfig(PinballBootMode.STANDALONE);
|
||
config.cameraNode = this.cameraNode;
|
||
config.renderContainer = this.renderContainer;
|
||
|
||
const benchmark = await PinballBootUtils.benchmarkBoot(this, config, 10);
|
||
|
||
console.log(`平均启动时间: ${benchmark.averageTime.toFixed(2)}ms`);
|
||
|
||
return benchmark;
|
||
}
|
||
```
|
||
|
||
#### 验证启动结果
|
||
```typescript
|
||
async bootWithValidation() {
|
||
const config = PinballBootstrap.createDefaultConfig(PinballBootMode.STANDALONE);
|
||
config.cameraNode = this.cameraNode;
|
||
config.renderContainer = this.renderContainer;
|
||
|
||
const bootstrap = PinballBootstrap.getInstance();
|
||
const result = await bootstrap.boot(this, config);
|
||
|
||
// 验证结果
|
||
const validation = PinballBootUtils.validateBootResult(result);
|
||
|
||
if (!validation.isValid) {
|
||
console.error('启动验证失败:', validation.issues.join(', '));
|
||
return null;
|
||
}
|
||
|
||
console.log('启动验证成功!');
|
||
return result;
|
||
}
|
||
```
|
||
|
||
## 错误处理
|
||
|
||
### 常见错误和解决方案
|
||
|
||
#### 1. 配置验证错误
|
||
```typescript
|
||
// 错误: 模式不支持
|
||
// 解决: 检查 PinballBootMode 枚举值
|
||
|
||
// 错误: 多人模式缺少服务器配置
|
||
// 解决: 添加 multiplayerConfig
|
||
config.multiplayerConfig = {
|
||
serverAddress: 'your-server-address',
|
||
playerName: 'player-name'
|
||
};
|
||
```
|
||
|
||
#### 2. 节点引用错误
|
||
```typescript
|
||
// 错误: 相机节点未设置
|
||
// 解决: 确保设置正确的相机节点
|
||
if (!config.cameraNode) {
|
||
console.warn('相机节点未设置,使用默认查找');
|
||
}
|
||
```
|
||
|
||
#### 3. 启动失败处理
|
||
```typescript
|
||
async bootWithFallback() {
|
||
try {
|
||
// 尝试启动首选模式
|
||
let result = await this.bootClientMultiplayer();
|
||
|
||
if (!result.success) {
|
||
console.warn('多人模式启动失败,回退到单机模式');
|
||
result = await PinballBootUtils.quickStartStandalone(this, this.cameraNode);
|
||
}
|
||
|
||
return result;
|
||
|
||
} catch (error) {
|
||
console.error('所有启动方式都失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
```
|
||
|
||
## 最佳实践
|
||
|
||
### 1. 配置管理
|
||
```typescript
|
||
// 将配置存储在单独的配置文件中
|
||
export const PINBALL_CONFIGS = {
|
||
MOBILE_STANDALONE: PinballBootUtils.createMobileConfig(PinballBootMode.STANDALONE),
|
||
DESKTOP_STANDALONE: PinballBootUtils.createDesktopConfig(PinballBootMode.STANDALONE),
|
||
PRODUCTION: PinballBootUtils.createProductionConfig(PinballBootMode.STANDALONE),
|
||
DEBUG: PinballBootUtils.createDebugConfig(PinballBootMode.STANDALONE)
|
||
};
|
||
```
|
||
|
||
### 2. 启动生命周期管理
|
||
```typescript
|
||
class GameLifecycleManager {
|
||
private bootResult: PinballBootResult = null;
|
||
|
||
async initialize() {
|
||
this.bootResult = await this.boot();
|
||
}
|
||
|
||
async shutdown() {
|
||
if (this.bootResult?.pinballManager) {
|
||
await this.bootResult.pinballManager.stopCurrentGame();
|
||
}
|
||
}
|
||
|
||
async restart() {
|
||
await this.shutdown();
|
||
await this.initialize();
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 错误监控
|
||
```typescript
|
||
async bootWithMonitoring() {
|
||
const config = this.createConfig();
|
||
|
||
try {
|
||
const result = await bootstrap.boot(this, config);
|
||
|
||
// 记录成功启动
|
||
this.analytics.trackEvent('pinball_boot_success', {
|
||
mode: result.mode,
|
||
timestamp: result.timestamp
|
||
});
|
||
|
||
return result;
|
||
|
||
} catch (error) {
|
||
// 记录启动失败
|
||
this.analytics.trackEvent('pinball_boot_failure', {
|
||
mode: config.mode,
|
||
error: error.message
|
||
});
|
||
|
||
throw error;
|
||
}
|
||
}
|
||
```
|
||
|
||
这个 Bootstrap 系统让 Pinball 游戏的启动变得更加灵活、可配置和可维护,同时保持了简单易用的接口。 |