109 lines
3.0 KiB
TypeScript
109 lines
3.0 KiB
TypeScript
import { Renderer } from '../core/renderer';
|
|
import { EngineComponent } from '../types/engine-component';
|
|
import {
|
|
ChangeEvent,
|
|
EngineEvents,
|
|
RemoveEvent,
|
|
ReparentEvent,
|
|
} from '../types/events';
|
|
import { EventEmitter } from '../utils/events';
|
|
import { Environment } from '../gameobjects/environment.object';
|
|
import { assetManager } from '../assets/manager';
|
|
import { WorldFile } from '../types/world-file';
|
|
import { World } from '../gameobjects/world.object';
|
|
|
|
/**
|
|
* Game level management component
|
|
* @listens change Applies changes to objects
|
|
* @listens remove Removes objects from scene
|
|
* @listens reparent Reparents object
|
|
*/
|
|
export class LevelComponent extends EngineComponent {
|
|
private world!: World;
|
|
private environment!: Environment;
|
|
private cleanUpEvents?: Function;
|
|
|
|
constructor(
|
|
protected renderer: Renderer,
|
|
protected events: EventEmitter<EngineEvents>
|
|
) {
|
|
super(renderer, events);
|
|
}
|
|
|
|
initialize(): void {
|
|
this.world = this.renderer.scene.getObjectByName('World') as World;
|
|
this.environment = this.renderer.scene.getObjectByName(
|
|
'Environment'
|
|
) as Environment;
|
|
this.cleanUpEvents = this.bindEvents();
|
|
}
|
|
|
|
update(delta: number): void {}
|
|
|
|
cleanUp(): void {
|
|
this.cleanUpEvents?.call(this);
|
|
}
|
|
|
|
public getSceneTree() {
|
|
return {
|
|
world: this.world,
|
|
environment: this.environment,
|
|
};
|
|
}
|
|
|
|
public serializeLevelSave(name: string): WorldFile {
|
|
const world = this.world.serialize();
|
|
const environment = this.environment.serialize();
|
|
const assets = assetManager.serialize();
|
|
return {
|
|
name,
|
|
world,
|
|
environment,
|
|
assets,
|
|
};
|
|
}
|
|
|
|
private bindEvents() {
|
|
const changeEvent = (event: ChangeEvent) => {
|
|
if (event.applied || !event.object) return;
|
|
const prop = (event.object as any)[event.property];
|
|
if (prop?.copy) prop.copy(event.value);
|
|
else (event.object as any)[event.property] = event.value;
|
|
};
|
|
|
|
const removeEvent = (event: RemoveEvent) => {
|
|
if (event.applied || !event.object) return;
|
|
if (Array.isArray(event.object)) {
|
|
event.object.forEach((object) => object.removeFromParent());
|
|
return;
|
|
}
|
|
|
|
event.object.removeFromParent();
|
|
};
|
|
|
|
const reparentEvent = (event: ReparentEvent) => {
|
|
if (event.applied || !event.object || !event.parent) return;
|
|
if (Array.isArray(event.object)) {
|
|
event.object.forEach((object) => {
|
|
object.removeFromParent();
|
|
event.parent.add(object);
|
|
});
|
|
return;
|
|
}
|
|
|
|
event.object.removeFromParent();
|
|
event.parent.add(event.object);
|
|
};
|
|
|
|
this.events.addListener('change', changeEvent);
|
|
this.events.addListener('remove', removeEvent);
|
|
this.events.addListener('reparent', reparentEvent);
|
|
|
|
return () => {
|
|
this.events.removeEventListener('change', changeEvent);
|
|
this.events.removeEventListener('remove', removeEvent);
|
|
this.events.removeEventListener('reparent', reparentEvent);
|
|
};
|
|
}
|
|
}
|