cocos基础工程

This commit is contained in:
janing
2025-11-28 18:10:10 +08:00
parent 4e4863c7e6
commit 9742bf21fa
88 changed files with 4626 additions and 0 deletions

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "73bc9ff5-962b-4dd1-801f-0671a621bc9b",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -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;
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "d101ed2a-e68c-4b3b-831b-04d84f0596f0",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "3efea1af-73f2-404f-a948-e059b92c65c1",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -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('客户端多人模式尚未实现');
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "57dd41d5-1108-443c-8888-9aa695b552ce",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -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('服务器多人模式尚未实现');
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "6f237677-8531-40fc-af0a-c1e9f020528a",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "b1ed032a-5ed8-4dee-b821-8d4a4558ae00",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "e796606d-57a8-45e7-b700-66f4c28ccaed",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -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'
};
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "9cdad6b2-b0b6-4223-b44f-fbdf0f37197c",
"files": [],
"subMetas": {},
"userData": {}
}

View 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';

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "618d7e5f-842b-4506-a4ad-f55fc18f102b",
"files": [],
"subMetas": {},
"userData": {}
}