for pathfinding we are now taking into consideration all tiles, looking for 'collides' property
This commit is contained in:
parent
7576cea7e0
commit
391fe7eed3
@ -115,15 +115,11 @@ export class GameMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getCollisionsGrid(): number[][] {
|
public getCollisionsGrid(): number[][] {
|
||||||
const collisionsLayer = this.findPhaserLayer("collisions");
|
|
||||||
if (!collisionsLayer) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
const grid: number[][] = [];
|
const grid: number[][] = [];
|
||||||
for (let y = 0; y < collisionsLayer.height; y += 1) {
|
for (let y = 0; y < this.map.height; y += 1) {
|
||||||
const row: number[] = [];
|
const row: number[] = [];
|
||||||
for (let x = 0; x < collisionsLayer.width; x += 1) {
|
for (let x = 0; x < this.map.width; x += 1) {
|
||||||
row.push(collisionsLayer.getTileAt(x, y) ? 1 : 0);
|
row.push(this.isCollidingAt(x, y) ? 1 : 0);
|
||||||
}
|
}
|
||||||
grid.push(row);
|
grid.push(row);
|
||||||
}
|
}
|
||||||
@ -138,10 +134,6 @@ export class GameMap {
|
|||||||
return { x: Math.floor(x / this.map.tilewidth), y: Math.floor(y / this.map.tileheight) };
|
return { x: Math.floor(x / this.map.tilewidth), y: Math.floor(y / this.map.tileheight) };
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
* Sets the position of the current player (in pixels)
|
||||||
* This will trigger events if properties are changing.
|
* This will trigger events if properties are changing.
|
||||||
@ -167,6 +159,151 @@ export class GameMap {
|
|||||||
this.triggerLayersChange();
|
this.triggerLayersChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getCurrentProperties(): Map<string, string | boolean | number> {
|
||||||
|
return this.lastProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getMap(): ITiledMap {
|
||||||
|
return this.map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.propertiesChangeCallbacks.get(propName);
|
||||||
|
if (callbacksArray === undefined) {
|
||||||
|
callbacksArray = new Array<PropertyChangeCallback>();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a callback called when the user moves inside another zone.
|
||||||
|
*/
|
||||||
|
public onEnterZone(callback: zoneChangeCallback) {
|
||||||
|
this.enterZoneCallbacks.push(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a callback called when the user moves outside another zone.
|
||||||
|
*/
|
||||||
|
public onLeaveZone(callback: zoneChangeCallback) {
|
||||||
|
this.leaveZoneCallbacks.push(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public findLayer(layerName: string): ITiledMapLayer | undefined {
|
||||||
|
return this.flatLayers.find((layer) => layer.name === layerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public findPhaserLayer(layerName: string): TilemapLayer | undefined {
|
||||||
|
return this.phaserLayers.find((layer) => layer.layer.name === layerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public findPhaserLayers(groupName: string): TilemapLayer[] {
|
||||||
|
return this.phaserLayers.filter((l) => l.layer.name.includes(groupName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public addTerrain(terrain: Phaser.Tilemaps.Tileset): void {
|
||||||
|
for (const phaserLayer of this.phaserLayers) {
|
||||||
|
phaserLayer.tileset.push(terrain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public putTile(tile: string | number | null, x: number, y: number, layer: string): void {
|
||||||
|
const phaserLayer = this.findPhaserLayer(layer);
|
||||||
|
if (phaserLayer) {
|
||||||
|
if (tile === null) {
|
||||||
|
phaserLayer.putTileAt(-1, x, y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const tileIndex = this.getIndexForTileType(tile);
|
||||||
|
if (tileIndex !== undefined) {
|
||||||
|
this.putTileInFlatLayer(tileIndex, x, y, layer);
|
||||||
|
const phaserTile = phaserLayer.putTileAt(tileIndex, x, y);
|
||||||
|
for (const property of this.getTileProperty(tileIndex)) {
|
||||||
|
if (property.name === GameMapProperties.COLLIDES && property.value) {
|
||||||
|
phaserTile.setCollision(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("The tile '" + tile + "' that you want to place doesn't exist.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("The layer '" + layer + "' does not exist (or is not a tilelaye).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public setLayerProperty(
|
||||||
|
layerName: string,
|
||||||
|
propertyName: string,
|
||||||
|
propertyValue: string | number | undefined | boolean
|
||||||
|
) {
|
||||||
|
const layer = this.findLayer(layerName);
|
||||||
|
if (layer === undefined) {
|
||||||
|
console.warn('Could not find layer "' + layerName + '" when calling setProperty');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (layer.properties === undefined) {
|
||||||
|
layer.properties = [];
|
||||||
|
}
|
||||||
|
const property = layer.properties.find((property) => property.name === propertyName);
|
||||||
|
if (property === undefined) {
|
||||||
|
if (propertyValue === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
layer.properties.push({ name: propertyName, type: typeof propertyValue, value: propertyValue });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (propertyValue === undefined) {
|
||||||
|
const index = layer.properties.indexOf(property);
|
||||||
|
layer.properties.splice(index, 1);
|
||||||
|
}
|
||||||
|
property.value = propertyValue;
|
||||||
|
|
||||||
|
this.triggerAllProperties();
|
||||||
|
this.triggerLayersChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger all the callbacks (used when exiting a map)
|
||||||
|
*/
|
||||||
|
public triggerExitCallbacks(): void {
|
||||||
|
const emptyProps = new Map<string, string | boolean | number>();
|
||||||
|
for (const [oldPropName, oldPropValue] of this.lastProperties.entries()) {
|
||||||
|
// We found a property that disappeared
|
||||||
|
this.trigger(oldPropName, oldPropValue, undefined, emptyProps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getLayersByKey(key: number): Array<ITiledMapLayer> {
|
||||||
|
return this.flatLayers.filter((flatLayer) => flatLayer.type === "tilelayer" && flatLayer.data[key] !== 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private isCollidingAt(x: number, y: number): boolean {
|
||||||
|
for (const layer of this.phaserLayers) {
|
||||||
|
if (layer.getTileAt(x, y)?.properties[GameMapProperties.COLLIDES]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private triggerAllProperties(): void {
|
private triggerAllProperties(): void {
|
||||||
const newProps = this.getProperties(this.key ?? 0);
|
const newProps = this.getProperties(this.key ?? 0);
|
||||||
const oldProps = this.lastProperties;
|
const oldProps = this.lastProperties;
|
||||||
@ -265,10 +402,6 @@ export class GameMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCurrentProperties(): Map<string, string | boolean | number> {
|
|
||||||
return this.lastProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getProperties(key: number): Map<string, string | boolean | number> {
|
private getProperties(key: number): Map<string, string | boolean | number> {
|
||||||
const properties = new Map<string, string | boolean | number>();
|
const properties = new Map<string, string | boolean | number>();
|
||||||
|
|
||||||
@ -310,10 +443,6 @@ export class GameMap {
|
|||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getMap(): ITiledMap {
|
|
||||||
return this.map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getTileProperty(index: number): Array<ITiledMapProperty> {
|
private getTileProperty(index: number): Array<ITiledMapProperty> {
|
||||||
if (this.tileSetPropertyMap[index]) {
|
if (this.tileSetPropertyMap[index]) {
|
||||||
return this.tileSetPropertyMap[index];
|
return this.tileSetPropertyMap[index];
|
||||||
@ -335,64 +464,6 @@ 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.propertiesChangeCallbacks.get(propName);
|
|
||||||
if (callbacksArray === undefined) {
|
|
||||||
callbacksArray = new Array<PropertyChangeCallback>();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a callback called when the user moves inside another zone.
|
|
||||||
*/
|
|
||||||
public onEnterZone(callback: zoneChangeCallback) {
|
|
||||||
this.enterZoneCallbacks.push(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a callback called when the user moves outside another zone.
|
|
||||||
*/
|
|
||||||
public onLeaveZone(callback: zoneChangeCallback) {
|
|
||||||
this.leaveZoneCallbacks.push(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public findLayer(layerName: string): ITiledMapLayer | undefined {
|
|
||||||
return this.flatLayers.find((layer) => layer.name === layerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public findPhaserLayer(layerName: string): TilemapLayer | undefined {
|
|
||||||
return this.phaserLayers.find((layer) => layer.layer.name === layerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public findPhaserLayers(groupName: string): TilemapLayer[] {
|
|
||||||
return this.phaserLayers.filter((l) => l.layer.name.includes(groupName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public addTerrain(terrain: Phaser.Tilemaps.Tileset): void {
|
|
||||||
for (const phaserLayer of this.phaserLayers) {
|
|
||||||
phaserLayer.tileset.push(terrain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private putTileInFlatLayer(index: number, x: number, y: number, layer: string): void {
|
private putTileInFlatLayer(index: number, x: number, y: number, layer: string): void {
|
||||||
const fLayer = this.findLayer(layer);
|
const fLayer = this.findLayer(layer);
|
||||||
if (fLayer == undefined) {
|
if (fLayer == undefined) {
|
||||||
@ -414,30 +485,6 @@ export class GameMap {
|
|||||||
fLayer.data[x + y * fLayer.width] = index;
|
fLayer.data[x + y * fLayer.width] = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public putTile(tile: string | number | null, x: number, y: number, layer: string): void {
|
|
||||||
const phaserLayer = this.findPhaserLayer(layer);
|
|
||||||
if (phaserLayer) {
|
|
||||||
if (tile === null) {
|
|
||||||
phaserLayer.putTileAt(-1, x, y);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tileIndex = this.getIndexForTileType(tile);
|
|
||||||
if (tileIndex !== undefined) {
|
|
||||||
this.putTileInFlatLayer(tileIndex, x, y, layer);
|
|
||||||
const phaserTile = phaserLayer.putTileAt(tileIndex, x, y);
|
|
||||||
for (const property of this.getTileProperty(tileIndex)) {
|
|
||||||
if (property.name === GameMapProperties.COLLIDES && property.value) {
|
|
||||||
phaserTile.setCollision(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error("The tile '" + tile + "' that you want to place doesn't exist.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error("The layer '" + layer + "' does not exist (or is not a tilelaye).");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getIndexForTileType(tile: string | number): number | undefined {
|
private getIndexForTileType(tile: string | number): number | undefined {
|
||||||
if (typeof tile == "number") {
|
if (typeof tile == "number") {
|
||||||
return tile;
|
return tile;
|
||||||
@ -445,48 +492,6 @@ export class GameMap {
|
|||||||
return this.tileNameMap.get(tile);
|
return this.tileNameMap.get(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setLayerProperty(
|
|
||||||
layerName: string,
|
|
||||||
propertyName: string,
|
|
||||||
propertyValue: string | number | undefined | boolean
|
|
||||||
) {
|
|
||||||
const layer = this.findLayer(layerName);
|
|
||||||
if (layer === undefined) {
|
|
||||||
console.warn('Could not find layer "' + layerName + '" when calling setProperty');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (layer.properties === undefined) {
|
|
||||||
layer.properties = [];
|
|
||||||
}
|
|
||||||
const property = layer.properties.find((property) => property.name === propertyName);
|
|
||||||
if (property === undefined) {
|
|
||||||
if (propertyValue === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
layer.properties.push({ name: propertyName, type: typeof propertyValue, value: propertyValue });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (propertyValue === undefined) {
|
|
||||||
const index = layer.properties.indexOf(property);
|
|
||||||
layer.properties.splice(index, 1);
|
|
||||||
}
|
|
||||||
property.value = propertyValue;
|
|
||||||
|
|
||||||
this.triggerAllProperties();
|
|
||||||
this.triggerLayersChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trigger all the callbacks (used when exiting a map)
|
|
||||||
*/
|
|
||||||
public triggerExitCallbacks(): void {
|
|
||||||
const emptyProps = new Map<string, string | boolean | number>();
|
|
||||||
for (const [oldPropName, oldPropValue] of this.lastProperties.entries()) {
|
|
||||||
// We found a property that disappeared
|
|
||||||
this.trigger(oldPropName, oldPropValue, undefined, emptyProps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getObjectsFromLayers(layers: ITiledMapLayer[]): ITiledMapObject[] {
|
private getObjectsFromLayers(layers: ITiledMapLayer[]): ITiledMapObject[] {
|
||||||
const objects: ITiledMapObject[] = [];
|
const objects: ITiledMapObject[] = [];
|
||||||
|
|
||||||
|
@ -42,12 +42,16 @@ export class Player extends Character {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.pathToFollow && activeUserInputEvents.anyExcept(UserInputEvent.SpeedUp)) {
|
||||||
|
this.pathToFollow = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
let x = 0;
|
let x = 0;
|
||||||
let y = 0;
|
let y = 0;
|
||||||
if ((state === "active" || state === "ending") && role === "follower") {
|
if ((state === "active" || state === "ending") && role === "follower") {
|
||||||
[x, y] = this.computeFollowMovement();
|
[x, y] = this.computeFollowMovement();
|
||||||
}
|
}
|
||||||
if (this.pathToFollow && this.pathToFollow.length !== 0) {
|
if (this.pathToFollow) {
|
||||||
[x, y] = this.computeFollowPathMovement();
|
[x, y] = this.computeFollowPathMovement();
|
||||||
}
|
}
|
||||||
this.inputStep(activeUserInputEvents, x, y);
|
this.inputStep(activeUserInputEvents, x, y);
|
||||||
@ -144,7 +148,10 @@ export class Player extends Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private computeFollowPathMovement(): number[] {
|
private computeFollowPathMovement(): number[] {
|
||||||
if (!this.pathToFollow || this.pathToFollow.length === 0) {
|
if (this.pathToFollow?.length === 0) {
|
||||||
|
this.pathToFollow = undefined;
|
||||||
|
}
|
||||||
|
if (!this.pathToFollow) {
|
||||||
return [0, 0];
|
return [0, 0];
|
||||||
}
|
}
|
||||||
const nextStep = this.pathToFollow[0];
|
const nextStep = this.pathToFollow[0];
|
||||||
@ -153,7 +160,7 @@ export class Player extends Character {
|
|||||||
const xDistance = nextStep.x - this.x;
|
const xDistance = nextStep.x - this.x;
|
||||||
const yDistance = nextStep.y - this.y;
|
const yDistance = nextStep.y - this.y;
|
||||||
const distance = Math.pow(xDistance, 2) + Math.pow(yDistance, 2);
|
const distance = Math.pow(xDistance, 2) + Math.pow(yDistance, 2);
|
||||||
if (distance < 10) {
|
if (distance < 200) {
|
||||||
this.pathToFollow.shift();
|
this.pathToFollow.shift();
|
||||||
}
|
}
|
||||||
return this.getMovementDirection(xDistance, yDistance, distance);
|
return this.getMovementDirection(xDistance, yDistance, distance);
|
||||||
|
@ -37,6 +37,15 @@ export class ActiveEventList {
|
|||||||
any(): boolean {
|
any(): boolean {
|
||||||
return Array.from(this.eventMap.values()).reduce((accu, curr) => accu || curr, false);
|
return Array.from(this.eventMap.values()).reduce((accu, curr) => accu || curr, false);
|
||||||
}
|
}
|
||||||
|
anyExcept(...exceptions: UserInputEvent[]): boolean {
|
||||||
|
const userInputEvents = Array.from(this.eventMap);
|
||||||
|
for (const event of userInputEvents) {
|
||||||
|
if (event[1] && !exceptions.includes(event[0])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//this class is responsible for catching user inputs and listing all active user actions at every game tick events.
|
//this class is responsible for catching user inputs and listing all active user actions at every game tick events.
|
||||||
|
Loading…
Reference in New Issue
Block a user