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,88 @@
/**
* 简单的事件总线实现
* 用于 Pinball 模块内部组件间通信
*/
export type EventCallback<T = any> = (data: T) => void;
export class EventBus {
private static instance: EventBus;
private events: Map<string, EventCallback[]> = new Map();
private constructor() { }
/**
* 获取单例实例
*/
static getInstance(): EventBus {
if (!EventBus.instance) {
EventBus.instance = new EventBus();
}
return EventBus.instance;
}
/**
* 订阅事件
*/
on<T = any>(event: string, callback: EventCallback<T>): void {
if (!this.events.has(event)) {
this.events.set(event, []);
}
this.events.get(event)!.push(callback);
}
/**
* 取消订阅事件
*/
off<T = any>(event: string, callback: EventCallback<T>): void {
const callbacks = this.events.get(event);
if (callbacks) {
const index = callbacks.indexOf(callback);
if (index > -1) {
callbacks.splice(index, 1);
}
}
}
/**
* 发射事件
*/
emit<T = any>(event: string, data?: T): void {
const callbacks = this.events.get(event);
if (callbacks) {
callbacks.forEach(callback => {
try {
callback(data);
} catch (error) {
console.error(`Error in event callback for event '${event}':`, error);
}
});
}
}
/**
* 只订阅一次事件
*/
once<T = any>(event: string, callback: EventCallback<T>): void {
const onceCallback: EventCallback<T> = (data: T) => {
callback(data);
this.off(event, onceCallback);
};
this.on(event, onceCallback);
}
/**
* 清理所有事件监听器
*/
clear(): void {
this.events.clear();
}
/**
* 获取事件监听器数量
*/
listenerCount(event: string): number {
const callbacks = this.events.get(event);
return callbacks ? callbacks.length : 0;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "1dc34aed-d9d7-4cd7-8bf7-5d4a1564882f",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,74 @@
/**
* Pinball 游戏核心数据结构定义
*/
/** 2D 向量 */
export interface Vector2 {
x: number;
y: number;
}
/** 物理体 ID */
export type BodyId = number;
/** 世界 ID */
export type WorldId = number;
/** 物理体数据 */
export interface PhysicsBodyData {
id: BodyId;
position: Vector2;
velocity: Vector2;
rotation: number;
angularVelocity: number;
bodyType: 'circle' | 'box';
radius?: number;
size?: Vector2;
isStatic: boolean;
}
/** 游戏状态 */
export interface GameState {
worldId: WorldId;
bodies: Map<BodyId, PhysicsBodyData>;
isPaused: boolean;
timeStep: number;
}
/** Pinball 配置 */
export interface PinballConfig {
mode: 'standalone' | 'client-multiplayer' | 'server-multiplayer';
serverAddress?: string;
wasmPath?: string;
physicsSettings?: {
gravity: Vector2;
timeStep: number;
};
renderSettings?: {
enableEffects: boolean;
maxParticles: number;
};
}
/** 物理设置 */
export interface PhysicsSettings {
gravity: Vector2;
timeStep: number;
maxBodies: number;
}
/** 游戏事件类型 */
export enum GameEventType {
PHYSICS_STEP = 'physics_step',
BODY_CREATED = 'body_created',
BODY_DESTROYED = 'body_destroyed',
WORLD_RESET = 'world_reset',
INPUT_RECEIVED = 'input_received'
}
/** 游戏事件数据 */
export interface GameEvent {
type: GameEventType;
data?: any;
timestamp: number;
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "ff4e5c1d-69eb-4234-9087-1b84b837d708",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,116 @@
/**
* 物理引擎接口
* 定义了不同物理引擎实现需要遵循的契约
*/
import { BodyId, PhysicsBodyData, PhysicsSettings, Vector2, WorldId } from './GameData';
export interface CreateCircleOptions {
position: Vector2;
radius: number;
isStatic: boolean;
density?: number;
restitution?: number;
friction?: number;
}
export interface CreateBoxOptions {
position: Vector2;
size: Vector2;
isStatic: boolean;
density?: number;
restitution?: number;
friction?: number;
}
export interface IPhysicsEngine {
/**
* 初始化物理引擎
*/
initialize(settings?: PhysicsSettings): Promise<void>;
/**
* 创建物理世界
*/
createWorld(gravity: Vector2): Promise<WorldId>;
/**
* 销毁物理世界
*/
destroyWorld(worldId: WorldId): Promise<void>;
/**
* 执行物理步进
*/
step(deltaTime: number, worldId?: WorldId): Promise<void>;
/**
* 创建圆形刚体
*/
createCircle(options: CreateCircleOptions): BodyId;
/**
* 创建矩形刚体
*/
createBox(options: CreateBoxOptions): BodyId;
/**
* 创建动态刚体
*/
createDynamicBody(worldId: WorldId, position: Vector2, radius: number): Promise<BodyId>;
/**
* 创建静态刚体
*/
createStaticBody(worldId: WorldId, position: Vector2, radius: number): Promise<BodyId>;
/**
* 销毁刚体
*/
destroyBody(worldId: WorldId, bodyId: BodyId): Promise<void>;
/**
* 移除刚体
*/
removeBody(bodyId: BodyId): void;
/**
* 获取刚体位置
*/
getBodyPosition(worldId: WorldId, bodyId: BodyId): Promise<Vector2 | null>;
/**
* 设置刚体位置
*/
setBodyPosition(worldId: WorldId, bodyId: BodyId, position: Vector2): Promise<void>;
/**
* 获取刚体速度
*/
getBodyVelocity(worldId: WorldId, bodyId: BodyId): Promise<Vector2 | null>;
/**
* 设置刚体速度
*/
setBodyVelocity(worldId: WorldId, bodyId: BodyId, velocity: Vector2): Promise<void>;
/**
* 获取刚体数据
*/
getBodyData(bodyId: BodyId): PhysicsBodyData | null;
/**
* 获取所有物理体数据
*/
getAllBodies(worldId: WorldId): Promise<PhysicsBodyData[]>;
/**
* 清理资源
*/
cleanup(): void;
/**
* 清理资源 (别名)
*/
dispose(): Promise<void>;
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "b15a76bd-406d-4463-8a9c-1e82229ab995",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,86 @@
/**
* 渲染器接口
* 定义了渲染系统需要实现的方法
*/
import { PhysicsBodyData, Vector2 } from './GameData';
/** 渲染对象数据 */
export interface RenderObject {
id: string;
position: Vector2;
radius: number;
color: { r: number; g: number; b: number; a: number };
layer: number;
}
/** 粒子效果数据 */
export interface ParticleEffect {
position: Vector2;
velocity: Vector2;
color: { r: number; g: number; b: number; a: number };
lifetime: number;
size: number;
}
export interface IRenderer {
/**
* 初始化渲染器
*/
initialize(parentNode: any): Promise<void>;
/**
* 渲染物理体
*/
renderBodies(bodies: PhysicsBodyData[]): void;
/**
* 创建渲染对象
*/
createRenderObject(body: PhysicsBodyData): RenderObject;
/**
* 更新渲染对象
*/
updateRenderObject(renderObject: RenderObject, body: PhysicsBodyData): void;
/**
* 移除渲染对象
*/
removeRenderObject(bodyId: string): void;
/**
* 播放粒子效果
*/
playParticleEffect(effect: ParticleEffect): void;
/**
* 清除所有渲染对象
*/
clear(): void;
/**
* 设置相机
*/
setCamera(camera: any): void;
/**
* 设置世界边界
*/
setWorldBounds(width: number, height: number): void;
/**
* 设置相机位置
*/
setCameraPosition(position: Vector2): void;
/**
* 设置相机缩放
*/
setCameraZoom(zoom: number): void;
/**
* 销毁渲染器
*/
dispose(): void;
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "afa401be-4482-4d0a-ae6c-1b1b94b7b992",
"files": [],
"subMetas": {},
"userData": {}
}