195 lines
5.7 KiB
JavaScript
195 lines
5.7 KiB
JavaScript
import {Assets} from '@pixi/assets';
|
|
import {Container as PixiContainer} from '@pixi/display';
|
|
import {Sprite} from '@pixi/sprite';
|
|
|
|
import Aabb from './aabb.js';
|
|
import createCrosshair from './crosshair.js';
|
|
import {deferredLighting, PointLight} from './lights.js';
|
|
|
|
export default class Entity {
|
|
static assets = {};
|
|
attached = false;
|
|
colliderAabb = new Aabb({color: 0xffffff});
|
|
container = new PixiContainer();
|
|
crosshair = createCrosshair();
|
|
debug = new PixiContainer();
|
|
diffuse = new Sprite();
|
|
isMainEntity = false;
|
|
normals = new Sprite();
|
|
point;
|
|
sprite = new PixiContainer();
|
|
visibleAabb = new Aabb({color: 0xff00ff});
|
|
constructor() {
|
|
this.diffuse.parentGroup = deferredLighting.diffuseGroup;
|
|
this.normals.parentGroup = deferredLighting.normalGroup;
|
|
this.container.addChild(this.diffuse);
|
|
this.container.addChild(this.normals);
|
|
this.container.addChild(this.crosshair);
|
|
this.debug.addChild(this.colliderAabb);
|
|
this.debug.addChild(this.visibleAabb);
|
|
}
|
|
addToContainer(container) {
|
|
if (this.attached || !container) {
|
|
return;
|
|
}
|
|
container.addChild(this.container);
|
|
container.addChild(this.debug);
|
|
this.attached = true;
|
|
}
|
|
static async loadAsset(source = '') {
|
|
if (!this.assets['']) {
|
|
const {Texture} = await import('@pixi/core');
|
|
this.assets[''] = {data: {meta: {}}, textures: {'': Texture.WHITE}};
|
|
}
|
|
if (!this.assets[source]) {
|
|
this.assets[source] = Assets.load(source);
|
|
}
|
|
return this.assets[source];
|
|
}
|
|
removeFromContainer() {
|
|
this.container.parent.removeChild(this.container);
|
|
this.debug.parent.removeChild(this.debug);
|
|
this.attached = false;
|
|
}
|
|
reset(entity, debug) {
|
|
this.entity = entity;
|
|
if (this.light) {
|
|
this.container.removeChild(this.light);
|
|
this.light = undefined;
|
|
}
|
|
this.setDebug(debug);
|
|
this.isMainEntity = false;
|
|
if (this.interactionAabb) {
|
|
this.debug.removeChild(this.interactionAabb);
|
|
}
|
|
this.interactionAabb = undefined;
|
|
}
|
|
setDebug(isDebugging) {
|
|
if (isDebugging) {
|
|
this.crosshair.alpha = 1;
|
|
this.debug.alpha = 1;
|
|
}
|
|
else {
|
|
this.crosshair.alpha = 0;
|
|
this.debug.alpha = 0;
|
|
}
|
|
}
|
|
setMainEntity() {
|
|
if (this.isMainEntity) {
|
|
return;
|
|
}
|
|
this.isMainEntity = true;
|
|
this.interactionAabb = new Aabb({color: 0x00ff00});
|
|
this.debug.addChild(this.interactionAabb);
|
|
}
|
|
static textureFromAsset(asset, animation, frame) {
|
|
if (!asset) {
|
|
return undefined;
|
|
}
|
|
let texture;
|
|
if (asset.data.animations) {
|
|
if (!animation) {
|
|
return undefined;
|
|
}
|
|
texture = asset.animations[animation][frame];
|
|
}
|
|
else {
|
|
texture = asset.textures[''];
|
|
}
|
|
return texture;
|
|
}
|
|
update({Direction, Light, Position, Sprite, VisibleAabb}) {
|
|
if (Light) {
|
|
if (!this.light) {
|
|
this.light = new PointLight(
|
|
0xffffff - 0x2244cc,
|
|
0,
|
|
);
|
|
}
|
|
this.light.brightness = Light.brightness;
|
|
}
|
|
if (Position) {
|
|
const {x, y} = this.entity.Position;
|
|
this.container.x = x;
|
|
this.container.y = y;
|
|
this.container.zIndex = y;
|
|
}
|
|
if (Sprite) {
|
|
const {diffuse, normals} = this;
|
|
if (!this.attached || 'alpha' in Sprite) {
|
|
diffuse.alpha = normals.alpha = this.entity.Sprite.alpha;
|
|
}
|
|
if (!this.attached || 'anchorX' in Sprite) {
|
|
diffuse.anchor.x = normals.anchor.x = this.entity.Sprite.anchorX;
|
|
}
|
|
if (!this.attached || 'anchorY' in Sprite) {
|
|
diffuse.anchor.y = normals.anchor.y = this.entity.Sprite.anchorY;
|
|
}
|
|
if (!this.attached || 'scaleX' in Sprite) {
|
|
diffuse.scale.x = normals.scale.x = this.entity.Sprite.scaleX;
|
|
}
|
|
if (!this.attached || 'scaleY' in Sprite) {
|
|
diffuse.scale.y = normals.scale.y = this.entity.Sprite.scaleY;
|
|
}
|
|
if (!this.attached || 'tint' in Sprite) {
|
|
diffuse.tint = normals.tint = this.entity.Sprite.tint;
|
|
}
|
|
if (
|
|
!this.attached
|
|
|| ('source' in Sprite)
|
|
|| ('animation' in Sprite)
|
|
|| ('frame' in Sprite)
|
|
) {
|
|
this.constructor.loadAsset(this.entity.Sprite.source).then(async (asset) => {
|
|
if (!this.entity?.Sprite) {
|
|
return;
|
|
}
|
|
const texture = await this.constructor.textureFromAsset(
|
|
asset,
|
|
this.entity.Sprite.animation,
|
|
this.entity.Sprite.frame,
|
|
);
|
|
diffuse.texture = texture;
|
|
if (asset.data.meta.normals) {
|
|
const {pathname} = new URL(
|
|
Sprite.source
|
|
.split('/')
|
|
.slice(0, -1)
|
|
.concat(asset.data.meta.normals)
|
|
.join('/'),
|
|
'http://example.org',
|
|
);
|
|
this.constructor.loadAsset(pathname).then(async (asset) => {
|
|
const texture = await this.constructor.textureFromAsset(
|
|
asset,
|
|
this.entity.Sprite.animation,
|
|
this.entity.Sprite.frame,
|
|
);
|
|
normals.texture = texture;
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
if (Direction) {
|
|
const {diffuse, normals} = this;
|
|
if ('direction' in Direction) {
|
|
if (this.entity.Sprite.rotates) {
|
|
const rotation = Direction.direction + this.entity.Sprite.rotation;
|
|
diffuse.rotation = rotation;
|
|
normals.rotation = rotation;
|
|
}
|
|
}
|
|
}
|
|
if (this.entity.Collider) {
|
|
this.colliderAabb.redraw(this.entity.Collider.aabb);
|
|
}
|
|
if (VisibleAabb) {
|
|
this.visibleAabb.redraw(this.entity.VisibleAabb);
|
|
}
|
|
if (this.isMainEntity) {
|
|
this.interactionAabb.redraw(this.entity.Interacts.aabb());
|
|
}
|
|
}
|
|
}
|