Merge branch 'develop' of github.com:thecodingmachine/workadventure into svelte_video_overlay
# Conflicts: # front/package.json # front/src/Components/App.svelte # front/src/Phaser/Game/GameScene.ts # front/src/Phaser/Menu/MenuScene.ts # front/src/WebRtc/MediaManager.ts
This commit is contained in:
commit
e4708149e0
172 changed files with 15268 additions and 2850 deletions
|
@ -8,6 +8,7 @@ import {Companion} from "../Companion/Companion";
|
|||
import type {GameScene} from "../Game/GameScene";
|
||||
import {DEPTH_INGAME_TEXT_INDEX} from "../Game/DepthIndexes";
|
||||
import {waScaleManager} from "../Services/WaScaleManager";
|
||||
import type OutlinePipelinePlugin from "phaser3-rex-plugins/plugins/outlinepipeline-plugin.js";
|
||||
|
||||
const playerNameY = - 25;
|
||||
|
||||
|
@ -32,6 +33,7 @@ export abstract class Character extends Container {
|
|||
public companion?: Companion;
|
||||
private emote: Phaser.GameObjects.Sprite | null = null;
|
||||
private emoteTween: Phaser.Tweens.Tween|null = null;
|
||||
scene: GameScene;
|
||||
|
||||
constructor(scene: GameScene,
|
||||
x: number,
|
||||
|
@ -46,6 +48,7 @@ export abstract class Character extends Container {
|
|||
companionTexturePromise?: Promise<string>
|
||||
) {
|
||||
super(scene, x, y/*, texture, frame*/);
|
||||
this.scene = scene;
|
||||
this.PlayerValue = name;
|
||||
this.invisible = true
|
||||
|
||||
|
@ -67,6 +70,19 @@ export abstract class Character extends Container {
|
|||
hitAreaCallback: Phaser.Geom.Circle.Contains, //eslint-disable-line @typescript-eslint/unbound-method
|
||||
useHandCursor: true,
|
||||
});
|
||||
|
||||
this.on('pointerover',() => {
|
||||
this.getOutlinePlugin()?.add(this.playerName, {
|
||||
thickness: 2,
|
||||
outlineColor: 0xffff00
|
||||
});
|
||||
this.scene.markDirty();
|
||||
});
|
||||
this.on('pointerout',() => {
|
||||
this.getOutlinePlugin()?.remove(this.playerName);
|
||||
this.scene.markDirty();
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
scene.add.existing(this);
|
||||
|
@ -86,6 +102,10 @@ export abstract class Character extends Container {
|
|||
}
|
||||
}
|
||||
|
||||
private getOutlinePlugin(): OutlinePipelinePlugin|undefined {
|
||||
return this.scene.plugins.get('rexOutlinePipeline') as unknown as OutlinePipelinePlugin|undefined;
|
||||
}
|
||||
|
||||
public addCompanion(name: string, texturePromise?: Promise<string>): void {
|
||||
if (typeof texturePromise !== 'undefined') {
|
||||
this.companion = new Companion(this.scene, this.x, this.y, name, texturePromise);
|
||||
|
|
|
@ -37,6 +37,7 @@ export abstract class DirtyScene extends ResizableScene {
|
|||
|
||||
this.events.on(Events.RENDER, () => {
|
||||
this.objectListChanged = false;
|
||||
this.dirty = false;
|
||||
});
|
||||
|
||||
this.physics.disableUpdate();
|
||||
|
@ -69,6 +70,10 @@ export abstract class DirtyScene extends ResizableScene {
|
|||
return this.dirty || this.objectListChanged;
|
||||
}
|
||||
|
||||
public markDirty(): void {
|
||||
this.events.once(Phaser.Scenes.Events.POST_UPDATE, () => this.dirty = true);
|
||||
}
|
||||
|
||||
public onResize(): void {
|
||||
this.objectListChanged = true;
|
||||
}
|
||||
|
|
|
@ -10,12 +10,7 @@ import {get} from "svelte/store";
|
|||
import {requestedCameraState, requestedMicrophoneState} from "../../Stores/MediaStore";
|
||||
import {helpCameraSettingsVisibleStore} from "../../Stores/HelpCameraSettingsStore";
|
||||
|
||||
export interface HasMovedEvent {
|
||||
direction: string;
|
||||
moving: boolean;
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This class should be responsible for any scene starting/stopping
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import type {ITiledMap, ITiledMapLayer} from "../Map/ITiledMap";
|
||||
import {LayersIterator} from "../Map/LayersIterator";
|
||||
import type {ITiledMap, ITiledMapLayer, ITiledMapLayerProperty} from "../Map/ITiledMap";
|
||||
import { flattenGroupLayersMap } from "../Map/LayersFlattener";
|
||||
import TilemapLayer = Phaser.Tilemaps.TilemapLayer;
|
||||
import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes";
|
||||
|
||||
export type PropertyChangeCallback = (newValue: string | number | boolean | undefined, oldValue: string | number | boolean | undefined, allProps: Map<string, string | boolean | number>) => void;
|
||||
|
||||
|
@ -8,15 +10,43 @@ export type PropertyChangeCallback = (newValue: string | number | boolean | unde
|
|||
* It is used to handle layer properties.
|
||||
*/
|
||||
export class GameMap {
|
||||
private key: number|undefined;
|
||||
private lastProperties = new Map<string, string|boolean|number>();
|
||||
private key: number | undefined;
|
||||
private lastProperties = new Map<string, string | boolean | number>();
|
||||
private callbacks = new Map<string, Array<PropertyChangeCallback>>();
|
||||
public readonly layersIterator: LayersIterator;
|
||||
|
||||
public constructor(private map: ITiledMap) {
|
||||
this.layersIterator = new LayersIterator(map);
|
||||
private tileSetPropertyMap: { [tile_index: number]: Array<ITiledMapLayerProperty> } = {}
|
||||
public readonly flatLayers: ITiledMapLayer[];
|
||||
public readonly phaserLayers: TilemapLayer[] = [];
|
||||
|
||||
public exitUrls: Array<string> = []
|
||||
|
||||
public constructor(private map: ITiledMap, phaserMap: Phaser.Tilemaps.Tilemap, terrains: Array<Phaser.Tilemaps.Tileset>) {
|
||||
this.flatLayers = flattenGroupLayersMap(map);
|
||||
let depth = -2;
|
||||
for (const layer of this.flatLayers) {
|
||||
if(layer.type === 'tilelayer'){
|
||||
this.phaserLayers.push(phaserMap.createLayer(layer.name, terrains, 0, 0).setDepth(depth));
|
||||
}
|
||||
if (layer.type === 'objectgroup' && layer.name === 'floorLayer') {
|
||||
depth = DEPTH_OVERLAY_INDEX;
|
||||
}
|
||||
}
|
||||
for (const tileset of map.tilesets) {
|
||||
tileset?.tiles?.forEach(tile => {
|
||||
if (tile.properties) {
|
||||
this.tileSetPropertyMap[tileset.firstgid + tile.id] = tile.properties
|
||||
tile.properties.forEach(prop => {
|
||||
if (prop.name == "exitUrl" && typeof prop.value == "string") {
|
||||
this.exitUrls.push(prop.value);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sets the position of the current player (in pixels)
|
||||
* This will trigger events if properties are changing.
|
||||
|
@ -51,21 +81,27 @@ export class GameMap {
|
|||
}
|
||||
}
|
||||
|
||||
public getCurrentProperties(): Map<string, string|boolean|number> {
|
||||
public getCurrentProperties(): Map<string, string | boolean | number> {
|
||||
return this.lastProperties;
|
||||
}
|
||||
|
||||
private getProperties(key: number): Map<string, string|boolean|number> {
|
||||
const properties = new Map<string, string|boolean|number>();
|
||||
private getProperties(key: number): Map<string, string | boolean | number> {
|
||||
const properties = new Map<string, string | boolean | number>();
|
||||
|
||||
for (const layer of this.layersIterator) {
|
||||
for (const layer of this.flatLayers) {
|
||||
if (layer.type !== 'tilelayer') {
|
||||
continue;
|
||||
}
|
||||
const tiles = layer.data as number[];
|
||||
if (tiles[key] == 0) {
|
||||
continue;
|
||||
|
||||
let tileIndex: number | undefined = undefined;
|
||||
if (layer.data) {
|
||||
const tiles = layer.data as number[];
|
||||
if (tiles[key] == 0) {
|
||||
continue;
|
||||
}
|
||||
tileIndex = tiles[key]
|
||||
}
|
||||
|
||||
// There is a tile in this layer, let's embed the properties
|
||||
if (layer.properties !== undefined) {
|
||||
for (const layerProperty of layer.properties) {
|
||||
|
@ -75,11 +111,25 @@ export class GameMap {
|
|||
properties.set(layerProperty.name, layerProperty.value);
|
||||
}
|
||||
}
|
||||
|
||||
if (tileIndex) {
|
||||
this.tileSetPropertyMap[tileIndex]?.forEach(property => {
|
||||
if (property.value) {
|
||||
properties.set(property.name, property.value)
|
||||
} else if (properties.has(property.name)) {
|
||||
properties.delete(property.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
public getMap(): ITiledMap{
|
||||
return this.map;
|
||||
}
|
||||
|
||||
private trigger(propName: string, oldValue: string | number | boolean | undefined, newValue: string | number | boolean | undefined, allProps: Map<string, string | boolean | number>) {
|
||||
const callbacksArray = this.callbacks.get(propName);
|
||||
if (callbacksArray !== undefined) {
|
||||
|
@ -100,4 +150,19 @@ export class GameMap {
|
|||
}
|
||||
callbacksArray.push(callback);
|
||||
}
|
||||
|
||||
public findLayer(layerName: string): ITiledMapLayer | undefined {
|
||||
return this.flatLayers.find((layer) => layer.name === layerName);
|
||||
}
|
||||
|
||||
public findPhaserLayer(layerName: string): TilemapLayer | undefined {
|
||||
return this.phaserLayers.find((layer) => layer.layer.name === layerName);
|
||||
}
|
||||
|
||||
public addTerrain(terrain : Phaser.Tilemaps.Tileset): void {
|
||||
for (const phaserLayer of this.phaserLayers) {
|
||||
phaserLayer.tileset.push(terrain);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,9 +1,9 @@
|
|||
import type {HasMovedEvent} from "./GameManager";
|
||||
import {MAX_EXTRAPOLATION_TIME} from "../../Enum/EnvironmentVariable";
|
||||
import type {PositionInterface} from "../../Connexion/ConnexionModels";
|
||||
import { MAX_EXTRAPOLATION_TIME } from "../../Enum/EnvironmentVariable";
|
||||
import type { PositionInterface } from "../../Connexion/ConnexionModels";
|
||||
import type { HasPlayerMovedEvent } from '../../Api/Events/HasPlayerMovedEvent';
|
||||
|
||||
export class PlayerMovement {
|
||||
public constructor(private startPosition: PositionInterface, private startTick: number, private endPosition: HasMovedEvent, private endTick: number) {
|
||||
public constructor(private startPosition: PositionInterface, private startTick: number, private endPosition: HasPlayerMovedEvent, private endTick: number) {
|
||||
}
|
||||
|
||||
public isOutdated(tick: number): boolean {
|
||||
|
@ -17,7 +17,7 @@ export class PlayerMovement {
|
|||
return tick > this.endTick + MAX_EXTRAPOLATION_TIME;
|
||||
}
|
||||
|
||||
public getPosition(tick: number): HasMovedEvent {
|
||||
public getPosition(tick: number): HasPlayerMovedEvent {
|
||||
// Special case: end position reached and end position is not moving
|
||||
if (tick >= this.endTick && this.endPosition.moving === false) {
|
||||
//console.log('Movement finished ', this.endPosition)
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
* This class is in charge of computing the position of all players.
|
||||
* Player movement is delayed by 200ms so position depends on ticks.
|
||||
*/
|
||||
import type {PlayerMovement} from "./PlayerMovement";
|
||||
import type {HasMovedEvent} from "./GameManager";
|
||||
import type { HasPlayerMovedEvent } from '../../Api/Events/HasPlayerMovedEvent';
|
||||
import type { PlayerMovement } from "./PlayerMovement";
|
||||
|
||||
export class PlayersPositionInterpolator {
|
||||
playerMovements: Map<number, PlayerMovement> = new Map<number, PlayerMovement>();
|
||||
|
||||
updatePlayerPosition(userId: number, playerMovement: PlayerMovement) : void {
|
||||
updatePlayerPosition(userId: number, playerMovement: PlayerMovement): void {
|
||||
this.playerMovements.set(userId, playerMovement);
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,8 @@ export class PlayersPositionInterpolator {
|
|||
this.playerMovements.delete(userId);
|
||||
}
|
||||
|
||||
getUpdatedPositions(tick: number) : Map<number, HasMovedEvent> {
|
||||
const positions = new Map<number, HasMovedEvent>();
|
||||
getUpdatedPositions(tick: number): Map<number, HasPlayerMovedEvent> {
|
||||
const positions = new Map<number, HasPlayerMovedEvent>();
|
||||
this.playerMovements.forEach((playerMovement: PlayerMovement, userId: number) => {
|
||||
if (playerMovement.isOutdated(tick)) {
|
||||
//console.log("outdated")
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* It has coordinates and an "activation radius"
|
||||
*/
|
||||
import Sprite = Phaser.GameObjects.Sprite;
|
||||
import {OutlinePipeline} from "../Shaders/OutlinePipeline";
|
||||
import type {GameScene} from "../Game/GameScene";
|
||||
import type OutlinePipelinePlugin from "phaser3-rex-plugins/plugins/outlinepipeline-plugin.js";
|
||||
|
||||
type EventCallback = (state: unknown, parameters: unknown) => void;
|
||||
|
||||
|
@ -42,11 +42,11 @@ export class ActionableItem {
|
|||
return;
|
||||
}
|
||||
this.isSelectable = true;
|
||||
if (this.sprite.pipeline) {
|
||||
// Commented out to try to fix MacOS issue
|
||||
/*this.sprite.setPipeline(OutlinePipeline.KEY);
|
||||
this.sprite.pipeline.set2f('uTextureSize', this.sprite.texture.getSourceImage().width, this.sprite.texture.getSourceImage().height);*/
|
||||
}
|
||||
|
||||
this.getOutlinePlugin()?.add(this.sprite, {
|
||||
thickness: 2,
|
||||
outlineColor: 0xffff00
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,8 +57,11 @@ export class ActionableItem {
|
|||
return;
|
||||
}
|
||||
this.isSelectable = false;
|
||||
// Commented out to try to fix MacOS issue
|
||||
//this.sprite.resetPipeline();
|
||||
this.getOutlinePlugin()?.remove(this.sprite);
|
||||
}
|
||||
|
||||
private getOutlinePlugin(): OutlinePipelinePlugin|undefined {
|
||||
return this.sprite.scene.plugins.get('rexOutlinePipeline') as unknown as OutlinePipelinePlugin|undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* Represents the interface for the Tiled exported data structure (JSON). Used
|
||||
* when loading resources via Resource loader.
|
||||
*/
|
||||
import TilemapLayer = Phaser.Tilemaps.TilemapLayer;
|
||||
|
||||
export interface ITiledMap {
|
||||
width: number;
|
||||
height: number;
|
||||
|
@ -81,6 +83,7 @@ export interface ITiledMapTileLayer {
|
|||
* Draw order (topdown (default), index)
|
||||
*/
|
||||
draworder?: string;
|
||||
phaserLayer?: TilemapLayer;
|
||||
}
|
||||
|
||||
export interface ITiledMapObjectLayer {
|
||||
|
@ -167,7 +170,7 @@ export interface ITiledTileSet {
|
|||
tilewidth: number;
|
||||
transparentcolor: string;
|
||||
terrains: ITiledMapTerrain[];
|
||||
tiles: {[key: string]: { terrain: number[] }};
|
||||
tiles?: Array<ITile>;
|
||||
|
||||
/**
|
||||
* Refers to external tileset file (should be JSON)
|
||||
|
@ -175,6 +178,13 @@ export interface ITiledTileSet {
|
|||
source: string;
|
||||
}
|
||||
|
||||
export interface ITile {
|
||||
id: number,
|
||||
type?: string
|
||||
|
||||
properties?: Array<ITiledMapLayerProperty>
|
||||
}
|
||||
|
||||
export interface ITiledMapTerrain {
|
||||
name: string;
|
||||
tile: number;
|
||||
|
|
21
front/src/Phaser/Map/LayersFlattener.ts
Normal file
21
front/src/Phaser/Map/LayersFlattener.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import type {ITiledMap, ITiledMapLayer} from "./ITiledMap";
|
||||
|
||||
/**
|
||||
* Flatten the grouped layers
|
||||
*/
|
||||
export function flattenGroupLayersMap(map: ITiledMap) {
|
||||
const flatLayers: ITiledMapLayer[] = [];
|
||||
flattenGroupLayers(map.layers, '', flatLayers);
|
||||
return flatLayers;
|
||||
}
|
||||
|
||||
function flattenGroupLayers(layers : ITiledMapLayer[], prefix : string, flatLayers: ITiledMapLayer[]) {
|
||||
for (const layer of layers) {
|
||||
if (layer.type === 'group') {
|
||||
flattenGroupLayers(layer.layers, prefix + layer.name + '/', flatLayers);
|
||||
} else {
|
||||
layer.name = prefix+layer.name
|
||||
flatLayers.push(layer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
import type {ITiledMap, ITiledMapLayer} from "./ITiledMap";
|
||||
|
||||
/**
|
||||
* Iterates over the layers of a map, flattening the grouped layers
|
||||
*/
|
||||
export class LayersIterator implements IterableIterator<ITiledMapLayer> {
|
||||
|
||||
private layers: ITiledMapLayer[] = [];
|
||||
private pointer: number = 0;
|
||||
|
||||
constructor(private map: ITiledMap) {
|
||||
this.initLayersList(map.layers, '');
|
||||
}
|
||||
|
||||
private initLayersList(layers : ITiledMapLayer[], prefix : string) {
|
||||
for (const layer of layers) {
|
||||
if (layer.type === 'group') {
|
||||
this.initLayersList(layer.layers, prefix + layer.name + '/');
|
||||
} else {
|
||||
const layerWithNewName = { ...layer };
|
||||
layerWithNewName.name = prefix+layerWithNewName.name;
|
||||
this.layers.push(layerWithNewName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public next(): IteratorResult<ITiledMapLayer> {
|
||||
if (this.pointer < this.layers.length) {
|
||||
return {
|
||||
done: false,
|
||||
value: this.layers[this.pointer++]
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
done: true,
|
||||
value: null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Symbol.iterator](): IterableIterator<ITiledMapLayer> {
|
||||
return new LayersIterator(this.map);
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ import {SelectCharacterScene, SelectCharacterSceneName} from "../Login/SelectCha
|
|||
import {SelectCompanionScene, SelectCompanionSceneName} from "../Login/SelectCompanionScene";
|
||||
import {gameManager} from "../Game/GameManager";
|
||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||
import {mediaManager} from "../../WebRtc/MediaManager";
|
||||
import {gameReportKey, gameReportRessource, ReportMenu} from "./ReportMenu";
|
||||
import {connectionManager} from "../../Connexion/ConnectionManager";
|
||||
import {GameConnexionTypes} from "../../Url/UrlManager";
|
||||
|
@ -12,6 +11,13 @@ import {worldFullWarningStream} from "../../Connexion/WorldFullWarningStream";
|
|||
import {menuIconVisible} from "../../Stores/MenuStore";
|
||||
import {videoConstraintStore} from "../../Stores/MediaStore";
|
||||
import {showReportScreenStore} from "../../Stores/ShowReportScreenStore";
|
||||
import { HtmlUtils } from '../../WebRtc/HtmlUtils';
|
||||
import { iframeListener } from '../../Api/IframeListener';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {registerMenuCommandStream} from "../../Api/Events/ui/MenuItemRegisterEvent";
|
||||
import {sendMenuClickedEvent} from "../../Api/iframe/Ui/MenuItem";
|
||||
import {consoleGlobalMessageManagerVisibleStore} from "../../Stores/ConsoleGlobalMessageManagerStore";
|
||||
import {get} from "svelte/store";
|
||||
|
||||
export const MenuSceneName = 'MenuScene';
|
||||
const gameMenuKey = 'gameMenu';
|
||||
|
@ -38,15 +44,41 @@ export class MenuScene extends Phaser.Scene {
|
|||
private menuButton!: Phaser.GameObjects.DOMElement;
|
||||
private warningContainer: WarningContainer | null = null;
|
||||
private warningContainerTimeout: NodeJS.Timeout | null = null;
|
||||
|
||||
private subscriptions = new Subscription()
|
||||
constructor() {
|
||||
super({key: MenuSceneName});
|
||||
super({ key: MenuSceneName });
|
||||
|
||||
this.gameQualityValue = localUserStore.getGameQualityValue();
|
||||
this.videoQualityValue = localUserStore.getVideoQualityValue();
|
||||
|
||||
this.subscriptions.add(registerMenuCommandStream.subscribe(menuCommand => {
|
||||
this.addMenuOption(menuCommand);
|
||||
}))
|
||||
|
||||
this.subscriptions.add(iframeListener.unregisterMenuCommandStream.subscribe(menuCommand => {
|
||||
this.destroyMenu(menuCommand);
|
||||
}))
|
||||
}
|
||||
|
||||
preload () {
|
||||
reset() {
|
||||
const addedMenuItems = [...this.menuElement.node.querySelectorAll(".fromApi")];
|
||||
for (let index = addedMenuItems.length - 1; index >= 0; index--) {
|
||||
addedMenuItems[index].remove()
|
||||
}
|
||||
}
|
||||
|
||||
public addMenuOption(menuText: string) {
|
||||
const wrappingSection = document.createElement("section")
|
||||
const escapedHtml = HtmlUtils.escapeHtml(menuText);
|
||||
wrappingSection.innerHTML = `<button class="fromApi" id="${escapedHtml}">${escapedHtml}</button>`
|
||||
const menuItemContainer = this.menuElement.node.querySelector("#gameMenu main");
|
||||
if (menuItemContainer) {
|
||||
menuItemContainer.querySelector(`#${escapedHtml}.fromApi`)?.remove()
|
||||
menuItemContainer.insertBefore(wrappingSection, menuItemContainer.querySelector("#socialLinks"))
|
||||
}
|
||||
}
|
||||
|
||||
preload() {
|
||||
this.load.html(gameMenuKey, 'resources/html/gameMenu.html');
|
||||
this.load.html(gameMenuIconKey, 'resources/html/gameMenuIcon.html');
|
||||
this.load.html(gameSettingsMenuKey, 'resources/html/gameQualityMenu.html');
|
||||
|
@ -69,11 +101,11 @@ export class MenuScene extends Phaser.Scene {
|
|||
this.gameShareElement = this.add.dom(middleX, -400).createFromCache(gameShare);
|
||||
MenuScene.revealMenusAfterInit(this.gameShareElement, gameShare);
|
||||
this.gameShareElement.addListener('click');
|
||||
this.gameShareElement.on('click', (event:MouseEvent) => {
|
||||
this.gameShareElement.on('click', (event: MouseEvent) => {
|
||||
event.preventDefault();
|
||||
if((event?.target as HTMLInputElement).id === 'gameShareFormSubmit') {
|
||||
if ((event?.target as HTMLInputElement).id === 'gameShareFormSubmit') {
|
||||
this.copyLink();
|
||||
}else if((event?.target as HTMLInputElement).id === 'gameShareFormCancel') {
|
||||
} else if ((event?.target as HTMLInputElement).id === 'gameShareFormCancel') {
|
||||
this.closeGameShare();
|
||||
}
|
||||
});
|
||||
|
@ -131,8 +163,8 @@ export class MenuScene extends Phaser.Scene {
|
|||
}
|
||||
//TODO bind with future metadata of card
|
||||
//if (connectionManager.getConnexionType === GameConnexionTypes.anonymous){
|
||||
const adminSection = this.menuElement.getChildByID('socialLinks') as HTMLElement;
|
||||
adminSection.hidden = false;
|
||||
const adminSection = this.menuElement.getChildByID('socialLinks') as HTMLElement;
|
||||
adminSection.hidden = false;
|
||||
//}
|
||||
this.tweens.add({
|
||||
targets: this.menuElement,
|
||||
|
@ -162,7 +194,7 @@ export class MenuScene extends Phaser.Scene {
|
|||
this.sideMenuOpened = false;
|
||||
this.closeAll();
|
||||
this.menuButton.getChildByID('openMenuButton').innerHTML = `<img src="/static/images/menu.svg">`;
|
||||
gameManager.getCurrentGameScene(this).ConsoleGlobalMessageManager.disabledMessageConsole();
|
||||
consoleGlobalMessageManagerVisibleStore.set(false);
|
||||
this.tweens.add({
|
||||
targets: this.menuElement,
|
||||
x: closedSideMenuX,
|
||||
|
@ -182,28 +214,28 @@ export class MenuScene extends Phaser.Scene {
|
|||
this.settingsMenuOpened = true;
|
||||
|
||||
const gameQualitySelect = this.gameQualityMenuElement.getChildByID('select-game-quality') as HTMLInputElement;
|
||||
gameQualitySelect.value = ''+this.gameQualityValue;
|
||||
gameQualitySelect.value = '' + this.gameQualityValue;
|
||||
const videoQualitySelect = this.gameQualityMenuElement.getChildByID('select-video-quality') as HTMLInputElement;
|
||||
videoQualitySelect.value = ''+this.videoQualityValue;
|
||||
videoQualitySelect.value = '' + this.videoQualityValue;
|
||||
|
||||
this.gameQualityMenuElement.addListener('click');
|
||||
this.gameQualityMenuElement.on('click', (event:MouseEvent) => {
|
||||
this.gameQualityMenuElement.on('click', (event: MouseEvent) => {
|
||||
event.preventDefault();
|
||||
if ((event?.target as HTMLInputElement).id === 'gameQualityFormSubmit') {
|
||||
const gameQualitySelect = this.gameQualityMenuElement.getChildByID('select-game-quality') as HTMLInputElement;
|
||||
const videoQualitySelect = this.gameQualityMenuElement.getChildByID('select-video-quality') as HTMLInputElement;
|
||||
this.saveSetting(parseInt(gameQualitySelect.value), parseInt(videoQualitySelect.value));
|
||||
} else if((event?.target as HTMLInputElement).id === 'gameQualityFormCancel') {
|
||||
} else if ((event?.target as HTMLInputElement).id === 'gameQualityFormCancel') {
|
||||
this.closeGameQualityMenu();
|
||||
}
|
||||
});
|
||||
|
||||
let middleY = this.scale.height / 2 - 392/2;
|
||||
if(middleY < 0){
|
||||
let middleY = this.scale.height / 2 - 392 / 2;
|
||||
if (middleY < 0) {
|
||||
middleY = 0;
|
||||
}
|
||||
let middleX = this.scale.width / 2 - 457/2;
|
||||
if(middleX < 0){
|
||||
let middleX = this.scale.width / 2 - 457 / 2;
|
||||
if (middleX < 0) {
|
||||
middleX = 0;
|
||||
}
|
||||
this.tweens.add({
|
||||
|
@ -229,7 +261,7 @@ export class MenuScene extends Phaser.Scene {
|
|||
}
|
||||
|
||||
|
||||
private openGameShare(): void{
|
||||
private openGameShare(): void {
|
||||
if (this.gameShareOpened) {
|
||||
this.closeGameShare();
|
||||
return;
|
||||
|
@ -243,11 +275,11 @@ export class MenuScene extends Phaser.Scene {
|
|||
this.gameShareOpened = true;
|
||||
|
||||
let middleY = this.scale.height / 2 - 85;
|
||||
if(middleY < 0){
|
||||
if (middleY < 0) {
|
||||
middleY = 0;
|
||||
}
|
||||
let middleX = this.scale.width / 2 - 200;
|
||||
if(middleX < 0){
|
||||
if (middleX < 0) {
|
||||
middleX = 0;
|
||||
}
|
||||
this.tweens.add({
|
||||
|
@ -259,7 +291,7 @@ export class MenuScene extends Phaser.Scene {
|
|||
});
|
||||
}
|
||||
|
||||
private closeGameShare(): void{
|
||||
private closeGameShare(): void {
|
||||
const gameShareInfo = this.gameShareElement.getChildByID('gameShareInfo') as HTMLParagraphElement;
|
||||
gameShareInfo.innerText = '';
|
||||
gameShareInfo.style.display = 'none';
|
||||
|
@ -272,12 +304,18 @@ export class MenuScene extends Phaser.Scene {
|
|||
});
|
||||
}
|
||||
|
||||
private onMenuClick(event:MouseEvent) {
|
||||
if((event?.target as HTMLInputElement).classList.contains('not-button')){
|
||||
private onMenuClick(event: MouseEvent) {
|
||||
const htmlMenuItem = (event?.target as HTMLInputElement);
|
||||
if (htmlMenuItem.classList.contains('not-button')) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
if (htmlMenuItem.classList.contains("fromApi")) {
|
||||
sendMenuClickedEvent(htmlMenuItem.id)
|
||||
return
|
||||
}
|
||||
|
||||
switch ((event?.target as HTMLInputElement).id) {
|
||||
case 'changeNameButton':
|
||||
this.closeSideMenu();
|
||||
|
@ -307,7 +345,11 @@ export class MenuScene extends Phaser.Scene {
|
|||
this.toggleFullscreen();
|
||||
break;
|
||||
case 'adminConsoleButton':
|
||||
gameManager.getCurrentGameScene(this).ConsoleGlobalMessageManager.activeMessageConsole();
|
||||
if (get(consoleGlobalMessageManagerVisibleStore)) {
|
||||
consoleGlobalMessageManagerVisibleStore.set(false);
|
||||
} else {
|
||||
consoleGlobalMessageManagerVisibleStore.set(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -319,7 +361,7 @@ export class MenuScene extends Phaser.Scene {
|
|||
gameShareInfo.style.display = 'block';
|
||||
}
|
||||
|
||||
private saveSetting(valueGame: number, valueVideo: number){
|
||||
private saveSetting(valueGame: number, valueVideo: number) {
|
||||
if (valueGame !== this.gameQualityValue) {
|
||||
this.gameQualityValue = valueGame;
|
||||
localUserStore.setGameQualityValue(valueGame);
|
||||
|
@ -340,7 +382,7 @@ export class MenuScene extends Phaser.Scene {
|
|||
window.open(sparkHost, '_blank');
|
||||
}
|
||||
|
||||
private closeAll(){
|
||||
private closeAll() {
|
||||
this.closeGameQualityMenu();
|
||||
this.closeGameShare();
|
||||
this.gameReportElement.close();
|
||||
|
@ -357,6 +399,10 @@ export class MenuScene extends Phaser.Scene {
|
|||
}
|
||||
}
|
||||
|
||||
public destroyMenu(menu: string) {
|
||||
this.menuElement.getChildByID(menu).remove();
|
||||
}
|
||||
|
||||
public isDirty(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
export class OutlinePipeline extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline {
|
||||
|
||||
// the unique id of this pipeline
|
||||
public static readonly KEY = 'Outline';
|
||||
|
||||
/**
|
||||
* @param {Phaser.Game} game - the controller of the game instance
|
||||
*/
|
||||
constructor(game: Phaser.Game)
|
||||
{
|
||||
super({
|
||||
game: game,
|
||||
fragShader: `
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D uMainSampler;
|
||||
uniform vec2 uTextureSize;
|
||||
|
||||
varying vec2 outTexCoord;
|
||||
varying float outTintEffect;
|
||||
varying vec4 outTint;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 texture = texture2D(uMainSampler, outTexCoord);
|
||||
vec4 texel = vec4(outTint.rgb * outTint.a, outTint.a);
|
||||
vec4 color = texture;
|
||||
|
||||
if (outTintEffect == 0.0)
|
||||
{
|
||||
color = texture * texel;
|
||||
}
|
||||
else if (outTintEffect == 1.0)
|
||||
{
|
||||
color.rgb = mix(texture.rgb, outTint.rgb * outTint.a, texture.a);
|
||||
color.a = texture.a * texel.a;
|
||||
}
|
||||
else if (outTintEffect == 2.0)
|
||||
{
|
||||
color = texel;
|
||||
}
|
||||
|
||||
vec2 onePixel = vec2(1.0, 1.0) / uTextureSize;
|
||||
float upAlpha = texture2D(uMainSampler, outTexCoord + vec2(0.0, onePixel.y)).a;
|
||||
float leftAlpha = texture2D(uMainSampler, outTexCoord + vec2(-onePixel.x, 0.0)).a;
|
||||
float downAlpha = texture2D(uMainSampler, outTexCoord + vec2(0.0, -onePixel.y)).a;
|
||||
float rightAlpha = texture2D(uMainSampler, outTexCoord + vec2(onePixel.x, 0.0)).a;
|
||||
|
||||
if (texture.a == 0.0 && max(max(upAlpha, downAlpha), max(leftAlpha, rightAlpha)) == 1.0)
|
||||
{
|
||||
color = vec4(1.0, 1.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
`
|
||||
});
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import type { Direction } from "../../types";
|
|||
import type {GameScene} from "../Game/GameScene";
|
||||
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
||||
import {MobileJoystick} from "../Components/MobileJoystick";
|
||||
import {enableUserInputsStore} from "../../Stores/UserInputStore";
|
||||
|
||||
interface UserInputManagerDatum {
|
||||
keyInstance: Phaser.Input.Keyboard.Key;
|
||||
|
@ -58,6 +59,10 @@ export class UserInputManager {
|
|||
if (touchScreenManager.supportTouchScreen) {
|
||||
this.initVirtualJoystick();
|
||||
}
|
||||
|
||||
enableUserInputsStore.subscribe((enable) => {
|
||||
enable ? this.restoreControls() : this.disableControls()
|
||||
})
|
||||
}
|
||||
|
||||
initVirtualJoystick() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue