FIX: rewrote the way scene exits are triggered
This commit is contained in:
parent
c5af6df7fa
commit
09d6d22a5d
|
@ -29,6 +29,25 @@ export class Room {
|
||||||
this.hash = idWithHash.substr(indexOfHash + 1);
|
this.hash = idWithHash.substr(indexOfHash + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static getIdFromIdentifier(identifier: string, baseUrl: string, currentInstance: string): {roomId: string, hash: string} {
|
||||||
|
let roomId = '';
|
||||||
|
let hash = '';
|
||||||
|
if (!identifier.startsWith('/_/') && !identifier.startsWith('/@/')) { //relative file link
|
||||||
|
const absoluteExitSceneUrl = new URL(identifier, baseUrl);
|
||||||
|
roomId = '_/'+currentInstance+'/'+absoluteExitSceneUrl.hostname + absoluteExitSceneUrl.pathname; //in case of a relative url, we need to create a public roomId
|
||||||
|
hash = absoluteExitSceneUrl.hash;
|
||||||
|
hash = hash.substring(1); //remove the leading diese
|
||||||
|
} else { //absolute room Id
|
||||||
|
const parts = identifier.split('#');
|
||||||
|
roomId = parts[0];
|
||||||
|
roomId = roomId.substring(1); //remove the leading slash
|
||||||
|
if (parts.length > 1) {
|
||||||
|
hash = parts[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {roomId, hash}
|
||||||
|
}
|
||||||
|
|
||||||
public async getMapUrl(): Promise<string> {
|
public async getMapUrl(): Promise<string> {
|
||||||
return new Promise<string>((resolve, reject) => {
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
|
|
@ -52,6 +52,7 @@ export class RoomConnection implements RoomConnection {
|
||||||
private static websocketFactory: null|((url: string)=>any) = null; // eslint-disable-line @typescript-eslint/no-explicit-any
|
private static websocketFactory: null|((url: string)=>any) = null; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
private closed: boolean = false;
|
private closed: boolean = false;
|
||||||
private tags: string[] = [];
|
private tags: string[] = [];
|
||||||
|
private intervalId!: NodeJS.Timeout;
|
||||||
|
|
||||||
public static setWebsocketFactory(websocketFactory: (url: string)=>any): void { // eslint-disable-line @typescript-eslint/no-explicit-any
|
public static setWebsocketFactory(websocketFactory: (url: string)=>any): void { // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
RoomConnection.websocketFactory = websocketFactory;
|
RoomConnection.websocketFactory = websocketFactory;
|
||||||
|
@ -89,8 +90,12 @@ export class RoomConnection implements RoomConnection {
|
||||||
this.socket.onopen = (ev) => {
|
this.socket.onopen = (ev) => {
|
||||||
//we manually ping every 20s to not be logged out by the server, even when the game is in background.
|
//we manually ping every 20s to not be logged out by the server, even when the game is in background.
|
||||||
const pingMessage = new PingMessage();
|
const pingMessage = new PingMessage();
|
||||||
setInterval(() => this.socket.send(pingMessage.serializeBinary().buffer), manualPingDelay);
|
this.intervalId = setInterval(() => this.socket.send(pingMessage.serializeBinary().buffer), manualPingDelay);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.socket.onclose = () => {
|
||||||
|
clearTimeout(this.intervalId);
|
||||||
|
}
|
||||||
|
|
||||||
this.socket.onmessage = (messageEvent) => {
|
this.socket.onmessage = (messageEvent) => {
|
||||||
const arrayBuffer: ArrayBuffer = messageEvent.data;
|
const arrayBuffer: ArrayBuffer = messageEvent.data;
|
||||||
|
|
|
@ -39,20 +39,16 @@ export class GameManager {
|
||||||
public async loadMap(room: Room, scenePlugin: Phaser.Scenes.ScenePlugin): Promise<void> {
|
public async loadMap(room: Room, scenePlugin: Phaser.Scenes.ScenePlugin): Promise<void> {
|
||||||
const roomID = room.id;
|
const roomID = room.id;
|
||||||
const mapUrl = await room.getMapUrl();
|
const mapUrl = await room.getMapUrl();
|
||||||
console.log('Loading map '+roomID+' at url '+mapUrl);
|
|
||||||
|
|
||||||
const gameIndex = scenePlugin.getIndex(mapUrl);
|
const gameIndex = scenePlugin.getIndex(roomID);
|
||||||
if(gameIndex === -1){
|
if(gameIndex === -1){
|
||||||
const game : Phaser.Scene = GameScene.createFromUrl(room, mapUrl);
|
const game : Phaser.Scene = GameScene.createFromUrl(room, mapUrl);
|
||||||
console.log('Adding scene '+mapUrl);
|
scenePlugin.add(roomID, game, false);
|
||||||
scenePlugin.add(mapUrl, game, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async goToStartingMap(scenePlugin: Phaser.Scenes.ScenePlugin) {
|
public goToStartingMap(scenePlugin: Phaser.Scenes.ScenePlugin): void {
|
||||||
const url = await this.startRoom.getMapUrl();
|
scenePlugin.start(this.startRoom.id);
|
||||||
console.log('Starting scene '+url);
|
|
||||||
scenePlugin.start(url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMes
|
||||||
import {ResizableScene} from "../Login/ResizableScene";
|
import {ResizableScene} from "../Login/ResizableScene";
|
||||||
import {Room} from "../../Connexion/Room";
|
import {Room} from "../../Connexion/Room";
|
||||||
import {jitsiFactory} from "../../WebRtc/JitsiFactory";
|
import {jitsiFactory} from "../../WebRtc/JitsiFactory";
|
||||||
|
import {urlManager} from "../../Url/UrlManager";
|
||||||
|
|
||||||
export interface GameSceneInitInterface {
|
export interface GameSceneInitInterface {
|
||||||
initPosition: PointInterface|null
|
initPosition: PointInterface|null
|
||||||
|
@ -123,7 +124,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
private createPromise: Promise<void>;
|
private createPromise: Promise<void>;
|
||||||
private createPromiseResolve!: (value?: void | PromiseLike<void>) => void;
|
private createPromiseResolve!: (value?: void | PromiseLike<void>) => void;
|
||||||
|
|
||||||
MapKey: string;
|
|
||||||
MapUrlFile: string;
|
MapUrlFile: string;
|
||||||
RoomId: string;
|
RoomId: string;
|
||||||
instance: string;
|
instance: string;
|
||||||
|
@ -137,7 +137,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
y: -1000
|
y: -1000
|
||||||
}
|
}
|
||||||
|
|
||||||
private PositionNextScene: Array<Array<{ key: string, hash: string }>> = new Array<Array<{ key: string, hash: string }>>();
|
|
||||||
private presentationModeSprite!: Sprite;
|
private presentationModeSprite!: Sprite;
|
||||||
private chatModeSprite!: Sprite;
|
private chatModeSprite!: Sprite;
|
||||||
private gameMap!: GameMap;
|
private gameMap!: GameMap;
|
||||||
|
@ -146,17 +145,14 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
private outlinedItem: ActionableItem|null = null;
|
private outlinedItem: ActionableItem|null = null;
|
||||||
private userInputManager!: UserInputManager;
|
private userInputManager!: UserInputManager;
|
||||||
|
|
||||||
static createFromUrl(room: Room, mapUrlFile: string, gameSceneKey: string|null = null): GameScene {
|
static createFromUrl(room: Room, mapUrlFile: string): GameScene {
|
||||||
// We use the map URL as a key
|
// We use the map URL as a key
|
||||||
if (gameSceneKey === null) {
|
return new GameScene(room, mapUrlFile);
|
||||||
gameSceneKey = mapUrlFile;
|
|
||||||
}
|
|
||||||
return new GameScene(room, mapUrlFile, gameSceneKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private room: Room, MapUrlFile: string, gameSceneKey: string) {
|
constructor(private room: Room, MapUrlFile: string) {
|
||||||
super({
|
super({
|
||||||
key: gameSceneKey
|
key: room.id
|
||||||
});
|
});
|
||||||
|
|
||||||
this.GameManager = gameManager;
|
this.GameManager = gameManager;
|
||||||
|
@ -164,7 +160,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
this.groups = new Map<number, Sprite>();
|
this.groups = new Map<number, Sprite>();
|
||||||
this.instance = room.getInstance();
|
this.instance = room.getInstance();
|
||||||
|
|
||||||
this.MapKey = MapUrlFile;
|
|
||||||
this.MapUrlFile = MapUrlFile;
|
this.MapUrlFile = MapUrlFile;
|
||||||
this.RoomId = room.id;
|
this.RoomId = room.id;
|
||||||
|
|
||||||
|
@ -183,15 +178,15 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
file: file.src
|
file: file.src
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.load.on('filecomplete-tilemapJSON-'+this.MapKey, (key: string, type: string, data: unknown) => {
|
this.load.on('filecomplete-tilemapJSON-'+this.MapUrlFile, (key: string, type: string, data: unknown) => {
|
||||||
this.onMapLoad(data);
|
this.onMapLoad(data);
|
||||||
});
|
});
|
||||||
//TODO strategy to add access token
|
//TODO strategy to add access token
|
||||||
this.load.tilemapTiledJSON(this.MapKey, this.MapUrlFile);
|
this.load.tilemapTiledJSON(this.MapUrlFile, this.MapUrlFile);
|
||||||
// If the map has already been loaded as part of another GameScene, the "on load" event will not be triggered.
|
// If the map has already been loaded as part of another GameScene, the "on load" event will not be triggered.
|
||||||
// In this case, we check in the cache to see if the map is here and trigger the event manually.
|
// In this case, we check in the cache to see if the map is here and trigger the event manually.
|
||||||
if (this.cache.tilemap.exists(this.MapKey)) {
|
if (this.cache.tilemap.exists(this.MapUrlFile)) {
|
||||||
const data = this.cache.tilemap.get(this.MapKey);
|
const data = this.cache.tilemap.get(this.MapUrlFile);
|
||||||
this.onMapLoad(data);
|
this.onMapLoad(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,14 +297,16 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
//hook initialisation
|
//hook initialisation
|
||||||
init(initData : GameSceneInitInterface) {
|
init(initData : GameSceneInitInterface) {
|
||||||
if (initData.initPosition !== undefined) {
|
if (initData.initPosition !== undefined) {
|
||||||
this.initPosition = initData.initPosition;
|
this.initPosition = initData.initPosition; //todo: still used?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//hook create scene
|
//hook create scene
|
||||||
create(): void {
|
create(): void {
|
||||||
|
urlManager.editUrlForCurrentRoom(this.room);
|
||||||
|
|
||||||
//initalise map
|
//initalise map
|
||||||
this.Map = this.add.tilemap(this.MapKey);
|
this.Map = this.add.tilemap(this.MapUrlFile);
|
||||||
this.gameMap = new GameMap(this.mapFile);
|
this.gameMap = new GameMap(this.mapFile);
|
||||||
const mapDirUrl = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/'));
|
const mapDirUrl = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/'));
|
||||||
this.mapFile.tilesets.forEach((tileset: ITiledTileSet) => {
|
this.mapFile.tilesets.forEach((tileset: ITiledTileSet) => {
|
||||||
|
@ -319,25 +316,21 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
//permit to set bound collision
|
//permit to set bound collision
|
||||||
this.physics.world.setBounds(0, 0, this.Map.widthInPixels, this.Map.heightInPixels);
|
this.physics.world.setBounds(0, 0, this.Map.widthInPixels, this.Map.heightInPixels);
|
||||||
|
|
||||||
// Let's alter browser history
|
|
||||||
let path = this.room.id;
|
|
||||||
if (this.room.hash) {
|
|
||||||
path += '#' + this.room.hash;
|
|
||||||
}
|
|
||||||
window.history.pushState({}, 'WorkAdventure', path);
|
|
||||||
|
|
||||||
//add layer on map
|
//add layer on map
|
||||||
this.Layers = new Array<Phaser.Tilemaps.StaticTilemapLayer>();
|
this.Layers = new Array<Phaser.Tilemaps.StaticTilemapLayer>();
|
||||||
let depth = -2;
|
let depth = -2;
|
||||||
for (const layer of this.mapFile.layers) {
|
for (const layer of this.mapFile.layers) {
|
||||||
if (layer.type === 'tilelayer') {
|
if (layer.type === 'tilelayer') {
|
||||||
this.addLayer(this.Map.createStaticLayer(layer.name, this.Terrains, 0, 0).setDepth(depth));
|
this.addLayer(this.Map.createStaticLayer(layer.name, this.Terrains, 0, 0).setDepth(depth));
|
||||||
}
|
|
||||||
if (layer.type === 'tilelayer' && this.getExitSceneUrl(layer) !== undefined) {
|
const exitSceneUrl = this.getExitSceneUrl(layer);
|
||||||
this.loadNextGameFromExitSceneUrl(layer, this.mapFile.width);
|
if (exitSceneUrl !== undefined) {
|
||||||
} else if (layer.type === 'tilelayer' && this.getExitUrl(layer) !== undefined) {
|
this.loadNextGame(exitSceneUrl);
|
||||||
console.log('Loading exitUrl ', this.getExitUrl(layer))
|
}
|
||||||
this.loadNextGameFromExitUrl(layer, this.mapFile.width);
|
const exitUrl = this.getExitUrl(layer);
|
||||||
|
if (exitUrl !== undefined) {
|
||||||
|
this.loadNextGame(exitUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (layer.type === 'objectgroup' && layer.name === 'floorLayer') {
|
if (layer.type === 'objectgroup' && layer.name === 'floorLayer') {
|
||||||
depth = 10000;
|
depth = 10000;
|
||||||
|
@ -482,7 +475,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
if (position === undefined) {
|
if (position === undefined) {
|
||||||
throw new Error('Position missing from UserMovedMessage');
|
throw new Error('Position missing from UserMovedMessage');
|
||||||
}
|
}
|
||||||
//console.log('Received position ', position.getX(), position.getY(), "from user", message.getUserid());
|
|
||||||
|
|
||||||
const messageUserMoved: MessageUserMovedInterface = {
|
const messageUserMoved: MessageUserMovedInterface = {
|
||||||
userId: message.getUserid(),
|
userId: message.getUserid(),
|
||||||
|
@ -515,7 +507,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
this.simplePeer.unregister();
|
this.simplePeer.unregister();
|
||||||
|
|
||||||
const gameSceneKey = 'somekey' + Math.round(Math.random() * 10000);
|
const gameSceneKey = 'somekey' + Math.round(Math.random() * 10000);
|
||||||
const game: Phaser.Scene = GameScene.createFromUrl(this.room, this.MapUrlFile, gameSceneKey);
|
const game: Phaser.Scene = GameScene.createFromUrl(this.room, this.MapUrlFile);
|
||||||
this.scene.add(gameSceneKey, game, true,
|
this.scene.add(gameSceneKey, game, true,
|
||||||
{
|
{
|
||||||
initPosition: {
|
initPosition: {
|
||||||
|
@ -581,6 +573,12 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private triggerOnMapLayerPropertyChange(){
|
private triggerOnMapLayerPropertyChange(){
|
||||||
|
this.gameMap.onPropertyChange('exitSceneUrl', (newValue, oldValue) => {
|
||||||
|
if (newValue) this.onMapExit(newValue as string);
|
||||||
|
});
|
||||||
|
this.gameMap.onPropertyChange('exitUrl', (newValue, oldValue) => {
|
||||||
|
if (newValue) this.onMapExit(newValue as string);
|
||||||
|
});
|
||||||
this.gameMap.onPropertyChange('openWebsite', (newValue, oldValue, allProps) => {
|
this.gameMap.onPropertyChange('openWebsite', (newValue, oldValue, allProps) => {
|
||||||
if (newValue === undefined) {
|
if (newValue === undefined) {
|
||||||
layoutManager.removeActionButton('openWebsite', this.userInputManager);
|
layoutManager.removeActionButton('openWebsite', this.userInputManager);
|
||||||
|
@ -635,6 +633,25 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onMapExit(exitKey: string) {
|
||||||
|
const {roomId, hash} = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance);
|
||||||
|
//todo: push the hash into the url
|
||||||
|
if (!roomId) throw new Error('Could not find the room from its exit key: '+exitKey);
|
||||||
|
if (roomId !== this.scene.key) {
|
||||||
|
// We are completely destroying the current scene to avoid using a half-backed instance when coming back to the same map.
|
||||||
|
this.connection.closeConnection();
|
||||||
|
this.simplePeer.unregister();
|
||||||
|
this.scene.stop();
|
||||||
|
this.scene.remove(this.scene.key);
|
||||||
|
this.scene.start(roomId, {hash});
|
||||||
|
} else {
|
||||||
|
//if the exit points to the current map, we simply teleport the user back to the startLayer
|
||||||
|
this.initPositionFromLayerName(this.room.hash || 'start');
|
||||||
|
this.CurrentPlayer.x = this.startX;
|
||||||
|
this.CurrentPlayer.y = this.startY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private switchLayoutMode(): void {
|
private switchLayoutMode(): void {
|
||||||
//if discussion is activated, this layout cannot be activated
|
//if discussion is activated, this layout cannot be activated
|
||||||
|
@ -691,14 +708,13 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
return this.getProperty(layer, "exitUrl") as string|undefined;
|
return this.getProperty(layer, "exitUrl") as string|undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated the map property exitSceneUrl is deprecated
|
||||||
|
*/
|
||||||
private getExitSceneUrl(layer: ITiledMapLayer): string|undefined {
|
private getExitSceneUrl(layer: ITiledMapLayer): string|undefined {
|
||||||
return this.getProperty(layer, "exitSceneUrl") as string|undefined;
|
return this.getProperty(layer, "exitSceneUrl") as string|undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getExitSceneInstance(layer: ITiledMapLayer): string|undefined {
|
|
||||||
return this.getProperty(layer, "exitInstance") as string|undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
private isStartLayer(layer: ITiledMapLayer): boolean {
|
private isStartLayer(layer: ITiledMapLayer): boolean {
|
||||||
return this.getProperty(layer, "startLayer") == true;
|
return this.getProperty(layer, "startLayer") == true;
|
||||||
}
|
}
|
||||||
|
@ -715,66 +731,11 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
return obj.value;
|
return obj.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadNextGameFromExitSceneUrl(layer: ITiledMapLayer, mapWidth: number) {
|
|
||||||
const exitSceneUrl = this.getExitSceneUrl(layer);
|
|
||||||
if (exitSceneUrl === undefined) {
|
|
||||||
throw new Error('Layer is not an exit scene layer.');
|
|
||||||
}
|
|
||||||
let instance = this.getExitSceneInstance(layer);
|
|
||||||
if (instance === undefined) {
|
|
||||||
instance = this.instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
const absoluteExitSceneUrl = new URL(exitSceneUrl, this.MapUrlFile).href;
|
|
||||||
const absoluteExitSceneUrlWithoutProtocol = absoluteExitSceneUrl.toString().substr(absoluteExitSceneUrl.toString().indexOf('://')+3);
|
|
||||||
const roomId = '_/'+instance+'/'+absoluteExitSceneUrlWithoutProtocol;
|
|
||||||
|
|
||||||
this.loadNextGame(layer, mapWidth, roomId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private loadNextGameFromExitUrl(layer: ITiledMapLayer, mapWidth: number) {
|
|
||||||
const exitUrl = this.getExitUrl(layer);
|
|
||||||
if (exitUrl === undefined) {
|
|
||||||
throw new Error('Layer is not an exit layer.');
|
|
||||||
}
|
|
||||||
const fullPath = new URL(exitUrl, window.location.toString()).pathname;
|
|
||||||
|
|
||||||
this.loadNextGame(layer, mapWidth, fullPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
//todo: push that into the gameManager
|
//todo: push that into the gameManager
|
||||||
private loadNextGame(layer: ITiledMapLayer, mapWidth: number, roomId: string){
|
private async loadNextGame(exitSceneIdentifier: string){
|
||||||
|
const {roomId, hash} = Room.getIdFromIdentifier(exitSceneIdentifier, this.MapUrlFile, this.instance);
|
||||||
const room = new Room(roomId);
|
const room = new Room(roomId);
|
||||||
gameManager.loadMap(room, this.scene);
|
await gameManager.loadMap(room, this.scene);
|
||||||
const exitSceneKey = roomId;
|
|
||||||
|
|
||||||
const tiles : number[] = layer.data as number[];
|
|
||||||
for (let key=0; key < tiles.length; key++) {
|
|
||||||
const objectKey = tiles[key];
|
|
||||||
if(objectKey === 0){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//key + 1 because the start x = 0;
|
|
||||||
const y : number = parseInt(((key + 1) / mapWidth).toString());
|
|
||||||
const x : number = key - (y * mapWidth);
|
|
||||||
|
|
||||||
let hash = new URL(roomId, this.MapUrlFile).hash;
|
|
||||||
if (hash) {
|
|
||||||
hash = hash.substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//push and save switching case
|
|
||||||
if (this.PositionNextScene[y] === undefined) {
|
|
||||||
this.PositionNextScene[y] = new Array<{key: string, hash: string}>();
|
|
||||||
}
|
|
||||||
room.getMapUrl().then((url: string) => {
|
|
||||||
this.PositionNextScene[y][x] = {
|
|
||||||
key: url,
|
|
||||||
hash
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private startUser(layer: ITiledMapLayer): PositionInterface {
|
private startUser(layer: ITiledMapLayer): PositionInterface {
|
||||||
|
@ -975,33 +936,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
||||||
}
|
}
|
||||||
player.updatePosition(moveEvent);
|
player.updatePosition(moveEvent);
|
||||||
});
|
});
|
||||||
|
|
||||||
const nextSceneKey = this.checkToExit();
|
|
||||||
if (!nextSceneKey) return;
|
|
||||||
if (nextSceneKey.key !== this.scene.key) {
|
|
||||||
// We are completely destroying the current scene to avoid using a half-backed instance when coming back to the same map.
|
|
||||||
this.connection.closeConnection();
|
|
||||||
this.simplePeer.unregister();
|
|
||||||
this.scene.stop();
|
|
||||||
this.scene.remove(this.scene.key);
|
|
||||||
this.scene.start(nextSceneKey.key);
|
|
||||||
} else {
|
|
||||||
//if the exit points to the current map, we simply teleport the user back to the startLayer
|
|
||||||
this.initPositionFromLayerName(this.room.hash || 'start');
|
|
||||||
this.CurrentPlayer.x = this.startX;
|
|
||||||
this.CurrentPlayer.y = this.startY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkToExit(): {key: string, hash: string} | null {
|
|
||||||
const x = Math.floor(this.CurrentPlayer.x / 32);
|
|
||||||
const y = Math.floor(this.CurrentPlayer.y / 32);
|
|
||||||
|
|
||||||
if (this.PositionNextScene[y] !== undefined && this.PositionNextScene[y][x] !== undefined) {
|
|
||||||
return this.PositionNextScene[y][x];
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import {Room} from "../Connexion/Room";
|
||||||
|
|
||||||
export enum GameConnexionTypes {
|
export enum GameConnexionTypes {
|
||||||
anonymous=1,
|
anonymous=1,
|
||||||
|
@ -44,6 +45,15 @@ class UrlManager {
|
||||||
history.pushState({}, 'WorkAdventure', newUrl);
|
history.pushState({}, 'WorkAdventure', newUrl);
|
||||||
return newUrl;
|
return newUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo: is it duplicated with editUrlForRoom() ?
|
||||||
|
public editUrlForCurrentRoom(room: Room): void {
|
||||||
|
let path = room.id;
|
||||||
|
if (room.hash) {
|
||||||
|
path += '#'+room.hash;
|
||||||
|
}
|
||||||
|
history.pushState({}, 'WorkAdventure', path);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
42
front/tests/Phaser/Game/RoomTest.ts
Normal file
42
front/tests/Phaser/Game/RoomTest.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import "jasmine";
|
||||||
|
import {Room} from "../../../src/Connexion/Room";
|
||||||
|
|
||||||
|
describe("Room getIdFromIdentifier()", () => {
|
||||||
|
it("should work with an absolute room id and no hash as parameter", () => {
|
||||||
|
const {roomId, hash} = Room.getIdFromIdentifier('/_/global/maps.workadventu.re/test2.json', '', '');
|
||||||
|
expect(roomId).toEqual('_/global/maps.workadventu.re/test2.json');
|
||||||
|
expect(hash).toEqual('');
|
||||||
|
});
|
||||||
|
it("should work with an absolute room id and a hash as parameters", () => {
|
||||||
|
const {roomId, hash} = Room.getIdFromIdentifier('/_/global/maps.workadventu.re/test2.json#start', '', '');
|
||||||
|
expect(roomId).toEqual('_/global/maps.workadventu.re/test2.json');
|
||||||
|
expect(hash).toEqual("start");
|
||||||
|
});
|
||||||
|
it("should work with an absolute room id, regardless of baseUrl or instance", () => {
|
||||||
|
const {roomId, hash} = Room.getIdFromIdentifier('/_/global/maps.workadventu.re/test2.json', 'https://another.domain/_/global/test.json', 'lol');
|
||||||
|
expect(roomId).toEqual('_/global/maps.workadventu.re/test2.json');
|
||||||
|
expect(hash).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("should work with a relative file link and no hash as parameters", () => {
|
||||||
|
const {roomId, hash} = Room.getIdFromIdentifier('./test2.json', 'https://maps.workadventu.re/test.json', 'global');
|
||||||
|
expect(roomId).toEqual('_/global/maps.workadventu.re/test2.json');
|
||||||
|
expect(hash).toEqual('');
|
||||||
|
});
|
||||||
|
it("should work with a relative file link with no dot", () => {
|
||||||
|
const {roomId, hash} = Room.getIdFromIdentifier('test2.json', 'https://maps.workadventu.re/test.json', 'global');
|
||||||
|
expect(roomId).toEqual('_/global/maps.workadventu.re/test2.json');
|
||||||
|
expect(hash).toEqual('');
|
||||||
|
});
|
||||||
|
it("should work with a relative file link two levels deep", () => {
|
||||||
|
const {roomId, hash} = Room.getIdFromIdentifier('../floor1/Floor1.json', 'https://maps.workadventu.re/floor0/Floor0.json', 'global');
|
||||||
|
expect(roomId).toEqual('_/global/maps.workadventu.re/floor1/Floor1.json');
|
||||||
|
expect(hash).toEqual('');
|
||||||
|
});
|
||||||
|
it("should work with a relative file link and a hash as parameters", () => {
|
||||||
|
const {roomId, hash} = Room.getIdFromIdentifier('./test2.json#start', 'https://maps.workadventu.re/test.json', 'global');
|
||||||
|
expect(roomId).toEqual('_/global/maps.workadventu.re/test2.json');
|
||||||
|
expect(hash).toEqual("start");
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue