Pathfinding manager will now return path steps in pixel units by default
This commit is contained in:
parent
f96eac4737
commit
f78392ceab
@ -34,7 +34,7 @@ import type { ChangeZoneEvent } from "./ChangeZoneEvent";
|
|||||||
import type { CameraSetEvent } from "./CameraSetEvent";
|
import type { CameraSetEvent } from "./CameraSetEvent";
|
||||||
import type { CameraFollowPlayerEvent } from "./CameraFollowPlayerEvent";
|
import type { CameraFollowPlayerEvent } from "./CameraFollowPlayerEvent";
|
||||||
import { isColorEvent } from "./ColorEvent";
|
import { isColorEvent } from "./ColorEvent";
|
||||||
import { isWalkPlayerToEventConfig } from "./WalkPlayerToEvent";
|
import { isMovePlayerToEventConfig } from "./MovePlayerToEvent";
|
||||||
|
|
||||||
export interface TypedMessageEvent<T> extends MessageEvent {
|
export interface TypedMessageEvent<T> extends MessageEvent {
|
||||||
data: T;
|
data: T;
|
||||||
@ -174,8 +174,8 @@ export const iframeQueryMapTypeGuards = {
|
|||||||
query: tg.isUndefined,
|
query: tg.isUndefined,
|
||||||
answer: isPlayerPosition,
|
answer: isPlayerPosition,
|
||||||
},
|
},
|
||||||
walkPlayerTo: {
|
movePlayerTo: {
|
||||||
query: isWalkPlayerToEventConfig,
|
query: isMovePlayerToEventConfig,
|
||||||
answer: isPlayerPosition,
|
answer: isPlayerPosition,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as tg from "generic-type-guard";
|
import * as tg from "generic-type-guard";
|
||||||
|
|
||||||
export const isWalkPlayerToEventConfig = new tg.IsInterface()
|
export const isMovePlayerToEventConfig = new tg.IsInterface()
|
||||||
.withProperties({
|
.withProperties({
|
||||||
x: tg.isNumber,
|
x: tg.isNumber,
|
||||||
y: tg.isNumber,
|
y: tg.isNumber,
|
||||||
@ -8,4 +8,4 @@ export const isWalkPlayerToEventConfig = new tg.IsInterface()
|
|||||||
})
|
})
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
export type WalkPlayerToEvent = tg.GuardedType<typeof isWalkPlayerToEventConfig>;
|
export type MovePlayerToEvent = tg.GuardedType<typeof isMovePlayerToEventConfig>;
|
@ -84,9 +84,9 @@ export class WorkadventurePlayerCommands extends IframeApiContribution<Workadven
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async walkTo(x: number, y: number, speed: number): Promise<{ x: number; y: number }> {
|
public async moveTo(x: number, y: number, speed: number): Promise<{ x: number; y: number }> {
|
||||||
return await queryWorkadventure({
|
return await queryWorkadventure({
|
||||||
type: "walkPlayerTo",
|
type: "movePlayerTo",
|
||||||
data: { x, y, speed },
|
data: { x, y, speed },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -569,7 +569,11 @@ export class GameScene extends DirtyScene {
|
|||||||
waScaleManager
|
waScaleManager
|
||||||
);
|
);
|
||||||
|
|
||||||
this.pathfindingManager = new PathfindingManager(this, this.gameMap.getCollisionsGrid());
|
this.pathfindingManager = new PathfindingManager(
|
||||||
|
this,
|
||||||
|
this.gameMap.getCollisionsGrid(),
|
||||||
|
this.gameMap.getTileDimensions()
|
||||||
|
);
|
||||||
biggestAvailableAreaStore.recompute();
|
biggestAvailableAreaStore.recompute();
|
||||||
this.cameraManager.startFollowPlayer(this.CurrentPlayer);
|
this.cameraManager.startFollowPlayer(this.CurrentPlayer);
|
||||||
|
|
||||||
@ -1457,9 +1461,20 @@ ${escapedMessage}
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
iframeListener.registerAnswerer("walkPlayerTo", () => {
|
iframeListener.registerAnswerer("movePlayerTo", (message) => {
|
||||||
// TODO: walk player to position, wait for promise to resolve
|
// TODO: walk player to position, wait for promise to resolve
|
||||||
console.log("WALK PLAYER TO ACTION CALLED");
|
const index = this.getGameMap().getTileIndexAt(message.x, message.y);
|
||||||
|
const startTile = this.getGameMap().getTileIndexAt(this.CurrentPlayer.x, this.CurrentPlayer.y);
|
||||||
|
this.getPathfindingManager()
|
||||||
|
.findPath(startTile, index, true, true)
|
||||||
|
.then((path) => {
|
||||||
|
// Remove first step as it is for the tile we are currently standing on
|
||||||
|
path.shift();
|
||||||
|
this.CurrentPlayer.setPathToFollow(path);
|
||||||
|
})
|
||||||
|
.catch((reason) => {
|
||||||
|
console.warn(reason);
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
x: this.CurrentPlayer.x,
|
x: this.CurrentPlayer.x,
|
||||||
y: this.CurrentPlayer.y,
|
y: this.CurrentPlayer.y,
|
||||||
|
@ -31,18 +31,11 @@ export class GameSceneUserInputHandler implements UserInputHandlerInterface {
|
|||||||
.getTileIndexAt(this.gameScene.CurrentPlayer.x, this.gameScene.CurrentPlayer.y);
|
.getTileIndexAt(this.gameScene.CurrentPlayer.x, this.gameScene.CurrentPlayer.y);
|
||||||
this.gameScene
|
this.gameScene
|
||||||
.getPathfindingManager()
|
.getPathfindingManager()
|
||||||
.findPath(startTile, index, true)
|
.findPath(startTile, index, true, true)
|
||||||
.then((path) => {
|
.then((path) => {
|
||||||
const tileDimensions = this.gameScene.getGameMap().getTileDimensions();
|
|
||||||
const pixelPath = path.map((step) => {
|
|
||||||
return {
|
|
||||||
x: step.x * tileDimensions.width + tileDimensions.width * 0.5,
|
|
||||||
y: step.y * tileDimensions.height + tileDimensions.height * 0.5,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
// Remove first step as it is for the tile we are currently standing on
|
// Remove first step as it is for the tile we are currently standing on
|
||||||
pixelPath.shift();
|
path.shift();
|
||||||
this.gameScene.CurrentPlayer.setPathToFollow(pixelPath);
|
this.gameScene.CurrentPlayer.setPathToFollow(path);
|
||||||
})
|
})
|
||||||
.catch((reason) => {
|
.catch((reason) => {
|
||||||
console.warn(reason);
|
console.warn(reason);
|
||||||
|
@ -6,20 +6,23 @@ export class PathfindingManager {
|
|||||||
|
|
||||||
private easyStar;
|
private easyStar;
|
||||||
private grid: number[][];
|
private grid: number[][];
|
||||||
|
private tileDimensions: { width: number; height: number };
|
||||||
|
|
||||||
constructor(scene: Phaser.Scene, collisionsGrid: number[][]) {
|
constructor(scene: Phaser.Scene, collisionsGrid: number[][], tileDimensions: { width: number; height: number }) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
|
|
||||||
this.easyStar = new EasyStar.js();
|
this.easyStar = new EasyStar.js();
|
||||||
this.easyStar.enableDiagonals();
|
this.easyStar.enableDiagonals();
|
||||||
|
|
||||||
this.grid = collisionsGrid;
|
this.grid = collisionsGrid;
|
||||||
|
this.tileDimensions = tileDimensions;
|
||||||
this.setEasyStarGrid(collisionsGrid);
|
this.setEasyStarGrid(collisionsGrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findPath(
|
public async findPath(
|
||||||
start: { x: number; y: number },
|
start: { x: number; y: number },
|
||||||
end: { x: number; y: number },
|
end: { x: number; y: number },
|
||||||
|
measuredInPixels: boolean = true,
|
||||||
tryFindingNearestAvailable: boolean = false
|
tryFindingNearestAvailable: boolean = false
|
||||||
): Promise<{ x: number; y: number }[]> {
|
): Promise<{ x: number; y: number }[]> {
|
||||||
let endPoints: { x: number; y: number }[] = [end];
|
let endPoints: { x: number; y: number }[] = [end];
|
||||||
@ -48,12 +51,21 @@ export class PathfindingManager {
|
|||||||
// rejected Promise will return undefined for path
|
// rejected Promise will return undefined for path
|
||||||
path = await this.getPath(start, endPoint).catch();
|
path = await this.getPath(start, endPoint).catch();
|
||||||
if (path && path.length > 0) {
|
if (path && path.length > 0) {
|
||||||
return path;
|
return measuredInPixels ? this.mapTileUnitsToPixels(path) : path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private mapTileUnitsToPixels(path: { x: number; y: number }[]): { x: number; y: number }[] {
|
||||||
|
return path.map((step) => {
|
||||||
|
return {
|
||||||
|
x: step.x * this.tileDimensions.width + this.tileDimensions.width * 0.5,
|
||||||
|
y: step.y * this.tileDimensions.height + this.tileDimensions.height * 0.5,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private getNeighbouringTiles(tile: { x: number; y: number }): { x: number; y: number }[] {
|
private getNeighbouringTiles(tile: { x: number; y: number }): { x: number; y: number }[] {
|
||||||
const xOffsets = [-1, 0, 1, 1, 1, 0, -1, -1];
|
const xOffsets = [-1, 0, 1, 1, 1, 0, -1, -1];
|
||||||
const yOffsets = [-1, -1, -1, 0, 1, 1, 1, 0];
|
const yOffsets = [-1, -1, -1, 0, 1, 1, 1, 0];
|
||||||
|
@ -5,31 +5,20 @@
|
|||||||
<script>
|
<script>
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener('load', () => {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
WA.camera.onCameraUpdate((worldView) => console.log(worldView));
|
|
||||||
WA.onInit().then(() => {
|
WA.onInit().then(() => {
|
||||||
console.log('After WA init');
|
console.log('After WA init');
|
||||||
const setCameraButton = document.getElementById('setCameraButton');
|
const movePlayerButton = document.getElementById('movePlayerButton');
|
||||||
const followPlayerButton = document.getElementById('followPlayerButton');
|
|
||||||
const xField = document.getElementById('x');
|
const xField = document.getElementById('x');
|
||||||
const yField = document.getElementById('y');
|
const yField = document.getElementById('y');
|
||||||
const widthField = document.getElementById('width');
|
const speedField = document.getElementById('speed');
|
||||||
const heightField = document.getElementById('height');
|
|
||||||
const smoothField = document.getElementById('smooth');
|
|
||||||
const lockField = document.getElementById('lock');
|
|
||||||
|
|
||||||
setCameraButton.addEventListener('click', () => {
|
movePlayerButton.addEventListener('click', async () => {
|
||||||
WA.camera.set(
|
const position = await WA.player.moveTo(
|
||||||
parseInt(xField.value),
|
parseInt(xField.value),
|
||||||
parseInt(yField.value),
|
parseInt(yField.value),
|
||||||
widthField.value ? parseInt(widthField.value) : undefined,
|
parseInt(speedField.value),
|
||||||
heightField.value ? parseInt(heightField.value) : undefined,
|
|
||||||
lockField.checked,
|
|
||||||
smoothField.checked,
|
|
||||||
);
|
);
|
||||||
});
|
console.log(position);
|
||||||
|
|
||||||
followPlayerButton.addEventListener('click', () => {
|
|
||||||
WA.camera.followPlayer(smoothField.checked);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -38,13 +27,9 @@
|
|||||||
<body>
|
<body>
|
||||||
X: <input type="text" id="x" value="496" /><br/>
|
X: <input type="text" id="x" value="496" /><br/>
|
||||||
Y: <input type="text" id="y" value="655" /><br/>
|
Y: <input type="text" id="y" value="655" /><br/>
|
||||||
width: <input type="text" id="width" value="480" /><br/>
|
Speed: <input type="text" id="speed" value="20" /><br/>
|
||||||
height: <input type="text" id="height" value="286" /><br/>
|
|
||||||
Smooth: <input type="checkbox" id="smooth" value=1 /><br/>
|
|
||||||
Lock: <input type="checkbox" id="lock" value=1 /><br/>
|
|
||||||
|
|
||||||
<button id="setCameraButton">Set Camera</button>
|
<button id="movePlayerButton">Move Player</button>
|
||||||
<button id="followPlayerButton">Follow Player</button>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user