From dbd06bda4e97ef1c45c6a98cc264e26b721c0f0a Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 26 Jan 2022 14:59:23 +0100 Subject: [PATCH] changing the way Outline is handled --- front/src/Phaser/Entity/Character.ts | 15 +++++++- front/src/Phaser/Game/GameScene.ts | 23 ++++++++++--- front/src/Phaser/Game/OutlineableInterface.ts | 6 ++++ .../UserInput/GameSceneUserInputHandler.ts | 2 +- front/src/Utils/CustomTypeGuards.ts | 5 +++ front/src/Utils/OutlineManager.ts | 34 +++++++++++++++++++ 6 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 front/src/Phaser/Game/OutlineableInterface.ts create mode 100644 front/src/Utils/CustomTypeGuards.ts create mode 100644 front/src/Utils/OutlineManager.ts diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 42bd4edf..db3f2f8d 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -15,6 +15,8 @@ import { TexturesHelper } from "../Helpers/TexturesHelper"; import type { PictureStore } from "../../Stores/PictureStore"; import { Unsubscriber, Writable, writable } from "svelte/store"; import { createColorStore } from "../../Stores/OutlineColorStore"; +import type { OutlineableInterface } from '../Game/OutlineableInterface'; +import type { OutlineConfig } from '../../Utils/OutlineManager'; const playerNameY = -25; @@ -28,7 +30,7 @@ interface AnimationData { const interactiveRadius = 35; -export abstract class Character extends Container { +export abstract class Character extends Container implements OutlineableInterface { private bubble: SpeechBubble | null = null; private readonly playerNameText: Text; public playerName: string; @@ -144,6 +146,17 @@ export abstract class Character extends Container { return { x: this.x, y: this.y }; } + public getOutlineConfig(): OutlineConfig { + return { + thickness: 2, + outlineColor: 0xffff00, + } + } + + public getObjectToOutline(): Phaser.GameObjects.GameObject { + return this.playerNameText; + } + private async getSnapshot(): Promise { const sprites = Array.from(this.sprites.values()).map((sprite) => { return { sprite, frame: 1 }; diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index a0a41a63..9f6f2c88 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -93,6 +93,9 @@ import { GameSceneUserInputHandler } from "../UserInput/GameSceneUserInputHandle import { locale } from "../../i18n/i18n-svelte"; import type { ActivatableInterface } from './ActivatableInterface'; import { MathUtils } from '../../Utils/MathUtils'; +import { OutlineManager } from '../../Utils/OutlineManager'; +import type { OutlineableInterface } from './OutlineableInterface'; +import { isOutlineable } from '../../Utils/CustomTypeGuards'; export interface GameSceneInitInterface { initPosition: PointInterface | null; @@ -191,7 +194,7 @@ export class GameScene extends DirtyScene { private gameMap!: GameMap; private actionableItems: Map = new Map(); // The item that can be selected by pressing the space key. - private nearestActivatableObject?: ActivatableInterface; + private selectedActivatableObject?: ActivatableInterface; private outlinedItem: ActionableItem | null = null; public userInputManager!: UserInputManager; private isReconnecting: boolean | undefined = undefined; @@ -206,6 +209,7 @@ export class GameScene extends DirtyScene { private emoteManager!: EmoteManager; private cameraManager!: CameraManager; private pathfindingManager!: PathfindingManager; + private outlineManager!: OutlineManager; private preloading: boolean = true; private startPositionCalculator!: StartPositionCalculator; private sharedVariablesManager!: SharedVariablesManager; @@ -577,6 +581,8 @@ export class GameScene extends DirtyScene { this.gameMap.getCollisionsGrid(), this.gameMap.getTileDimensions() ); + + this.outlineManager = new OutlineManager(this); biggestAvailableAreaStore.recompute(); this.cameraManager.startFollowPlayer(this.CurrentPlayer); @@ -1679,9 +1685,16 @@ ${escapedMessage} private handleCurrentPlayerHasMovedEvent(event: HasPlayerMovedEvent): void { //listen event to share position of user this.pushPlayerPosition(event); - this.nearestActivatableObject = this.findNearestActivatableObject(); - this.outlineItem(event); this.gameMap.setPosition(event.x, event.y); + + const newNearestObject = this.findNearestActivatableObject(); + if (this.selectedActivatableObject === newNearestObject) { + return; + } + this.outlineManager.tryRemoveOutline(this.selectedActivatableObject); + this.selectedActivatableObject = newNearestObject; + this.outlineManager.tryAddOutline(this.selectedActivatableObject); + // this.outlineItem(event); } private findNearestActivatableObject(): ActivatableInterface | undefined { @@ -2226,7 +2239,7 @@ ${escapedMessage} return this.pathfindingManager; } - public getNearestActivatableObject(): ActivatableInterface | undefined { - return this.nearestActivatableObject + public getSelectedActivatableObject(): ActivatableInterface | undefined { + return this.selectedActivatableObject; } } diff --git a/front/src/Phaser/Game/OutlineableInterface.ts b/front/src/Phaser/Game/OutlineableInterface.ts new file mode 100644 index 00000000..b135e17a --- /dev/null +++ b/front/src/Phaser/Game/OutlineableInterface.ts @@ -0,0 +1,6 @@ +import type { OutlineConfig } from '../../Utils/OutlineManager'; + +export interface OutlineableInterface { + getObjectToOutline: () => Phaser.GameObjects.GameObject; + getOutlineConfig: () => OutlineConfig; +} \ No newline at end of file diff --git a/front/src/Phaser/UserInput/GameSceneUserInputHandler.ts b/front/src/Phaser/UserInput/GameSceneUserInputHandler.ts index eac233bd..e4f35d2a 100644 --- a/front/src/Phaser/UserInput/GameSceneUserInputHandler.ts +++ b/front/src/Phaser/UserInput/GameSceneUserInputHandler.ts @@ -54,7 +54,7 @@ export class GameSceneUserInputHandler implements UserInputHandlerInterface { public handleSpaceKeyUpEvent(event: Event): Event { this.gameScene.activateOutlinedItem(); - this.gameScene.getNearestActivatableObject()?.activate(); + this.gameScene.getSelectedActivatableObject()?.activate(); return event; } } diff --git a/front/src/Utils/CustomTypeGuards.ts b/front/src/Utils/CustomTypeGuards.ts new file mode 100644 index 00000000..4db719cb --- /dev/null +++ b/front/src/Utils/CustomTypeGuards.ts @@ -0,0 +1,5 @@ +import type { OutlineableInterface } from '../Phaser/Game/OutlineableInterface'; + +export function isOutlineable(object: unknown): object is OutlineableInterface { + return (object as unknown as OutlineableInterface)?.getObjectToOutline() !== undefined; +} \ No newline at end of file diff --git a/front/src/Utils/OutlineManager.ts b/front/src/Utils/OutlineManager.ts new file mode 100644 index 00000000..05aa82a0 --- /dev/null +++ b/front/src/Utils/OutlineManager.ts @@ -0,0 +1,34 @@ +import type OutlinePipelinePlugin from 'phaser3-rex-plugins/plugins/outlinepipeline-plugin.js'; +import { isOutlineable } from './CustomTypeGuards'; + +export interface OutlineConfig { + thickness: number; + outlineColor: number; +} + +export class OutlineManager { + + private scene: Phaser.Scene; + + private outlinePlugin?: OutlinePipelinePlugin + + constructor(scene: Phaser.Scene) { + this.scene = scene; + this.outlinePlugin = + this.scene.plugins.get("rexOutlinePipeline") as unknown as OutlinePipelinePlugin | undefined; + } + + public tryAddOutline(object: unknown): void { + if (!isOutlineable(object)) { + return; + } + this.outlinePlugin?.add(object.getObjectToOutline(), object.getOutlineConfig()); + } + + public tryRemoveOutline(object: unknown): void { + if (!isOutlineable(object)) { + return; + } + this.outlinePlugin?.remove(object.getObjectToOutline()); + } +} \ No newline at end of file