Files
shooter-demo/client-cocos/assets/scripts/Modules/Pinball/PinballManager.ts

400 lines
11 KiB
TypeScript
Raw Normal View History

2025-11-28 18:10:10 +08:00
/**
* PinballManager - Pinball模块主控制器
* Pinball模块的生命周期管理和模式切换
*/
import { _decorator, Camera, Component, director, Director, game, Game, Node, Scene } from 'cc';
import { EventBus } from './Core/EventBus';
import { GameState, PinballConfig } from './Core/GameData';
import { StandaloneMode } from './GameModes/StandaloneMode';
const { ccclass, property } = _decorator;
export enum PinballMode {
STANDALONE = 'standalone',
CLIENT_MULTIPLAYER = 'client-multiplayer',
SERVER_MULTIPLAYER = 'server-multiplayer'
}
@ccclass('PinballManager')
export class PinballManager extends Component {
@property({
type: Node,
tooltip: "主相机节点,用于渲染游戏画面"
})
cameraNode: Node = null;
@property({
type: Node,
tooltip: "渲染容器节点,所有游戏对象将在此节点下渲染"
})
renderContainer: Node = null;
@property({
type: Node,
tooltip: "UI容器节点用于显示游戏UI界面"
})
uiContainer: Node = null;
@property({
tooltip: "启动时的默认游戏模式"
})
defaultMode: PinballMode = PinballMode.STANDALONE;
@property({
tooltip: "是否在启动时自动开始游戏"
})
autoStart: boolean = true;
@property({
tooltip: "调试模式,启用详细日志"
})
debugMode: boolean = true;
// 核心系统
private eventBus: EventBus = null;
private currentMode: PinballMode = null;
private currentGameMode: Component = null;
private mainCamera: Camera = null;
// 游戏状态
private isInitialized: boolean = false;
private isPaused: boolean = false;
private gameConfig: PinballConfig = null;
/**
* PinballManager
*
*/
async Start(): Promise<boolean> {
this.log('[PinballManager] Start 开始');
try {
// 初始化事件总线
this.eventBus = EventBus.getInstance();
// 验证必需的节点
if (!this.validateRequiredNodes()) {
console.error('[PinballManager] 必需节点验证失败');
return false;
}
// 获取主相机
this.initializeCamera();
// 创建默认配置
this.createDefaultConfig();
// 注册全局事件监听器
this.registerGlobalEvents();
// 初始化完成
this.isInitialized = true;
this.log('[PinballManager] 初始化完成');
this.log('[PinballManager] Start 完成');
return true;
} catch (error) {
console.error('[PinballManager] Start 过程中发生错误:', error);
return false;
}
}
/**
* PinballManager
*/
Stop(): void {
this.log('[PinballManager] Stop 开始');
this.cleanup();
this.isInitialized = false;
this.log('[PinballManager] Stop 完成');
}
// 保留 onDestroy 作为安全清理
onDestroy() {
this.Stop();
}
/**
*
*/
private validateRequiredNodes(): boolean {
if (!this.cameraNode) {
console.error('[PinballManager] cameraNode 未设置');
return false;
}
if (!this.renderContainer) {
console.error('[PinballManager] renderContainer 未设置');
return false;
}
return true;
}
/**
*
*/
private initializeCamera(): void {
this.mainCamera = this.cameraNode.getComponent(Camera);
if (!this.mainCamera) {
console.error('[PinballManager] 主相机组件未找到');
return;
}
this.log('主相机初始化完成');
}
/**
*
*/
private createDefaultConfig(): void {
this.gameConfig = {
mode: this.defaultMode,
physicsSettings: {
gravity: { x: 0, y: -9.81 },
timeStep: 1 / 60
},
renderSettings: {
enableEffects: true,
maxParticles: 500
},
wasmPath: 'assets/wasm/pinball_physics.wasm'
};
this.log('默认配置创建完成', this.gameConfig);
}
/**
*
*/
private registerGlobalEvents(): void {
// 监听场景切换事件 - Cocos Creator 3.x 中使用静态常量
director.on(Director.EVENT_BEFORE_SCENE_LAUNCH, this.onSceneChange, this);
// 监听游戏暂停/恢复 - Cocos Creator 3.x 中使用game事件
game.on(Game.EVENT_HIDE, this.onGamePause, this);
game.on(Game.EVENT_SHOW, this.onGameResume, this);
this.log('全局事件监听器注册完成');
}
/**
*
*/
public async startGame(mode: PinballMode): Promise<boolean> {
if (!this.isInitialized) {
console.error('[PinballManager] 尚未初始化');
return false;
}
if (this.currentGameMode) {
await this.stopCurrentGame();
}
this.log(`开始启动游戏模式: ${mode}`);
try {
switch (mode) {
case PinballMode.STANDALONE:
await this.startStandaloneMode();
break;
case PinballMode.CLIENT_MULTIPLAYER:
console.warn('[PinballManager] Client Multiplayer 模式尚未实现');
return false;
case PinballMode.SERVER_MULTIPLAYER:
console.warn('[PinballManager] Server Multiplayer 模式尚未实现');
return false;
default:
console.error(`[PinballManager] 未知游戏模式: ${mode}`);
return false;
}
this.currentMode = mode;
this.gameConfig.mode = mode;
this.log(`游戏模式 ${mode} 启动成功`);
// 发送游戏开始事件
this.eventBus.emit('game.started', { mode });
return true;
} catch (error) {
console.error(`[PinballManager] 启动游戏模式 ${mode} 失败:`, error);
return false;
}
}
/**
* Standalone模式
*/
private async startStandaloneMode(): Promise<void> {
// 添加StandaloneMode组件
const standaloneMode = this.node.addComponent(StandaloneMode);
// 设置所需的引用
standaloneMode.gameCamera = this.mainCamera;
standaloneMode.renderNode = this.renderContainer;
standaloneMode.boundsNode = this.renderContainer; // 简化设置
// StandaloneMode 会在 onLoad 中自动初始化
this.currentGameMode = standaloneMode;
this.log('Standalone模式启动完成');
}
/**
*
*/
public async stopCurrentGame(): Promise<void> {
if (!this.currentGameMode) {
return;
}
this.log(`停止当前游戏模式: ${this.currentMode}`);
// 销毁当前游戏模式组件
this.currentGameMode.destroy();
this.currentGameMode = null;
this.currentMode = null;
// 发送游戏停止事件
this.eventBus.emit('game.stopped', {});
this.log('当前游戏模式已停止');
}
/**
*
*/
public pauseGame(): void {
if (this.isPaused) {
return;
}
this.isPaused = true;
this.eventBus.emit('game.paused', {});
this.log('游戏已暂停');
}
/**
*
*/
public resumeGame(): void {
if (!this.isPaused) {
return;
}
this.isPaused = false;
this.eventBus.emit('game.resumed', {});
this.log('游戏已恢复');
}
/**
*
*/
public async restartGame(): Promise<boolean> {
const currentMode = this.currentMode;
if (currentMode) {
await this.stopCurrentGame();
return await this.startGame(currentMode);
}
return false;
}
/**
*
*/
public async switchMode(newMode: PinballMode): Promise<boolean> {
if (this.currentMode === newMode) {
this.log(`已经是 ${newMode} 模式`);
return true;
}
return await this.startGame(newMode);
}
/**
*
*/
private onSceneChange(scene: Scene): void {
this.log('场景切换事件');
// 可以在此处理场景切换时的清理工作
}
/**
*
*/
private onGamePause(): void {
this.pauseGame();
}
/**
*
*/
private onGameResume(): void {
this.resumeGame();
}
/**
*
*/
private cleanup(): void {
// 清理全局事件监听器
director.off(Director.EVENT_BEFORE_SCENE_LAUNCH, this.onSceneChange, this);
game.off(Game.EVENT_HIDE, this.onGamePause, this);
game.off(Game.EVENT_SHOW, this.onGameResume, this);
// 停止当前游戏
if (this.currentGameMode) {
this.stopCurrentGame();
}
this.log('PinballManager 资源清理完成');
}
/**
*
*/
public getGameState(): GameState | null {
if (this.currentGameMode && this.currentGameMode instanceof StandaloneMode) {
return this.currentGameMode.getGameStats() as any;
}
return null;
}
/**
*
*/
public getConfig(): PinballConfig {
return this.gameConfig;
}
/**
*
*/
public updateConfig(newConfig: Partial<PinballConfig>): void {
this.gameConfig = { ...this.gameConfig, ...newConfig };
this.log('游戏配置已更新', this.gameConfig);
}
/**
*
*/
private log(message: string, data?: any): void {
if (this.debugMode) {
if (data) {
console.log(`[PinballManager] ${message}`, data);
} else {
console.log(`[PinballManager] ${message}`);
}
}
}
}