ActivatablesManager and little cleanup
This commit is contained in:
parent
68c4a5f5ce
commit
8b8c24f6ef
94
front/src/Phaser/Game/ActivatablesManager.ts
Normal file
94
front/src/Phaser/Game/ActivatablesManager.ts
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import { isOutlineable } from '../../Utils/CustomTypeGuards';
|
||||||
|
import { MathUtils } from '../../Utils/MathUtils';
|
||||||
|
import type { Player } from '../Player/Player';
|
||||||
|
import type { ActivatableInterface } from './ActivatableInterface';
|
||||||
|
|
||||||
|
export class ActivatablesManager {
|
||||||
|
|
||||||
|
// The item that can be selected by pressing the space key.
|
||||||
|
private selectedActivatableObjectByDistance?: ActivatableInterface;
|
||||||
|
private selectedActivatableObjectByPointer?: ActivatableInterface;
|
||||||
|
private activatableObjectsDistances: Map<ActivatableInterface, number> = new Map<ActivatableInterface, number>();
|
||||||
|
|
||||||
|
private currentPlayer: Player;
|
||||||
|
|
||||||
|
constructor(currentPlayer: Player) {
|
||||||
|
this.currentPlayer = currentPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public handlePointerOverActivatableObject(object: ActivatableInterface): void {
|
||||||
|
if (this.selectedActivatableObjectByPointer === object) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isOutlineable(this.selectedActivatableObjectByDistance)) {
|
||||||
|
this.selectedActivatableObjectByDistance?.characterFarAwayOutline();
|
||||||
|
}
|
||||||
|
if (isOutlineable(this.selectedActivatableObjectByPointer)) {
|
||||||
|
this.selectedActivatableObjectByPointer?.pointerOutOutline();
|
||||||
|
}
|
||||||
|
this.selectedActivatableObjectByPointer = object;
|
||||||
|
if (isOutlineable(this.selectedActivatableObjectByPointer)) {
|
||||||
|
this.selectedActivatableObjectByPointer?.pointerOverOutline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public handlePointerOutActivatableObject(): void {
|
||||||
|
if (isOutlineable(this.selectedActivatableObjectByPointer)) {
|
||||||
|
this.selectedActivatableObjectByPointer?.pointerOutOutline();
|
||||||
|
}
|
||||||
|
this.selectedActivatableObjectByPointer = undefined;
|
||||||
|
if (isOutlineable(this.selectedActivatableObjectByDistance)) {
|
||||||
|
this.selectedActivatableObjectByDistance?.characterCloseByOutline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSelectedActivatableObject(): ActivatableInterface | undefined {
|
||||||
|
return this.selectedActivatableObjectByPointer ?? this.selectedActivatableObjectByDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public deduceSelectedActivatableObjectByDistance(): void {
|
||||||
|
const newNearestObject = this.findNearestActivatableObject();
|
||||||
|
if (this.selectedActivatableObjectByDistance === newNearestObject) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// update value but do not change the outline
|
||||||
|
if (this.selectedActivatableObjectByPointer) {
|
||||||
|
this.selectedActivatableObjectByDistance = newNearestObject;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isOutlineable(this.selectedActivatableObjectByDistance)) {
|
||||||
|
this.selectedActivatableObjectByDistance?.characterFarAwayOutline();
|
||||||
|
}
|
||||||
|
this.selectedActivatableObjectByDistance = newNearestObject;
|
||||||
|
if (isOutlineable(this.selectedActivatableObjectByDistance)) {
|
||||||
|
this.selectedActivatableObjectByDistance?.characterCloseByOutline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private findNearestActivatableObject(): ActivatableInterface | undefined {
|
||||||
|
let shortestDistance: number = Infinity;
|
||||||
|
let closestObject: ActivatableInterface | undefined = undefined;
|
||||||
|
|
||||||
|
for (const [object, distance] of this.activatableObjectsDistances.entries()) {
|
||||||
|
if (object.activationRadius > distance && shortestDistance > distance) {
|
||||||
|
shortestDistance = distance;
|
||||||
|
closestObject = object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return closestObject;
|
||||||
|
}
|
||||||
|
public updateActivatableObjectsDistances(objects: ActivatableInterface[]): void {
|
||||||
|
const currentPlayerPos = this.currentPlayer.getPosition();
|
||||||
|
for (const object of objects) {
|
||||||
|
const distance = MathUtils.distanceBetween(currentPlayerPos, object.getPosition());
|
||||||
|
this.activatableObjectsDistances.set(object, distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateDistanceForSingleActivatableObject(object: ActivatableInterface): void {
|
||||||
|
this.activatableObjectsDistances.set(
|
||||||
|
object,
|
||||||
|
MathUtils.distanceBetween(this.currentPlayer.getPosition(), object.getPosition()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -49,6 +49,7 @@ import { GameMapPropertiesListener } from "./GameMapPropertiesListener";
|
|||||||
import { analyticsClient } from "../../Administration/AnalyticsClient";
|
import { analyticsClient } from "../../Administration/AnalyticsClient";
|
||||||
import { GameMapProperties } from "./GameMapProperties";
|
import { GameMapProperties } from "./GameMapProperties";
|
||||||
import { PathfindingManager } from "../../Utils/PathfindingManager";
|
import { PathfindingManager } from "../../Utils/PathfindingManager";
|
||||||
|
import { ActivatablesManager } from './ActivatablesManager';
|
||||||
import type {
|
import type {
|
||||||
GroupCreatedUpdatedMessageInterface,
|
GroupCreatedUpdatedMessageInterface,
|
||||||
MessageUserMovedInterface,
|
MessageUserMovedInterface,
|
||||||
@ -91,9 +92,6 @@ import { MapStore } from "../../Stores/Utils/MapStore";
|
|||||||
import { followUsersColorStore } from "../../Stores/FollowStore";
|
import { followUsersColorStore } from "../../Stores/FollowStore";
|
||||||
import { GameSceneUserInputHandler } from "../UserInput/GameSceneUserInputHandler";
|
import { GameSceneUserInputHandler } from "../UserInput/GameSceneUserInputHandler";
|
||||||
import { locale } from "../../i18n/i18n-svelte";
|
import { locale } from "../../i18n/i18n-svelte";
|
||||||
import type { ActivatableInterface } from './ActivatableInterface';
|
|
||||||
import { MathUtils } from '../../Utils/MathUtils';
|
|
||||||
import { isOutlineable } from '../../Utils/CustomTypeGuards';
|
|
||||||
export interface GameSceneInitInterface {
|
export interface GameSceneInitInterface {
|
||||||
initPosition: PointInterface | null;
|
initPosition: PointInterface | null;
|
||||||
reconnecting: boolean;
|
reconnecting: boolean;
|
||||||
@ -190,11 +188,6 @@ export class GameScene extends DirtyScene {
|
|||||||
|
|
||||||
private gameMap!: GameMap;
|
private gameMap!: GameMap;
|
||||||
private actionableItems: Map<number, ActionableItem> = new Map<number, ActionableItem>();
|
private actionableItems: Map<number, ActionableItem> = new Map<number, ActionableItem>();
|
||||||
// The item that can be selected by pressing the space key.
|
|
||||||
private selectedActivatableObjectByDistance?: ActivatableInterface;
|
|
||||||
private selectedActivatableObjectByPointer?: ActivatableInterface;
|
|
||||||
private activatableObjectsDistances: Map<ActivatableInterface, number> = new Map<ActivatableInterface, number>();
|
|
||||||
private outlinedItem: ActionableItem | null = null;
|
|
||||||
public userInputManager!: UserInputManager;
|
public userInputManager!: UserInputManager;
|
||||||
private isReconnecting: boolean | undefined = undefined;
|
private isReconnecting: boolean | undefined = undefined;
|
||||||
private playerName!: string;
|
private playerName!: string;
|
||||||
@ -208,6 +201,7 @@ export class GameScene extends DirtyScene {
|
|||||||
private emoteManager!: EmoteManager;
|
private emoteManager!: EmoteManager;
|
||||||
private cameraManager!: CameraManager;
|
private cameraManager!: CameraManager;
|
||||||
private pathfindingManager!: PathfindingManager;
|
private pathfindingManager!: PathfindingManager;
|
||||||
|
private activatablesManager!: ActivatablesManager;
|
||||||
private preloading: boolean = true;
|
private preloading: boolean = true;
|
||||||
private startPositionCalculator!: StartPositionCalculator;
|
private startPositionCalculator!: StartPositionCalculator;
|
||||||
private sharedVariablesManager!: SharedVariablesManager;
|
private sharedVariablesManager!: SharedVariablesManager;
|
||||||
@ -580,6 +574,8 @@ export class GameScene extends DirtyScene {
|
|||||||
this.gameMap.getTileDimensions()
|
this.gameMap.getTileDimensions()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.activatablesManager = new ActivatablesManager(this.CurrentPlayer);
|
||||||
|
|
||||||
biggestAvailableAreaStore.recompute();
|
biggestAvailableAreaStore.recompute();
|
||||||
this.cameraManager.startFollowPlayer(this.CurrentPlayer);
|
this.cameraManager.startFollowPlayer(this.CurrentPlayer);
|
||||||
|
|
||||||
@ -685,10 +681,6 @@ export class GameScene extends DirtyScene {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public activateOutlinedItem(): void {
|
|
||||||
this.outlinedItem?.activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the connection to Pusher.
|
* Initializes the connection to Pusher.
|
||||||
*/
|
*/
|
||||||
@ -1683,56 +1675,8 @@ ${escapedMessage}
|
|||||||
//listen event to share position of user
|
//listen event to share position of user
|
||||||
this.pushPlayerPosition(event);
|
this.pushPlayerPosition(event);
|
||||||
this.gameMap.setPosition(event.x, event.y);
|
this.gameMap.setPosition(event.x, event.y);
|
||||||
this.updateActivatableObjectsDistances();
|
this.activatablesManager.updateActivatableObjectsDistances([...Array.from(this.MapPlayersByKey.values()), ...this.actionableItems.values()]);
|
||||||
this.deduceSelectedActivatableObjectByDistance();
|
this.activatablesManager.deduceSelectedActivatableObjectByDistance();
|
||||||
// this.outlineItem(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
private deduceSelectedActivatableObjectByDistance(): void {
|
|
||||||
const newNearestObject = this.findNearestActivatableObject();
|
|
||||||
if (this.selectedActivatableObjectByDistance === newNearestObject) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// update value but do not change the outline
|
|
||||||
if (this.selectedActivatableObjectByPointer) {
|
|
||||||
this.selectedActivatableObjectByDistance = newNearestObject;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isOutlineable(this.selectedActivatableObjectByDistance)) {
|
|
||||||
this.selectedActivatableObjectByDistance?.characterFarAwayOutline();
|
|
||||||
}
|
|
||||||
this.selectedActivatableObjectByDistance = newNearestObject;
|
|
||||||
if (isOutlineable(this.selectedActivatableObjectByDistance)) {
|
|
||||||
this.selectedActivatableObjectByDistance?.characterCloseByOutline();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateDistanceForSingleActivatableObject(object: ActivatableInterface): void {
|
|
||||||
this.activatableObjectsDistances.set(
|
|
||||||
object,
|
|
||||||
MathUtils.distanceBetween(this.CurrentPlayer.getPosition(), object.getPosition()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateActivatableObjectsDistances(): void {
|
|
||||||
const currentPlayerPos = this.CurrentPlayer.getPosition();
|
|
||||||
for (const object of [...Array.from(this.MapPlayersByKey.values()), ...this.actionableItems.values()]) {
|
|
||||||
const distance = MathUtils.distanceBetween(currentPlayerPos, object.getPosition());
|
|
||||||
this.activatableObjectsDistances.set(object, distance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private findNearestActivatableObject(): ActivatableInterface | undefined {
|
|
||||||
let shortestDistance: number = Infinity;
|
|
||||||
let closestObject: ActivatableInterface | undefined = undefined;
|
|
||||||
|
|
||||||
for (const [object, distance] of this.activatableObjectsDistances.entries()) {
|
|
||||||
if (object.activationRadius > distance && shortestDistance > distance) {
|
|
||||||
shortestDistance = distance;
|
|
||||||
closestObject = object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return closestObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private createCollisionWithPlayer() {
|
private createCollisionWithPlayer() {
|
||||||
@ -1822,49 +1766,6 @@ ${escapedMessage}
|
|||||||
// Otherwise, do nothing.
|
// Otherwise, do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the correct item to outline and outline it (if there is an item to be outlined)
|
|
||||||
* @param event
|
|
||||||
*/
|
|
||||||
private outlineItem(event: HasPlayerMovedEvent): void {
|
|
||||||
let x = event.x;
|
|
||||||
let y = event.y;
|
|
||||||
switch (event.direction) {
|
|
||||||
case PlayerAnimationDirections.Up:
|
|
||||||
y -= 32;
|
|
||||||
break;
|
|
||||||
case PlayerAnimationDirections.Down:
|
|
||||||
y += 32;
|
|
||||||
break;
|
|
||||||
case PlayerAnimationDirections.Left:
|
|
||||||
x -= 32;
|
|
||||||
break;
|
|
||||||
case PlayerAnimationDirections.Right:
|
|
||||||
x += 32;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error('Unexpected direction "' + event.direction + '"');
|
|
||||||
}
|
|
||||||
|
|
||||||
let shortestDistance: number = Infinity;
|
|
||||||
let selectedItem: ActionableItem | null = null;
|
|
||||||
for (const item of this.actionableItems.values()) {
|
|
||||||
const distance = item.actionableDistance(x, y);
|
|
||||||
if (distance !== null && distance < shortestDistance) {
|
|
||||||
shortestDistance = distance;
|
|
||||||
selectedItem = item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.outlinedItem === selectedItem) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.outlinedItem?.notSelectable();
|
|
||||||
this.outlinedItem = selectedItem;
|
|
||||||
this.outlinedItem?.selectable();
|
|
||||||
}
|
|
||||||
|
|
||||||
private doPushPlayerPosition(event: HasPlayerMovedEvent): void {
|
private doPushPlayerPosition(event: HasPlayerMovedEvent): void {
|
||||||
this.lastMoveEventSent = event;
|
this.lastMoveEventSent = event;
|
||||||
this.lastSentTick = this.currentTick;
|
this.lastSentTick = this.currentTick;
|
||||||
@ -1905,8 +1806,8 @@ ${escapedMessage}
|
|||||||
this.doUpdatePlayerPosition(event.event);
|
this.doUpdatePlayerPosition(event.event);
|
||||||
const remotePlayer = this.MapPlayersByKey.get(event.event.userId);
|
const remotePlayer = this.MapPlayersByKey.get(event.event.userId);
|
||||||
if (remotePlayer) {
|
if (remotePlayer) {
|
||||||
this.updateDistanceForSingleActivatableObject(remotePlayer);
|
this.activatablesManager.updateDistanceForSingleActivatableObject(remotePlayer);
|
||||||
this.deduceSelectedActivatableObjectByDistance();
|
this.activatablesManager.deduceSelectedActivatableObjectByDistance();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GroupCreatedUpdatedEvent":
|
case "GroupCreatedUpdatedEvent":
|
||||||
@ -2002,30 +1903,12 @@ ${escapedMessage}
|
|||||||
player.updatePosition(addPlayerData.position);
|
player.updatePosition(addPlayerData.position);
|
||||||
|
|
||||||
player.on(Phaser.Input.Events.POINTER_OVER, () => {
|
player.on(Phaser.Input.Events.POINTER_OVER, () => {
|
||||||
if (this.selectedActivatableObjectByPointer === player) {
|
this.activatablesManager.handlePointerOverActivatableObject(player);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isOutlineable(this.selectedActivatableObjectByDistance)) {
|
|
||||||
this.selectedActivatableObjectByDistance?.characterFarAwayOutline();
|
|
||||||
}
|
|
||||||
if (isOutlineable(this.selectedActivatableObjectByPointer)) {
|
|
||||||
this.selectedActivatableObjectByPointer?.pointerOutOutline();
|
|
||||||
}
|
|
||||||
this.selectedActivatableObjectByPointer = player;
|
|
||||||
if (isOutlineable(this.selectedActivatableObjectByPointer)) {
|
|
||||||
this.selectedActivatableObjectByPointer?.pointerOverOutline();
|
|
||||||
}
|
|
||||||
this.markDirty();
|
this.markDirty();
|
||||||
});
|
});
|
||||||
|
|
||||||
player.on(Phaser.Input.Events.POINTER_OUT, () => {
|
player.on(Phaser.Input.Events.POINTER_OUT, () => {
|
||||||
if (isOutlineable(this.selectedActivatableObjectByPointer)) {
|
this.activatablesManager.handlePointerOutActivatableObject();
|
||||||
this.selectedActivatableObjectByPointer?.pointerOutOutline();
|
|
||||||
}
|
|
||||||
this.selectedActivatableObjectByPointer = undefined;
|
|
||||||
if (isOutlineable(this.selectedActivatableObjectByDistance)) {
|
|
||||||
this.selectedActivatableObjectByDistance?.characterCloseByOutline();
|
|
||||||
}
|
|
||||||
this.markDirty();
|
this.markDirty();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -2295,7 +2178,7 @@ ${escapedMessage}
|
|||||||
return this.pathfindingManager;
|
return this.pathfindingManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSelectedActivatableObject(): ActivatableInterface | undefined {
|
public getActivatablesManager(): ActivatablesManager {
|
||||||
return this.selectedActivatableObjectByPointer ?? this.selectedActivatableObjectByDistance;
|
return this.activatablesManager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,7 @@ export class GameSceneUserInputHandler implements UserInputHandlerInterface {
|
|||||||
public handlePointerDownEvent(pointer: Phaser.Input.Pointer, gameObjects: Phaser.GameObjects.GameObject[]): void {}
|
public handlePointerDownEvent(pointer: Phaser.Input.Pointer, gameObjects: Phaser.GameObjects.GameObject[]): void {}
|
||||||
|
|
||||||
public handleSpaceKeyUpEvent(event: Event): Event {
|
public handleSpaceKeyUpEvent(event: Event): Event {
|
||||||
this.gameScene.activateOutlinedItem();
|
this.gameScene.getActivatablesManager().getSelectedActivatableObject()?.activate();
|
||||||
this.gameScene.getSelectedActivatableObject()?.activate();
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user