From 45e254b93177f402d0781412d7daeed130025eb3 Mon Sep 17 00:00:00 2001 From: Piotr 'pwh' Hanusiak Date: Wed, 13 Apr 2022 14:31:18 +0200 Subject: [PATCH 01/19] visible indicator for hero. Using images in order to fix graphic circles glitching out during movement --- .../icons/icon_status_indicator_inside.png | Bin 0 -> 123 bytes .../icons/icon_status_indicator_outline.png | Bin 0 -> 5422 bytes .../src/Phaser/Components/PlayerStatusDot.ts | 51 ++- front/src/Phaser/Entity/Character.ts | 6 +- front/src/Phaser/Game/GameScene.ts | 7 +- front/src/Phaser/Game/PlayerMovement.ts | 1 - front/src/Phaser/Helpers/TexturesHelper.ts | 16 + front/src/Phaser/Player/Player.ts | 1 - maps/tests/index.html | 8 + maps/tests/status_indicator.json | 322 ++++++++++++++++++ 10 files changed, 389 insertions(+), 23 deletions(-) create mode 100644 front/public/resources/icons/icon_status_indicator_inside.png create mode 100644 front/public/resources/icons/icon_status_indicator_outline.png create mode 100644 maps/tests/status_indicator.json diff --git a/front/public/resources/icons/icon_status_indicator_inside.png b/front/public/resources/icons/icon_status_indicator_inside.png new file mode 100644 index 0000000000000000000000000000000000000000..29a2daad7bed626d30170202016c23836202670e GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^EFjFm1SHiab7}%9#^NA%Cx&(BWL|<~(j9#r85lP9 zbN@+X1@buyJR*x382Ao@Fyrz36)8YL0Z$jl5Q*^QAN?#HkN*7UXSh8<|6(j(+isv7 NgQu&X%Q~loCIJ2U9}oZl literal 0 HcmV?d00001 diff --git a/front/public/resources/icons/icon_status_indicator_outline.png b/front/public/resources/icons/icon_status_indicator_outline.png new file mode 100644 index 0000000000000000000000000000000000000000..67f86ec5dfded15555651f98b29199bf105bf95c GIT binary patch literal 5422 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 X#dNwRQfyNU8N(R#MP5}N(dqvMrG8J& literal 0 HcmV?d00001 diff --git a/front/src/Phaser/Components/PlayerStatusDot.ts b/front/src/Phaser/Components/PlayerStatusDot.ts index af893b2f..4e09451a 100644 --- a/front/src/Phaser/Components/PlayerStatusDot.ts +++ b/front/src/Phaser/Components/PlayerStatusDot.ts @@ -1,36 +1,46 @@ import { Easing } from "../../types"; -export class PlayerStatusDot extends Phaser.GameObjects.Container { - private graphics: Phaser.GameObjects.Graphics; +export enum PlayerStatus { + Online = "Online", + Silenced = "Silenced", + Away = "Away", +} - private away: boolean; +export class PlayerStatusDot extends Phaser.GameObjects.Container { + private statusImage: Phaser.GameObjects.Image; + private statusImageOutline: Phaser.GameObjects.Image; + + private status: PlayerStatus; private readonly COLORS = { - // online: 0x00ff00, - // away: 0xffff00, online: 0x8cc43f, onlineOutline: 0x427a25, away: 0xf5931e, awayOutline: 0x875d13, + silenced: 0xe74c3c, + silencedOutline: 0xc0392b, }; constructor(scene: Phaser.Scene, x: number, y: number) { super(scene, x, y); - this.away = false; + this.status = PlayerStatus.Online; + + this.statusImage = this.scene.add.image(0, 0, "iconStatusIndicatorInside"); + this.statusImageOutline = this.scene.add.image(0, 0, "iconStatusIndicatorOutline"); + + this.add([this.statusImage, this.statusImageOutline]); - this.graphics = this.scene.add.graphics(); - this.add(this.graphics); this.redraw(); this.scene.add.existing(this); } - public setAway(away: boolean = true, instant: boolean = false): void { - if (this.away === away) { + public setStatus(status: PlayerStatus, instant: boolean = false): void { + if (this.status === status) { return; } - this.away = away; + this.status = status; if (instant) { this.redraw(); } else { @@ -56,10 +66,19 @@ export class PlayerStatusDot extends Phaser.GameObjects.Container { } private redraw(): void { - this.graphics.clear(); - this.graphics.fillStyle(this.away ? this.COLORS.away : this.COLORS.online); - this.graphics.lineStyle(1, this.away ? this.COLORS.awayOutline : this.COLORS.onlineOutline); - this.graphics.fillCircle(0, 0, 3); - this.graphics.strokeCircle(0, 0, 3); + const colors = this.getColors(); + this.statusImage.setTintFill(colors.filling); + this.statusImageOutline.setTintFill(colors.outline); + } + + private getColors(): { filling: number; outline: number } { + switch (this.status) { + case PlayerStatus.Online: + return { filling: this.COLORS.online, outline: this.COLORS.onlineOutline }; + case PlayerStatus.Away: + return { filling: this.COLORS.away, outline: this.COLORS.awayOutline }; + case PlayerStatus.Silenced: + return { filling: this.COLORS.silenced, outline: this.COLORS.silencedOutline }; + } } } diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 681efd29..0982351e 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -19,7 +19,7 @@ import type { OutlineableInterface } from "../Game/OutlineableInterface"; import type CancelablePromise from "cancelable-promise"; import { TalkIcon } from "../Components/TalkIcon"; import { Deferred } from "ts-deferred"; -import { PlayerStatusDot } from "../Components/PlayerStatusDot"; +import { PlayerStatus, PlayerStatusDot } from "../Components/PlayerStatusDot"; const playerNameY = -25; const interactiveRadius = 35; @@ -236,8 +236,8 @@ export abstract class Character extends Container implements OutlineableInterfac this.talkIcon.show(show, forceClose); } - public setAwayStatus(away: boolean = true, instant: boolean = false): void { - this.statusDot.setAway(away, instant); + public setStatus(status: PlayerStatus, instant: boolean = false): void { + this.statusDot.setStatus(status, instant); } public addCompanion(name: string, texturePromise?: CancelablePromise): void { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index a2bd5279..5fa11d4b 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -102,6 +102,7 @@ import { Deferred } from "ts-deferred"; import { SuperLoaderPlugin } from "../Services/SuperLoaderPlugin"; import { PlayerDetailsUpdatedMessage } from "../../Messages/ts-proto-generated/protos/messages"; import { privacyShutdownStore } from "../../Stores/PrivacyShutdownStore"; +import { PlayerStatus } from "../Components/PlayerStatusDot"; export interface GameSceneInitInterface { initPosition: PointInterface | null; reconnecting: boolean; @@ -250,6 +251,8 @@ export class GameScene extends DirtyScene { this.listenToIframeEvents(); this.load.image("iconTalk", "/resources/icons/icon_talking.png"); + this.load.image("iconStatusIndicatorInside", "/resources/icons/icon_status_indicator_inside.png"); + this.load.image("iconStatusIndicatorOutline", "/resources/icons/icon_status_indicator_outline.png"); if (touchScreenManager.supportTouchScreen) { this.load.image(joystickBaseKey, joystickBaseImg); @@ -1954,7 +1957,7 @@ ${escapedMessage} player.setApiOutlineColor(addPlayerData.outlineColor); } if (addPlayerData.away !== undefined) { - player.setAwayStatus(addPlayerData.away, true); + player.setStatus(addPlayerData.away ? PlayerStatus.Away : PlayerStatus.Online, true); } this.MapPlayers.add(player); this.MapPlayersByKey.set(player.userId, player); @@ -2106,7 +2109,7 @@ ${escapedMessage} character.showTalkIcon(message.details?.showVoiceIndicator); } if (message.details?.away !== undefined) { - character.setAwayStatus(message.details?.away); + character.setStatus(message.details?.away ? PlayerStatus.Away : PlayerStatus.Online); } } diff --git a/front/src/Phaser/Game/PlayerMovement.ts b/front/src/Phaser/Game/PlayerMovement.ts index fc14078d..80b4ddcc 100644 --- a/front/src/Phaser/Game/PlayerMovement.ts +++ b/front/src/Phaser/Game/PlayerMovement.ts @@ -34,7 +34,6 @@ export class PlayerMovement { const y = (this.endPosition.y - this.startPosition.y) * ((tick - this.startTick) / (this.endTick - this.startTick)) + this.startPosition.y; - //console.log('Computed position ', x, y) return { x, y, diff --git a/front/src/Phaser/Helpers/TexturesHelper.ts b/front/src/Phaser/Helpers/TexturesHelper.ts index 6c0f1aab..4476461f 100644 --- a/front/src/Phaser/Helpers/TexturesHelper.ts +++ b/front/src/Phaser/Helpers/TexturesHelper.ts @@ -67,4 +67,20 @@ export class TexturesHelper { rectangleTexture.generateTexture(textureKey, width, height); rectangleTexture.destroy(); } + + public static createCircleTexture( + scene: Phaser.Scene, + textureKey: string, + radius: number, + color: number, + outlineColor?: number, + outlineThickness?: number + ): void { + const circleTexture = scene.add.graphics().fillStyle(color, 1).fillCircle(radius, radius, radius); + if (outlineColor) { + circleTexture.lineStyle(outlineThickness ?? 1, outlineColor).strokeCircle(radius, radius, radius); + } + circleTexture.generateTexture(textureKey, radius * 2, radius * 2); + circleTexture.destroy(); + } } diff --git a/front/src/Phaser/Player/Player.ts b/front/src/Phaser/Player/Player.ts index cae7b496..65e423a4 100644 --- a/front/src/Phaser/Player/Player.ts +++ b/front/src/Phaser/Player/Player.ts @@ -28,7 +28,6 @@ export class Player extends Character { companionTexturePromise?: CancelablePromise ) { super(Scene, x, y, texturesPromise, name, direction, moving, 1, true, companion, companionTexturePromise); - this.statusDot.setVisible(false); //the current player model should be push away by other players to prevent conflict this.getBody().setImmovable(false); } diff --git a/maps/tests/index.html b/maps/tests/index.html index e625aa6d..c7db9456 100644 --- a/maps/tests/index.html +++ b/maps/tests/index.html @@ -471,6 +471,14 @@ Away mode settings + + + Success Failure Pending + + + Test Status Indicator + + diff --git a/front/src/Components/MyCamera.svelte b/front/src/Components/MyCamera.svelte index 7f97ff22..8ddda1a9 100644 --- a/front/src/Components/MyCamera.svelte +++ b/front/src/Components/MyCamera.svelte @@ -1,10 +1,11 @@ diff --git a/front/src/Components/MyCamera.svelte b/front/src/Components/MyCamera.svelte index 8ddda1a9..8f4b2094 100644 --- a/front/src/Components/MyCamera.svelte +++ b/front/src/Components/MyCamera.svelte @@ -1,11 +1,10 @@
@@ -94,7 +87,7 @@
@@ -103,7 +96,7 @@
@@ -113,26 +106,26 @@
- {#if $requestedScreenSharingState && !isSilent} + {#if $requestedScreenSharingState && !$silentStore} Start screen sharing {:else} Stop screen sharing {/if}
-
- {#if $requestedCameraState && !isSilent} +
+ {#if $requestedCameraState && !$silentStore} Turn on webcam {:else} Turn off webcam {/if}
-
- {#if $requestedMicrophoneState && !isSilent} +
+ {#if $requestedMicrophoneState && !$silentStore} Turn on microphone {:else} Turn off microphone diff --git a/front/src/Components/MyCamera.svelte b/front/src/Components/MyCamera.svelte index 8f4b2094..d72a8eee 100644 --- a/front/src/Components/MyCamera.svelte +++ b/front/src/Components/MyCamera.svelte @@ -20,11 +20,6 @@ unsubscribeLocalStreamStore(); }); - let isSilent: boolean; - const unsubscribeIsSilent = silentStore.subscribe((silent) => { - isSilent = silent; - }); - let cameraContainer: HTMLDivElement; onMount(() => { @@ -40,16 +35,14 @@ } }); }); - - onDestroy(unsubscribeIsSilent);
- {#if isSilent} + {#if $silentStore}
{$LL.camera.my.silentZone()}
{:else if $localStreamStore.type === "success" && $localStreamStore.stream}