Implement on enter/leave layer events
This commit is contained in:
parent
0b08d9251e
commit
934e24f837
14 changed files with 222 additions and 18 deletions
|
@ -2,6 +2,7 @@ import type { ITiledMap, ITiledMapLayer, ITiledMapProperty } from "../Map/ITiled
|
|||
import { flattenGroupLayersMap } from "../Map/LayersFlattener";
|
||||
import TilemapLayer = Phaser.Tilemaps.TilemapLayer;
|
||||
import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes";
|
||||
import { iframeListener } from "../../Api/IframeListener";
|
||||
|
||||
export type PropertyChangeCallback = (
|
||||
newValue: string | number | boolean | undefined,
|
||||
|
@ -9,14 +10,25 @@ export type PropertyChangeCallback = (
|
|||
allProps: Map<string, string | boolean | number>
|
||||
) => void;
|
||||
|
||||
export type layerChangeCallback = (
|
||||
layersChangedByAction: Array<ITiledMapLayer>,
|
||||
allLayersOnNewPosition: Array<ITiledMapLayer>,
|
||||
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* A wrapper around a ITiledMap interface to provide additional capabilities.
|
||||
* It is used to handle layer properties.
|
||||
*/
|
||||
export class GameMap {
|
||||
// oldKey is the index of the previous tile.
|
||||
private oldKey: number | undefined;
|
||||
// key is the index of the current tile.
|
||||
private key: number | undefined;
|
||||
private lastProperties = new Map<string, string | boolean | number>();
|
||||
private callbacks = new Map<string, Array<PropertyChangeCallback>>();
|
||||
private propertiesChangeCallbacks = new Map<string, Array<PropertyChangeCallback>>();
|
||||
private enterLayerCallbacks = Array<layerChangeCallback>();
|
||||
private leaveLayerCallbacks = Array<layerChangeCallback>();
|
||||
private tileNameMap = new Map<string, number>();
|
||||
|
||||
private tileSetPropertyMap: { [tile_index: number]: Array<ITiledMapProperty> } = {};
|
||||
|
@ -68,22 +80,32 @@ export class GameMap {
|
|||
return [];
|
||||
}
|
||||
|
||||
private getLayersByKey(key: number): Array<ITiledMapLayer> {
|
||||
return this.flatLayers.filter(flatLayer => flatLayer.type === 'tilelayer' && flatLayer.data[key] !== 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the current player (in pixels)
|
||||
* This will trigger events if properties are changing.
|
||||
*/
|
||||
public setPosition(x: number, y: number) {
|
||||
this.oldKey = this.key;
|
||||
|
||||
const xMap = Math.floor(x / this.map.tilewidth);
|
||||
const yMap = Math.floor(y / this.map.tileheight);
|
||||
const key = xMap + yMap * this.map.width;
|
||||
|
||||
if (key === this.key) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.key = key;
|
||||
this.triggerAll();
|
||||
|
||||
this.triggerAllProperties();
|
||||
this.triggerLayersChange();
|
||||
}
|
||||
|
||||
private triggerAll(): void {
|
||||
private triggerAllProperties(): void {
|
||||
const newProps = this.getProperties(this.key ?? 0);
|
||||
const oldProps = this.lastProperties;
|
||||
this.lastProperties = newProps;
|
||||
|
@ -105,6 +127,36 @@ export class GameMap {
|
|||
}
|
||||
}
|
||||
|
||||
private triggerLayersChange() {
|
||||
const layersByOldKey = this.oldKey ? this.getLayersByKey(this.oldKey) : [];
|
||||
const layersByNewKey = this.key ? this.getLayersByKey(this.key) : [];
|
||||
|
||||
const enterLayers = new Set(layersByNewKey);
|
||||
const leaveLayers = new Set(layersByOldKey);
|
||||
|
||||
enterLayers.forEach(layer => {
|
||||
if (leaveLayers.has(layer)) {
|
||||
leaveLayers.delete(layer);
|
||||
enterLayers.delete(layer);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (enterLayers.size > 0) {
|
||||
const layerArray = Array.from(enterLayers);
|
||||
for (const callback of this.enterLayerCallbacks) {
|
||||
callback(layerArray, layersByNewKey);
|
||||
}
|
||||
}
|
||||
|
||||
if (leaveLayers.size > 0) {
|
||||
const layerArray = Array.from(leaveLayers);
|
||||
for (const callback of this.leaveLayerCallbacks) {
|
||||
callback(layerArray, layersByNewKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getCurrentProperties(): Map<string, string | boolean | number> {
|
||||
return this.lastProperties;
|
||||
}
|
||||
|
@ -167,7 +219,7 @@ export class GameMap {
|
|||
newValue: string | number | boolean | undefined,
|
||||
allProps: Map<string, string | boolean | number>
|
||||
) {
|
||||
const callbacksArray = this.callbacks.get(propName);
|
||||
const callbacksArray = this.propertiesChangeCallbacks.get(propName);
|
||||
if (callbacksArray !== undefined) {
|
||||
for (const callback of callbacksArray) {
|
||||
callback(newValue, oldValue, allProps);
|
||||
|
@ -179,14 +231,28 @@ export class GameMap {
|
|||
* Registers a callback called when the user moves to a tile where the property propName is different from the last tile the user was on.
|
||||
*/
|
||||
public onPropertyChange(propName: string, callback: PropertyChangeCallback) {
|
||||
let callbacksArray = this.callbacks.get(propName);
|
||||
let callbacksArray = this.propertiesChangeCallbacks.get(propName);
|
||||
if (callbacksArray === undefined) {
|
||||
callbacksArray = new Array<PropertyChangeCallback>();
|
||||
this.callbacks.set(propName, callbacksArray);
|
||||
this.propertiesChangeCallbacks.set(propName, callbacksArray);
|
||||
}
|
||||
callbacksArray.push(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback called when the user moves inside another layer.
|
||||
*/
|
||||
public onEnterLayer(callback: layerChangeCallback) {
|
||||
this.enterLayerCallbacks.push(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback called when the user moves outside another layer.
|
||||
*/
|
||||
public onLeaveLayer(callback: layerChangeCallback) {
|
||||
this.leaveLayerCallbacks.push(callback);
|
||||
}
|
||||
|
||||
public findLayer(layerName: string): ITiledMapLayer | undefined {
|
||||
return this.flatLayers.find((layer) => layer.name === layerName);
|
||||
}
|
||||
|
@ -284,7 +350,8 @@ export class GameMap {
|
|||
}
|
||||
property.value = propertyValue;
|
||||
|
||||
this.triggerAll();
|
||||
this.triggerAllProperties();
|
||||
this.triggerLayersChange();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue