workadventure/front/src/Phaser/Items/ActionableItem.ts

96 lines
3.3 KiB
TypeScript
Raw Normal View History

/**
* An actionable item represents an in-game object that can be activated using the space-bar.
* It has coordinates and an "activation radius"
*/
import Sprite = Phaser.GameObjects.Sprite;
import {OutlinePipeline} from "../Shaders/OutlinePipeline";
import type {GameScene} from "../Game/GameScene";
2020-07-27 22:36:07 +02:00
type EventCallback = (state: unknown, parameters: unknown) => void;
export class ActionableItem {
private readonly activationRadiusSquared : number;
private isSelectable: boolean = false;
2020-07-27 22:36:07 +02:00
private callbacks: Map<string, Array<EventCallback>> = new Map<string, Array<EventCallback>>();
2020-07-27 22:36:07 +02:00
public constructor(private id: number, private sprite: Sprite, private eventHandler: GameScene, private activationRadius: number, private onActivateCallback: (item: ActionableItem) => void) {
this.activationRadiusSquared = activationRadius * activationRadius;
}
2020-07-27 22:36:07 +02:00
public getId(): number {
return this.id;
}
/**
* Returns the square of the distance to the object center IF we are in item action range
* OR null if we are out of range.
*/
public actionableDistance(x: number, y: number): number|null {
2020-07-23 18:47:28 +02:00
const distanceSquared = (x - this.sprite.x)*(x - this.sprite.x) + (y - this.sprite.y)*(y - this.sprite.y);
if (distanceSquared < this.activationRadiusSquared) {
return distanceSquared;
} else {
return null;
}
}
/**
* Show the outline of the sprite.
*/
public selectable(): void {
if (this.isSelectable) {
return;
}
this.isSelectable = true;
if (this.sprite.pipeline) {
// Commented out to try to fix MacOS issue
/*this.sprite.setPipeline(OutlinePipeline.KEY);
this.sprite.pipeline.set2f('uTextureSize', this.sprite.texture.getSourceImage().width, this.sprite.texture.getSourceImage().height);*/
}
}
/**
* Hide the outline of the sprite
*/
public notSelectable(): void {
if (!this.isSelectable) {
return;
}
this.isSelectable = false;
// Commented out to try to fix MacOS issue
//this.sprite.resetPipeline();
}
/**
* Triggered when the "space" key is pressed and the object is in range of being activated.
*/
public activate(): void {
2020-07-27 22:36:07 +02:00
this.onActivateCallback(this);
}
2020-07-27 22:36:07 +02:00
public emit(eventName: string, state: unknown, parameters: unknown = null): void {
this.eventHandler.emitActionableEvent(this.id, eventName, state, parameters);
// Also, execute the action locally.
this.fire(eventName, state, parameters);
}
2020-07-27 22:36:07 +02:00
public on(eventName: string, callback: EventCallback): void {
let callbacksArray: Array<EventCallback>|undefined = this.callbacks.get(eventName);
if (callbacksArray === undefined) {
callbacksArray = new Array<EventCallback>();
this.callbacks.set(eventName, callbacksArray);
}
callbacksArray.push(callback);
}
public fire(eventName: string, state: unknown, parameters: unknown): void {
const callbacksArray = this.callbacks.get(eventName);
if (callbacksArray === undefined) {
return;
}
for (const callback of callbacksArray) {
callback(state, parameters);
}
}
}