Merging with develop
This commit is contained in:
parent
3d5c222957
commit
cdd61bdb2c
135 changed files with 4313 additions and 2128 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,7 +101,6 @@ export const createLoadingPromise = (
|
|||
frameConfig: FrameConfig
|
||||
) => {
|
||||
return new Promise<BodyResourceDescriptionInterface>((res, rej) => {
|
||||
console.log("count", loadPlugin.listenerCount("loaderror"));
|
||||
if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
|
||||
return res(playerResourceDescriptor);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
import type {PointInterface} from "../../Connexion/ConnexionModels";
|
||||
import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||
import type { PointInterface } from "../../Connexion/ConnexionModels";
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -28,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;
|
||||
|
@ -68,20 +68,19 @@ export class GameManager {
|
|||
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);
|
||||
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 (
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { ITiledMap, ITiledMapLayer, ITiledMapLayerProperty } from "../Map/ITiledMap";
|
||||
import type { ITiledMap, ITiledMapLayer, ITiledMapProperty } from "../Map/ITiledMap";
|
||||
import { flattenGroupLayersMap } from "../Map/LayersFlattener";
|
||||
import TilemapLayer = Phaser.Tilemaps.TilemapLayer;
|
||||
import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes";
|
||||
|
@ -19,7 +19,7 @@ export class GameMap {
|
|||
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<ITiledMapProperty> } = {};
|
||||
public readonly flatLayers: ITiledMapLayer[];
|
||||
public readonly phaserLayers: TilemapLayer[] = [];
|
||||
|
||||
|
@ -61,7 +61,7 @@ export class GameMap {
|
|||
}
|
||||
}
|
||||
|
||||
public getPropertiesForIndex(index: number): Array<ITiledMapLayerProperty> {
|
||||
public getPropertiesForIndex(index: number): Array<ITiledMapProperty> {
|
||||
if (this.tileSetPropertyMap[index]) {
|
||||
return this.tileSetPropertyMap[index];
|
||||
}
|
||||
|
@ -151,8 +151,11 @@ export class GameMap {
|
|||
return this.map;
|
||||
}
|
||||
|
||||
private getTileProperty(index: number): Array<ITiledMapLayerProperty> {
|
||||
return this.tileSetPropertyMap[index];
|
||||
private getTileProperty(index: number): Array<ITiledMapProperty> {
|
||||
if (this.tileSetPropertyMap[index]) {
|
||||
return this.tileSetPropertyMap[index];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
private trigger(
|
||||
|
@ -189,6 +192,10 @@ export class GameMap {
|
|||
return this.phaserLayers.find((layer) => layer.layer.name === layerName);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -198,37 +205,45 @@ export class GameMap {
|
|||
private putTileInFlatLayer(index: number, x: number, y: number, layer: string): void {
|
||||
const fLayer = this.findLayer(layer);
|
||||
if (fLayer == undefined) {
|
||||
console.error("The layer that you want to change doesn't exist.");
|
||||
console.error("The layer '" + layer + "' that you want to change doesn't exist.");
|
||||
return;
|
||||
}
|
||||
if (fLayer.type !== "tilelayer") {
|
||||
console.error("The layer that you want to change is not a tilelayer. Tile can only be put in 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 that you want to change is only readable.");
|
||||
console.error("Data of the layer '" + layer + "' that you want to change is only readable.");
|
||||
return;
|
||||
}
|
||||
fLayer.data[x + y * fLayer.height] = index;
|
||||
fLayer.data[x + y * fLayer.width] = index;
|
||||
}
|
||||
|
||||
public putTile(tile: string | number, x: number, y: number, layer: string): void {
|
||||
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 === "true") {
|
||||
if (property.name === "collides" && property.value) {
|
||||
phaserTile.setCollision(true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error("The tile that you want to place doesn't exist.");
|
||||
console.error("The tile '" + tile + "' that you want to place doesn't exist.");
|
||||
}
|
||||
} else {
|
||||
console.error("The layer that you want to change is not a tilelayer. Tile can only be put in tilelayer.");
|
||||
console.error("The layer '" + layer + "' does not exist (or is not a tilelaye).");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,13 +47,7 @@ import { RemotePlayer } from "../Entity/RemotePlayer";
|
|||
import type { ActionableItem } from "../Items/ActionableItem";
|
||||
import type { ItemFactoryInterface } from "../Items/ItemFactoryInterface";
|
||||
import { SelectCharacterScene, SelectCharacterSceneName } from "../Login/SelectCharacterScene";
|
||||
import type {
|
||||
ITiledMap,
|
||||
ITiledMapLayer,
|
||||
ITiledMapLayerProperty,
|
||||
ITiledMapObject,
|
||||
ITiledTileSet,
|
||||
} from "../Map/ITiledMap";
|
||||
import type { ITiledMap, ITiledMapLayer, ITiledMapProperty, ITiledMapObject, ITiledTileSet } from "../Map/ITiledMap";
|
||||
import { MenuScene, MenuSceneName } from "../Menu/MenuScene";
|
||||
import { PlayerAnimationDirections } from "../Player/Animation";
|
||||
import { hasMovedEventName, Player, requestEmoteEventName } from "../Player/Player";
|
||||
|
@ -92,6 +86,9 @@ import { peerStore, screenSharingPeerStore } from "../../Stores/PeerStore";
|
|||
import { videoFocusStore } from "../../Stores/VideoFocusStore";
|
||||
import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore";
|
||||
import { isMessageReferenceEvent, isTriggerMessageEvent } from "../../Api/Events/ui/TriggerMessageEvent";
|
||||
import { SharedVariablesManager } from "./SharedVariablesManager";
|
||||
import { playersStore } from "../../Stores/PlayersStore";
|
||||
import { chatVisibilityStore } from "../../Stores/ChatStore";
|
||||
|
||||
export interface GameSceneInitInterface {
|
||||
initPosition: PointInterface | null;
|
||||
|
@ -169,9 +166,10 @@ export class GameScene extends DirtyScene {
|
|||
private createPromiseResolve!: (value?: void | PromiseLike<void>) => void;
|
||||
private iframeSubscriptionList!: Array<Subscription>;
|
||||
private peerStoreUnsubscribe!: () => void;
|
||||
private chatVisibilityUnsubscribe!: () => void;
|
||||
private biggestAvailableAreaStoreUnsubscribe!: () => void;
|
||||
MapUrlFile: string;
|
||||
RoomId: string;
|
||||
roomUrl: string;
|
||||
instance: string;
|
||||
|
||||
currentTick!: number;
|
||||
|
@ -200,18 +198,19 @@ export class GameScene extends DirtyScene {
|
|||
private mapTransitioning: boolean = false; //used to prevent transitions happenning at the same time.
|
||||
private emoteManager!: EmoteManager;
|
||||
private preloading: boolean = true;
|
||||
startPositionCalculator!: StartPositionCalculator;
|
||||
private startPositionCalculator!: StartPositionCalculator;
|
||||
private sharedVariablesManager!: SharedVariablesManager;
|
||||
|
||||
constructor(private room: Room, MapUrlFile: string, customKey?: string | undefined) {
|
||||
super({
|
||||
key: customKey ?? room.id,
|
||||
key: customKey ?? room.key,
|
||||
});
|
||||
this.Terrains = [];
|
||||
this.groups = new Map<number, Sprite>();
|
||||
this.instance = room.getInstance();
|
||||
|
||||
this.MapUrlFile = MapUrlFile;
|
||||
this.RoomId = room.id;
|
||||
this.roomUrl = room.key;
|
||||
|
||||
this.createPromise = new Promise<void>((resolve, reject): void => {
|
||||
this.createPromiseResolve = resolve;
|
||||
|
@ -463,11 +462,13 @@ export class GameScene extends DirtyScene {
|
|||
if (layer.type === "tilelayer") {
|
||||
const exitSceneUrl = this.getExitSceneUrl(layer);
|
||||
if (exitSceneUrl !== undefined) {
|
||||
this.loadNextGame(exitSceneUrl);
|
||||
this.loadNextGame(
|
||||
Room.getRoomPathFromExitSceneUrl(exitSceneUrl, window.location.toString(), this.MapUrlFile)
|
||||
);
|
||||
}
|
||||
const exitUrl = this.getExitUrl(layer);
|
||||
if (exitUrl !== undefined) {
|
||||
this.loadNextGame(exitUrl);
|
||||
this.loadNextGameFromExitUrl(exitUrl);
|
||||
}
|
||||
}
|
||||
if (layer.type === "objectgroup") {
|
||||
|
@ -480,7 +481,7 @@ export class GameScene extends DirtyScene {
|
|||
}
|
||||
|
||||
this.gameMap.exitUrls.forEach((exitUrl) => {
|
||||
this.loadNextGame(exitUrl);
|
||||
this.loadNextGameFromExitUrl(exitUrl);
|
||||
});
|
||||
|
||||
this.startPositionCalculator = new StartPositionCalculator(
|
||||
|
@ -571,6 +572,10 @@ export class GameScene extends DirtyScene {
|
|||
}
|
||||
oldPeerNumber = newPeerNumber;
|
||||
});
|
||||
|
||||
this.chatVisibilityUnsubscribe = chatVisibilityStore.subscribe((v) => {
|
||||
this.openChatIcon.setVisible(!v);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -581,7 +586,7 @@ export class GameScene extends DirtyScene {
|
|||
|
||||
connectionManager
|
||||
.connectToRoomSocket(
|
||||
this.RoomId,
|
||||
this.roomUrl,
|
||||
this.playerName,
|
||||
this.characterLayers,
|
||||
{
|
||||
|
@ -598,6 +603,8 @@ export class GameScene extends DirtyScene {
|
|||
.then((onConnect: OnConnectInterface) => {
|
||||
this.connection = onConnect.connection;
|
||||
|
||||
playersStore.connectToRoomConnection(this.connection);
|
||||
|
||||
this.connection.onUserJoins((message: MessageUserJoined) => {
|
||||
const userMessage: AddPlayerInterface = {
|
||||
userId: message.userId,
|
||||
|
@ -606,6 +613,7 @@ export class GameScene extends DirtyScene {
|
|||
position: message.position,
|
||||
visitCardUrl: message.visitCardUrl,
|
||||
companion: message.companion,
|
||||
userUuid: message.userUuid,
|
||||
};
|
||||
this.addPlayer(userMessage);
|
||||
});
|
||||
|
@ -689,12 +697,12 @@ export class GameScene extends DirtyScene {
|
|||
const self = this;
|
||||
this.simplePeer.registerPeerConnectionListener({
|
||||
onConnect(peer) {
|
||||
self.openChatIcon.setVisible(true);
|
||||
//self.openChatIcon.setVisible(true);
|
||||
audioManager.decreaseVolume();
|
||||
},
|
||||
onDisconnect(userId: number) {
|
||||
if (self.simplePeer.getNbConnections() === 0) {
|
||||
self.openChatIcon.setVisible(false);
|
||||
//self.openChatIcon.setVisible(false);
|
||||
audioManager.restoreVolume();
|
||||
}
|
||||
},
|
||||
|
@ -707,6 +715,13 @@ export class GameScene extends DirtyScene {
|
|||
this.gameMap.setPosition(event.x, event.y);
|
||||
});
|
||||
|
||||
// Set up variables manager
|
||||
this.sharedVariablesManager = new SharedVariablesManager(
|
||||
this.connection,
|
||||
this.gameMap,
|
||||
onConnect.room.variables
|
||||
);
|
||||
|
||||
//this.initUsersPosition(roomJoinedMessage.users);
|
||||
this.connectionAnswerPromiseResolve(onConnect.room);
|
||||
// Analyze tags to find if we are admin. If yes, show console.
|
||||
|
@ -766,10 +781,13 @@ export class GameScene extends DirtyScene {
|
|||
|
||||
private triggerOnMapLayerPropertyChange() {
|
||||
this.gameMap.onPropertyChange("exitSceneUrl", (newValue, oldValue) => {
|
||||
if (newValue) this.onMapExit(newValue as string);
|
||||
if (newValue)
|
||||
this.onMapExit(
|
||||
Room.getRoomPathFromExitSceneUrl(newValue as string, window.location.toString(), this.MapUrlFile)
|
||||
);
|
||||
});
|
||||
this.gameMap.onPropertyChange("exitUrl", (newValue, oldValue) => {
|
||||
if (newValue) this.onMapExit(newValue as string);
|
||||
if (newValue) this.onMapExit(Room.getRoomPathFromExitUrl(newValue as string, window.location.toString()));
|
||||
});
|
||||
this.gameMap.onPropertyChange("openWebsite", (newValue, oldValue, allProps) => {
|
||||
if (newValue === undefined) {
|
||||
|
@ -994,9 +1012,9 @@ ${escapedMessage}
|
|||
);
|
||||
this.iframeSubscriptionList.push(
|
||||
iframeListener.loadPageStream.subscribe((url: string) => {
|
||||
this.loadNextGame(url).then(() => {
|
||||
this.loadNextGameFromExitUrl(url).then(() => {
|
||||
this.events.once(EVENT_TYPE.POST_UPDATE, () => {
|
||||
this.onMapExit(url);
|
||||
this.onMapExit(Room.getRoomPathFromExitUrl(url, window.location.toString()));
|
||||
});
|
||||
});
|
||||
})
|
||||
|
@ -1039,20 +1057,24 @@ ${escapedMessage}
|
|||
})
|
||||
);
|
||||
|
||||
this.iframeSubscriptionList.push(
|
||||
iframeListener.dataLayerChangeStream.subscribe(() => {
|
||||
iframeListener.sendDataLayerEvent({ data: this.gameMap.getMap() });
|
||||
})
|
||||
);
|
||||
iframeListener.registerAnswerer("getMapData", () => {
|
||||
return {
|
||||
data: this.gameMap.getMap(),
|
||||
};
|
||||
});
|
||||
|
||||
iframeListener.registerAnswerer("getState", () => {
|
||||
iframeListener.registerAnswerer("getState", async () => {
|
||||
// The sharedVariablesManager is not instantiated before the connection is established. So we need to wait
|
||||
// for the connection to send back the answer.
|
||||
await this.connectionAnswerPromise;
|
||||
return {
|
||||
mapUrl: this.MapUrlFile,
|
||||
startLayerName: this.startPositionCalculator.startLayerName,
|
||||
uuid: localUserStore.getLocalUser()?.uuid,
|
||||
nickname: localUserStore.getName(),
|
||||
roomId: this.RoomId,
|
||||
nickname: this.playerName,
|
||||
roomId: this.roomUrl,
|
||||
tags: this.connection ? this.connection.getAllTags() : [],
|
||||
variables: this.sharedVariablesManager.variables,
|
||||
};
|
||||
});
|
||||
this.iframeSubscriptionList.push(
|
||||
|
@ -1076,17 +1098,12 @@ ${escapedMessage}
|
|||
},
|
||||
this.userInputManager
|
||||
);
|
||||
}),
|
||||
isTriggerMessageEvent
|
||||
})
|
||||
);
|
||||
|
||||
iframeListener.registerAnswerer(
|
||||
"removeTriggerMessage",
|
||||
(message) => {
|
||||
layoutManager.removeActionButton(message.uuid, this.userInputManager);
|
||||
},
|
||||
isMessageReferenceEvent
|
||||
);
|
||||
iframeListener.registerAnswerer("removeTriggerMessage", (message) => {
|
||||
layoutManager.removeActionButton(message.uuid, this.userInputManager);
|
||||
});
|
||||
}
|
||||
|
||||
private setPropertyLayer(
|
||||
|
@ -1099,53 +1116,86 @@ ${escapedMessage}
|
|||
console.warn('Could not find layer "' + layerName + '" when calling setProperty');
|
||||
return;
|
||||
}
|
||||
if (propertyName === "exitUrl" && typeof propertyValue === "string") {
|
||||
this.loadNextGameFromExitUrl(propertyValue);
|
||||
}
|
||||
if (layer.properties === undefined) {
|
||||
layer.properties = [];
|
||||
}
|
||||
const property = layer.properties.find((property) => property.name === propertyName);
|
||||
if (property === undefined) {
|
||||
if (propertyValue === undefined) {
|
||||
return;
|
||||
}
|
||||
layer.properties.push({ name: propertyName, type: typeof propertyValue, value: propertyValue });
|
||||
return;
|
||||
}
|
||||
if (propertyValue === undefined) {
|
||||
const index = layer.properties.indexOf(property);
|
||||
layer.properties.splice(index, 1);
|
||||
}
|
||||
property.value = propertyValue;
|
||||
}
|
||||
|
||||
private setLayerVisibility(layerName: string, visible: boolean): void {
|
||||
const phaserLayer = this.gameMap.findPhaserLayer(layerName);
|
||||
if (phaserLayer === undefined) {
|
||||
console.warn('Could not find layer "' + layerName + '" when calling WA.hideLayer / WA.showLayer');
|
||||
return;
|
||||
if (phaserLayer != undefined) {
|
||||
phaserLayer.setVisible(visible);
|
||||
phaserLayer.setCollisionByProperty({ collides: true }, visible);
|
||||
} else {
|
||||
const phaserLayers = this.gameMap.findPhaserLayers(layerName + "/");
|
||||
if (phaserLayers === []) {
|
||||
console.warn(
|
||||
'Could not find layer with name that contains "' +
|
||||
layerName +
|
||||
'" when calling WA.hideLayer / WA.showLayer'
|
||||
);
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < phaserLayers.length; i++) {
|
||||
phaserLayers[i].setVisible(visible);
|
||||
phaserLayers[i].setCollisionByProperty({ collides: true }, visible);
|
||||
}
|
||||
}
|
||||
phaserLayer.setVisible(visible);
|
||||
this.dirty = true;
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
private getMapDirUrl(): string {
|
||||
return this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf("/"));
|
||||
}
|
||||
|
||||
private onMapExit(exitKey: string) {
|
||||
private async onMapExit(roomUrl: URL) {
|
||||
if (this.mapTransitioning) return;
|
||||
this.mapTransitioning = true;
|
||||
const { roomId, hash } = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance);
|
||||
if (!roomId) throw new Error("Could not find the room from its exit key: " + exitKey);
|
||||
if (hash) {
|
||||
urlManager.pushStartLayerNameToUrl(hash);
|
||||
|
||||
let targetRoom: Room;
|
||||
try {
|
||||
targetRoom = await Room.createRoom(roomUrl);
|
||||
} catch (e: unknown) {
|
||||
console.error('Error while fetching new room "' + roomUrl.toString() + '"', e);
|
||||
this.mapTransitioning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (roomUrl.hash) {
|
||||
urlManager.pushStartLayerNameToUrl(roomUrl.hash);
|
||||
}
|
||||
|
||||
const menuScene: MenuScene = this.scene.get(MenuSceneName) as MenuScene;
|
||||
menuScene.reset();
|
||||
if (roomId !== this.scene.key) {
|
||||
if (this.scene.get(roomId) === null) {
|
||||
console.error("next room not loaded", exitKey);
|
||||
|
||||
if (!targetRoom.isEqual(this.room)) {
|
||||
if (this.scene.get(targetRoom.key) === null) {
|
||||
console.error("next room not loaded", targetRoom.key);
|
||||
return;
|
||||
}
|
||||
this.cleanupClosingScene();
|
||||
this.scene.stop();
|
||||
this.scene.start(targetRoom.key);
|
||||
this.scene.remove(this.scene.key);
|
||||
this.scene.start(roomId);
|
||||
} else {
|
||||
//if the exit points to the current map, we simply teleport the user back to the startLayer
|
||||
this.startPositionCalculator.initPositionFromLayerName(hash, hash);
|
||||
this.startPositionCalculator.initPositionFromLayerName(roomUrl.hash, roomUrl.hash);
|
||||
this.CurrentPlayer.x = this.startPositionCalculator.startPosition.x;
|
||||
this.CurrentPlayer.y = this.startPositionCalculator.startPosition.y;
|
||||
setTimeout(() => (this.mapTransitioning = false), 500);
|
||||
|
@ -1172,8 +1222,13 @@ ${escapedMessage}
|
|||
this.pinchManager?.destroy();
|
||||
this.emoteManager.destroy();
|
||||
this.peerStoreUnsubscribe();
|
||||
this.chatVisibilityUnsubscribe();
|
||||
this.biggestAvailableAreaStoreUnsubscribe();
|
||||
iframeListener.unregisterAnswerer("getMapData");
|
||||
iframeListener.unregisterAnswerer("getState");
|
||||
iframeListener.unregisterAnswerer("triggerMessage");
|
||||
iframeListener.unregisterAnswerer("removeTriggerMessage");
|
||||
this.sharedVariablesManager?.close();
|
||||
|
||||
mediaManager.hideGameOverlay();
|
||||
|
||||
|
@ -1213,12 +1268,12 @@ ${escapedMessage}
|
|||
}
|
||||
|
||||
private getProperty(layer: ITiledMapLayer | ITiledMap, name: string): string | boolean | number | undefined {
|
||||
const properties: ITiledMapLayerProperty[] | undefined = layer.properties;
|
||||
const properties: ITiledMapProperty[] | undefined = layer.properties;
|
||||
if (!properties) {
|
||||
return undefined;
|
||||
}
|
||||
const obj = properties.find(
|
||||
(property: ITiledMapLayerProperty) => property.name.toLowerCase() === name.toLowerCase()
|
||||
(property: ITiledMapProperty) => property.name.toLowerCase() === name.toLowerCase()
|
||||
);
|
||||
if (obj === undefined) {
|
||||
return undefined;
|
||||
|
@ -1227,20 +1282,27 @@ ${escapedMessage}
|
|||
}
|
||||
|
||||
private getProperties(layer: ITiledMapLayer | ITiledMap, name: string): (string | number | boolean | undefined)[] {
|
||||
const properties: ITiledMapLayerProperty[] | undefined = layer.properties;
|
||||
const properties: ITiledMapProperty[] | undefined = layer.properties;
|
||||
if (!properties) {
|
||||
return [];
|
||||
}
|
||||
return properties
|
||||
.filter((property: ITiledMapLayerProperty) => property.name.toLowerCase() === name.toLowerCase())
|
||||
.filter((property: ITiledMapProperty) => property.name.toLowerCase() === name.toLowerCase())
|
||||
.map((property) => property.value);
|
||||
}
|
||||
|
||||
private loadNextGameFromExitUrl(exitUrl: string): Promise<void> {
|
||||
return this.loadNextGame(Room.getRoomPathFromExitUrl(exitUrl, window.location.toString()));
|
||||
}
|
||||
|
||||
//todo: push that into the gameManager
|
||||
private loadNextGame(exitSceneIdentifier: string): Promise<void> {
|
||||
const { roomId, hash } = Room.getIdFromIdentifier(exitSceneIdentifier, this.MapUrlFile, this.instance);
|
||||
const room = new Room(roomId);
|
||||
return gameManager.loadMap(room, this.scene).catch(() => {});
|
||||
private async loadNextGame(exitRoomPath: URL): Promise<void> {
|
||||
try {
|
||||
const room = await Room.createRoom(exitRoomPath);
|
||||
return gameManager.loadMap(room, this.scene);
|
||||
} catch (e: unknown) {
|
||||
console.warn('Error while pre-loading exit room "' + exitRoomPath.toString() + '"', e);
|
||||
}
|
||||
}
|
||||
|
||||
//todo: in a dedicated class/function?
|
||||
|
@ -1683,7 +1745,7 @@ ${escapedMessage}
|
|||
this.scene.start(ErrorSceneName, {
|
||||
title: "Banned",
|
||||
subTitle: "You were banned from WorkAdventure",
|
||||
message: "If you want more information, you may contact us at: workadventure@thecodingmachine.com",
|
||||
message: "If you want more information, you may contact us at: hello@workadventu.re",
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1698,14 +1760,14 @@ ${escapedMessage}
|
|||
this.scene.start(ErrorSceneName, {
|
||||
title: "Connection rejected",
|
||||
subTitle: "The world you are trying to join is full. Try again later.",
|
||||
message: "If you want more information, you may contact us at: workadventure@thecodingmachine.com",
|
||||
message: "If you want more information, you may contact us at: hello@workadventu.re",
|
||||
});
|
||||
} else {
|
||||
this.scene.start(ErrorSceneName, {
|
||||
title: "Connection rejected",
|
||||
subTitle: "You cannot join the World. Try again later. \n\r \n\r Error: " + message + ".",
|
||||
message:
|
||||
"If you want more information, you may contact administrator or contact us at: workadventure@thecodingmachine.com",
|
||||
"If you want more information, you may contact administrator or contact us at: hello@workadventu.re",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
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;
|
||||
}
|
167
front/src/Phaser/Game/SharedVariablesManager.ts
Normal file
167
front/src/Phaser/Game/SharedVariablesManager.ts
Normal file
|
@ -0,0 +1,167 @@
|
|||
import type { RoomConnection } from "../../Connexion/RoomConnection";
|
||||
import { iframeListener } from "../../Api/IframeListener";
|
||||
import type { Subscription } from "rxjs";
|
||||
import type { GameMap } from "./GameMap";
|
||||
import type { ITile, ITiledMapObject } from "../Map/ITiledMap";
|
||||
import type { Var } from "svelte/types/compiler/interfaces";
|
||||
import { init } from "svelte/internal";
|
||||
|
||||
interface Variable {
|
||||
defaultValue: unknown;
|
||||
readableBy?: string;
|
||||
writableBy?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores variables and provides a bridge between scripts and the pusher server.
|
||||
*/
|
||||
export class SharedVariablesManager {
|
||||
private _variables = new Map<string, unknown>();
|
||||
private variableObjects: Map<string, Variable>;
|
||||
|
||||
constructor(
|
||||
private roomConnection: RoomConnection,
|
||||
private gameMap: GameMap,
|
||||
serverVariables: Map<string, unknown>
|
||||
) {
|
||||
// We initialize the list of variable object at room start. The objects cannot be edited later
|
||||
// (otherwise, this would cause a security issue if the scripting API can edit this list of objects)
|
||||
this.variableObjects = SharedVariablesManager.findVariablesInMap(gameMap);
|
||||
|
||||
// Let's initialize default values
|
||||
for (const [name, variableObject] of this.variableObjects.entries()) {
|
||||
if (variableObject.readableBy && !this.roomConnection.hasTag(variableObject.readableBy)) {
|
||||
// Do not initialize default value for variables that are not readable
|
||||
continue;
|
||||
}
|
||||
|
||||
this._variables.set(name, variableObject.defaultValue);
|
||||
}
|
||||
|
||||
// Override default values with the variables from the server:
|
||||
for (const [name, value] of serverVariables) {
|
||||
this._variables.set(name, value);
|
||||
}
|
||||
|
||||
roomConnection.onSetVariable((name, value) => {
|
||||
this._variables.set(name, value);
|
||||
|
||||
// On server change, let's notify the iframes
|
||||
iframeListener.setVariable({
|
||||
key: name,
|
||||
value: value,
|
||||
});
|
||||
});
|
||||
|
||||
// When a variable is modified from an iFrame
|
||||
iframeListener.registerAnswerer("setVariable", (event, source) => {
|
||||
const key = event.key;
|
||||
|
||||
const object = this.variableObjects.get(key);
|
||||
|
||||
if (object === undefined) {
|
||||
const errMsg =
|
||||
'A script is trying to modify variable "' +
|
||||
key +
|
||||
'" but this variable is not defined in the map.' +
|
||||
'There should be an object in the map whose name is "' +
|
||||
key +
|
||||
'" and whose type is "variable"';
|
||||
console.error(errMsg);
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
if (object.writableBy && !this.roomConnection.hasTag(object.writableBy)) {
|
||||
const errMsg =
|
||||
'A script is trying to modify variable "' +
|
||||
key +
|
||||
'" but this variable is only writable for users with tag "' +
|
||||
object.writableBy +
|
||||
'".';
|
||||
console.error(errMsg);
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
// Let's stop any propagation of the value we set is the same as the existing value.
|
||||
if (JSON.stringify(event.value) === JSON.stringify(this._variables.get(key))) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._variables.set(key, event.value);
|
||||
|
||||
// Dispatch to the room connection.
|
||||
this.roomConnection.emitSetVariableEvent(key, event.value);
|
||||
|
||||
// Dispatch to other iframes
|
||||
iframeListener.dispatchVariableToOtherIframes(key, event.value, source);
|
||||
});
|
||||
}
|
||||
|
||||
private static findVariablesInMap(gameMap: GameMap): Map<string, Variable> {
|
||||
const objects = new Map<string, Variable>();
|
||||
for (const layer of gameMap.getMap().layers) {
|
||||
if (layer.type === "objectgroup") {
|
||||
for (const object of layer.objects) {
|
||||
if (object.type === "variable") {
|
||||
if (object.template) {
|
||||
console.warn(
|
||||
'Warning, a variable object is using a Tiled "template". WorkAdventure does not support objects generated from Tiled templates.'
|
||||
);
|
||||
}
|
||||
|
||||
// We store a copy of the object (to make it immutable)
|
||||
objects.set(object.name, this.iTiledObjectToVariable(object));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
private static iTiledObjectToVariable(object: ITiledMapObject): Variable {
|
||||
const variable: Variable = {
|
||||
defaultValue: undefined,
|
||||
};
|
||||
|
||||
if (object.properties) {
|
||||
for (const property of object.properties) {
|
||||
const value = property.value;
|
||||
switch (property.name) {
|
||||
case "default":
|
||||
variable.defaultValue = value;
|
||||
break;
|
||||
case "writableBy":
|
||||
if (typeof value !== "string") {
|
||||
throw new Error(
|
||||
'The writableBy property of variable "' + object.name + '" must be a string'
|
||||
);
|
||||
}
|
||||
if (value) {
|
||||
variable.writableBy = value;
|
||||
}
|
||||
break;
|
||||
case "readableBy":
|
||||
if (typeof value !== "string") {
|
||||
throw new Error(
|
||||
'The readableBy property of variable "' + object.name + '" must be a string'
|
||||
);
|
||||
}
|
||||
if (value) {
|
||||
variable.readableBy = value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
iframeListener.unregisterAnswerer("setVariable");
|
||||
}
|
||||
|
||||
get variables(): Map<string, unknown> {
|
||||
return this._variables;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import type { PositionInterface } from "../../Connexion/ConnexionModels";
|
||||
import type { ITiledMap, ITiledMapLayer, ITiledMapLayerProperty, ITiledMapTileLayer } from "../Map/ITiledMap";
|
||||
import type { ITiledMap, ITiledMapLayer, ITiledMapProperty, ITiledMapTileLayer } from "../Map/ITiledMap";
|
||||
import type { GameMap } from "./GameMap";
|
||||
|
||||
const defaultStartLayerName = "start";
|
||||
|
@ -112,12 +112,12 @@ export class StartPositionCalculator {
|
|||
}
|
||||
|
||||
private getProperty(layer: ITiledMapLayer | ITiledMap, name: string): string | boolean | number | undefined {
|
||||
const properties: ITiledMapLayerProperty[] | undefined = layer.properties;
|
||||
const properties: ITiledMapProperty[] | undefined = layer.properties;
|
||||
if (!properties) {
|
||||
return undefined;
|
||||
}
|
||||
const obj = properties.find(
|
||||
(property: ITiledMapLayerProperty) => property.name.toLowerCase() === name.toLowerCase()
|
||||
(property: ITiledMapProperty) => property.name.toLowerCase() === name.toLowerCase()
|
||||
);
|
||||
if (obj === undefined) {
|
||||
return undefined;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -16,7 +16,7 @@ export interface ITiledMap {
|
|||
* Map orientation (orthogonal)
|
||||
*/
|
||||
orientation: string;
|
||||
properties?: ITiledMapLayerProperty[];
|
||||
properties?: ITiledMapProperty[];
|
||||
|
||||
/**
|
||||
* Render order (right-down)
|
||||
|
@ -33,7 +33,7 @@ export interface ITiledMap {
|
|||
type?: string;
|
||||
}
|
||||
|
||||
export interface ITiledMapLayerProperty {
|
||||
export interface ITiledMapProperty {
|
||||
name: string;
|
||||
type: string;
|
||||
value: string | boolean | number | undefined;
|
||||
|
@ -51,7 +51,7 @@ export interface ITiledMapGroupLayer {
|
|||
id?: number;
|
||||
name: string;
|
||||
opacity: number;
|
||||
properties?: ITiledMapLayerProperty[];
|
||||
properties?: ITiledMapProperty[];
|
||||
|
||||
type: "group";
|
||||
visible: boolean;
|
||||
|
@ -69,7 +69,7 @@ export interface ITiledMapTileLayer {
|
|||
height: number;
|
||||
name: string;
|
||||
opacity: number;
|
||||
properties?: ITiledMapLayerProperty[];
|
||||
properties?: ITiledMapProperty[];
|
||||
encoding?: string;
|
||||
compression?: string;
|
||||
|
||||
|
@ -91,7 +91,7 @@ export interface ITiledMapObjectLayer {
|
|||
height: number;
|
||||
name: string;
|
||||
opacity: number;
|
||||
properties?: ITiledMapLayerProperty[];
|
||||
properties?: ITiledMapProperty[];
|
||||
encoding?: string;
|
||||
compression?: string;
|
||||
|
||||
|
@ -117,7 +117,7 @@ export interface ITiledMapObject {
|
|||
gid: number;
|
||||
height: number;
|
||||
name: string;
|
||||
properties: { [key: string]: string };
|
||||
properties?: ITiledMapProperty[];
|
||||
rotation: number;
|
||||
type: string;
|
||||
visible: boolean;
|
||||
|
@ -141,6 +141,7 @@ export interface ITiledMapObject {
|
|||
polyline: { x: number; y: number }[];
|
||||
|
||||
text?: ITiledText;
|
||||
template?: string;
|
||||
}
|
||||
|
||||
export interface ITiledText {
|
||||
|
@ -163,7 +164,7 @@ export interface ITiledTileSet {
|
|||
imagewidth: number;
|
||||
margin: number;
|
||||
name: string;
|
||||
properties: { [key: string]: string };
|
||||
properties?: ITiledMapProperty[];
|
||||
spacing: number;
|
||||
tilecount: number;
|
||||
tileheight: number;
|
||||
|
@ -182,7 +183,7 @@ export interface ITile {
|
|||
id: number;
|
||||
type?: string;
|
||||
|
||||
properties?: Array<ITiledMapLayerProperty>;
|
||||
properties?: ITiledMapProperty[];
|
||||
}
|
||||
|
||||
export interface ITiledMapTerrain {
|
||||
|
|
|
@ -18,6 +18,9 @@ import { registerMenuCommandStream } from "../../Api/Events/ui/MenuItemRegisterE
|
|||
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";
|
||||
|
@ -97,6 +100,10 @@ export class MenuScene extends Phaser.Scene {
|
|||
this.menuElement.setOrigin(0);
|
||||
MenuScene.revealMenusAfterInit(this.menuElement, "gameMenu");
|
||||
|
||||
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");
|
||||
|
@ -120,7 +127,11 @@ export class MenuScene extends Phaser.Scene {
|
|||
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);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -137,6 +148,9 @@ export class MenuScene extends Phaser.Scene {
|
|||
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
|
||||
|
@ -352,6 +366,9 @@ export class MenuScene extends Phaser.Scene {
|
|||
case "toggleFullscreen":
|
||||
this.toggleFullscreen();
|
||||
break;
|
||||
case "enableNotification":
|
||||
this.enableNotification();
|
||||
break;
|
||||
case "adminConsoleButton":
|
||||
if (get(consoleGlobalMessageManagerVisibleStore)) {
|
||||
consoleGlobalMessageManagerVisibleStore.set(false);
|
||||
|
@ -414,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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import {TextField} from "../Components/TextField";
|
||||
import { TextField } from "../Components/TextField";
|
||||
import Image = Phaser.GameObjects.Image;
|
||||
import Sprite = Phaser.GameObjects.Sprite;
|
||||
import Text = Phaser.GameObjects.Text;
|
||||
import ScenePlugin = Phaser.Scenes.ScenePlugin;
|
||||
import {WAError} from "./WAError";
|
||||
import { WAError } from "./WAError";
|
||||
|
||||
export const ErrorSceneName = "ErrorScene";
|
||||
enum Textures {
|
||||
icon = "icon",
|
||||
mainFont = "main_font"
|
||||
mainFont = "main_font",
|
||||
}
|
||||
|
||||
export class ErrorScene extends Phaser.Scene {
|
||||
|
@ -23,25 +23,21 @@ export class ErrorScene extends Phaser.Scene {
|
|||
|
||||
constructor() {
|
||||
super({
|
||||
key: ErrorSceneName
|
||||
key: ErrorSceneName,
|
||||
});
|
||||
}
|
||||
|
||||
init({title, subTitle, message}: { title?: string, subTitle?: string, message?: string }) {
|
||||
this.title = title ? title : '';
|
||||
this.subTitle = subTitle ? subTitle : '';
|
||||
this.message = message ? message : '';
|
||||
init({ title, subTitle, message }: { title?: string; subTitle?: string; message?: string }) {
|
||||
this.title = title ? title : "";
|
||||
this.subTitle = subTitle ? subTitle : "";
|
||||
this.message = message ? message : "";
|
||||
}
|
||||
|
||||
preload() {
|
||||
this.load.image(Textures.icon, "resources/logos/tcm_full.png");
|
||||
this.load.image(Textures.icon, "static/images/favicons/favicon-32x32.png");
|
||||
// Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap
|
||||
this.load.bitmapFont(Textures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
||||
this.load.spritesheet(
|
||||
'cat',
|
||||
'resources/characters/pipoya/Cat 01-1.png',
|
||||
{frameWidth: 32, frameHeight: 32}
|
||||
);
|
||||
this.load.bitmapFont(Textures.mainFont, "resources/fonts/arcade.png", "resources/fonts/arcade.xml");
|
||||
this.load.spritesheet("cat", "resources/characters/pipoya/Cat 01-1.png", { frameWidth: 32, frameHeight: 32 });
|
||||
}
|
||||
|
||||
create() {
|
||||
|
@ -50,15 +46,25 @@ export class ErrorScene extends Phaser.Scene {
|
|||
|
||||
this.titleField = new TextField(this, this.game.renderer.width / 2, this.game.renderer.height / 2, this.title);
|
||||
|
||||
this.subTitleField = new TextField(this, this.game.renderer.width / 2, this.game.renderer.height / 2 + 24, this.subTitle);
|
||||
this.subTitleField = new TextField(
|
||||
this,
|
||||
this.game.renderer.width / 2,
|
||||
this.game.renderer.height / 2 + 24,
|
||||
this.subTitle
|
||||
);
|
||||
|
||||
this.messageField = this.add.text(this.game.renderer.width / 2, this.game.renderer.height / 2 + 48, this.message, {
|
||||
fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif',
|
||||
fontSize: '10px'
|
||||
});
|
||||
this.messageField = this.add.text(
|
||||
this.game.renderer.width / 2,
|
||||
this.game.renderer.height / 2 + 48,
|
||||
this.message,
|
||||
{
|
||||
fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif',
|
||||
fontSize: "10px",
|
||||
}
|
||||
);
|
||||
this.messageField.setOrigin(0.5, 0.5);
|
||||
|
||||
this.cat = this.physics.add.sprite(this.game.renderer.width / 2, this.game.renderer.height / 2 - 32, 'cat', 6);
|
||||
this.cat = this.physics.add.sprite(this.game.renderer.width / 2, this.game.renderer.height / 2 - 32, "cat", 6);
|
||||
this.cat.flipY = true;
|
||||
}
|
||||
|
||||
|
@ -69,38 +75,38 @@ export class ErrorScene extends Phaser.Scene {
|
|||
public static showError(error: any, scene: ScenePlugin): void {
|
||||
console.error(error);
|
||||
|
||||
if (typeof error === 'string' || error instanceof String) {
|
||||
if (typeof error === "string" || error instanceof String) {
|
||||
scene.start(ErrorSceneName, {
|
||||
title: 'An error occurred',
|
||||
subTitle: error
|
||||
title: "An error occurred",
|
||||
subTitle: error,
|
||||
});
|
||||
} else if (error instanceof WAError) {
|
||||
scene.start(ErrorSceneName, {
|
||||
title: error.title,
|
||||
subTitle: error.subTitle,
|
||||
message: error.details
|
||||
message: error.details,
|
||||
});
|
||||
} else if (error.response) {
|
||||
// Axios HTTP error
|
||||
// client received an error response (5xx, 4xx)
|
||||
scene.start(ErrorSceneName, {
|
||||
title: 'HTTP ' + error.response.status + ' - ' + error.response.statusText,
|
||||
subTitle: 'An error occurred while accessing URL:',
|
||||
message: error.response.config.url
|
||||
title: "HTTP " + error.response.status + " - " + error.response.statusText,
|
||||
subTitle: "An error occurred while accessing URL:",
|
||||
message: error.response.config.url,
|
||||
});
|
||||
} else if (error.request) {
|
||||
// Axios HTTP error
|
||||
// client never received a response, or request never left
|
||||
scene.start(ErrorSceneName, {
|
||||
title: 'Network error',
|
||||
subTitle: error.message
|
||||
title: "Network error",
|
||||
subTitle: error.message,
|
||||
});
|
||||
} else if (error instanceof Error) {
|
||||
// Error
|
||||
scene.start(ErrorSceneName, {
|
||||
title: 'An error occurred',
|
||||
title: "An error occurred",
|
||||
subTitle: error.name,
|
||||
message: error.message
|
||||
message: error.message,
|
||||
});
|
||||
} else {
|
||||
throw error;
|
||||
|
@ -114,7 +120,7 @@ export class ErrorScene extends Phaser.Scene {
|
|||
scene.start(ErrorSceneName, {
|
||||
title,
|
||||
subTitle,
|
||||
message
|
||||
message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {TextField} from "../Components/TextField";
|
||||
import { TextField } from "../Components/TextField";
|
||||
import Image = Phaser.GameObjects.Image;
|
||||
import Sprite = Phaser.GameObjects.Sprite;
|
||||
|
||||
export const ReconnectingSceneName = "ReconnectingScene";
|
||||
enum ReconnectingTextures {
|
||||
icon = "icon",
|
||||
mainFont = "main_font"
|
||||
mainFont = "main_font",
|
||||
}
|
||||
|
||||
export class ReconnectingScene extends Phaser.Scene {
|
||||
|
@ -14,35 +14,40 @@ export class ReconnectingScene extends Phaser.Scene {
|
|||
|
||||
constructor() {
|
||||
super({
|
||||
key: ReconnectingSceneName
|
||||
key: ReconnectingSceneName,
|
||||
});
|
||||
}
|
||||
|
||||
preload() {
|
||||
this.load.image(ReconnectingTextures.icon, "resources/logos/tcm_full.png");
|
||||
this.load.image(ReconnectingTextures.icon, "static/images/favicons/favicon-32x32.png");
|
||||
// Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap
|
||||
this.load.bitmapFont(ReconnectingTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
||||
this.load.spritesheet(
|
||||
'cat',
|
||||
'resources/characters/pipoya/Cat 01-1.png',
|
||||
{frameWidth: 32, frameHeight: 32}
|
||||
);
|
||||
this.load.bitmapFont(ReconnectingTextures.mainFont, "resources/fonts/arcade.png", "resources/fonts/arcade.xml");
|
||||
this.load.spritesheet("cat", "resources/characters/pipoya/Cat 01-1.png", { frameWidth: 32, frameHeight: 32 });
|
||||
}
|
||||
|
||||
create() {
|
||||
this.logo = new Image(this, this.game.renderer.width - 30, this.game.renderer.height - 20, ReconnectingTextures.icon);
|
||||
this.logo = new Image(
|
||||
this,
|
||||
this.game.renderer.width - 30,
|
||||
this.game.renderer.height - 20,
|
||||
ReconnectingTextures.icon
|
||||
);
|
||||
this.add.existing(this.logo);
|
||||
|
||||
this.reconnectingField = new TextField(this, this.game.renderer.width / 2, this.game.renderer.height / 2, "Connection lost. Reconnecting...");
|
||||
this.reconnectingField = new TextField(
|
||||
this,
|
||||
this.game.renderer.width / 2,
|
||||
this.game.renderer.height / 2,
|
||||
"Connection lost. Reconnecting..."
|
||||
);
|
||||
|
||||
const cat = this.physics.add.sprite(this.game.renderer.width / 2, this.game.renderer.height / 2 - 32, 'cat');
|
||||
const cat = this.physics.add.sprite(this.game.renderer.width / 2, this.game.renderer.height / 2 - 32, "cat");
|
||||
this.anims.create({
|
||||
key: 'right',
|
||||
frames: this.anims.generateFrameNumbers('cat', { start: 6, end: 8 }),
|
||||
key: "right",
|
||||
frames: this.anims.generateFrameNumbers("cat", { start: 6, end: 8 }),
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
repeat: -1,
|
||||
});
|
||||
cat.play('right');
|
||||
|
||||
cat.play("right");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue