diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index a32944e2..6eeacd0c 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -130,6 +130,14 @@ export class GameMap { return grid; } + public getTileDimensions(): { width: number; height: number } { + return { width: this.map.tilewidth, height: this.map.tileheight }; + } + + public getTileIndexAt(x: number, y: number): { x: number; y: number } { + return { x: Math.floor(x / this.map.tilewidth), y: Math.floor(y / this.map.tileheight) }; + } + private getLayersByKey(key: number): Array { return this.flatLayers.filter((flatLayer) => flatLayer.type === "tilelayer" && flatLayer.data[key] !== 0); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 6bb4b724..26e4004a 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -570,7 +570,6 @@ export class GameScene extends DirtyScene { ); this.pathfindingManager = new PathfindingManager(this, this.gameMap.getCollisionsGrid()); - this.pathfindingManager.findPath({ x: 1, y: 3 }, { x: 29, y: 3 }); biggestAvailableAreaStore.recompute(); this.cameraManager.startFollowPlayer(this.CurrentPlayer); @@ -2174,4 +2173,16 @@ ${escapedMessage} this.scene.stop(this.scene.key); this.scene.remove(this.scene.key); } + + public getGameMap(): GameMap { + return this.gameMap; + } + + public getCameraManager(): CameraManager { + return this.cameraManager; + } + + public getPathfindingManager(): PathfindingManager { + return this.pathfindingManager; + } } diff --git a/front/src/Phaser/Player/Player.ts b/front/src/Phaser/Player/Player.ts index e340eeed..11e3b436 100644 --- a/front/src/Phaser/Player/Player.ts +++ b/front/src/Phaser/Player/Player.ts @@ -11,6 +11,8 @@ export const hasMovedEventName = "hasMoved"; export const requestEmoteEventName = "requestEmote"; export class Player extends Character { + private pathToFollow?: { x: number; y: number }[]; + constructor( Scene: GameScene, x: number, @@ -28,6 +30,44 @@ export class Player extends Character { this.getBody().setImmovable(false); } + public moveUser(delta: number, activeUserInputEvents: ActiveEventList): void { + const state = get(followStateStore); + const role = get(followRoleStore); + + if (activeUserInputEvents.get(UserInputEvent.Follow)) { + if (state === "off" && this.scene.groups.size > 0) { + this.sendFollowRequest(); + } else if (state === "active") { + followStateStore.set("ending"); + } + } + + let x = 0; + let y = 0; + if ((state === "active" || state === "ending") && role === "follower") { + [x, y] = this.computeFollowMovement(); + } + if (this.pathToFollow && this.pathToFollow.length !== 0) { + [x, y] = this.computeFollowPathMovement(); + } + this.inputStep(activeUserInputEvents, x, y); + } + + public sendFollowRequest() { + this.scene.connection?.emitFollowRequest(); + followRoleStore.set("leader"); + followStateStore.set("active"); + } + + public startFollowing() { + followStateStore.set("active"); + this.scene.connection?.emitFollowConfirmation(); + } + + public setPathToFollow(path: { x: number; y: number }[]): void { + this.pathToFollow = path; + } + private inputStep(activeEvents: ActiveEventList, x: number, y: number) { // Process input events if (activeEvents.get(UserInputEvent.MoveUp)) { @@ -98,34 +138,21 @@ export class Player extends Character { return [xMovement, yMovement]; } - public moveUser(delta: number, activeUserInputEvents: ActiveEventList): void { - const state = get(followStateStore); - const role = get(followRoleStore); - - if (activeUserInputEvents.get(UserInputEvent.Follow)) { - if (state === "off" && this.scene.groups.size > 0) { - this.sendFollowRequest(); - } else if (state === "active") { - followStateStore.set("ending"); - } + private computeFollowPathMovement(): number[] { + if (!this.pathToFollow || this.pathToFollow.length === 0) { + return [0, 0]; } + const nextStep = this.pathToFollow[0]; - let x = 0; - let y = 0; - if ((state === "active" || state === "ending") && role === "follower") { - [x, y] = this.computeFollowMovement(); + // Compute movement direction + const xDistance = nextStep.x - this.x; + const yDistance = nextStep.y - this.y; + const distance = Math.pow(xDistance, 2) + Math.pow(yDistance, 2); + if (distance < 200) { + this.pathToFollow.shift(); } - this.inputStep(activeUserInputEvents, x, y); - } - - public sendFollowRequest() { - this.scene.connection?.emitFollowRequest(); - followRoleStore.set("leader"); - followStateStore.set("active"); - } - - public startFollowing() { - followStateStore.set("active"); - this.scene.connection?.emitFollowConfirmation(); + const xMovement = xDistance / Math.sqrt(distance); + const yMovement = yDistance / Math.sqrt(distance); + return [xMovement, yMovement]; } } diff --git a/front/src/Phaser/UserInput/GameSceneUserInputHandler.ts b/front/src/Phaser/UserInput/GameSceneUserInputHandler.ts index b1b07ddc..f351ccf0 100644 --- a/front/src/Phaser/UserInput/GameSceneUserInputHandler.ts +++ b/front/src/Phaser/UserInput/GameSceneUserInputHandler.ts @@ -19,8 +19,27 @@ export class GameSceneUserInputHandler implements UserInputHandlerInterface { } public handlePointerUpEvent(pointer: Phaser.Input.Pointer, gameObjects: Phaser.GameObjects.GameObject[]): void { - const camera = this.gameScene.cameras.main; - console.log(`${pointer.x + camera.scrollX}, ${pointer.y + camera.scrollY}`); + const camera = this.gameScene.getCameraManager().getCamera(); + const index = this.gameScene + .getGameMap() + .getTileIndexAt(pointer.x + camera.scrollX, pointer.y + camera.scrollY); + const startTile = this.gameScene + .getGameMap() + .getTileIndexAt(this.gameScene.CurrentPlayer.x, this.gameScene.CurrentPlayer.y); + this.gameScene + .getPathfindingManager() + .findPath(startTile, index) + .then((path) => { + const tileDimensions = this.gameScene.getGameMap().getTileDimensions(); + const pixelPath = path.map((step) => { + return { x: step.x * tileDimensions.width, y: step.y * tileDimensions.height }; + }); + this.gameScene.CurrentPlayer.setPathToFollow([...pixelPath]); + console.log(pixelPath); + }) + .catch((reason) => { + console.log(reason); + }); } public handleSpaceKeyUpEvent(event: Event): Event { diff --git a/front/src/Utils/PathfindingManager.ts b/front/src/Utils/PathfindingManager.ts index 157c624e..17a6dee2 100644 --- a/front/src/Utils/PathfindingManager.ts +++ b/front/src/Utils/PathfindingManager.ts @@ -9,28 +9,30 @@ export class PathfindingManager { this.scene = scene; this.easyStar = new EasyStar.js(); + this.easyStar.disableDiagonals(); this.setGrid(collisionsGrid); } - public findPath(start: { x: number; y: number }, end: { x: number; y: number }): void { - console.log("TRY TO FIND PATH"); - this.easyStar.findPath(start.x, start.y, end.x, end.y, (path) => { - if (path === null) { - console.warn("Path was not found."); - } else { - console.log("path was found"); - console.log(path); - } + public async findPath( + start: { x: number; y: number }, + end: { x: number; y: number } + ): Promise<{ x: number; y: number }[]> { + return new Promise((resolve, reject) => { + this.easyStar.findPath(start.x, start.y, end.x, end.y, (path) => { + if (path === null) { + reject("Path was not found"); + } else { + resolve(path); + } + }); + this.easyStar.calculate(); }); - this.easyStar.calculate(); } private setGrid(grid: number[][]): void { - console.log(grid); this.easyStar.setGrid(grid); this.easyStar.setAcceptableTiles([0]); // zeroes are walkable - this.logGridToTheConsole(grid); } private logGridToTheConsole(grid: number[][]): void {