Merge branch 'develop' of github.com:thecodingmachine/workadventure into twemojiEmoteMenu
This commit is contained in:
commit
83bd19c8dc
163 changed files with 5252 additions and 3394 deletions
|
@ -1,7 +1,7 @@
|
|||
import {discussionManager} from "../../WebRtc/DiscussionManager";
|
||||
import {DEPTH_INGAME_TEXT_INDEX} from "../Game/DepthIndexes";
|
||||
import { DEPTH_INGAME_TEXT_INDEX } from "../Game/DepthIndexes";
|
||||
import { chatVisibilityStore } from "../../Stores/ChatStore";
|
||||
|
||||
export const openChatIconName = 'openChatIcon';
|
||||
export const openChatIconName = "openChatIcon";
|
||||
export class OpenChatIcon extends Phaser.GameObjects.Image {
|
||||
constructor(scene: Phaser.Scene, x: number, y: number) {
|
||||
super(scene, x, y, openChatIconName, 3);
|
||||
|
@ -9,9 +9,9 @@ export class OpenChatIcon extends Phaser.GameObjects.Image {
|
|||
this.setScrollFactor(0, 0);
|
||||
this.setOrigin(0, 1);
|
||||
this.setInteractive();
|
||||
this.setVisible(false);
|
||||
//this.setVisible(false);
|
||||
this.setDepth(DEPTH_INGAME_TEXT_INDEX);
|
||||
|
||||
this.on("pointerup", () => discussionManager.showDiscussionPart());
|
||||
this.on("pointerup", () => chatVisibilityStore.set(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ export class TextUtils {
|
|||
options.align = object.text.halign;
|
||||
}
|
||||
|
||||
console.warn(options);
|
||||
const textElem = scene.add.text(object.x, object.y, object.text.text, options);
|
||||
textElem.setAngle(object.rotation);
|
||||
}
|
||||
|
|
|
@ -1,90 +1,123 @@
|
|||
import LoaderPlugin = Phaser.Loader.LoaderPlugin;
|
||||
import type {CharacterTexture} from "../../Connexion/LocalUser";
|
||||
import {BodyResourceDescriptionInterface, LAYERS, PLAYER_RESOURCES} from "./PlayerTextures";
|
||||
import type { CharacterTexture } from "../../Connexion/LocalUser";
|
||||
import { BodyResourceDescriptionInterface, LAYERS, PLAYER_RESOURCES } from "./PlayerTextures";
|
||||
|
||||
export interface FrameConfig {
|
||||
frameWidth: number,
|
||||
frameHeight: number,
|
||||
frameWidth: number;
|
||||
frameHeight: number;
|
||||
}
|
||||
|
||||
export const loadAllLayers = (load: LoaderPlugin): BodyResourceDescriptionInterface[][] => {
|
||||
const returnArray:BodyResourceDescriptionInterface[][] = [];
|
||||
LAYERS.forEach(layer => {
|
||||
const layerArray:BodyResourceDescriptionInterface[] = [];
|
||||
const returnArray: BodyResourceDescriptionInterface[][] = [];
|
||||
LAYERS.forEach((layer) => {
|
||||
const layerArray: BodyResourceDescriptionInterface[] = [];
|
||||
Object.values(layer).forEach((textureDescriptor) => {
|
||||
layerArray.push(textureDescriptor);
|
||||
load.spritesheet(textureDescriptor.name,textureDescriptor.img,{frameWidth: 32, frameHeight: 32});
|
||||
})
|
||||
returnArray.push(layerArray)
|
||||
load.spritesheet(textureDescriptor.name, textureDescriptor.img, { frameWidth: 32, frameHeight: 32 });
|
||||
});
|
||||
returnArray.push(layerArray);
|
||||
});
|
||||
return returnArray;
|
||||
}
|
||||
};
|
||||
export const loadAllDefaultModels = (load: LoaderPlugin): BodyResourceDescriptionInterface[] => {
|
||||
const returnArray = Object.values(PLAYER_RESOURCES);
|
||||
returnArray.forEach((playerResource: BodyResourceDescriptionInterface) => {
|
||||
load.spritesheet(playerResource.name, playerResource.img, {frameWidth: 32, frameHeight: 32});
|
||||
load.spritesheet(playerResource.name, playerResource.img, { frameWidth: 32, frameHeight: 32 });
|
||||
});
|
||||
return returnArray;
|
||||
}
|
||||
};
|
||||
|
||||
export const loadCustomTexture = (loaderPlugin: LoaderPlugin, texture: CharacterTexture) : Promise<BodyResourceDescriptionInterface> => {
|
||||
const name = 'customCharacterTexture'+texture.id;
|
||||
const playerResourceDescriptor: BodyResourceDescriptionInterface = {name, img: texture.url, level: texture.level}
|
||||
export const loadCustomTexture = (
|
||||
loaderPlugin: LoaderPlugin,
|
||||
texture: CharacterTexture
|
||||
): Promise<BodyResourceDescriptionInterface> => {
|
||||
const name = "customCharacterTexture" + texture.id;
|
||||
const playerResourceDescriptor: BodyResourceDescriptionInterface = { name, img: texture.url, level: texture.level };
|
||||
return createLoadingPromise(loaderPlugin, playerResourceDescriptor, {
|
||||
frameWidth: 32,
|
||||
frameHeight: 32
|
||||
frameHeight: 32,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, texturekeys:Array<string|BodyResourceDescriptionInterface>): Promise<string[]> => {
|
||||
const promisesList:Promise<unknown>[] = [];
|
||||
texturekeys.forEach((textureKey: string|BodyResourceDescriptionInterface) => {
|
||||
export const lazyLoadPlayerCharacterTextures = (
|
||||
loadPlugin: LoaderPlugin,
|
||||
texturekeys: Array<string | BodyResourceDescriptionInterface>
|
||||
): Promise<string[]> => {
|
||||
const promisesList: Promise<unknown>[] = [];
|
||||
texturekeys.forEach((textureKey: string | BodyResourceDescriptionInterface) => {
|
||||
try {
|
||||
//TODO refactor
|
||||
const playerResourceDescriptor = getRessourceDescriptor(textureKey);
|
||||
if (playerResourceDescriptor && !loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
|
||||
promisesList.push(createLoadingPromise(loadPlugin, playerResourceDescriptor, {
|
||||
frameWidth: 32,
|
||||
frameHeight: 32
|
||||
}));
|
||||
promisesList.push(
|
||||
createLoadingPromise(loadPlugin, playerResourceDescriptor, {
|
||||
frameWidth: 32,
|
||||
frameHeight: 32,
|
||||
})
|
||||
);
|
||||
}
|
||||
}catch (err){
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
let returnPromise:Promise<Array<string|BodyResourceDescriptionInterface>>;
|
||||
let returnPromise: Promise<Array<string | BodyResourceDescriptionInterface>>;
|
||||
if (promisesList.length > 0) {
|
||||
loadPlugin.start();
|
||||
returnPromise = Promise.all(promisesList).then(() => texturekeys);
|
||||
} else {
|
||||
returnPromise = Promise.resolve(texturekeys);
|
||||
}
|
||||
return returnPromise.then((keys) => keys.map((key) => {
|
||||
return typeof key !== 'string' ? key.name : key;
|
||||
}))
|
||||
}
|
||||
|
||||
export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptionInterface): BodyResourceDescriptionInterface => {
|
||||
if (typeof textureKey !== 'string' && textureKey.img) {
|
||||
//If the loading fail, we render the default model instead.
|
||||
return returnPromise
|
||||
.then((keys) =>
|
||||
keys.map((key) => {
|
||||
return typeof key !== "string" ? key.name : key;
|
||||
})
|
||||
)
|
||||
.catch(() => lazyLoadPlayerCharacterTextures(loadPlugin, ["color_22", "eyes_23"]));
|
||||
};
|
||||
|
||||
export const getRessourceDescriptor = (
|
||||
textureKey: string | BodyResourceDescriptionInterface
|
||||
): BodyResourceDescriptionInterface => {
|
||||
if (typeof textureKey !== "string" && textureKey.img) {
|
||||
return textureKey;
|
||||
}
|
||||
const textureName:string = typeof textureKey === 'string' ? textureKey : textureKey.name;
|
||||
const textureName: string = typeof textureKey === "string" ? textureKey : textureKey.name;
|
||||
const playerResource = PLAYER_RESOURCES[textureName];
|
||||
if (playerResource !== undefined) return playerResource;
|
||||
|
||||
for (let i=0; i<LAYERS.length;i++) {
|
||||
for (let i = 0; i < LAYERS.length; i++) {
|
||||
const playerResource = LAYERS[i][textureName];
|
||||
if (playerResource !== undefined) return playerResource;
|
||||
}
|
||||
throw 'Could not find a data for texture '+textureName;
|
||||
}
|
||||
throw "Could not find a data for texture " + textureName;
|
||||
};
|
||||
|
||||
export const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor: BodyResourceDescriptionInterface, frameConfig: FrameConfig) => {
|
||||
return new Promise<BodyResourceDescriptionInterface>((res) => {
|
||||
export const createLoadingPromise = (
|
||||
loadPlugin: LoaderPlugin,
|
||||
playerResourceDescriptor: BodyResourceDescriptionInterface,
|
||||
frameConfig: FrameConfig
|
||||
) => {
|
||||
return new Promise<BodyResourceDescriptionInterface>((res, rej) => {
|
||||
if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
|
||||
return res(playerResourceDescriptor);
|
||||
}
|
||||
loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, frameConfig);
|
||||
loadPlugin.once('filecomplete-spritesheet-' + playerResourceDescriptor.name, () => res(playerResourceDescriptor));
|
||||
const errorCallback = (file: { src: string }) => {
|
||||
if (file.src !== playerResourceDescriptor.img) return;
|
||||
console.error("failed loading player ressource: ", playerResourceDescriptor);
|
||||
rej(playerResourceDescriptor);
|
||||
loadPlugin.off("filecomplete-spritesheet-" + playerResourceDescriptor.name, successCallback);
|
||||
loadPlugin.off("loaderror", errorCallback);
|
||||
};
|
||||
const successCallback = () => {
|
||||
loadPlugin.off("loaderror", errorCallback);
|
||||
res(playerResourceDescriptor);
|
||||
};
|
||||
|
||||
loadPlugin.once("filecomplete-spritesheet-" + playerResourceDescriptor.name, successCallback);
|
||||
loadPlugin.on("loaderror", errorCallback);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
import type {PointInterface} from "../../Connexion/ConnexionModels";
|
||||
import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||
import type {PlayerInterface} from "./PlayerInterface";
|
||||
|
||||
export interface AddPlayerInterface {
|
||||
userId: number;
|
||||
name: string;
|
||||
characterLayers: BodyResourceDescriptionInterface[];
|
||||
export interface AddPlayerInterface extends PlayerInterface {
|
||||
position: PointInterface;
|
||||
visitCardUrl: string|null;
|
||||
companion: string|null;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import {ResizableScene} from "../Login/ResizableScene";
|
||||
import { ResizableScene } from "../Login/ResizableScene";
|
||||
import GameObject = Phaser.GameObjects.GameObject;
|
||||
import Events = Phaser.Scenes.Events;
|
||||
import AnimationEvents = Phaser.Animations.Events;
|
||||
import StructEvents = Phaser.Structs.Events;
|
||||
import {SKIP_RENDER_OPTIMIZATIONS} from "../../Enum/EnvironmentVariable";
|
||||
import { SKIP_RENDER_OPTIMIZATIONS } from "../../Enum/EnvironmentVariable";
|
||||
|
||||
/**
|
||||
* A scene that can track its dirty/pristine state.
|
||||
*/
|
||||
export abstract class DirtyScene extends ResizableScene {
|
||||
private isAlreadyTracking: boolean = false;
|
||||
protected dirty:boolean = true;
|
||||
private objectListChanged:boolean = true;
|
||||
protected dirty: boolean = true;
|
||||
private objectListChanged: boolean = true;
|
||||
private physicsEnabled: boolean = false;
|
||||
|
||||
/**
|
||||
|
@ -59,7 +59,6 @@ export abstract class DirtyScene extends ResizableScene {
|
|||
this.physicsEnabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private trackAnimation(): void {
|
||||
|
@ -71,7 +70,7 @@ export abstract class DirtyScene extends ResizableScene {
|
|||
}
|
||||
|
||||
public markDirty(): void {
|
||||
this.events.once(Phaser.Scenes.Events.POST_UPDATE, () => this.dirty = true);
|
||||
this.events.once(Phaser.Scenes.Events.POST_UPDATE, () => (this.dirty = true));
|
||||
}
|
||||
|
||||
public onResize(): void {
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
import {GameScene} from "./GameScene";
|
||||
import {connectionManager} from "../../Connexion/ConnectionManager";
|
||||
import type {Room} from "../../Connexion/Room";
|
||||
import {MenuScene, MenuSceneName} from "../Menu/MenuScene";
|
||||
import {LoginSceneName} from "../Login/LoginScene";
|
||||
import {SelectCharacterSceneName} from "../Login/SelectCharacterScene";
|
||||
import {EnableCameraSceneName} from "../Login/EnableCameraScene";
|
||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||
import {get} from "svelte/store";
|
||||
import {requestedCameraState, requestedMicrophoneState} from "../../Stores/MediaStore";
|
||||
import {helpCameraSettingsVisibleStore} from "../../Stores/HelpCameraSettingsStore";
|
||||
|
||||
|
||||
import { GameScene } from "./GameScene";
|
||||
import { connectionManager } from "../../Connexion/ConnectionManager";
|
||||
import type { Room } from "../../Connexion/Room";
|
||||
import { MenuScene, MenuSceneName } from "../Menu/MenuScene";
|
||||
import { LoginSceneName } from "../Login/LoginScene";
|
||||
import { SelectCharacterSceneName } from "../Login/SelectCharacterScene";
|
||||
import { EnableCameraSceneName } from "../Login/EnableCameraScene";
|
||||
import { localUserStore } from "../../Connexion/LocalUserStore";
|
||||
import { get } from "svelte/store";
|
||||
import { requestedCameraState, requestedMicrophoneState } from "../../Stores/MediaStore";
|
||||
import { helpCameraSettingsVisibleStore } from "../../Stores/HelpCameraSettingsStore";
|
||||
|
||||
/**
|
||||
* This class should be responsible for any scene starting/stopping
|
||||
*/
|
||||
export class GameManager {
|
||||
private playerName: string|null;
|
||||
private characterLayers: string[]|null;
|
||||
private companion: string|null;
|
||||
private startRoom!:Room;
|
||||
currentGameSceneName: string|null = null;
|
||||
private playerName: string | null;
|
||||
private characterLayers: string[] | null;
|
||||
private companion: string | null;
|
||||
private startRoom!: Room;
|
||||
currentGameSceneName: string | null = null;
|
||||
|
||||
constructor() {
|
||||
this.playerName = localUserStore.getName();
|
||||
|
@ -30,7 +28,7 @@ export class GameManager {
|
|||
|
||||
public async init(scenePlugin: Phaser.Scenes.ScenePlugin): Promise<string> {
|
||||
this.startRoom = await connectionManager.initGameConnexion();
|
||||
await this.loadMap(this.startRoom, scenePlugin);
|
||||
this.loadMap(this.startRoom, scenePlugin);
|
||||
|
||||
if (!this.playerName) {
|
||||
return LoginSceneName;
|
||||
|
@ -51,43 +49,44 @@ export class GameManager {
|
|||
localUserStore.setCharacterLayers(layers);
|
||||
}
|
||||
|
||||
getPlayerName(): string|null {
|
||||
getPlayerName(): string | null {
|
||||
return this.playerName;
|
||||
}
|
||||
|
||||
getCharacterLayers(): string[] {
|
||||
if (!this.characterLayers) {
|
||||
throw 'characterLayers are not set';
|
||||
throw "characterLayers are not set";
|
||||
}
|
||||
return this.characterLayers;
|
||||
}
|
||||
|
||||
|
||||
setCompanion(companion: string|null): void {
|
||||
setCompanion(companion: string | null): void {
|
||||
this.companion = companion;
|
||||
}
|
||||
|
||||
getCompanion(): string|null {
|
||||
getCompanion(): string | null {
|
||||
return this.companion;
|
||||
}
|
||||
|
||||
public async loadMap(room: Room, scenePlugin: Phaser.Scenes.ScenePlugin): Promise<void> {
|
||||
const roomID = room.id;
|
||||
const mapDetail = await room.getMapDetail();
|
||||
public loadMap(room: Room, scenePlugin: Phaser.Scenes.ScenePlugin) {
|
||||
const roomID = room.key;
|
||||
|
||||
const gameIndex = scenePlugin.getIndex(roomID);
|
||||
if(gameIndex === -1){
|
||||
const game : Phaser.Scene = new GameScene(room, mapDetail.mapUrl);
|
||||
if (gameIndex === -1) {
|
||||
const game: Phaser.Scene = new GameScene(room, room.mapUrl);
|
||||
scenePlugin.add(roomID, game, false);
|
||||
}
|
||||
}
|
||||
|
||||
public goToStartingMap(scenePlugin: Phaser.Scenes.ScenePlugin): void {
|
||||
console.log('starting '+ (this.currentGameSceneName || this.startRoom.id))
|
||||
scenePlugin.start(this.currentGameSceneName || this.startRoom.id);
|
||||
console.log("starting " + (this.currentGameSceneName || this.startRoom.key));
|
||||
scenePlugin.start(this.currentGameSceneName || this.startRoom.key);
|
||||
scenePlugin.launch(MenuSceneName);
|
||||
|
||||
if(!localUserStore.getHelpCameraSettingsShown() && (!get(requestedMicrophoneState) || !get(requestedCameraState))){
|
||||
if (
|
||||
!localUserStore.getHelpCameraSettingsShown() &&
|
||||
(!get(requestedMicrophoneState) || !get(requestedCameraState))
|
||||
) {
|
||||
helpCameraSettingsVisibleStore.set(true);
|
||||
localUserStore.setHelpCameraSettingsShown();
|
||||
}
|
||||
|
@ -104,7 +103,7 @@ export class GameManager {
|
|||
* This will close the socket connections and stop the gameScene, but won't remove it.
|
||||
*/
|
||||
leaveGame(scene: Phaser.Scene, targetSceneName: string, sceneClass: Phaser.Scene): void {
|
||||
if (this.currentGameSceneName === null) throw 'No current scene id set!';
|
||||
if (this.currentGameSceneName === null) throw "No current scene id set!";
|
||||
const gameScene: GameScene = scene.scene.get(this.currentGameSceneName) as GameScene;
|
||||
gameScene.cleanupClosingScene();
|
||||
scene.scene.stop(this.currentGameSceneName);
|
||||
|
@ -123,13 +122,13 @@ export class GameManager {
|
|||
scene.scene.start(this.currentGameSceneName);
|
||||
scene.scene.wake(MenuSceneName);
|
||||
} else {
|
||||
scene.scene.run(fallbackSceneName)
|
||||
scene.scene.run(fallbackSceneName);
|
||||
}
|
||||
}
|
||||
|
||||
public getCurrentGameScene(scene: Phaser.Scene): GameScene {
|
||||
if (this.currentGameSceneName === null) throw 'No current scene id set!';
|
||||
return scene.scene.get(this.currentGameSceneName) as GameScene
|
||||
if (this.currentGameSceneName === null) throw "No current scene id set!";
|
||||
return scene.scene.get(this.currentGameSceneName) as GameScene;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import type {ITiledMap, ITiledMapLayer, ITiledMapLayerProperty} from "../Map/ITiledMap";
|
||||
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;
|
||||
export type PropertyChangeCallback = (
|
||||
newValue: string | number | boolean | undefined,
|
||||
oldValue: string | number | boolean | undefined,
|
||||
allProps: Map<string, string | boolean | number>
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* A wrapper around a ITiledMap interface to provide additional capabilities.
|
||||
|
@ -13,39 +17,56 @@ export class GameMap {
|
|||
private key: number | undefined;
|
||||
private lastProperties = new Map<string, string | boolean | number>();
|
||||
private callbacks = new Map<string, Array<PropertyChangeCallback>>();
|
||||
private tileNameMap = new Map<string, number>();
|
||||
|
||||
private tileSetPropertyMap: { [tile_index: number]: Array<ITiledMapLayerProperty> } = {}
|
||||
private tileSetPropertyMap: { [tile_index: number]: Array<ITiledMapLayerProperty> } = {};
|
||||
public readonly flatLayers: ITiledMapLayer[];
|
||||
public readonly phaserLayers: TilemapLayer[] = [];
|
||||
|
||||
public exitUrls: Array<string> = []
|
||||
public exitUrls: Array<string> = [];
|
||||
|
||||
public constructor(private map: ITiledMap, phaserMap: Phaser.Tilemaps.Tilemap, terrains: Array<Phaser.Tilemaps.Tileset>) {
|
||||
public hasStartTile = false;
|
||||
|
||||
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'){
|
||||
if (layer.type === "tilelayer") {
|
||||
this.phaserLayers.push(phaserMap.createLayer(layer.name, terrains, 0, 0).setDepth(depth));
|
||||
}
|
||||
if (layer.type === 'objectgroup' && layer.name === 'floorLayer') {
|
||||
if (layer.type === "objectgroup" && layer.name === "floorLayer") {
|
||||
depth = DEPTH_OVERLAY_INDEX;
|
||||
}
|
||||
}
|
||||
for (const tileset of map.tilesets) {
|
||||
tileset?.tiles?.forEach(tile => {
|
||||
tileset?.tiles?.forEach((tile) => {
|
||||
if (tile.properties) {
|
||||
this.tileSetPropertyMap[tileset.firstgid + tile.id] = tile.properties
|
||||
tile.properties.forEach(prop => {
|
||||
this.tileSetPropertyMap[tileset.firstgid + tile.id] = tile.properties;
|
||||
tile.properties.forEach((prop) => {
|
||||
if (prop.name == "name" && typeof prop.value == "string") {
|
||||
this.tileNameMap.set(prop.value, tileset.firstgid + tile.id);
|
||||
}
|
||||
if (prop.name == "exitUrl" && typeof prop.value == "string") {
|
||||
this.exitUrls.push(prop.value);
|
||||
} else if (prop.name == "start") {
|
||||
this.hasStartTile = true;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public getPropertiesForIndex(index: number): Array<ITiledMapLayerProperty> {
|
||||
if (this.tileSetPropertyMap[index]) {
|
||||
return this.tileSetPropertyMap[index];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the current player (in pixels)
|
||||
|
@ -89,7 +110,7 @@ export class GameMap {
|
|||
const properties = new Map<string, string | boolean | number>();
|
||||
|
||||
for (const layer of this.flatLayers) {
|
||||
if (layer.type !== 'tilelayer') {
|
||||
if (layer.type !== "tilelayer") {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -99,7 +120,7 @@ export class GameMap {
|
|||
if (tiles[key] == 0) {
|
||||
continue;
|
||||
}
|
||||
tileIndex = tiles[key]
|
||||
tileIndex = tiles[key];
|
||||
}
|
||||
|
||||
// There is a tile in this layer, let's embed the properties
|
||||
|
@ -113,24 +134,36 @@ export class GameMap {
|
|||
}
|
||||
|
||||
if (tileIndex) {
|
||||
this.tileSetPropertyMap[tileIndex]?.forEach(property => {
|
||||
this.tileSetPropertyMap[tileIndex]?.forEach((property) => {
|
||||
if (property.value) {
|
||||
properties.set(property.name, property.value)
|
||||
properties.set(property.name, property.value);
|
||||
} else if (properties.has(property.name)) {
|
||||
properties.delete(property.name)
|
||||
properties.delete(property.name);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
public getMap(): ITiledMap{
|
||||
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>) {
|
||||
private getTileProperty(index: number): Array<ITiledMapLayerProperty> {
|
||||
if (this.tileSetPropertyMap[index]) {
|
||||
return this.tileSetPropertyMap[index];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
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) {
|
||||
for (const callback of callbacksArray) {
|
||||
|
@ -159,10 +192,65 @@ export class GameMap {
|
|||
return this.phaserLayers.find((layer) => layer.layer.name === layerName);
|
||||
}
|
||||
|
||||
public addTerrain(terrain : Phaser.Tilemaps.Tileset): void {
|
||||
public findPhaserLayers(groupName: string): TilemapLayer[] {
|
||||
return this.phaserLayers.filter((l) => l.layer.name.includes(groupName));
|
||||
}
|
||||
|
||||
public addTerrain(terrain: Phaser.Tilemaps.Tileset): void {
|
||||
for (const phaserLayer of this.phaserLayers) {
|
||||
phaserLayer.tileset.push(terrain);
|
||||
}
|
||||
}
|
||||
|
||||
private putTileInFlatLayer(index: number, x: number, y: number, layer: string): void {
|
||||
const fLayer = this.findLayer(layer);
|
||||
if (fLayer == undefined) {
|
||||
console.error("The layer '" + layer + "' that you want to change doesn't exist.");
|
||||
return;
|
||||
}
|
||||
if (fLayer.type !== "tilelayer") {
|
||||
console.error(
|
||||
"The layer '" +
|
||||
layer +
|
||||
"' that you want to change is not a tilelayer. Tile can only be put in tilelayer."
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (typeof fLayer.data === "string") {
|
||||
console.error("Data of the layer '" + layer + "' that you want to change is only readable.");
|
||||
return;
|
||||
}
|
||||
fLayer.data[x + y * fLayer.width] = index;
|
||||
}
|
||||
|
||||
public putTile(tile: string | number | null, x: number, y: number, layer: string): void {
|
||||
const phaserLayer = this.findPhaserLayer(layer);
|
||||
if (phaserLayer) {
|
||||
if (tile === null) {
|
||||
phaserLayer.putTileAt(-1, x, y);
|
||||
return;
|
||||
}
|
||||
const tileIndex = this.getIndexForTileType(tile);
|
||||
if (tileIndex !== undefined) {
|
||||
this.putTileInFlatLayer(tileIndex, x, y, layer);
|
||||
const phaserTile = phaserLayer.putTileAt(tileIndex, x, y);
|
||||
for (const property of this.getTileProperty(tileIndex)) {
|
||||
if (property.name === "collides" && property.value) {
|
||||
phaserTile.setCollision(true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error("The tile '" + tile + "' that you want to place doesn't exist.");
|
||||
}
|
||||
} else {
|
||||
console.error("The layer '" + layer + "' does not exist (or is not a tilelaye).");
|
||||
}
|
||||
}
|
||||
|
||||
private getIndexForTileType(tile: string | number): number | undefined {
|
||||
if (typeof tile == "number") {
|
||||
return tile;
|
||||
}
|
||||
return this.tileNameMap.get(tile);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
11
front/src/Phaser/Game/PlayerInterface.ts
Normal file
11
front/src/Phaser/Game/PlayerInterface.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import type { BodyResourceDescriptionInterface } from "../Entity/PlayerTextures";
|
||||
|
||||
export interface PlayerInterface {
|
||||
userId: number;
|
||||
name: string;
|
||||
characterLayers: BodyResourceDescriptionInterface[];
|
||||
visitCardUrl: string | null;
|
||||
companion: string | null;
|
||||
userUuid: string;
|
||||
color?: string;
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
import { MAX_EXTRAPOLATION_TIME } from "../../Enum/EnvironmentVariable";
|
||||
import type { PositionInterface } from "../../Connexion/ConnexionModels";
|
||||
import type { HasPlayerMovedEvent } from '../../Api/Events/HasPlayerMovedEvent';
|
||||
import type { HasPlayerMovedEvent } from "../../Api/Events/HasPlayerMovedEvent";
|
||||
|
||||
export class PlayerMovement {
|
||||
public constructor(private startPosition: PositionInterface, private startTick: number, private endPosition: HasPlayerMovedEvent, private endTick: number) {
|
||||
}
|
||||
public constructor(
|
||||
private startPosition: PositionInterface,
|
||||
private startTick: number,
|
||||
private endPosition: HasPlayerMovedEvent,
|
||||
private endTick: number
|
||||
) {}
|
||||
|
||||
public isOutdated(tick: number): boolean {
|
||||
//console.log(tick, this.endTick, MAX_EXTRAPOLATION_TIME)
|
||||
|
@ -24,14 +28,18 @@ export class PlayerMovement {
|
|||
return this.endPosition;
|
||||
}
|
||||
|
||||
const x = (this.endPosition.x - this.startPosition.x) * ((tick - this.startTick) / (this.endTick - this.startTick)) + this.startPosition.x;
|
||||
const y = (this.endPosition.y - this.startPosition.y) * ((tick - this.startTick) / (this.endTick - this.startTick)) + this.startPosition.y;
|
||||
const x =
|
||||
(this.endPosition.x - this.startPosition.x) * ((tick - this.startTick) / (this.endTick - this.startTick)) +
|
||||
this.startPosition.x;
|
||||
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,
|
||||
direction: this.endPosition.direction,
|
||||
moving: true
|
||||
}
|
||||
moving: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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 { HasPlayerMovedEvent } from '../../Api/Events/HasPlayerMovedEvent';
|
||||
import type { HasPlayerMovedEvent } from "../../Api/Events/HasPlayerMovedEvent";
|
||||
import type { PlayerMovement } from "./PlayerMovement";
|
||||
|
||||
export class PlayersPositionInterpolator {
|
||||
|
@ -24,7 +24,7 @@ export class PlayersPositionInterpolator {
|
|||
this.playerMovements.delete(userId);
|
||||
}
|
||||
//console.log("moving")
|
||||
positions.set(userId, playerMovement.getPosition(tick))
|
||||
positions.set(userId, playerMovement.getPosition(tick));
|
||||
});
|
||||
return positions;
|
||||
}
|
||||
|
|
127
front/src/Phaser/Game/StartPositionCalculator.ts
Normal file
127
front/src/Phaser/Game/StartPositionCalculator.ts
Normal file
|
@ -0,0 +1,127 @@
|
|||
import type { PositionInterface } from "../../Connexion/ConnexionModels";
|
||||
import type { ITiledMap, ITiledMapLayer, ITiledMapLayerProperty, ITiledMapTileLayer } from "../Map/ITiledMap";
|
||||
import type { GameMap } from "./GameMap";
|
||||
|
||||
const defaultStartLayerName = "start";
|
||||
|
||||
export class StartPositionCalculator {
|
||||
public startPosition!: PositionInterface;
|
||||
|
||||
constructor(
|
||||
private readonly gameMap: GameMap,
|
||||
private readonly mapFile: ITiledMap,
|
||||
private readonly initPosition: PositionInterface | null,
|
||||
public readonly startLayerName: string | null
|
||||
) {
|
||||
this.initStartXAndStartY();
|
||||
}
|
||||
private initStartXAndStartY() {
|
||||
// If there is an init position passed
|
||||
if (this.initPosition !== null) {
|
||||
this.startPosition = this.initPosition;
|
||||
} else {
|
||||
// Now, let's find the start layer
|
||||
if (this.startLayerName) {
|
||||
this.initPositionFromLayerName(this.startLayerName, this.startLayerName);
|
||||
}
|
||||
if (this.startPosition === undefined) {
|
||||
// If we have no start layer specified or if the hash passed does not exist, let's go with the default start position.
|
||||
this.initPositionFromLayerName(defaultStartLayerName, this.startLayerName);
|
||||
}
|
||||
}
|
||||
// Still no start position? Something is wrong with the map, we need a "start" layer.
|
||||
if (this.startPosition === undefined) {
|
||||
console.warn(
|
||||
'This map is missing a layer named "start" that contains the available default start positions.'
|
||||
);
|
||||
// Let's start in the middle of the map
|
||||
this.startPosition = {
|
||||
x: this.mapFile.width * 16,
|
||||
y: this.mapFile.height * 16,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param selectedLayer this is always the layer that is selected with the hash in the url
|
||||
* @param selectedOrDefaultLayer this can also be the {defaultStartLayerName} if the {selectedLayer} didnt yield any start points
|
||||
*/
|
||||
public initPositionFromLayerName(selectedOrDefaultLayer: string | null, selectedLayer: string | null) {
|
||||
if (!selectedOrDefaultLayer) {
|
||||
selectedOrDefaultLayer = defaultStartLayerName;
|
||||
}
|
||||
for (const layer of this.gameMap.flatLayers) {
|
||||
if (
|
||||
(selectedOrDefaultLayer === layer.name || layer.name.endsWith("/" + selectedOrDefaultLayer)) &&
|
||||
layer.type === "tilelayer" &&
|
||||
(selectedOrDefaultLayer === defaultStartLayerName || this.isStartLayer(layer))
|
||||
) {
|
||||
const startPosition = this.startUser(layer, selectedLayer);
|
||||
this.startPosition = {
|
||||
x: startPosition.x + this.mapFile.tilewidth / 2,
|
||||
y: startPosition.y + this.mapFile.tileheight / 2,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private isStartLayer(layer: ITiledMapLayer): boolean {
|
||||
return this.getProperty(layer, "startLayer") == true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param selectedLayer this is always the layer that is selected with the hash in the url
|
||||
* @param selectedOrDefaultLayer this can also be the default layer if the {selectedLayer} didnt yield any start points
|
||||
*/
|
||||
private startUser(selectedOrDefaultLayer: ITiledMapTileLayer, selectedLayer: string | null): PositionInterface {
|
||||
const tiles = selectedOrDefaultLayer.data;
|
||||
if (typeof tiles === "string") {
|
||||
throw new Error("The content of a JSON map must be filled as a JSON array, not as a string");
|
||||
}
|
||||
const possibleStartPositions: PositionInterface[] = [];
|
||||
tiles.forEach((objectKey: number, key: number) => {
|
||||
if (objectKey === 0) {
|
||||
return;
|
||||
}
|
||||
const y = Math.floor(key / selectedOrDefaultLayer.width);
|
||||
const x = key % selectedOrDefaultLayer.width;
|
||||
|
||||
if (selectedLayer && this.gameMap.hasStartTile) {
|
||||
const properties = this.gameMap.getPropertiesForIndex(objectKey);
|
||||
if (
|
||||
!properties.length ||
|
||||
!properties.some((property) => property.name == "start" && property.value == selectedLayer)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
possibleStartPositions.push({ x: x * this.mapFile.tilewidth, y: y * this.mapFile.tilewidth });
|
||||
});
|
||||
// Get a value at random amongst allowed values
|
||||
if (possibleStartPositions.length === 0) {
|
||||
console.warn('The start layer "' + selectedOrDefaultLayer.name + '" for this map is empty.');
|
||||
return {
|
||||
x: 0,
|
||||
y: 0,
|
||||
};
|
||||
}
|
||||
// Choose one of the available start positions at random amongst the list of available start positions.
|
||||
return possibleStartPositions[Math.floor(Math.random() * possibleStartPositions.length)];
|
||||
}
|
||||
|
||||
private getProperty(layer: ITiledMapLayer | ITiledMap, name: string): string | boolean | number | undefined {
|
||||
const properties: ITiledMapLayerProperty[] | undefined = layer.properties;
|
||||
if (!properties) {
|
||||
return undefined;
|
||||
}
|
||||
const obj = properties.find(
|
||||
(property: ITiledMapLayerProperty) => property.name.toLowerCase() === name.toLowerCase()
|
||||
);
|
||||
if (obj === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return obj.value;
|
||||
}
|
||||
}
|
|
@ -1,18 +1,19 @@
|
|||
import {EnableCameraSceneName} from "./EnableCameraScene";
|
||||
import { EnableCameraSceneName } from "./EnableCameraScene";
|
||||
import Rectangle = Phaser.GameObjects.Rectangle;
|
||||
import {loadAllLayers} from "../Entity/PlayerTexturesLoadingManager";
|
||||
import { loadAllLayers } from "../Entity/PlayerTexturesLoadingManager";
|
||||
import Sprite = Phaser.GameObjects.Sprite;
|
||||
import {gameManager} from "../Game/GameManager";
|
||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||
import {addLoader} from "../Components/Loader";
|
||||
import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
||||
import {areCharacterLayersValid} from "../../Connexion/LocalUser";
|
||||
import { gameManager } from "../Game/GameManager";
|
||||
import { localUserStore } from "../../Connexion/LocalUserStore";
|
||||
import { addLoader } from "../Components/Loader";
|
||||
import type { BodyResourceDescriptionInterface } from "../Entity/PlayerTextures";
|
||||
import { AbstractCharacterScene } from "./AbstractCharacterScene";
|
||||
import { areCharacterLayersValid } from "../../Connexion/LocalUser";
|
||||
import { SelectCharacterSceneName } from "./SelectCharacterScene";
|
||||
import {customCharacterSceneVisibleStore} from "../../Stores/CustomCharacterStore";
|
||||
import {waScaleManager} from "../Services/WaScaleManager";
|
||||
import {isMobile} from "../../Enum/EnvironmentVariable";
|
||||
import {CustomizedCharacter} from "../Entity/CustomizedCharacter";
|
||||
import { activeRowStore, customCharacterSceneVisibleStore } from "../../Stores/CustomCharacterStore";
|
||||
import { waScaleManager } from "../Services/WaScaleManager";
|
||||
import { isMobile } from "../../Enum/EnvironmentVariable";
|
||||
import { CustomizedCharacter } from "../Entity/CustomizedCharacter";
|
||||
import { get } from "svelte/store";
|
||||
|
||||
export const CustomizeSceneName = "CustomizeScene";
|
||||
|
||||
|
@ -21,7 +22,6 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
|
||||
private selectedLayers: number[] = [0];
|
||||
private containersRow: CustomizedCharacter[][] = [];
|
||||
public activeRow:number = 0;
|
||||
private layers: BodyResourceDescriptionInterface[][] = [];
|
||||
|
||||
protected lazyloadingAttempt = true; //permit to update texture loaded after renderer
|
||||
|
@ -31,16 +31,19 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
|
||||
constructor() {
|
||||
super({
|
||||
key: CustomizeSceneName
|
||||
key: CustomizeSceneName,
|
||||
});
|
||||
}
|
||||
|
||||
preload() {
|
||||
|
||||
this.loadCustomSceneSelectCharacters().then((bodyResourceDescriptions) => {
|
||||
bodyResourceDescriptions.forEach((bodyResourceDescription) => {
|
||||
if(bodyResourceDescription.level == undefined || bodyResourceDescription.level < 0 || bodyResourceDescription.level > 5 ){
|
||||
throw 'Texture level is null';
|
||||
if (
|
||||
bodyResourceDescription.level == undefined ||
|
||||
bodyResourceDescription.level < 0 ||
|
||||
bodyResourceDescription.level > 5
|
||||
) {
|
||||
throw "Texture level is null";
|
||||
}
|
||||
this.layers[bodyResourceDescription.level].unshift(bodyResourceDescription);
|
||||
});
|
||||
|
@ -50,14 +53,13 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
this.layers = loadAllLayers(this.load);
|
||||
this.lazyloadingAttempt = false;
|
||||
|
||||
|
||||
//this function must stay at the end of preload function
|
||||
addLoader(this);
|
||||
}
|
||||
|
||||
create() {
|
||||
customCharacterSceneVisibleStore.set(true);
|
||||
this.events.addListener('wake', () => {
|
||||
this.events.addListener("wake", () => {
|
||||
waScaleManager.saveZoom();
|
||||
waScaleManager.zoomModifier = isMobile() ? 3 : 1;
|
||||
customCharacterSceneVisibleStore.set(true);
|
||||
|
@ -66,8 +68,13 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
waScaleManager.saveZoom();
|
||||
waScaleManager.zoomModifier = isMobile() ? 3 : 1;
|
||||
|
||||
this.Rectangle = this.add.rectangle(this.cameras.main.worldView.x + this.cameras.main.width / 2, this.cameras.main.worldView.y + this.cameras.main.height / 3, 32, 33)
|
||||
this.Rectangle.setStrokeStyle(2, 0xFFFFFF);
|
||||
this.Rectangle = this.add.rectangle(
|
||||
this.cameras.main.worldView.x + this.cameras.main.width / 2,
|
||||
this.cameras.main.worldView.y + this.cameras.main.height / 3,
|
||||
32,
|
||||
33
|
||||
);
|
||||
this.Rectangle.setStrokeStyle(2, 0xffffff);
|
||||
this.add.existing(this.Rectangle);
|
||||
|
||||
this.createCustomizeLayer(0, 0, 0);
|
||||
|
@ -78,24 +85,24 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
this.createCustomizeLayer(0, 0, 5);
|
||||
|
||||
this.moveLayers();
|
||||
this.input.keyboard.on('keyup-ENTER', () => {
|
||||
this.input.keyboard.on("keyup-ENTER", () => {
|
||||
this.nextSceneToCamera();
|
||||
});
|
||||
this.input.keyboard.on('keyup-BACKSPACE', () => {
|
||||
this.input.keyboard.on("keyup-BACKSPACE", () => {
|
||||
this.backToPreviousScene();
|
||||
});
|
||||
|
||||
// Note: the key bindings are not directly put on the moveCursorVertically or moveCursorHorizontally methods
|
||||
// because if 2 such events are fired close to one another, it makes the whole application crawl to a halt (for a reason I cannot
|
||||
// explain, the list of sprites managed by the update list become immense
|
||||
this.input.keyboard.on('keyup-RIGHT', () => this.moveHorizontally = 1);
|
||||
this.input.keyboard.on('keyup-LEFT', () => this.moveHorizontally = -1);
|
||||
this.input.keyboard.on('keyup-DOWN', () => this.moveVertically = 1);
|
||||
this.input.keyboard.on('keyup-UP', () => this.moveVertically = -1);
|
||||
this.input.keyboard.on("keyup-RIGHT", () => (this.moveHorizontally = 1));
|
||||
this.input.keyboard.on("keyup-LEFT", () => (this.moveHorizontally = -1));
|
||||
this.input.keyboard.on("keyup-DOWN", () => (this.moveVertically = 1));
|
||||
this.input.keyboard.on("keyup-UP", () => (this.moveVertically = -1));
|
||||
|
||||
const customCursorPosition = localUserStore.getCustomCursorPosition();
|
||||
if (customCursorPosition) {
|
||||
this.activeRow = customCursorPosition.activeRow;
|
||||
activeRowStore.set(customCursorPosition.activeRow);
|
||||
this.selectedLayers = customCursorPosition.selectedLayers;
|
||||
this.moveLayers();
|
||||
this.updateSelectedLayer();
|
||||
|
@ -113,31 +120,30 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
}
|
||||
|
||||
private doMoveCursorHorizontally(index: number): void {
|
||||
this.selectedLayers[this.activeRow] += index;
|
||||
if (this.selectedLayers[this.activeRow] < 0) {
|
||||
this.selectedLayers[this.activeRow] = 0
|
||||
} else if(this.selectedLayers[this.activeRow] > this.layers[this.activeRow].length - 1) {
|
||||
this.selectedLayers[this.activeRow] = this.layers[this.activeRow].length - 1
|
||||
this.selectedLayers[get(activeRowStore)] += index;
|
||||
if (this.selectedLayers[get(activeRowStore)] < 0) {
|
||||
this.selectedLayers[get(activeRowStore)] = 0;
|
||||
} else if (this.selectedLayers[get(activeRowStore)] > this.layers[get(activeRowStore)].length - 1) {
|
||||
this.selectedLayers[get(activeRowStore)] = this.layers[get(activeRowStore)].length - 1;
|
||||
}
|
||||
this.moveLayers();
|
||||
this.updateSelectedLayer();
|
||||
this.saveInLocalStorage();
|
||||
}
|
||||
|
||||
private doMoveCursorVertically(index:number): void {
|
||||
|
||||
this.activeRow += index;
|
||||
if (this.activeRow < 0) {
|
||||
this.activeRow = 0
|
||||
} else if (this.activeRow > this.layers.length - 1) {
|
||||
this.activeRow = this.layers.length - 1
|
||||
private doMoveCursorVertically(index: number): void {
|
||||
activeRowStore.set(get(activeRowStore) + index);
|
||||
if (get(activeRowStore) < 0) {
|
||||
activeRowStore.set(0);
|
||||
} else if (get(activeRowStore) > this.layers.length - 1) {
|
||||
activeRowStore.set(this.layers.length - 1);
|
||||
}
|
||||
this.moveLayers();
|
||||
this.saveInLocalStorage();
|
||||
}
|
||||
|
||||
private saveInLocalStorage() {
|
||||
localUserStore.setCustomCursorPosition(this.activeRow, this.selectedLayers);
|
||||
localUserStore.setCustomCursorPosition(get(activeRowStore), this.selectedLayers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,7 +179,7 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
* @param selectedItem, The number of the item select (0 for black body...)
|
||||
*/
|
||||
private generateCharacter(x: number, y: number, layerNumber: number, selectedItem: number) {
|
||||
return new CustomizedCharacter(this, x, y, this.getContainerChildren(layerNumber,selectedItem));
|
||||
return new CustomizedCharacter(this, x, y, this.getContainerChildren(layerNumber, selectedItem));
|
||||
}
|
||||
|
||||
private getContainerChildren(layerNumber: number, selectedItem: number): Array<string> {
|
||||
|
@ -188,7 +194,7 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
}
|
||||
children.push(this.layers[j][layer].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
|
@ -202,17 +208,16 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
const screenHeight = this.game.renderer.height;
|
||||
for (let i = 0; i < this.containersRow.length; i++) {
|
||||
for (let j = 0; j < this.containersRow[i].length; j++) {
|
||||
let selectedX = this.selectedLayers[i];
|
||||
if (selectedX === undefined) {
|
||||
selectedX = 0;
|
||||
}
|
||||
this.containersRow[i][j].x = screenCenterX + (j - selectedX) * 40;
|
||||
this.containersRow[i][j].y = screenCenterY + (i - this.activeRow) * 40;
|
||||
const alpha1 = Math.abs(selectedX - j)*47*2/screenWidth;
|
||||
const alpha2 = Math.abs(this.activeRow - i)*49*2/screenHeight;
|
||||
this.containersRow[i][j].setAlpha((1 -alpha1)*(1 - alpha2));
|
||||
let selectedX = this.selectedLayers[i];
|
||||
if (selectedX === undefined) {
|
||||
selectedX = 0;
|
||||
}
|
||||
this.containersRow[i][j].x = screenCenterX + (j - selectedX) * 40;
|
||||
this.containersRow[i][j].y = screenCenterY + (i - get(activeRowStore)) * 40;
|
||||
const alpha1 = (Math.abs(selectedX - j) * 47 * 2) / screenWidth;
|
||||
const alpha2 = (Math.abs(get(activeRowStore) - i) * 49 * 2) / screenHeight;
|
||||
this.containersRow[i][j].setAlpha((1 - alpha1) * (1 - alpha2));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,8 +233,8 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
}
|
||||
|
||||
private updateSelectedLayer() {
|
||||
for(let i = 0; i < this.containersRow.length; i++){
|
||||
for(let j = 0; j < this.containersRow[i].length; j++){
|
||||
for (let i = 0; i < this.containersRow.length; i++) {
|
||||
for (let j = 0; j < this.containersRow[i].length; j++) {
|
||||
const children = this.getContainerChildren(i, j);
|
||||
this.containersRow[i][j].updateSprites(children);
|
||||
}
|
||||
|
@ -237,8 +242,7 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
}
|
||||
|
||||
update(time: number, delta: number): void {
|
||||
|
||||
if(this.lazyloadingAttempt){
|
||||
if (this.lazyloadingAttempt) {
|
||||
this.moveLayers();
|
||||
this.lazyloadingAttempt = false;
|
||||
}
|
||||
|
@ -253,38 +257,35 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public onResize(): void {
|
||||
public onResize(): void {
|
||||
this.moveLayers();
|
||||
|
||||
this.Rectangle.x = this.cameras.main.worldView.x + this.cameras.main.width / 2;
|
||||
this.Rectangle.y = this.cameras.main.worldView.y + this.cameras.main.height / 3;
|
||||
}
|
||||
|
||||
public nextSceneToCamera(){
|
||||
const layers: string[] = [];
|
||||
let i = 0;
|
||||
for (const layerItem of this.selectedLayers) {
|
||||
if (layerItem !== undefined) {
|
||||
layers.push(this.layers[i][layerItem].name);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!areCharacterLayersValid(layers)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gameManager.setCharacterLayers(layers);
|
||||
this.scene.sleep(CustomizeSceneName);
|
||||
waScaleManager.restoreZoom();
|
||||
this.events.removeListener('wake');
|
||||
gameManager.tryResumingGame(this, EnableCameraSceneName);
|
||||
customCharacterSceneVisibleStore.set(false);
|
||||
}
|
||||
|
||||
public backToPreviousScene(){
|
||||
public nextSceneToCamera() {
|
||||
const layers: string[] = [];
|
||||
let i = 0;
|
||||
for (const layerItem of this.selectedLayers) {
|
||||
if (layerItem !== undefined) {
|
||||
layers.push(this.layers[i][layerItem].name);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!areCharacterLayersValid(layers)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gameManager.setCharacterLayers(layers);
|
||||
this.scene.sleep(CustomizeSceneName);
|
||||
waScaleManager.restoreZoom();
|
||||
this.events.removeListener("wake");
|
||||
gameManager.tryResumingGame(this, EnableCameraSceneName);
|
||||
customCharacterSceneVisibleStore.set(false);
|
||||
}
|
||||
|
||||
public backToPreviousScene() {
|
||||
this.scene.sleep(CustomizeSceneName);
|
||||
waScaleManager.restoreZoom();
|
||||
this.scene.run(SelectCharacterSceneName);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import {gameManager} from "../Game/GameManager";
|
||||
import {Scene} from "phaser";
|
||||
import {ErrorScene} from "../Reconnecting/ErrorScene";
|
||||
import {WAError} from "../Reconnecting/WAError";
|
||||
import {waScaleManager} from "../Services/WaScaleManager";
|
||||
import { gameManager } from "../Game/GameManager";
|
||||
import { Scene } from "phaser";
|
||||
import { ErrorScene } from "../Reconnecting/ErrorScene";
|
||||
import { WAError } from "../Reconnecting/WAError";
|
||||
import { waScaleManager } from "../Services/WaScaleManager";
|
||||
|
||||
export const EntrySceneName = "EntryScene";
|
||||
|
||||
|
@ -13,26 +13,32 @@ export const EntrySceneName = "EntryScene";
|
|||
export class EntryScene extends Scene {
|
||||
constructor() {
|
||||
super({
|
||||
key: EntrySceneName
|
||||
key: EntrySceneName,
|
||||
});
|
||||
}
|
||||
|
||||
create() {
|
||||
|
||||
gameManager.init(this.scene).then((nextSceneName) => {
|
||||
// Let's rescale before starting the game
|
||||
// We can do it at this stage.
|
||||
waScaleManager.applyNewSize();
|
||||
this.scene.start(nextSceneName);
|
||||
}).catch((err) => {
|
||||
if (err.response && err.response.status == 404) {
|
||||
ErrorScene.showError(new WAError(
|
||||
'Access link incorrect',
|
||||
'Could not find map. Please check your access link.',
|
||||
'If you want more information, you may contact administrator or contact us at: workadventure@thecodingmachine.com'), this.scene);
|
||||
} else {
|
||||
ErrorScene.showError(err, this.scene);
|
||||
}
|
||||
});
|
||||
gameManager
|
||||
.init(this.scene)
|
||||
.then((nextSceneName) => {
|
||||
// Let's rescale before starting the game
|
||||
// We can do it at this stage.
|
||||
waScaleManager.applyNewSize();
|
||||
this.scene.start(nextSceneName);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.response && err.response.status == 404) {
|
||||
ErrorScene.showError(
|
||||
new WAError(
|
||||
"Access link incorrect",
|
||||
"Could not find map. Please check your access link.",
|
||||
"If you want more information, you may contact administrator or contact us at: hello@workadventu.re"
|
||||
),
|
||||
this.scene
|
||||
);
|
||||
} else {
|
||||
ErrorScene.showError(err, this.scene);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
import {gameManager} from "../Game/GameManager";
|
||||
import { gameManager } from "../Game/GameManager";
|
||||
import Rectangle = Phaser.GameObjects.Rectangle;
|
||||
import {EnableCameraSceneName} from "./EnableCameraScene";
|
||||
import {CustomizeSceneName} from "./CustomizeScene";
|
||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||
import {loadAllDefaultModels} from "../Entity/PlayerTexturesLoadingManager";
|
||||
import {addLoader} from "../Components/Loader";
|
||||
import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
||||
import {areCharacterLayersValid} from "../../Connexion/LocalUser";
|
||||
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
||||
import {PinchManager} from "../UserInput/PinchManager";
|
||||
import {selectCharacterSceneVisibleStore} from "../../Stores/SelectCharacterStore";
|
||||
import {waScaleManager} from "../Services/WaScaleManager";
|
||||
import {isMobile} from "../../Enum/EnvironmentVariable";
|
||||
import { EnableCameraSceneName } from "./EnableCameraScene";
|
||||
import { CustomizeSceneName } from "./CustomizeScene";
|
||||
import { localUserStore } from "../../Connexion/LocalUserStore";
|
||||
import { loadAllDefaultModels } from "../Entity/PlayerTexturesLoadingManager";
|
||||
import { addLoader } from "../Components/Loader";
|
||||
import type { BodyResourceDescriptionInterface } from "../Entity/PlayerTextures";
|
||||
import { AbstractCharacterScene } from "./AbstractCharacterScene";
|
||||
import { areCharacterLayersValid } from "../../Connexion/LocalUser";
|
||||
import { touchScreenManager } from "../../Touch/TouchScreenManager";
|
||||
import { PinchManager } from "../UserInput/PinchManager";
|
||||
import { selectCharacterSceneVisibleStore } from "../../Stores/SelectCharacterStore";
|
||||
import { waScaleManager } from "../Services/WaScaleManager";
|
||||
import { isMobile } from "../../Enum/EnvironmentVariable";
|
||||
|
||||
//todo: put this constants in a dedicated file
|
||||
export const SelectCharacterSceneName = "SelectCharacterScene";
|
||||
|
||||
export class SelectCharacterScene extends AbstractCharacterScene {
|
||||
protected readonly nbCharactersPerRow = 6;
|
||||
protected selectedPlayer!: Phaser.Physics.Arcade.Sprite|null; // null if we are selecting the "customize" option
|
||||
protected selectedPlayer!: Phaser.Physics.Arcade.Sprite | null; // null if we are selecting the "customize" option
|
||||
protected players: Array<Phaser.Physics.Arcade.Sprite> = new Array<Phaser.Physics.Arcade.Sprite>();
|
||||
protected playerModels!: BodyResourceDescriptionInterface[];
|
||||
|
||||
|
@ -38,7 +38,6 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
}
|
||||
|
||||
preload() {
|
||||
|
||||
this.loadSelectSceneCharacters().then((bodyResourceDescriptions) => {
|
||||
bodyResourceDescriptions.forEach((bodyResourceDescription) => {
|
||||
this.playerModels.push(bodyResourceDescription);
|
||||
|
@ -54,7 +53,7 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
|
||||
create() {
|
||||
selectCharacterSceneVisibleStore.set(true);
|
||||
this.events.addListener('wake', () => {
|
||||
this.events.addListener("wake", () => {
|
||||
waScaleManager.saveZoom();
|
||||
waScaleManager.zoomModifier = isMobile() ? 2 : 1;
|
||||
selectCharacterSceneVisibleStore.set(true);
|
||||
|
@ -68,26 +67,26 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
waScaleManager.zoomModifier = isMobile() ? 2 : 1;
|
||||
|
||||
const rectangleXStart = this.game.renderer.width / 2 - (this.nbCharactersPerRow / 2) * 32 + 16;
|
||||
this.selectedRectangle = this.add.rectangle(rectangleXStart, 90, 32, 32).setStrokeStyle(2, 0xFFFFFF);
|
||||
this.selectedRectangle = this.add.rectangle(rectangleXStart, 90, 32, 32).setStrokeStyle(2, 0xffffff);
|
||||
this.selectedRectangle.setDepth(2);
|
||||
|
||||
/*create user*/
|
||||
this.createCurrentPlayer();
|
||||
|
||||
this.input.keyboard.on('keyup-ENTER', () => {
|
||||
this.input.keyboard.on("keyup-ENTER", () => {
|
||||
return this.nextSceneToCameraScene();
|
||||
});
|
||||
|
||||
this.input.keyboard.on('keydown-RIGHT', () => {
|
||||
this.input.keyboard.on("keydown-RIGHT", () => {
|
||||
this.moveToRight();
|
||||
});
|
||||
this.input.keyboard.on('keydown-LEFT', () => {
|
||||
this.input.keyboard.on("keydown-LEFT", () => {
|
||||
this.moveToLeft();
|
||||
});
|
||||
this.input.keyboard.on('keydown-UP', () => {
|
||||
this.input.keyboard.on("keydown-UP", () => {
|
||||
this.moveToUp();
|
||||
});
|
||||
this.input.keyboard.on('keydown-DOWN', () => {
|
||||
this.input.keyboard.on("keydown-DOWN", () => {
|
||||
this.moveToDown();
|
||||
});
|
||||
}
|
||||
|
@ -96,7 +95,7 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
if (this.selectedPlayer !== null && !areCharacterLayersValid([this.selectedPlayer.texture.key])) {
|
||||
return;
|
||||
}
|
||||
if(!this.selectedPlayer){
|
||||
if (!this.selectedPlayer) {
|
||||
return;
|
||||
}
|
||||
this.scene.stop(SelectCharacterSceneName);
|
||||
|
@ -105,7 +104,7 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
gameManager.tryResumingGame(this, EnableCameraSceneName);
|
||||
this.players = [];
|
||||
selectCharacterSceneVisibleStore.set(false);
|
||||
this.events.removeListener('wake');
|
||||
this.events.removeListener("wake");
|
||||
}
|
||||
|
||||
public nextSceneToCustomizeScene(): void {
|
||||
|
@ -119,11 +118,11 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
}
|
||||
|
||||
createCurrentPlayer(): void {
|
||||
for (let i = 0; i <this.playerModels.length; i++) {
|
||||
for (let i = 0; i < this.playerModels.length; i++) {
|
||||
const playerResource = this.playerModels[i];
|
||||
|
||||
//check already exist texture
|
||||
if(this.players.find((c) => c.texture.key === playerResource.name)){
|
||||
if (this.players.find((c) => c.texture.key === playerResource.name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -132,9 +131,9 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
this.setUpPlayer(player, i);
|
||||
this.anims.create({
|
||||
key: playerResource.name,
|
||||
frames: this.anims.generateFrameNumbers(playerResource.name, {start: 0, end: 11}),
|
||||
frames: this.anims.generateFrameNumbers(playerResource.name, { start: 0, end: 11 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
repeat: -1,
|
||||
});
|
||||
player.setInteractive().on("pointerdown", () => {
|
||||
if (this.pointerClicked) {
|
||||
|
@ -153,77 +152,79 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
});
|
||||
this.players.push(player);
|
||||
}
|
||||
if (this.currentSelectUser >= this.players.length) {
|
||||
this.currentSelectUser = 0;
|
||||
}
|
||||
this.selectedPlayer = this.players[this.currentSelectUser];
|
||||
this.selectedPlayer.play(this.playerModels[this.currentSelectUser].name);
|
||||
}
|
||||
|
||||
protected moveUser(){
|
||||
for(let i = 0; i < this.players.length; i++){
|
||||
protected moveUser() {
|
||||
for (let i = 0; i < this.players.length; i++) {
|
||||
const player = this.players[i];
|
||||
this.setUpPlayer(player, i);
|
||||
}
|
||||
this.updateSelectedPlayer();
|
||||
}
|
||||
|
||||
public moveToLeft(){
|
||||
if(this.currentSelectUser === 0){
|
||||
public moveToLeft() {
|
||||
if (this.currentSelectUser === 0) {
|
||||
return;
|
||||
}
|
||||
this.currentSelectUser -= 1;
|
||||
this.moveUser();
|
||||
}
|
||||
|
||||
public moveToRight(){
|
||||
if(this.currentSelectUser === (this.players.length - 1)){
|
||||
public moveToRight() {
|
||||
if (this.currentSelectUser === this.players.length - 1) {
|
||||
return;
|
||||
}
|
||||
this.currentSelectUser += 1;
|
||||
this.moveUser();
|
||||
}
|
||||
|
||||
protected moveToUp(){
|
||||
if(this.currentSelectUser < this.nbCharactersPerRow){
|
||||
protected moveToUp() {
|
||||
if (this.currentSelectUser < this.nbCharactersPerRow) {
|
||||
return;
|
||||
}
|
||||
this.currentSelectUser -= this.nbCharactersPerRow;
|
||||
this.moveUser();
|
||||
}
|
||||
|
||||
protected moveToDown(){
|
||||
if((this.currentSelectUser + this.nbCharactersPerRow) > (this.players.length - 1)){
|
||||
protected moveToDown() {
|
||||
if (this.currentSelectUser + this.nbCharactersPerRow > this.players.length - 1) {
|
||||
return;
|
||||
}
|
||||
this.currentSelectUser += this.nbCharactersPerRow;
|
||||
this.moveUser();
|
||||
}
|
||||
|
||||
protected defineSetupPlayer(num: number){
|
||||
protected defineSetupPlayer(num: number) {
|
||||
const deltaX = 32;
|
||||
const deltaY = 32;
|
||||
let [playerX, playerY] = this.getCharacterPosition(); // player X and player y are middle of the
|
||||
|
||||
playerX = ( (playerX - (deltaX * 2.5)) + ((deltaX) * (num % this.nbCharactersPerRow)) ); // calcul position on line users
|
||||
playerY = ( (playerY - (deltaY * 2)) + ((deltaY) * ( Math.floor(num / this.nbCharactersPerRow) )) ); // calcul position on column users
|
||||
playerX = playerX - deltaX * 2.5 + deltaX * (num % this.nbCharactersPerRow); // calcul position on line users
|
||||
playerY = playerY - deltaY * 2 + deltaY * Math.floor(num / this.nbCharactersPerRow); // calcul position on column users
|
||||
|
||||
const playerVisible = true;
|
||||
const playerScale = 1;
|
||||
const playerOpacity = 1;
|
||||
|
||||
// if selected
|
||||
if( num === this.currentSelectUser ){
|
||||
if (num === this.currentSelectUser) {
|
||||
this.selectedRectangle.setX(playerX);
|
||||
this.selectedRectangle.setY(playerY);
|
||||
}
|
||||
|
||||
return {playerX, playerY, playerScale, playerOpacity, playerVisible}
|
||||
return { playerX, playerY, playerScale, playerOpacity, playerVisible };
|
||||
}
|
||||
|
||||
protected setUpPlayer(player: Phaser.Physics.Arcade.Sprite, num: number){
|
||||
|
||||
const {playerX, playerY, playerScale, playerOpacity, playerVisible} = this.defineSetupPlayer(num);
|
||||
protected setUpPlayer(player: Phaser.Physics.Arcade.Sprite, num: number) {
|
||||
const { playerX, playerY, playerScale, playerOpacity, playerVisible } = this.defineSetupPlayer(num);
|
||||
player.setBounce(0.2);
|
||||
player.setCollideWorldBounds(false);
|
||||
player.setVisible( playerVisible );
|
||||
player.setVisible(playerVisible);
|
||||
player.setScale(playerScale, playerScale);
|
||||
player.setAlpha(playerOpacity);
|
||||
player.setX(playerX);
|
||||
|
@ -234,10 +235,7 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
* Returns pixel position by on column and row number
|
||||
*/
|
||||
protected getCharacterPosition(): [number, number] {
|
||||
return [
|
||||
this.game.renderer.width / 2,
|
||||
this.game.renderer.height / 2.5
|
||||
];
|
||||
return [this.game.renderer.width / 2, this.game.renderer.height / 2.5];
|
||||
}
|
||||
|
||||
protected updateSelectedPlayer(): void {
|
||||
|
@ -256,7 +254,7 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
this.pointerClicked = false;
|
||||
}
|
||||
|
||||
if(this.lazyloadingAttempt){
|
||||
if (this.lazyloadingAttempt) {
|
||||
//re-render players list
|
||||
this.createCurrentPlayer();
|
||||
this.moveUser();
|
||||
|
|
|
@ -36,7 +36,7 @@ export interface ITiledMap {
|
|||
export interface ITiledMapLayerProperty {
|
||||
name: string;
|
||||
type: string;
|
||||
value: string|boolean|number|undefined;
|
||||
value: string | boolean | number | undefined;
|
||||
}
|
||||
|
||||
/*export interface ITiledMapLayerBooleanProperty {
|
||||
|
@ -48,7 +48,7 @@ export interface ITiledMapLayerProperty {
|
|||
export type ITiledMapLayer = ITiledMapGroupLayer | ITiledMapObjectLayer | ITiledMapTileLayer;
|
||||
|
||||
export interface ITiledMapGroupLayer {
|
||||
id?: number,
|
||||
id?: number;
|
||||
name: string;
|
||||
opacity: number;
|
||||
properties?: ITiledMapLayerProperty[];
|
||||
|
@ -64,8 +64,8 @@ export interface ITiledMapGroupLayer {
|
|||
}
|
||||
|
||||
export interface ITiledMapTileLayer {
|
||||
id?: number,
|
||||
data: number[]|string;
|
||||
id?: number;
|
||||
data: number[] | string;
|
||||
height: number;
|
||||
name: string;
|
||||
opacity: number;
|
||||
|
@ -87,7 +87,7 @@ export interface ITiledMapTileLayer {
|
|||
}
|
||||
|
||||
export interface ITiledMapObjectLayer {
|
||||
id?: number,
|
||||
id?: number;
|
||||
height: number;
|
||||
name: string;
|
||||
opacity: number;
|
||||
|
@ -117,7 +117,7 @@ export interface ITiledMapObject {
|
|||
gid: number;
|
||||
height: number;
|
||||
name: string;
|
||||
properties: {[key: string]: string};
|
||||
properties: { [key: string]: string };
|
||||
rotation: number;
|
||||
type: string;
|
||||
visible: boolean;
|
||||
|
@ -133,26 +133,26 @@ export interface ITiledMapObject {
|
|||
/**
|
||||
* Polygon points
|
||||
*/
|
||||
polygon: {x: number, y: number}[];
|
||||
polygon: { x: number; y: number }[];
|
||||
|
||||
/**
|
||||
* Polyline points
|
||||
*/
|
||||
polyline: {x: number, y: number}[];
|
||||
polyline: { x: number; y: number }[];
|
||||
|
||||
text?: ITiledText
|
||||
text?: ITiledText;
|
||||
}
|
||||
|
||||
export interface ITiledText {
|
||||
text: string,
|
||||
wrap?: boolean,
|
||||
fontfamily?: string,
|
||||
pixelsize?: number,
|
||||
color?: string,
|
||||
underline?: boolean,
|
||||
italic?: boolean,
|
||||
strikeout?: boolean,
|
||||
halign?: "center"|"right"|"justify"|"left"
|
||||
text: string;
|
||||
wrap?: boolean;
|
||||
fontfamily?: string;
|
||||
pixelsize?: number;
|
||||
color?: string;
|
||||
underline?: boolean;
|
||||
italic?: boolean;
|
||||
strikeout?: boolean;
|
||||
halign?: "center" | "right" | "justify" | "left";
|
||||
}
|
||||
|
||||
export interface ITiledTileSet {
|
||||
|
@ -163,7 +163,7 @@ export interface ITiledTileSet {
|
|||
imagewidth: number;
|
||||
margin: number;
|
||||
name: string;
|
||||
properties: {[key: string]: string};
|
||||
properties: { [key: string]: string };
|
||||
spacing: number;
|
||||
tilecount: number;
|
||||
tileheight: number;
|
||||
|
@ -179,10 +179,10 @@ export interface ITiledTileSet {
|
|||
}
|
||||
|
||||
export interface ITile {
|
||||
id: number,
|
||||
type?: string
|
||||
id: number;
|
||||
type?: string;
|
||||
|
||||
properties?: Array<ITiledMapLayerProperty>
|
||||
properties?: Array<ITiledMapLayerProperty>;
|
||||
}
|
||||
|
||||
export interface ITiledMapTerrain {
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import type {ITiledMap, ITiledMapLayer} from "./ITiledMap";
|
||||
import type { ITiledMap, ITiledMapLayer } from "./ITiledMap";
|
||||
|
||||
/**
|
||||
* Flatten the grouped layers
|
||||
*/
|
||||
export function flattenGroupLayersMap(map: ITiledMap) {
|
||||
const flatLayers: ITiledMapLayer[] = [];
|
||||
flattenGroupLayers(map.layers, '', flatLayers);
|
||||
flattenGroupLayers(map.layers, "", flatLayers);
|
||||
return flatLayers;
|
||||
}
|
||||
|
||||
function flattenGroupLayers(layers : ITiledMapLayer[], prefix : string, flatLayers: ITiledMapLayer[]) {
|
||||
function flattenGroupLayers(layers: ITiledMapLayer[], prefix: string, flatLayers: ITiledMapLayer[]) {
|
||||
for (const layer of layers) {
|
||||
if (layer.type === 'group') {
|
||||
flattenGroupLayers(layer.layers, prefix + layer.name + '/', flatLayers);
|
||||
if (layer.type === "group") {
|
||||
flattenGroupLayers(layer.layers, prefix + layer.name + "/", flatLayers);
|
||||
} else {
|
||||
layer.name = prefix+layer.name
|
||||
layer.name = prefix + layer.name;
|
||||
flatLayers.push(layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,32 @@
|
|||
import {LoginScene, LoginSceneName} from "../Login/LoginScene";
|
||||
import {SelectCharacterScene, SelectCharacterSceneName} from "../Login/SelectCharacterScene";
|
||||
import {SelectCompanionScene, SelectCompanionSceneName} from "../Login/SelectCompanionScene";
|
||||
import {gameManager} from "../Game/GameManager";
|
||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||
import {gameReportKey, gameReportRessource, ReportMenu} from "./ReportMenu";
|
||||
import {connectionManager} from "../../Connexion/ConnectionManager";
|
||||
import {GameConnexionTypes} from "../../Url/UrlManager";
|
||||
import {WarningContainer, warningContainerHtml, warningContainerKey} from "../Components/WarningContainer";
|
||||
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";
|
||||
import { LoginScene, LoginSceneName } from "../Login/LoginScene";
|
||||
import { SelectCharacterScene, SelectCharacterSceneName } from "../Login/SelectCharacterScene";
|
||||
import { SelectCompanionScene, SelectCompanionSceneName } from "../Login/SelectCompanionScene";
|
||||
import { gameManager } from "../Game/GameManager";
|
||||
import { localUserStore } from "../../Connexion/LocalUserStore";
|
||||
import { gameReportKey, gameReportRessource, ReportMenu } from "./ReportMenu";
|
||||
import { connectionManager } from "../../Connexion/ConnectionManager";
|
||||
import { GameConnexionTypes } from "../../Url/UrlManager";
|
||||
import { WarningContainer, warningContainerHtml, warningContainerKey } from "../Components/WarningContainer";
|
||||
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";
|
||||
import { playersStore } from "../../Stores/PlayersStore";
|
||||
import { mediaManager } from "../../WebRtc/MediaManager";
|
||||
import { chatVisibilityStore } from "../../Stores/ChatStore";
|
||||
|
||||
export const MenuSceneName = 'MenuScene';
|
||||
const gameMenuKey = 'gameMenu';
|
||||
const gameMenuIconKey = 'gameMenuIcon';
|
||||
const gameSettingsMenuKey = 'gameSettingsMenu';
|
||||
const gameShare = 'gameShare';
|
||||
export const MenuSceneName = "MenuScene";
|
||||
const gameMenuKey = "gameMenu";
|
||||
const gameMenuIconKey = "gameMenuIcon";
|
||||
const gameSettingsMenuKey = "gameSettingsMenu";
|
||||
const gameShare = "gameShare";
|
||||
|
||||
const closedSideMenuX = -1000;
|
||||
const openedSideMenuX = 0;
|
||||
|
@ -44,45 +47,49 @@ 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()
|
||||
private subscriptions = new Subscription();
|
||||
constructor() {
|
||||
super({ key: MenuSceneName });
|
||||
|
||||
this.gameQualityValue = localUserStore.getGameQualityValue();
|
||||
this.videoQualityValue = localUserStore.getVideoQualityValue();
|
||||
|
||||
this.subscriptions.add(registerMenuCommandStream.subscribe(menuCommand => {
|
||||
this.addMenuOption(menuCommand);
|
||||
}))
|
||||
this.subscriptions.add(
|
||||
registerMenuCommandStream.subscribe((menuCommand) => {
|
||||
this.addMenuOption(menuCommand);
|
||||
})
|
||||
);
|
||||
|
||||
this.subscriptions.add(iframeListener.unregisterMenuCommandStream.subscribe(menuCommand => {
|
||||
this.destroyMenu(menuCommand);
|
||||
}))
|
||||
this.subscriptions.add(
|
||||
iframeListener.unregisterMenuCommandStream.subscribe((menuCommand) => {
|
||||
this.destroyMenu(menuCommand);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
reset() {
|
||||
const addedMenuItems = [...this.menuElement.node.querySelectorAll(".fromApi")];
|
||||
for (let index = addedMenuItems.length - 1; index >= 0; index--) {
|
||||
addedMenuItems[index].remove()
|
||||
addedMenuItems[index].remove();
|
||||
}
|
||||
}
|
||||
|
||||
public addMenuOption(menuText: string) {
|
||||
const wrappingSection = document.createElement("section")
|
||||
const wrappingSection = document.createElement("section");
|
||||
const escapedHtml = HtmlUtils.escapeHtml(menuText);
|
||||
wrappingSection.innerHTML = `<button class="fromApi" id="${escapedHtml}">${escapedHtml}</button>`
|
||||
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"))
|
||||
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');
|
||||
this.load.html(gameShare, 'resources/html/gameShare.html');
|
||||
this.load.html(gameMenuKey, "resources/html/gameMenu.html");
|
||||
this.load.html(gameMenuIconKey, "resources/html/gameMenuIcon.html");
|
||||
this.load.html(gameSettingsMenuKey, "resources/html/gameQualityMenu.html");
|
||||
this.load.html(gameShare, "resources/html/gameShare.html");
|
||||
this.load.html(gameReportKey, gameReportRessource);
|
||||
this.load.html(warningContainerKey, warningContainerHtml);
|
||||
}
|
||||
|
@ -91,46 +98,59 @@ export class MenuScene extends Phaser.Scene {
|
|||
menuIconVisible.set(true);
|
||||
this.menuElement = this.add.dom(closedSideMenuX, 30).createFromCache(gameMenuKey);
|
||||
this.menuElement.setOrigin(0);
|
||||
MenuScene.revealMenusAfterInit(this.menuElement, 'gameMenu');
|
||||
MenuScene.revealMenusAfterInit(this.menuElement, "gameMenu");
|
||||
|
||||
const middleX = (window.innerWidth / 3) - 298;
|
||||
if (mediaManager.hasNotification()) {
|
||||
HtmlUtils.getElementByIdOrFail("enableNotification").hidden = true;
|
||||
}
|
||||
|
||||
const middleX = window.innerWidth / 3 - 298;
|
||||
this.gameQualityMenuElement = this.add.dom(middleX, -400).createFromCache(gameSettingsMenuKey);
|
||||
MenuScene.revealMenusAfterInit(this.gameQualityMenuElement, 'gameQuality');
|
||||
|
||||
MenuScene.revealMenusAfterInit(this.gameQualityMenuElement, "gameQuality");
|
||||
|
||||
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.addListener("click");
|
||||
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();
|
||||
}
|
||||
});
|
||||
|
||||
this.gameReportElement = new ReportMenu(this, connectionManager.getConnexionType === GameConnexionTypes.anonymous);
|
||||
this.gameReportElement = new ReportMenu(
|
||||
this,
|
||||
connectionManager.getConnexionType === GameConnexionTypes.anonymous
|
||||
);
|
||||
showReportScreenStore.subscribe((user) => {
|
||||
if (user !== null) {
|
||||
this.closeAll();
|
||||
this.gameReportElement.open(user.userId, user.userName);
|
||||
const uuid = playersStore.getPlayerById(user.userId)?.userUuid;
|
||||
if (uuid === undefined) {
|
||||
throw new Error("Could not find UUID for user with ID " + user.userId);
|
||||
}
|
||||
this.gameReportElement.open(uuid, user.userName);
|
||||
}
|
||||
});
|
||||
|
||||
this.input.keyboard.on('keyup-TAB', () => {
|
||||
this.input.keyboard.on("keyup-TAB", () => {
|
||||
this.sideMenuOpened ? this.closeSideMenu() : this.openSideMenu();
|
||||
});
|
||||
this.menuButton = this.add.dom(0, 0).createFromCache(gameMenuIconKey);
|
||||
this.menuButton.addListener('click');
|
||||
this.menuButton.on('click', () => {
|
||||
this.menuButton.addListener("click");
|
||||
this.menuButton.on("click", () => {
|
||||
this.sideMenuOpened ? this.closeSideMenu() : this.openSideMenu();
|
||||
});
|
||||
|
||||
this.menuElement.addListener('click');
|
||||
this.menuElement.on('click', this.onMenuClick.bind(this));
|
||||
this.menuElement.addListener("click");
|
||||
this.menuElement.on("click", this.onMenuClick.bind(this));
|
||||
|
||||
worldFullWarningStream.stream.subscribe(() => this.showWorldCapacityWarning());
|
||||
chatVisibilityStore.subscribe((v) => {
|
||||
this.menuButton.setVisible(!v);
|
||||
});
|
||||
}
|
||||
|
||||
//todo put this method in a parent menuElement class
|
||||
|
@ -145,7 +165,7 @@ export class MenuScene extends Phaser.Scene {
|
|||
public revealMenuIcon(): void {
|
||||
//TODO fix me: add try catch because at the same time, 'this.menuButton' variable doesn't exist and there is error on 'getChildByID' function
|
||||
try {
|
||||
(this.menuButton.getChildByID('menuIcon') as HTMLElement).hidden = false;
|
||||
(this.menuButton.getChildByID("menuIcon") as HTMLElement).hidden = false;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
@ -155,22 +175,22 @@ export class MenuScene extends Phaser.Scene {
|
|||
if (this.sideMenuOpened) return;
|
||||
this.closeAll();
|
||||
this.sideMenuOpened = true;
|
||||
this.menuButton.getChildByID('openMenuButton').innerHTML = 'X';
|
||||
this.menuButton.getChildByID("openMenuButton").innerHTML = "X";
|
||||
const connection = gameManager.getCurrentGameScene(this).connection;
|
||||
if (connection && connection.isAdmin()) {
|
||||
const adminSection = this.menuElement.getChildByID('adminConsoleSection') as HTMLElement;
|
||||
const adminSection = this.menuElement.getChildByID("adminConsoleSection") as HTMLElement;
|
||||
adminSection.hidden = false;
|
||||
}
|
||||
//TODO bind with future metadata of card
|
||||
//if (connectionManager.getConnexionType === GameConnexionTypes.anonymous){
|
||||
const adminSection = this.menuElement.getChildByID('socialLinks') as HTMLElement;
|
||||
const adminSection = this.menuElement.getChildByID("socialLinks") as HTMLElement;
|
||||
adminSection.hidden = false;
|
||||
//}
|
||||
this.tweens.add({
|
||||
targets: this.menuElement,
|
||||
x: openedSideMenuX,
|
||||
duration: 500,
|
||||
ease: 'Power3'
|
||||
ease: "Power3",
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -183,23 +203,22 @@ export class MenuScene extends Phaser.Scene {
|
|||
}
|
||||
this.warningContainerTimeout = setTimeout(() => {
|
||||
this.warningContainer?.destroy();
|
||||
this.warningContainer = null
|
||||
this.warningContainerTimeout = null
|
||||
this.warningContainer = null;
|
||||
this.warningContainerTimeout = null;
|
||||
}, 120000);
|
||||
|
||||
}
|
||||
|
||||
private closeSideMenu(): void {
|
||||
if (!this.sideMenuOpened) return;
|
||||
this.sideMenuOpened = false;
|
||||
this.closeAll();
|
||||
this.menuButton.getChildByID('openMenuButton').innerHTML = `<img src="/static/images/menu.svg">`;
|
||||
this.menuButton.getChildByID("openMenuButton").innerHTML = `<img src="/static/images/menu.svg">`;
|
||||
consoleGlobalMessageManagerVisibleStore.set(false);
|
||||
this.tweens.add({
|
||||
targets: this.menuElement,
|
||||
x: closedSideMenuX,
|
||||
duration: 500,
|
||||
ease: 'Power3'
|
||||
ease: "Power3",
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -213,19 +232,23 @@ export class MenuScene extends Phaser.Scene {
|
|||
|
||||
this.settingsMenuOpened = true;
|
||||
|
||||
const gameQualitySelect = this.gameQualityMenuElement.getChildByID('select-game-quality') as HTMLInputElement;
|
||||
gameQualitySelect.value = '' + this.gameQualityValue;
|
||||
const videoQualitySelect = this.gameQualityMenuElement.getChildByID('select-video-quality') as HTMLInputElement;
|
||||
videoQualitySelect.value = '' + this.videoQualityValue;
|
||||
const gameQualitySelect = this.gameQualityMenuElement.getChildByID("select-game-quality") as HTMLInputElement;
|
||||
gameQualitySelect.value = "" + this.gameQualityValue;
|
||||
const videoQualitySelect = this.gameQualityMenuElement.getChildByID("select-video-quality") as HTMLInputElement;
|
||||
videoQualitySelect.value = "" + this.videoQualityValue;
|
||||
|
||||
this.gameQualityMenuElement.addListener('click');
|
||||
this.gameQualityMenuElement.on('click', (event: MouseEvent) => {
|
||||
this.gameQualityMenuElement.addListener("click");
|
||||
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;
|
||||
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();
|
||||
}
|
||||
});
|
||||
|
@ -243,7 +266,7 @@ export class MenuScene extends Phaser.Scene {
|
|||
y: middleY,
|
||||
x: middleX,
|
||||
duration: 1000,
|
||||
ease: 'Power3'
|
||||
ease: "Power3",
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -251,16 +274,15 @@ export class MenuScene extends Phaser.Scene {
|
|||
if (!this.settingsMenuOpened) return;
|
||||
this.settingsMenuOpened = false;
|
||||
|
||||
this.gameQualityMenuElement.removeListener('click');
|
||||
this.gameQualityMenuElement.removeListener("click");
|
||||
this.tweens.add({
|
||||
targets: this.gameQualityMenuElement,
|
||||
y: -400,
|
||||
duration: 1000,
|
||||
ease: 'Power3'
|
||||
ease: "Power3",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private openGameShare(): void {
|
||||
if (this.gameShareOpened) {
|
||||
this.closeGameShare();
|
||||
|
@ -269,7 +291,7 @@ export class MenuScene extends Phaser.Scene {
|
|||
//close all
|
||||
this.closeAll();
|
||||
|
||||
const gameShareLink = this.gameShareElement.getChildByID('gameShareLink') as HTMLInputElement;
|
||||
const gameShareLink = this.gameShareElement.getChildByID("gameShareLink") as HTMLInputElement;
|
||||
gameShareLink.value = location.toString();
|
||||
|
||||
this.gameShareOpened = true;
|
||||
|
@ -287,64 +309,67 @@ export class MenuScene extends Phaser.Scene {
|
|||
y: middleY,
|
||||
x: middleX,
|
||||
duration: 1000,
|
||||
ease: 'Power3'
|
||||
ease: "Power3",
|
||||
});
|
||||
}
|
||||
|
||||
private closeGameShare(): void {
|
||||
const gameShareInfo = this.gameShareElement.getChildByID('gameShareInfo') as HTMLParagraphElement;
|
||||
gameShareInfo.innerText = '';
|
||||
gameShareInfo.style.display = 'none';
|
||||
const gameShareInfo = this.gameShareElement.getChildByID("gameShareInfo") as HTMLParagraphElement;
|
||||
gameShareInfo.innerText = "";
|
||||
gameShareInfo.style.display = "none";
|
||||
this.gameShareOpened = false;
|
||||
this.tweens.add({
|
||||
targets: this.gameShareElement,
|
||||
y: -400,
|
||||
duration: 1000,
|
||||
ease: 'Power3'
|
||||
ease: "Power3",
|
||||
});
|
||||
}
|
||||
|
||||
private onMenuClick(event: MouseEvent) {
|
||||
const htmlMenuItem = (event?.target as HTMLInputElement);
|
||||
if (htmlMenuItem.classList.contains('not-button')) {
|
||||
const htmlMenuItem = event?.target as HTMLInputElement;
|
||||
if (htmlMenuItem.classList.contains("not-button")) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
if (htmlMenuItem.classList.contains("fromApi")) {
|
||||
sendMenuClickedEvent(htmlMenuItem.id)
|
||||
return
|
||||
sendMenuClickedEvent(htmlMenuItem.id);
|
||||
return;
|
||||
}
|
||||
|
||||
switch ((event?.target as HTMLInputElement).id) {
|
||||
case 'changeNameButton':
|
||||
case "changeNameButton":
|
||||
this.closeSideMenu();
|
||||
gameManager.leaveGame(this, LoginSceneName, new LoginScene());
|
||||
break;
|
||||
case 'sparkButton':
|
||||
case "sparkButton":
|
||||
this.gotToCreateMapPage();
|
||||
break;
|
||||
case 'changeSkinButton':
|
||||
case "changeSkinButton":
|
||||
this.closeSideMenu();
|
||||
gameManager.leaveGame(this, SelectCharacterSceneName, new SelectCharacterScene());
|
||||
break;
|
||||
case 'changeCompanionButton':
|
||||
case "changeCompanionButton":
|
||||
this.closeSideMenu();
|
||||
gameManager.leaveGame(this, SelectCompanionSceneName, new SelectCompanionScene());
|
||||
break;
|
||||
case 'closeButton':
|
||||
case "closeButton":
|
||||
this.closeSideMenu();
|
||||
break;
|
||||
case 'shareButton':
|
||||
case "shareButton":
|
||||
this.openGameShare();
|
||||
break;
|
||||
case 'editGameSettingsButton':
|
||||
case "editGameSettingsButton":
|
||||
this.openGameSettingsMenu();
|
||||
break;
|
||||
case 'toggleFullscreen':
|
||||
case "toggleFullscreen":
|
||||
this.toggleFullscreen();
|
||||
break;
|
||||
case 'adminConsoleButton':
|
||||
case "enableNotification":
|
||||
this.enableNotification();
|
||||
break;
|
||||
case "adminConsoleButton":
|
||||
if (get(consoleGlobalMessageManagerVisibleStore)) {
|
||||
consoleGlobalMessageManagerVisibleStore.set(false);
|
||||
} else {
|
||||
|
@ -356,9 +381,9 @@ export class MenuScene extends Phaser.Scene {
|
|||
|
||||
private async copyLink() {
|
||||
await navigator.clipboard.writeText(location.toString());
|
||||
const gameShareInfo = this.gameShareElement.getChildByID('gameShareInfo') as HTMLParagraphElement;
|
||||
gameShareInfo.innerText = 'Link copied, you can share it now!';
|
||||
gameShareInfo.style.display = 'block';
|
||||
const gameShareInfo = this.gameShareElement.getChildByID("gameShareInfo") as HTMLParagraphElement;
|
||||
gameShareInfo.innerText = "Link copied, you can share it now!";
|
||||
gameShareInfo.style.display = "block";
|
||||
}
|
||||
|
||||
private saveSetting(valueGame: number, valueVideo: number) {
|
||||
|
@ -378,8 +403,8 @@ export class MenuScene extends Phaser.Scene {
|
|||
private gotToCreateMapPage() {
|
||||
//const sparkHost = 'https://'+window.location.host.replace('play.', '')+'/choose-map.html';
|
||||
//TODO fix me: this button can to send us on WorkAdventure BO.
|
||||
const sparkHost = 'https://workadventu.re/getting-started';
|
||||
window.open(sparkHost, '_blank');
|
||||
const sparkHost = "https://workadventu.re/getting-started";
|
||||
window.open(sparkHost, "_blank");
|
||||
}
|
||||
|
||||
private closeAll() {
|
||||
|
@ -389,10 +414,10 @@ export class MenuScene extends Phaser.Scene {
|
|||
}
|
||||
|
||||
private toggleFullscreen() {
|
||||
const body = document.querySelector('body')
|
||||
const body = document.querySelector("body");
|
||||
if (body) {
|
||||
if (document.fullscreenElement ?? document.fullscreen) {
|
||||
document.exitFullscreen()
|
||||
document.exitFullscreen();
|
||||
} else {
|
||||
body.requestFullscreen();
|
||||
}
|
||||
|
@ -406,4 +431,12 @@ export class MenuScene extends Phaser.Scene {
|
|||
public isDirty(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
private enableNotification() {
|
||||
mediaManager.requestNotification().then(() => {
|
||||
if (mediaManager.hasNotification()) {
|
||||
HtmlUtils.getElementByIdOrFail("enableNotification").hidden = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import {MenuScene} from "./MenuScene";
|
||||
import {gameManager} from "../Game/GameManager";
|
||||
import {blackListManager} from "../../WebRtc/BlackListManager";
|
||||
import { MenuScene } from "./MenuScene";
|
||||
import { gameManager } from "../Game/GameManager";
|
||||
import { blackListManager } from "../../WebRtc/BlackListManager";
|
||||
import { playersStore } from "../../Stores/PlayersStore";
|
||||
|
||||
export const gameReportKey = 'gameReport';
|
||||
export const gameReportRessource = 'resources/html/gameReport.html';
|
||||
export const gameReportKey = "gameReport";
|
||||
export const gameReportRessource = "resources/html/gameReport.html";
|
||||
|
||||
export class ReportMenu extends Phaser.GameObjects.DOMElement {
|
||||
private opened: boolean = false;
|
||||
|
||||
private userId!: number;
|
||||
private userName!: string|undefined;
|
||||
private userUuid!: string;
|
||||
private userName!: string | undefined;
|
||||
private anonymous: boolean;
|
||||
|
||||
constructor(scene: Phaser.Scene, anonymous: boolean) {
|
||||
|
@ -18,46 +19,46 @@ export class ReportMenu extends Phaser.GameObjects.DOMElement {
|
|||
this.createFromCache(gameReportKey);
|
||||
|
||||
if (this.anonymous) {
|
||||
const divToHide = this.getChildByID('reportSection') as HTMLElement;
|
||||
const divToHide = this.getChildByID("reportSection") as HTMLElement;
|
||||
divToHide.hidden = true;
|
||||
const textToHide = this.getChildByID('askActionP') as HTMLElement;
|
||||
const textToHide = this.getChildByID("askActionP") as HTMLElement;
|
||||
textToHide.hidden = true;
|
||||
}
|
||||
|
||||
scene.add.existing(this);
|
||||
MenuScene.revealMenusAfterInit(this, gameReportKey);
|
||||
|
||||
this.addListener('click');
|
||||
this.on('click', (event:MouseEvent) => {
|
||||
this.addListener("click");
|
||||
this.on("click", (event: MouseEvent) => {
|
||||
event.preventDefault();
|
||||
if ((event?.target as HTMLInputElement).id === 'gameReportFormSubmit') {
|
||||
if ((event?.target as HTMLInputElement).id === "gameReportFormSubmit") {
|
||||
this.submitReport();
|
||||
} else if((event?.target as HTMLInputElement).id === 'gameReportFormCancel') {
|
||||
} else if ((event?.target as HTMLInputElement).id === "gameReportFormCancel") {
|
||||
this.close();
|
||||
} else if((event?.target as HTMLInputElement).id === 'toggleBlockButton') {
|
||||
} else if ((event?.target as HTMLInputElement).id === "toggleBlockButton") {
|
||||
this.toggleBlock();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public open(userId: number, userName: string|undefined): void {
|
||||
public open(userUuid: string, userName: string | undefined): void {
|
||||
if (this.opened) {
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
|
||||
this.userId = userId;
|
||||
this.userUuid = userUuid;
|
||||
this.userName = userName;
|
||||
|
||||
const mainEl = this.getChildByID('gameReport') as HTMLElement;
|
||||
const mainEl = this.getChildByID("gameReport") as HTMLElement;
|
||||
this.x = this.getCenteredX(mainEl);
|
||||
this.y = this.getHiddenY(mainEl);
|
||||
|
||||
const gameTitleReport = this.getChildByID('nameReported') as HTMLElement;
|
||||
gameTitleReport.innerText = userName || '';
|
||||
const gameTitleReport = this.getChildByID("nameReported") as HTMLElement;
|
||||
gameTitleReport.innerText = userName || "";
|
||||
|
||||
const blockButton = this.getChildByID('toggleBlockButton') as HTMLElement;
|
||||
blockButton.innerText = blackListManager.isBlackListed(this.userId) ? 'Unblock this user' : 'Block this user';
|
||||
const blockButton = this.getChildByID("toggleBlockButton") as HTMLElement;
|
||||
blockButton.innerText = blackListManager.isBlackListed(this.userUuid) ? "Unblock this user" : "Block this user";
|
||||
|
||||
this.opened = true;
|
||||
|
||||
|
@ -67,19 +68,19 @@ export class ReportMenu extends Phaser.GameObjects.DOMElement {
|
|||
targets: this,
|
||||
y: this.getCenteredY(mainEl),
|
||||
duration: 1000,
|
||||
ease: 'Power3'
|
||||
ease: "Power3",
|
||||
});
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
gameManager.getCurrentGameScene(this.scene).userInputManager.restoreControls();
|
||||
this.opened = false;
|
||||
const mainEl = this.getChildByID('gameReport') as HTMLElement;
|
||||
const mainEl = this.getChildByID("gameReport") as HTMLElement;
|
||||
this.scene.tweens.add({
|
||||
targets: this,
|
||||
y: this.getHiddenY(mainEl),
|
||||
duration: 1000,
|
||||
ease: 'Power3'
|
||||
ease: "Power3",
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -88,31 +89,32 @@ export class ReportMenu extends Phaser.GameObjects.DOMElement {
|
|||
return window.innerWidth / 4 - mainEl.clientWidth / 2;
|
||||
}
|
||||
private getHiddenY(mainEl: HTMLElement): number {
|
||||
return - mainEl.clientHeight - 50;
|
||||
return -mainEl.clientHeight - 50;
|
||||
}
|
||||
private getCenteredY(mainEl: HTMLElement): number {
|
||||
return window.innerHeight / 4 - mainEl.clientHeight / 2;
|
||||
}
|
||||
|
||||
private toggleBlock(): void {
|
||||
!blackListManager.isBlackListed(this.userId) ? blackListManager.blackList(this.userId) : blackListManager.cancelBlackList(this.userId);
|
||||
!blackListManager.isBlackListed(this.userUuid)
|
||||
? blackListManager.blackList(this.userUuid)
|
||||
: blackListManager.cancelBlackList(this.userUuid);
|
||||
this.close();
|
||||
}
|
||||
|
||||
private submitReport(): void{
|
||||
const gamePError = this.getChildByID('gameReportErr') as HTMLParagraphElement;
|
||||
gamePError.innerText = '';
|
||||
gamePError.style.display = 'none';
|
||||
const gameTextArea = this.getChildByID('gameReportInput') as HTMLInputElement;
|
||||
if(!gameTextArea || !gameTextArea.value){
|
||||
gamePError.innerText = 'Report message cannot to be empty.';
|
||||
gamePError.style.display = 'block';
|
||||
private submitReport(): void {
|
||||
const gamePError = this.getChildByID("gameReportErr") as HTMLParagraphElement;
|
||||
gamePError.innerText = "";
|
||||
gamePError.style.display = "none";
|
||||
const gameTextArea = this.getChildByID("gameReportInput") as HTMLInputElement;
|
||||
if (!gameTextArea || !gameTextArea.value) {
|
||||
gamePError.innerText = "Report message cannot to be empty.";
|
||||
gamePError.style.display = "block";
|
||||
return;
|
||||
}
|
||||
gameManager.getCurrentGameScene(this.scene).connection?.emitReportPlayerMessage(
|
||||
this.userId,
|
||||
gameTextArea.value
|
||||
);
|
||||
gameManager
|
||||
.getCurrentGameScene(this.scene)
|
||||
.connection?.emitReportPlayerMessage(this.userUuid, gameTextArea.value);
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue