freeblox/packages/engine/src/components/environment.ts

73 lines
2.4 KiB
TypeScript

import { AmbientLight, Color, DirectionalLight } from 'three';
import { EngineEvents, EnvironmentEvent } from '../types/events';
import { EngineComponent } from '../types/engine-component';
import { Renderer } from '../core/renderer';
import { EventEmitter } from '../utils/events';
import { Environment } from '../gameobjects/environment.object';
import { environmentDefaults } from '../defaults/environment';
/**
* This component manages game environment and world lighting.
* @listens setEnvironment
*/
export class EnvironmentComponent extends EngineComponent {
public name = EnvironmentComponent.name;
public ambient!: AmbientLight;
public directional!: DirectionalLight;
public object = new Environment();
private cleanUpEvents?: Function;
constructor(
protected renderer: Renderer,
protected events: EventEmitter<EngineEvents>
) {
super(renderer, events);
}
initialize(): void {
this.renderer.scene.add(this.object);
this.renderer.renderer.setClearColor(environmentDefaults.clearColor);
this.ambient = new AmbientLight(
environmentDefaults.ambientColor,
environmentDefaults.ambientStrength
);
this.directional = new DirectionalLight(
environmentDefaults.sunColor,
environmentDefaults.sunStrength
);
this.directional.position.copy(environmentDefaults.sunPosition);
this.renderer.scene.add(this.ambient);
this.renderer.scene.add(this.directional);
this.cleanUpEvents = this.bindEvents();
}
update(delta: number): void {}
dispose(): void {
this.renderer.scene.remove(this.ambient);
this.renderer.scene.remove(this.directional);
this.cleanUpEvents?.call(this);
}
private bindEvents() {
const setEnvironmentEvent = (event: EnvironmentEvent) => {
if (event.sunColor) this.directional.color = new Color(event.sunColor);
if (event.sunPosition) this.directional.position.copy(event.sunPosition);
if (event.sunStrength) this.directional.intensity = event.sunStrength;
if (event.ambientColor)
this.ambient.color = new Color(event.ambientColor);
if (event.ambientStrength) this.ambient.intensity = event.ambientStrength;
if (event.clearColor)
this.renderer.renderer.setClearColor(event.clearColor);
};
this.events.addListener('setEnvironment', setEnvironmentEvent);
return () => {
this.events.removeEventListener('setEnvironment', setEnvironmentEvent);
};
}
}