Adding a GameMap class that helps tracking when the properties of the tiles the user is changes (when the user moves)
This commit is contained in:
parent
4d90d4b50b
commit
168697eb46
97
front/src/Phaser/Game/GameMap.ts
Normal file
97
front/src/Phaser/Game/GameMap.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import {ITiledMap} from "../Map/ITiledMap";
|
||||||
|
|
||||||
|
export type PropertyChangeCallback = (oldValue: string | number | boolean | undefined, newValue: string | number | boolean | undefined) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper around a ITiledMap interface to provide additional capabilities.
|
||||||
|
* It is used to handle layer properties.
|
||||||
|
*/
|
||||||
|
export class GameMap {
|
||||||
|
private key: number|undefined;
|
||||||
|
private lastProperties = new Map<string, string|boolean|number>();
|
||||||
|
private callbacks = new Map<string, Array<PropertyChangeCallback>>();
|
||||||
|
|
||||||
|
public constructor(private map: ITiledMap) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of the current player (in pixels)
|
||||||
|
* This will trigger events if properties are changing.
|
||||||
|
*/
|
||||||
|
public setPosition(x: number, y: number) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
const newProps = this.getProperties(key);
|
||||||
|
const oldProps = this.lastProperties;
|
||||||
|
|
||||||
|
// Let's compare the 2 maps:
|
||||||
|
// First new properties vs oldProperties
|
||||||
|
for (const [newPropName, newPropValue] of newProps.entries()) {
|
||||||
|
const oldPropValue = oldProps.get(newPropName);
|
||||||
|
if (oldPropValue !== newPropValue) {
|
||||||
|
this.trigger(newPropName, oldPropValue, newPropValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [oldPropName, oldPropValue] of oldProps.entries()) {
|
||||||
|
if (!newProps.has(oldPropName)) {
|
||||||
|
// We found a property that disappeared
|
||||||
|
this.trigger(oldPropName, oldPropValue, undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastProperties = newProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getProperties(key: number): Map<string, string|boolean|number> {
|
||||||
|
const properties = new Map<string, string|boolean|number>();
|
||||||
|
|
||||||
|
for (const layer of this.map.layers) {
|
||||||
|
if (layer.type !== 'tilelayer') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const tiles = layer.data as number[];
|
||||||
|
if (tiles[key] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// There is a tile in this layer, let's embed the properties
|
||||||
|
if (layer.properties !== undefined) {
|
||||||
|
for (const layerProperty of layer.properties) {
|
||||||
|
if (layerProperty.value === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
properties.set(layerProperty.name, layerProperty.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private trigger(propName: string, oldValue: string | number | boolean | undefined, newValue: string | number | boolean | undefined) {
|
||||||
|
let callbacksArray = this.callbacks.get(propName);
|
||||||
|
if (callbacksArray !== undefined) {
|
||||||
|
for (const callback of callbacksArray) {
|
||||||
|
callback(oldValue, newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
if (callbacksArray === undefined) {
|
||||||
|
callbacksArray = new Array<PropertyChangeCallback>();
|
||||||
|
this.callbacks.set(propName, callbacksArray);
|
||||||
|
}
|
||||||
|
callbacksArray.push(callback);
|
||||||
|
}
|
||||||
|
}
|
@ -28,6 +28,7 @@ import Sprite = Phaser.GameObjects.Sprite;
|
|||||||
import CanvasTexture = Phaser.Textures.CanvasTexture;
|
import CanvasTexture = Phaser.Textures.CanvasTexture;
|
||||||
import GameObject = Phaser.GameObjects.GameObject;
|
import GameObject = Phaser.GameObjects.GameObject;
|
||||||
import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
|
import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
|
||||||
|
import {GameMap} from "./GameMap";
|
||||||
|
|
||||||
|
|
||||||
export enum Textures {
|
export enum Textures {
|
||||||
@ -109,6 +110,7 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
private presentationModeSprite!: Sprite;
|
private presentationModeSprite!: Sprite;
|
||||||
private chatModeSprite!: Sprite;
|
private chatModeSprite!: Sprite;
|
||||||
private repositionCallback!: (this: Window, ev: UIEvent) => void;
|
private repositionCallback!: (this: Window, ev: UIEvent) => void;
|
||||||
|
private gameMap!: GameMap;
|
||||||
|
|
||||||
static createFromUrl(mapUrlFile: string, instance: string, key: string|null = null): GameScene {
|
static createFromUrl(mapUrlFile: string, instance: string, key: string|null = null): GameScene {
|
||||||
const mapKey = GameScene.getMapKeyByUrl(mapUrlFile);
|
const mapKey = GameScene.getMapKeyByUrl(mapUrlFile);
|
||||||
@ -278,6 +280,7 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
create(): void {
|
create(): void {
|
||||||
//initalise map
|
//initalise map
|
||||||
this.Map = this.add.tilemap(this.MapKey);
|
this.Map = this.add.tilemap(this.MapKey);
|
||||||
|
this.gameMap = new GameMap(this.mapFile);
|
||||||
const mapDirUrl = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/'));
|
const mapDirUrl = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/'));
|
||||||
this.mapFile.tilesets.forEach((tileset: ITiledTileSet) => {
|
this.mapFile.tilesets.forEach((tileset: ITiledTileSet) => {
|
||||||
this.Terrains.push(this.Map.addTilesetImage(tileset.name, `${mapDirUrl}/${tileset.image}`, tileset.tilewidth, tileset.tileheight, tileset.margin, tileset.spacing/*, tileset.firstgid*/));
|
this.Terrains.push(this.Map.addTilesetImage(tileset.name, `${mapDirUrl}/${tileset.image}`, tileset.tilewidth, tileset.tileheight, tileset.margin, tileset.spacing/*, tileset.firstgid*/));
|
||||||
@ -411,6 +414,10 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
|
|
||||||
// From now, this game scene will be notified of reposition events
|
// From now, this game scene will be notified of reposition events
|
||||||
layoutManager.setListener(this);
|
layoutManager.setListener(this);
|
||||||
|
|
||||||
|
this.gameMap.onPropertyChange('startLayer', (oldValue, newValue) => {
|
||||||
|
console.log('startLayer', oldValue, newValue);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private switchLayoutMode(): void {
|
private switchLayoutMode(): void {
|
||||||
@ -589,6 +596,9 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
|
|
||||||
//listen event to share position of user
|
//listen event to share position of user
|
||||||
this.CurrentPlayer.on(hasMovedEventName, this.pushPlayerPosition.bind(this))
|
this.CurrentPlayer.on(hasMovedEventName, this.pushPlayerPosition.bind(this))
|
||||||
|
this.CurrentPlayer.on(hasMovedEventName, (event: HasMovedEvent) => {
|
||||||
|
this.gameMap.setPosition(event.x, event.y);
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user