Merge pull request #1827 from thecodingmachine/activatable-fixes

Activatable fixes
This commit is contained in:
David Négrier 2022-02-07 14:39:40 +01:00 committed by GitHub
commit cffafe9f15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 109 additions and 42 deletions

View File

@ -9,4 +9,7 @@ export interface UserInputHandlerInterface {
handlePointerUpEvent: (pointer: Phaser.Input.Pointer, gameObjects: Phaser.GameObjects.GameObject[]) => void; handlePointerUpEvent: (pointer: Phaser.Input.Pointer, gameObjects: Phaser.GameObjects.GameObject[]) => void;
handlePointerDownEvent: (pointer: Phaser.Input.Pointer, gameObjects: Phaser.GameObjects.GameObject[]) => void; handlePointerDownEvent: (pointer: Phaser.Input.Pointer, gameObjects: Phaser.GameObjects.GameObject[]) => void;
handleSpaceKeyUpEvent: (event: Event) => Event; handleSpaceKeyUpEvent: (event: Event) => Event;
addSpaceEventListener: (callback: Function) => void;
removeSpaceEventListner: (callback: Function) => void;
} }

View File

@ -159,6 +159,27 @@ export abstract class Character extends Container implements OutlineableInterfac
return { x: this.x, y: this.y }; return { x: this.x, y: this.y };
} }
/**
* Returns position based on where player is currently facing
* @param shift How far from player should the point of interest be.
*/
public getDirectionalActivationPosition(shift: number): { x: number; y: number } {
switch (this.lastDirection) {
case PlayerAnimationDirections.Down: {
return { x: this.x, y: this.y + shift };
}
case PlayerAnimationDirections.Left: {
return { x: this.x - shift, y: this.y };
}
case PlayerAnimationDirections.Right: {
return { x: this.x + shift, y: this.y };
}
case PlayerAnimationDirections.Up: {
return { x: this.x, y: this.y - shift };
}
}
}
public getObjectToOutline(): Phaser.GameObjects.GameObject { public getObjectToOutline(): Phaser.GameObjects.GameObject {
return this.playerNameText; return this.playerNameText;
} }
@ -455,16 +476,16 @@ export abstract class Character extends Container implements OutlineableInterfac
this.outlineColorStore.removeApiColor(); this.outlineColorStore.removeApiColor();
} }
public pointerOverOutline(): void { public pointerOverOutline(color: number): void {
this.outlineColorStore.pointerOver(); this.outlineColorStore.pointerOver(color);
} }
public pointerOutOutline(): void { public pointerOutOutline(): void {
this.outlineColorStore.pointerOut(); this.outlineColorStore.pointerOut();
} }
public characterCloseByOutline(): void { public characterCloseByOutline(color: number): void {
this.outlineColorStore.characterCloseBy(); this.outlineColorStore.characterCloseBy(color);
} }
public characterFarAwayOutline(): void { public characterFarAwayOutline(): void {

View File

@ -11,6 +11,11 @@ export class ActivatablesManager {
private currentPlayer: Player; private currentPlayer: Player;
private canSelectByDistance: boolean = true;
private readonly outlineColor = 0xffff00;
private readonly directionalActivationPositionShift = 50;
constructor(currentPlayer: Player) { constructor(currentPlayer: Player) {
this.currentPlayer = currentPlayer; this.currentPlayer = currentPlayer;
} }
@ -27,7 +32,7 @@ export class ActivatablesManager {
} }
this.selectedActivatableObjectByPointer = object; this.selectedActivatableObjectByPointer = object;
if (isOutlineable(this.selectedActivatableObjectByPointer)) { if (isOutlineable(this.selectedActivatableObjectByPointer)) {
this.selectedActivatableObjectByPointer?.pointerOverOutline(); this.selectedActivatableObjectByPointer?.pointerOverOutline(this.outlineColor);
} }
} }
@ -37,7 +42,7 @@ export class ActivatablesManager {
} }
this.selectedActivatableObjectByPointer = undefined; this.selectedActivatableObjectByPointer = undefined;
if (isOutlineable(this.selectedActivatableObjectByDistance)) { if (isOutlineable(this.selectedActivatableObjectByDistance)) {
this.selectedActivatableObjectByDistance?.characterCloseByOutline(); this.selectedActivatableObjectByDistance?.characterCloseByOutline(this.outlineColor);
} }
} }
@ -46,6 +51,9 @@ export class ActivatablesManager {
} }
public deduceSelectedActivatableObjectByDistance(): void { public deduceSelectedActivatableObjectByDistance(): void {
if (!this.canSelectByDistance) {
return;
}
const newNearestObject = this.findNearestActivatableObject(); const newNearestObject = this.findNearestActivatableObject();
if (this.selectedActivatableObjectByDistance === newNearestObject) { if (this.selectedActivatableObjectByDistance === newNearestObject) {
return; return;
@ -60,10 +68,42 @@ export class ActivatablesManager {
} }
this.selectedActivatableObjectByDistance = newNearestObject; this.selectedActivatableObjectByDistance = newNearestObject;
if (isOutlineable(this.selectedActivatableObjectByDistance)) { if (isOutlineable(this.selectedActivatableObjectByDistance)) {
this.selectedActivatableObjectByDistance?.characterCloseByOutline(); this.selectedActivatableObjectByDistance?.characterCloseByOutline(this.outlineColor);
} }
} }
public updateActivatableObjectsDistances(objects: ActivatableInterface[]): void {
const currentPlayerPos = this.currentPlayer.getDirectionalActivationPosition(
this.directionalActivationPositionShift
);
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.getDirectionalActivationPosition(this.directionalActivationPositionShift),
object.getPosition()
)
);
}
public disableSelectingByDistance(): void {
this.canSelectByDistance = false;
if (isOutlineable(this.selectedActivatableObjectByDistance)) {
this.selectedActivatableObjectByDistance?.characterFarAwayOutline();
}
this.selectedActivatableObjectByDistance = undefined;
}
public enableSelectingByDistance(): void {
this.canSelectByDistance = true;
}
private findNearestActivatableObject(): ActivatableInterface | undefined { private findNearestActivatableObject(): ActivatableInterface | undefined {
let shortestDistance: number = Infinity; let shortestDistance: number = Infinity;
let closestObject: ActivatableInterface | undefined = undefined; let closestObject: ActivatableInterface | undefined = undefined;
@ -76,18 +116,8 @@ export class ActivatablesManager {
} }
return closestObject; 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 { public isSelectingByDistanceEnabled(): boolean {
this.activatableObjectsDistances.set( return this.canSelectByDistance;
object,
MathUtils.distanceBetween(this.currentPlayer.getPosition(), object.getPosition())
);
} }
} }

View File

@ -1737,6 +1737,12 @@ ${escapedMessage}
emoteMenuStore.openEmoteMenu(); emoteMenuStore.openEmoteMenu();
} }
}); });
this.CurrentPlayer.on(Phaser.Input.Events.POINTER_OVER, (pointer: Phaser.Input.Pointer) => {
this.CurrentPlayer.pointerOverOutline(0x00ffff);
});
this.CurrentPlayer.on(Phaser.Input.Events.POINTER_OUT, (pointer: Phaser.Input.Pointer) => {
this.CurrentPlayer.pointerOutOutline();
});
this.CurrentPlayer.on(requestEmoteEventName, (emoteKey: string) => { this.CurrentPlayer.on(requestEmoteEventName, (emoteKey: string) => {
this.connection?.emitEmoteEvent(emoteKey); this.connection?.emitEmoteEvent(emoteKey);
analyticsClient.launchEmote(emoteKey); analyticsClient.launchEmote(emoteKey);

View File

@ -3,8 +3,8 @@ export interface OutlineableInterface {
removeFollowOutlineColor(): void; removeFollowOutlineColor(): void;
setApiOutlineColor(color: number): void; setApiOutlineColor(color: number): void;
removeApiOutlineColor(): void; removeApiOutlineColor(): void;
pointerOverOutline(): void; pointerOverOutline(color: number): void;
pointerOutOutline(): void; pointerOutOutline(): void;
characterCloseByOutline(): void; characterCloseByOutline(color: number): void;
characterFarAwayOutline(): void; characterFarAwayOutline(): void;
} }

View File

@ -53,10 +53,20 @@ 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 {
const activatable = this.gameScene.getActivatablesManager().getSelectedActivatableObject(); const activatableManager = this.gameScene.getActivatablesManager();
if (activatable && activatable.isActivatable()) { const activatable = activatableManager.getSelectedActivatableObject();
if (activatable && activatable.isActivatable() && activatableManager.isSelectingByDistanceEnabled()) {
activatable.activate(); activatable.activate();
} }
return event; return event;
} }
public addSpaceEventListener(callback: Function): void {
this.gameScene.input.keyboard.addListener("keyup-SPACE", callback);
this.gameScene.getActivatablesManager().disableSelectingByDistance();
}
public removeSpaceEventListner(callback: Function): void {
this.gameScene.input.keyboard.removeListener("keyup-SPACE", callback);
this.gameScene.getActivatablesManager().enableSelectingByDistance();
}
} }

View File

@ -223,10 +223,10 @@ export class UserInputManager {
} }
addSpaceEventListner(callback: Function) { addSpaceEventListner(callback: Function) {
this.scene.input.keyboard.addListener("keyup-SPACE", callback); this.userInputHandler.addSpaceEventListener(callback);
} }
removeSpaceEventListner(callback: Function) { removeSpaceEventListner(callback: Function) {
this.scene.input.keyboard.removeListener("keyup-SPACE", callback); this.userInputHandler.removeSpaceEventListner(callback);
} }
destroy(): void { destroy(): void {

View File

@ -1,4 +1,5 @@
import { derived, writable } from "svelte/store"; import { derived, writable } from "svelte/store";
import type { ActivatablesManager } from "../Phaser/Game/ActivatablesManager";
import type { UserInputManager } from "../Phaser/UserInput/UserInputManager"; import type { UserInputManager } from "../Phaser/UserInput/UserInputManager";
export interface LayoutManagerAction { export interface LayoutManagerAction {

View File

@ -5,38 +5,33 @@ export function createColorStore() {
let followColor: number | undefined = undefined; let followColor: number | undefined = undefined;
let apiColor: number | undefined = undefined; let apiColor: number | undefined = undefined;
let pointedByPointer: number | undefined = undefined;
let pointedByPointer: boolean = false; let pointedByCharacter: number | undefined = undefined;
let pointedByCharacter: boolean = false;
const updateColor = () => { const updateColor = () => {
if (pointedByPointer || pointedByCharacter) { set(pointedByPointer ?? pointedByCharacter ?? followColor ?? apiColor);
set(0xffff00);
} else {
set(followColor ?? apiColor);
}
}; };
return { return {
subscribe, subscribe,
pointerOver() { pointerOver(color: number) {
pointedByPointer = true; pointedByPointer = color;
updateColor(); updateColor();
}, },
pointerOut() { pointerOut() {
pointedByPointer = false; pointedByPointer = undefined;
updateColor(); updateColor();
}, },
characterCloseBy() { characterCloseBy(color: number) {
pointedByCharacter = true; pointedByCharacter = color;
updateColor(); updateColor();
}, },
characterFarAway() { characterFarAway() {
pointedByCharacter = false; pointedByCharacter = undefined;
updateColor(); updateColor();
}, },

View File

@ -2,6 +2,7 @@
# yarn lockfile v1 # yarn lockfile v1
"husky@^6.0.0": husky@^7.0.1:
"resolved" "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz" version "7.0.4"
"version" "6.0.0" resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535"
integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==