cocos基础工程
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* 启动器基类
|
||||
* 定义不同启动模式的统一接口
|
||||
*/
|
||||
|
||||
import { Component } from 'cc';
|
||||
import { PinballManager } from '../PinballManager';
|
||||
import { PinballBootConfig } from './BootTypes';
|
||||
|
||||
export abstract class BaseBooter {
|
||||
|
||||
/**
|
||||
* 启动特定模式的游戏
|
||||
* @param hostComponent 宿主组件
|
||||
* @param config 启动配置
|
||||
*/
|
||||
abstract boot(hostComponent: Component, config: PinballBootConfig): Promise<PinballManager>;
|
||||
|
||||
/**
|
||||
* 应用配置到 PinballManager
|
||||
* @param pinballManager PinballManager 实例
|
||||
* @param config 启动配置
|
||||
*/
|
||||
protected applyConfiguration(pinballManager: PinballManager, config: PinballBootConfig): void {
|
||||
// 设置节点引用
|
||||
if (config.cameraNode) {
|
||||
pinballManager.cameraNode = config.cameraNode;
|
||||
}
|
||||
|
||||
if (config.renderContainer) {
|
||||
pinballManager.renderContainer = config.renderContainer;
|
||||
}
|
||||
|
||||
if (config.uiContainer) {
|
||||
pinballManager.uiContainer = config.uiContainer;
|
||||
}
|
||||
|
||||
// 设置基础配置
|
||||
pinballManager.autoStart = config.autoStart !== false; // 默认为 true
|
||||
pinballManager.debugMode = config.debugMode || false;
|
||||
|
||||
// 应用自定义配置
|
||||
if (config.physicsConfig || config.renderConfig || config.wasmPath) {
|
||||
const pinballConfig = pinballManager.getConfig();
|
||||
|
||||
if (!pinballConfig) {
|
||||
pinballManager.updateConfig(config);
|
||||
} else {
|
||||
if (config.physicsConfig) {
|
||||
pinballConfig.physicsSettings = {
|
||||
...pinballConfig.physicsSettings,
|
||||
gravity: config.physicsConfig.gravity || { x: 0, y: -9.81 },
|
||||
timeStep: config.physicsConfig.timeStep || 1 / 60
|
||||
};
|
||||
}
|
||||
|
||||
if (config.renderConfig) {
|
||||
pinballConfig.renderSettings = {
|
||||
...pinballConfig.renderSettings,
|
||||
enableEffects: config.renderConfig.enableEffects !== false,
|
||||
maxParticles: config.renderConfig.maxParticles || 500
|
||||
};
|
||||
}
|
||||
|
||||
if (config.wasmPath) {
|
||||
pinballConfig.wasmPath = config.wasmPath;
|
||||
}
|
||||
|
||||
pinballManager.updateConfig(pinballConfig);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件日志输出
|
||||
*/
|
||||
protected log(message: string, enabled?: boolean): void {
|
||||
if (enabled !== false) {
|
||||
console.log(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "73bc9ff5-962b-4dd1-801f-0671a621bc9b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Pinball 启动配置接口
|
||||
*/
|
||||
|
||||
import { Node } from 'cc';
|
||||
|
||||
export enum PinballBootMode {
|
||||
STANDALONE = 'standalone',
|
||||
CLIENT_MULTIPLAYER = 'client-multiplayer',
|
||||
SERVER_MULTIPLAYER = 'server-multiplayer'
|
||||
}
|
||||
|
||||
export interface PinballBootConfig {
|
||||
/** 启动模式 */
|
||||
mode: PinballBootMode;
|
||||
|
||||
/** 主相机节点 */
|
||||
cameraNode?: Node;
|
||||
|
||||
/** 渲染容器节点 */
|
||||
renderContainer?: Node;
|
||||
|
||||
/** UI容器节点 */
|
||||
uiContainer?: Node;
|
||||
|
||||
/** 是否启用调试模式 */
|
||||
debugMode?: boolean;
|
||||
|
||||
/** 是否自动启动 */
|
||||
autoStart?: boolean;
|
||||
|
||||
/** 物理引擎配置 */
|
||||
physicsConfig?: {
|
||||
gravity?: { x: number; y: number };
|
||||
timeStep?: number;
|
||||
};
|
||||
|
||||
/** 渲染配置 */
|
||||
renderConfig?: {
|
||||
enableEffects?: boolean;
|
||||
maxParticles?: number;
|
||||
};
|
||||
|
||||
/** 多人模式配置 */
|
||||
multiplayerConfig?: {
|
||||
serverAddress?: string;
|
||||
playerName?: string;
|
||||
roomId?: string;
|
||||
};
|
||||
|
||||
/** WASM文件路径 */
|
||||
wasmPath?: string;
|
||||
}
|
||||
|
||||
export interface PinballBootResult {
|
||||
/** 启动是否成功 */
|
||||
success: boolean;
|
||||
|
||||
/** 错误信息(如果失败) */
|
||||
error?: string;
|
||||
|
||||
/** 启动的模式 */
|
||||
mode: PinballBootMode;
|
||||
|
||||
/** PinballManager 实例 */
|
||||
pinballManager?: any;
|
||||
|
||||
/** 启动时间戳 */
|
||||
timestamp: number;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "d101ed2a-e68c-4b3b-831b-04d84f0596f0",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "3efea1af-73f2-404f-a948-e059b92c65c1",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Client Multiplayer 模式启动器
|
||||
*/
|
||||
|
||||
import { Component } from 'cc';
|
||||
import { PinballManager } from '../../PinballManager';
|
||||
import { BaseBooter } from '../BaseBooter';
|
||||
import { PinballBootConfig } from '../BootTypes';
|
||||
|
||||
export class ClientMultiplayerBooter extends BaseBooter {
|
||||
|
||||
async boot(hostComponent: Component, config: PinballBootConfig): Promise<PinballManager> {
|
||||
this.log('[ClientMultiplayerBooter] 正在启动客户端多人模式...', config.debugMode);
|
||||
|
||||
// TODO: 实现客户端多人模式启动逻辑
|
||||
// 1. 连接到游戏服务器
|
||||
// 2. 加入游戏房间
|
||||
// 3. 设置网络同步和状态管理
|
||||
|
||||
throw new Error('客户端多人模式尚未实现');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "57dd41d5-1108-443c-8888-9aa695b552ce",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Server Multiplayer 模式启动器
|
||||
*/
|
||||
|
||||
import { Component } from 'cc';
|
||||
import { PinballManager } from '../../PinballManager';
|
||||
import { BaseBooter } from '../BaseBooter';
|
||||
import { PinballBootConfig } from '../BootTypes';
|
||||
|
||||
export class ServerMultiplayerBooter extends BaseBooter {
|
||||
|
||||
async boot(hostComponent: Component, config: PinballBootConfig): Promise<PinballManager> {
|
||||
this.log('[ServerMultiplayerBooter] 正在启动服务器多人模式...', config.debugMode);
|
||||
|
||||
// TODO: 实现服务器多人模式启动逻辑
|
||||
// 1. 连接到 SpacetimeDB
|
||||
// 2. 创建房间或加入现有房间
|
||||
// 3. 设置网络同步
|
||||
|
||||
throw new Error('服务器多人模式尚未实现');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "6f237677-8531-40fc-af0a-c1e9f020528a",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Standalone 模式启动器
|
||||
*/
|
||||
|
||||
import { Component } from 'cc';
|
||||
import { PinballManager, PinballMode } from '../../PinballManager';
|
||||
import { BaseBooter } from '../BaseBooter';
|
||||
import { PinballBootConfig } from '../BootTypes';
|
||||
|
||||
export class StandaloneBooter extends BaseBooter {
|
||||
|
||||
async boot(hostComponent: Component, config: PinballBootConfig): Promise<PinballManager> {
|
||||
this.log('[StandaloneBooter] 正在启动 Standalone 模式...', config.debugMode);
|
||||
|
||||
// 创建或获取 PinballManager 组件
|
||||
let pinballManager = hostComponent.getComponent(PinballManager);
|
||||
if (!pinballManager) {
|
||||
pinballManager = hostComponent.addComponent(PinballManager);
|
||||
}
|
||||
|
||||
// 应用配置
|
||||
this.applyConfiguration(pinballManager, config);
|
||||
|
||||
// 设置默认模式
|
||||
pinballManager.defaultMode = PinballMode.STANDALONE;
|
||||
|
||||
// 启动 PinballManager(在配置应用后)
|
||||
const startSuccess = await pinballManager.Start();
|
||||
if (!startSuccess) {
|
||||
throw new Error('PinballManager 启动失败');
|
||||
}
|
||||
|
||||
// 启动 Standalone 模式
|
||||
const success = await pinballManager.startGame(PinballMode.STANDALONE);
|
||||
if (!success) {
|
||||
throw new Error('Standalone 模式启动失败');
|
||||
}
|
||||
|
||||
this.log('[StandaloneBooter] Standalone 模式启动完成', config.debugMode);
|
||||
return pinballManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "b1ed032a-5ed8-4dee-b821-8d4a4558ae00",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* Pinball 启动工具类
|
||||
* 提供常用的启动配置和便捷方法
|
||||
*/
|
||||
|
||||
import { Component } from 'cc';
|
||||
import { PinballBootConfig, PinballBootMode, PinballBootResult, PinballBootstrap } from './index';
|
||||
|
||||
export class PinballBootUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 创建高性能配置(适合移动设备)
|
||||
*/
|
||||
public static createMobileConfig(mode: PinballBootMode): PinballBootConfig {
|
||||
const config = PinballBootstrap.createDefaultConfig(mode);
|
||||
|
||||
// 移动设备优化配置
|
||||
config.renderConfig = {
|
||||
enableEffects: false, // 关闭粒子效果以提升性能
|
||||
maxParticles: 100 // 降低粒子数量
|
||||
};
|
||||
|
||||
config.physicsConfig = {
|
||||
gravity: { x: 0, y: -9.81 },
|
||||
timeStep: 1 / 30 // 降低物理步进频率
|
||||
};
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建高质量配置(适合桌面设备)
|
||||
*/
|
||||
public static createDesktopConfig(mode: PinballBootMode): PinballBootConfig {
|
||||
const config = PinballBootstrap.createDefaultConfig(mode);
|
||||
|
||||
// 桌面设备高质量配置
|
||||
config.renderConfig = {
|
||||
enableEffects: true, // 启用所有粒子效果
|
||||
maxParticles: 1000 // 更多粒子数量
|
||||
};
|
||||
|
||||
config.physicsConfig = {
|
||||
gravity: { x: 0, y: -9.81 },
|
||||
timeStep: 1 / 120 // 更高的物理步进频率
|
||||
};
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建调试配置
|
||||
*/
|
||||
public static createDebugConfig(mode: PinballBootMode): PinballBootConfig {
|
||||
const config = PinballBootstrap.createDefaultConfig(mode);
|
||||
config.debugMode = true;
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建生产配置
|
||||
*/
|
||||
public static createProductionConfig(mode: PinballBootMode): PinballBootConfig {
|
||||
const config = PinballBootstrap.createDefaultConfig(mode);
|
||||
config.debugMode = false;
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量启动多个模式(用于测试)
|
||||
*/
|
||||
public static async batchBoot(
|
||||
hostComponent: Component,
|
||||
configs: PinballBootConfig[]
|
||||
): Promise<PinballBootResult[]> {
|
||||
const bootstrap = PinballBootstrap.getInstance();
|
||||
const results: PinballBootResult[] = [];
|
||||
|
||||
for (const config of configs) {
|
||||
console.log(`[PinballBootUtils] 批量启动: ${config.mode}`);
|
||||
const result = await bootstrap.boot(hostComponent, config);
|
||||
results.push(result);
|
||||
|
||||
// 如果启动失败,停止批量启动
|
||||
if (!result.success) {
|
||||
console.error(`[PinballBootUtils] 批量启动在 ${config.mode} 模式失败: ${result.error}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* 性能基准测试启动
|
||||
*/
|
||||
public static async benchmarkBoot(
|
||||
hostComponent: Component,
|
||||
config: PinballBootConfig,
|
||||
iterations: number = 5
|
||||
): Promise<{ averageTime: number; results: PinballBootResult[] }> {
|
||||
const bootstrap = PinballBootstrap.getInstance();
|
||||
const results: PinballBootResult[] = [];
|
||||
let totalTime = 0;
|
||||
|
||||
console.log(`[PinballBootUtils] 开始性能基准测试,迭代次数: ${iterations}`);
|
||||
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
const startTime = performance.now();
|
||||
const result = await bootstrap.boot(hostComponent, config);
|
||||
const endTime = performance.now();
|
||||
|
||||
const duration = endTime - startTime;
|
||||
totalTime += duration;
|
||||
|
||||
results.push(result);
|
||||
|
||||
console.log(`[PinballBootUtils] 第 ${i + 1} 次启动耗时: ${duration.toFixed(2)}ms`);
|
||||
|
||||
// 清理资源准备下一次测试
|
||||
if (result.success && result.pinballManager) {
|
||||
await result.pinballManager.stopCurrentGame();
|
||||
}
|
||||
}
|
||||
|
||||
const averageTime = totalTime / iterations;
|
||||
console.log(`[PinballBootUtils] 平均启动时间: ${averageTime.toFixed(2)}ms`);
|
||||
|
||||
return { averageTime, results };
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证启动结果
|
||||
*/
|
||||
public static validateBootResult(result: PinballBootResult): {
|
||||
isValid: boolean;
|
||||
issues: string[];
|
||||
} {
|
||||
const issues: string[] = [];
|
||||
|
||||
if (!result.success) {
|
||||
issues.push(`启动失败: ${result.error}`);
|
||||
}
|
||||
|
||||
if (!result.pinballManager) {
|
||||
issues.push('PinballManager 实例不存在');
|
||||
}
|
||||
|
||||
if (!result.mode) {
|
||||
issues.push('启动模式未定义');
|
||||
}
|
||||
|
||||
if (!result.timestamp || result.timestamp <= 0) {
|
||||
issues.push('时间戳无效');
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: issues.length === 0,
|
||||
issues
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成启动报告
|
||||
*/
|
||||
public static generateBootReport(results: PinballBootResult[]): string {
|
||||
const successCount = results.filter(r => r.success).length;
|
||||
const failureCount = results.length - successCount;
|
||||
|
||||
let report = '=== Pinball 启动报告 ===\n';
|
||||
report += `总启动次数: ${results.length}\n`;
|
||||
report += `成功启动: ${successCount}\n`;
|
||||
report += `启动失败: ${failureCount}\n`;
|
||||
report += `成功率: ${((successCount / results.length) * 100).toFixed(1)}%\n\n`;
|
||||
|
||||
if (failureCount > 0) {
|
||||
report += '失败详情:\n';
|
||||
results.filter(r => !r.success).forEach((result, index) => {
|
||||
report += `${index + 1}. ${result.mode}: ${result.error}\n`;
|
||||
});
|
||||
}
|
||||
|
||||
return report;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "e796606d-57a8-45e7-b700-66f4c28ccaed",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Pinball 启动管理器
|
||||
* 负责维护游戏启动状态和调度具体启动器
|
||||
*/
|
||||
|
||||
import { Component } from 'cc';
|
||||
import { PinballBootConfig, PinballBootMode, PinballBootResult } from './BootTypes';
|
||||
import { ClientMultiplayerBooter } from './Mode/ClientMultiplayerBooter';
|
||||
import { ServerMultiplayerBooter } from './Mode/ServerMultiplayerBooter';
|
||||
import { StandaloneBooter } from './Mode/StandaloneBooter';
|
||||
|
||||
export class PinballBootstrap {
|
||||
private static instance: PinballBootstrap;
|
||||
private currentResult: PinballBootResult | null = null;
|
||||
|
||||
/** 获取单例实例 */
|
||||
public static getInstance(): PinballBootstrap {
|
||||
if (!PinballBootstrap.instance) {
|
||||
PinballBootstrap.instance = new PinballBootstrap();
|
||||
}
|
||||
return PinballBootstrap.instance;
|
||||
}
|
||||
|
||||
private constructor() { }
|
||||
|
||||
/**
|
||||
* 启动 Pinball 游戏
|
||||
*/
|
||||
public async boot(hostComponent: Component, config: PinballBootConfig): Promise<PinballBootResult> {
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
console.log(`[PinballBootstrap] 开始启动 ${config.mode} 模式`);
|
||||
|
||||
// 获取对应的启动器
|
||||
const booter = this.getBooter(config.mode);
|
||||
|
||||
// 执行启动
|
||||
const pinballManager = await booter.boot(hostComponent, config);
|
||||
|
||||
// 记录启动结果
|
||||
this.currentResult = {
|
||||
success: true,
|
||||
mode: config.mode,
|
||||
pinballManager,
|
||||
timestamp: startTime
|
||||
};
|
||||
|
||||
console.log(`[PinballBootstrap] ${config.mode} 模式启动成功`);
|
||||
return this.currentResult;
|
||||
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
console.error(`[PinballBootstrap] 启动失败:`, error);
|
||||
|
||||
this.currentResult = {
|
||||
success: false,
|
||||
error: errorMessage,
|
||||
mode: config.mode,
|
||||
timestamp: startTime
|
||||
};
|
||||
|
||||
return this.currentResult;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取启动器实例
|
||||
*/
|
||||
private getBooter(mode: PinballBootMode) {
|
||||
switch (mode) {
|
||||
case PinballBootMode.STANDALONE:
|
||||
return new StandaloneBooter();
|
||||
case PinballBootMode.CLIENT_MULTIPLAYER:
|
||||
return new ClientMultiplayerBooter();
|
||||
case PinballBootMode.SERVER_MULTIPLAYER:
|
||||
return new ServerMultiplayerBooter();
|
||||
default:
|
||||
throw new Error(`不支持的启动模式: ${mode}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前启动结果
|
||||
*/
|
||||
public getCurrentResult(): PinballBootResult | null {
|
||||
return this.currentResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除启动状态
|
||||
*/
|
||||
public clearState(): void {
|
||||
this.currentResult = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建默认配置
|
||||
*/
|
||||
public static createDefaultConfig(mode: PinballBootMode): PinballBootConfig {
|
||||
return {
|
||||
mode,
|
||||
debugMode: true,
|
||||
autoStart: true,
|
||||
physicsConfig: {
|
||||
gravity: { x: 0, y: -9.81 },
|
||||
timeStep: 1 / 60
|
||||
},
|
||||
renderConfig: {
|
||||
enableEffects: true,
|
||||
maxParticles: 500
|
||||
},
|
||||
wasmPath: 'assets/wasm/pinball_physics.wasm'
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "9cdad6b2-b0b6-4223-b44f-fbdf0f37197c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
12
client-cocos/assets/scripts/Modules/Pinball/Boot/index.ts
Normal file
12
client-cocos/assets/scripts/Modules/Pinball/Boot/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Pinball Boot 模块入口
|
||||
* 导出启动相关的所有类型和类
|
||||
*/
|
||||
|
||||
export { PinballBootMode } from './BootTypes';
|
||||
export type {
|
||||
PinballBootConfig,
|
||||
PinballBootResult
|
||||
} from './BootTypes';
|
||||
export { PinballBootstrap } from './PinballBootstrap';
|
||||
export { PinballBootUtils } from './PinballBootUtils';
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "618d7e5f-842b-4506-a4ad-f55fc18f102b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Reference in New Issue
Block a user