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); } 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}, container) { 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 (!this.attached) { const {diffuse, normals} = this; diffuse.rotation = 0; normals.rotation = 0; } if (Direction) { const {diffuse, normals} = this; if (!this.attached || 'direction' in Direction) { if (this.entity.Sprite.rotates) { const rotation = this.entity.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()); } if (this.attached || !container) { return; } container.addChild(this.container); container.addChild(this.debug); this.attached = true; } }