Refactoring connection to be part of a GameScene
Most of the refactoring issues we are seeing are probably due to the fact that we are trying to manipulate a ScenePlugin out of a Scene (the GameManager is not a Scene and holds a reference to a ScenePlugin coming from a Scene that might get invalidated by Phaser 3). Furthermore, if we want in the future to be able to scale, scenes could be hosted on different servers. Therefore, it makes no sense to have one connexion for the whole application. Instead, we should have one connexion for each scene.
This commit is contained in:
parent
593e0dc642
commit
d785a8a1bf
@ -1,4 +1,4 @@
|
|||||||
import {GameManager} from "./Phaser/Game/GameManager";
|
import {gameManager, GameManager} from "./Phaser/Game/GameManager";
|
||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
import {API_URL} from "./Enum/EnvironmentVariable";
|
import {API_URL} from "./Enum/EnvironmentVariable";
|
||||||
import {MessageUI} from "./Logger/MessageUI";
|
import {MessageUI} from "./Logger/MessageUI";
|
||||||
@ -118,36 +118,12 @@ export interface WebRtcSignalMessageInterface {
|
|||||||
signal: SignalData
|
signal: SignalData
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConnectionInterface {
|
|
||||||
socket: Socket|null;
|
|
||||||
token: string|null;
|
|
||||||
name: string|null;
|
|
||||||
userId: string|null;
|
|
||||||
|
|
||||||
createConnection(name: string, characterSelected: string): Promise<ConnectionInterface>;
|
|
||||||
|
|
||||||
loadStartMap(): Promise<StartMapInterface>;
|
|
||||||
|
|
||||||
joinARoom(roomId: string, startX: number, startY: number, direction: string, moving: boolean): void;
|
|
||||||
|
|
||||||
sharePosition(x: number, y: number, direction: string, moving: boolean): void;
|
|
||||||
|
|
||||||
/*webrtc*/
|
|
||||||
sendWebrtcSignal(signal: unknown, roomId: string, userId?: string|null, receiverId?: string): void;
|
|
||||||
|
|
||||||
receiveWebrtcSignal(callBack: Function): void;
|
|
||||||
|
|
||||||
receiveWebrtcStart(callBack: (message: WebRtcStartMessageInterface) => void): void;
|
|
||||||
|
|
||||||
disconnectMessage(callBack: (message: WebRtcDisconnectMessageInterface) => void): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StartMapInterface {
|
export interface StartMapInterface {
|
||||||
mapUrlStart: string,
|
mapUrlStart: string,
|
||||||
startInstance: string
|
startInstance: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Connection implements ConnectionInterface {
|
export class Connection implements Connection {
|
||||||
socket: Socket|null = null;
|
socket: Socket|null = null;
|
||||||
token: string|null = null;
|
token: string|null = null;
|
||||||
name: string|null = null; // TODO: drop "name" storage here
|
name: string|null = null; // TODO: drop "name" storage here
|
||||||
@ -159,32 +135,28 @@ export class Connection implements ConnectionInterface {
|
|||||||
lastPositionShared: PointInterface|null = null;
|
lastPositionShared: PointInterface|null = null;
|
||||||
lastRoom: string|null = null;
|
lastRoom: string|null = null;
|
||||||
|
|
||||||
constructor(GameManager: GameManager) {
|
private constructor(GameManager: GameManager) {
|
||||||
this.GameManager = GameManager;
|
this.GameManager = GameManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
createConnection(name: string, characterSelected: string): Promise<ConnectionInterface> {
|
public static createConnection(name: string, characterSelected: string): Promise<Connection> {
|
||||||
this.name = name;
|
let connection = new Connection(gameManager);
|
||||||
this.character = characterSelected;
|
connection.name = name;
|
||||||
|
connection.character = characterSelected;
|
||||||
return Axios.post(`${API_URL}/login`, {name: name})
|
return Axios.post(`${API_URL}/login`, {name: name})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.token = res.data.token;
|
connection.token = res.data.token;
|
||||||
this.socket = SocketIo(`${API_URL}`, {
|
connection.socket = SocketIo(`${API_URL}`, {
|
||||||
query: {
|
query: {
|
||||||
token: this.token
|
token: connection.token
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//listen event
|
//listen event
|
||||||
this.disconnectServer();
|
connection.disconnectServer();
|
||||||
this.errorMessage();
|
connection.errorMessage();
|
||||||
this.groupUpdatedOrCreated();
|
|
||||||
this.groupDeleted();
|
|
||||||
this.onUserJoins();
|
|
||||||
this.onUserMoved();
|
|
||||||
this.onUserLeft();
|
|
||||||
|
|
||||||
return this.connectSocketServer();
|
return connection.connectSocketServer();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@ -192,6 +164,14 @@ export class Connection implements ConnectionInterface {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public closeConnection(): void {
|
||||||
|
this.socket?.close();
|
||||||
|
this.socket = null;
|
||||||
|
this.lastPositionShared = null;
|
||||||
|
this.lastRoom = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private getSocket(): Socket {
|
private getSocket(): Socket {
|
||||||
if (this.socket === null) {
|
if (this.socket === null) {
|
||||||
throw new Error('Socket not initialized while using Connection')
|
throw new Error('Socket not initialized while using Connection')
|
||||||
@ -199,12 +179,8 @@ export class Connection implements ConnectionInterface {
|
|||||||
return this.socket;
|
return this.socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
connectSocketServer(): Promise<Connection>{
|
||||||
*
|
return new Promise<Connection>((resolve, reject) => {
|
||||||
* @param character
|
|
||||||
*/
|
|
||||||
connectSocketServer(): Promise<ConnectionInterface>{
|
|
||||||
return new Promise<ConnectionInterface>((resolve, reject) => {
|
|
||||||
this.getSocket().emit(EventMessage.SET_PLAYER_DETAILS, {
|
this.getSocket().emit(EventMessage.SET_PLAYER_DETAILS, {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
character: this.character
|
character: this.character
|
||||||
@ -237,24 +213,18 @@ export class Connection implements ConnectionInterface {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO add middleware with access token to secure api
|
|
||||||
loadStartMap() : Promise<StartMapInterface> {
|
|
||||||
return Axios.get(`${API_URL}/start-map`)
|
|
||||||
.then((res) => {
|
|
||||||
return res.data;
|
|
||||||
}).catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
throw err;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
joinARoom(roomId: string, startX: number, startY: number, direction: string, moving: boolean): void {
|
joinARoom(roomId: string, startX: number, startY: number, direction: string, moving: boolean): Promise<MessageUserPositionInterface[]> {
|
||||||
const point = new Point(startX, startY, direction, moving);
|
const point = new Point(startX, startY, direction, moving);
|
||||||
this.lastPositionShared = point;
|
this.lastPositionShared = point;
|
||||||
this.getSocket().emit(EventMessage.JOIN_ROOM, { roomId, position: {x: startX, y: startY, direction, moving }}, (userPositions: MessageUserPositionInterface[]) => {
|
let promise = new Promise<MessageUserPositionInterface[]>((resolve, reject) => {
|
||||||
this.GameManager.initUsersPosition(userPositions);
|
this.getSocket().emit(EventMessage.JOIN_ROOM, { roomId, position: {x: startX, y: startY, direction, moving }}, (userPositions: MessageUserPositionInterface[]) => {
|
||||||
});
|
//this.GameManager.initUsersPosition(userPositions);
|
||||||
|
resolve(userPositions);
|
||||||
|
});
|
||||||
|
})
|
||||||
this.lastRoom = roomId;
|
this.lastRoom = roomId;
|
||||||
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
sharePosition(x : number, y : number, direction : string, moving: boolean) : void{
|
sharePosition(x : number, y : number, direction : string, moving: boolean) : void{
|
||||||
@ -266,35 +236,24 @@ export class Connection implements ConnectionInterface {
|
|||||||
this.getSocket().emit(EventMessage.USER_POSITION, point);
|
this.getSocket().emit(EventMessage.USER_POSITION, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onUserJoins(): void {
|
public onUserJoins(callback: (message: MessageUserJoined) => void): void {
|
||||||
this.getSocket().on(EventMessage.JOIN_ROOM, (message: MessageUserJoined) => {
|
this.getSocket().on(EventMessage.JOIN_ROOM, callback);
|
||||||
this.GameManager.onUserJoins(message);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onUserMoved(): void {
|
public onUserMoved(callback: (message: MessageUserMovedInterface) => void): void {
|
||||||
this.getSocket().on(EventMessage.USER_MOVED, (message: MessageUserMovedInterface) => {
|
this.getSocket().on(EventMessage.USER_MOVED, callback);
|
||||||
this.GameManager.onUserMoved(message);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onUserLeft(): void {
|
public onUserLeft(callback: (userId: string) => void): void {
|
||||||
this.getSocket().on(EventMessage.USER_LEFT, (userId: string) => {
|
this.getSocket().on(EventMessage.USER_LEFT, callback);
|
||||||
this.GameManager.onUserLeft(userId);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private groupUpdatedOrCreated(): void {
|
public onGroupUpdatedOrCreated(callback: (groupCreateUpdateMessage: GroupCreatedUpdatedMessageInterface) => void): void {
|
||||||
this.getSocket().on(EventMessage.GROUP_CREATE_UPDATE, (groupCreateUpdateMessage: GroupCreatedUpdatedMessageInterface) => {
|
this.getSocket().on(EventMessage.GROUP_CREATE_UPDATE, callback);
|
||||||
//console.log('Group ', groupCreateUpdateMessage.groupId, " position :", groupCreateUpdateMessage.position.x, groupCreateUpdateMessage.position.y)
|
|
||||||
this.GameManager.shareGroupPosition(groupCreateUpdateMessage);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private groupDeleted(): void {
|
public onGroupDeleted(callback: (groupId: string) => void): void {
|
||||||
this.getSocket().on(EventMessage.GROUP_DELETE, (groupId: string) => {
|
this.getSocket().on(EventMessage.GROUP_DELETE, callback)
|
||||||
this.GameManager.deleteGroup(groupId);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendWebrtcSignal(signal: unknown, roomId: string, userId? : string|null, receiverId? : string) {
|
sendWebrtcSignal(signal: unknown, roomId: string, userId? : string|null, receiverId? : string) {
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
import {GameScene} from "./GameScene";
|
import {GameScene} from "./GameScene";
|
||||||
import {
|
import {
|
||||||
Connection, ConnectionInterface,
|
Connection,
|
||||||
GroupCreatedUpdatedMessageInterface,
|
GroupCreatedUpdatedMessageInterface,
|
||||||
ListMessageUserPositionInterface,
|
ListMessageUserPositionInterface,
|
||||||
MessageUserJoined,
|
MessageUserJoined,
|
||||||
MessageUserMovedInterface,
|
MessageUserMovedInterface,
|
||||||
MessageUserPositionInterface,
|
MessageUserPositionInterface,
|
||||||
Point,
|
Point,
|
||||||
PointInterface
|
PointInterface, StartMapInterface
|
||||||
} from "../../Connection";
|
} from "../../Connection";
|
||||||
import {SimplePeer} from "../../WebRtc/SimplePeer";
|
import {SimplePeer} from "../../WebRtc/SimplePeer";
|
||||||
import {AddPlayerInterface} from "./AddPlayerInterface";
|
import {AddPlayerInterface} from "./AddPlayerInterface";
|
||||||
import {ReconnectingScene, ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
|
import {ReconnectingScene, ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
|
||||||
import ScenePlugin = Phaser.Scenes.ScenePlugin;
|
import ScenePlugin = Phaser.Scenes.ScenePlugin;
|
||||||
import {Scene} from "phaser";
|
import {Scene} from "phaser";
|
||||||
|
import Axios from "axios";
|
||||||
|
import {API_URL} from "../../Enum/EnvironmentVariable";
|
||||||
|
|
||||||
/*export enum StatusGameManagerEnum {
|
/*export enum StatusGameManagerEnum {
|
||||||
IN_PROGRESS = 1,
|
IN_PROGRESS = 1,
|
||||||
@ -34,7 +36,7 @@ export interface MapObject {
|
|||||||
|
|
||||||
export class GameManager {
|
export class GameManager {
|
||||||
//status: number;
|
//status: number;
|
||||||
private ConnectionInstance: Connection;
|
//private ConnectionInstance: Connection;
|
||||||
private currentGameScene: GameScene|null = null;
|
private currentGameScene: GameScene|null = null;
|
||||||
private playerName: string;
|
private playerName: string;
|
||||||
SimplePeer : SimplePeer;
|
SimplePeer : SimplePeer;
|
||||||
@ -44,24 +46,26 @@ export class GameManager {
|
|||||||
//this.status = StatusGameManagerEnum.IN_PROGRESS;
|
//this.status = StatusGameManagerEnum.IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public connect(name: string, characterUserSelected : string): Promise<ConnectionInterface> {
|
public storePlayerDetails(name: string, characterUserSelected : string) /*: Promise<Connection>*/ {
|
||||||
this.playerName = name;
|
this.playerName = name;
|
||||||
this.characterUserSelected = characterUserSelected;
|
this.characterUserSelected = characterUserSelected;
|
||||||
this.ConnectionInstance = new Connection(this);
|
/*this.ConnectionInstance = new Connection(this);
|
||||||
return this.ConnectionInstance.createConnection(name, characterUserSelected).then((data : ConnectionInterface) => {
|
return this.ConnectionInstance.createConnection(name, characterUserSelected).then((data : Connection) => {
|
||||||
this.SimplePeer = new SimplePeer(this.ConnectionInstance);
|
this.SimplePeer = new SimplePeer(this.ConnectionInstance);
|
||||||
return data;
|
return data;
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
loadStartMap(){
|
loadStartMap() : Promise<StartMapInterface> {
|
||||||
return this.ConnectionInstance.loadStartMap().then((data) => {
|
return Axios.get(`${API_URL}/start-map`)
|
||||||
return data;
|
.then((res) => {
|
||||||
}).catch((err) => {
|
return res.data;
|
||||||
throw err;
|
}).catch((err) => {
|
||||||
});
|
console.error(err);
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentGameScene(gameScene: GameScene) {
|
setCurrentGameScene(gameScene: GameScene) {
|
||||||
@ -78,81 +82,14 @@ export class GameManager {
|
|||||||
//this.status = StatusGameManagerEnum.CURRENT_USER_CREATED;
|
//this.status = StatusGameManagerEnum.CURRENT_USER_CREATED;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
joinRoom(sceneKey: string, startX: number, startY: number, direction: string, moving: boolean){
|
|
||||||
this.ConnectionInstance.joinARoom(sceneKey, startX, startY, direction, moving);
|
|
||||||
}
|
|
||||||
|
|
||||||
onUserJoins(message: MessageUserJoined): void {
|
|
||||||
const userMessage: AddPlayerInterface = {
|
|
||||||
userId: message.userId,
|
|
||||||
character: message.character,
|
|
||||||
name: message.name,
|
|
||||||
position: message.position
|
|
||||||
}
|
|
||||||
this.getCurrentGameScene().addPlayer(userMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
onUserMoved(message: MessageUserMovedInterface): void {
|
|
||||||
this.getCurrentGameScene().updatePlayerPosition(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
onUserLeft(userId: string): void {
|
|
||||||
this.getCurrentGameScene().removePlayer(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
initUsersPosition(usersPosition: MessageUserPositionInterface[]): void {
|
|
||||||
// Shall we wait for room to be loaded?
|
|
||||||
/*if (this.status === StatusGameManagerEnum.IN_PROGRESS) {
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
try {
|
|
||||||
this.getCurrentGameScene().initUsersPosition(usersPosition)
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Share group position in game
|
|
||||||
*/
|
|
||||||
shareGroupPosition(groupPositionMessage: GroupCreatedUpdatedMessageInterface): void {
|
|
||||||
/*if (this.status === StatusGameManagerEnum.IN_PROGRESS) {
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
try {
|
|
||||||
this.getCurrentGameScene().shareGroupPosition(groupPositionMessage)
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteGroup(groupId: string): void {
|
|
||||||
/*if (this.status === StatusGameManagerEnum.IN_PROGRESS) {
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
try {
|
|
||||||
this.getCurrentGameScene().deleteGroup(groupId)
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getPlayerName(): string {
|
getPlayerName(): string {
|
||||||
return this.playerName;
|
return this.playerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPlayerId(): string|null {
|
|
||||||
return this.ConnectionInstance.userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCharacterSelected(): string {
|
getCharacterSelected(): string {
|
||||||
return this.characterUserSelected;
|
return this.characterUserSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
pushPlayerPosition(event: HasMovedEvent) {
|
|
||||||
this.ConnectionInstance.sharePosition(event.x, event.y, event.direction, event.moving);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadMap(mapUrl: string, scene: Phaser.Scenes.ScenePlugin, instance: string): string {
|
loadMap(mapUrl: string, scene: Phaser.Scenes.ScenePlugin, instance: string): string {
|
||||||
const sceneKey = GameScene.getMapKeyByUrl(mapUrl);
|
const sceneKey = GameScene.getMapKeyByUrl(mapUrl);
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {GameManager, gameManager, HasMovedEvent} from "./GameManager";
|
import {GameManager, gameManager, HasMovedEvent} from "./GameManager";
|
||||||
import {
|
import {
|
||||||
GroupCreatedUpdatedMessageInterface,
|
Connection,
|
||||||
|
GroupCreatedUpdatedMessageInterface, MessageUserJoined,
|
||||||
MessageUserMovedInterface,
|
MessageUserMovedInterface,
|
||||||
MessageUserPositionInterface, PointInterface, PositionInterface
|
MessageUserPositionInterface, PointInterface, PositionInterface
|
||||||
} from "../../Connection";
|
} from "../../Connection";
|
||||||
@ -23,6 +24,7 @@ import {PlayersPositionInterpolator} from "./PlayersPositionInterpolator";
|
|||||||
import {RemotePlayer} from "../Entity/RemotePlayer";
|
import {RemotePlayer} from "../Entity/RemotePlayer";
|
||||||
import GameObject = Phaser.GameObjects.GameObject;
|
import GameObject = Phaser.GameObjects.GameObject;
|
||||||
import { Queue } from 'queue-typescript';
|
import { Queue } from 'queue-typescript';
|
||||||
|
import {SimplePeer} from "../../WebRtc/SimplePeer";
|
||||||
|
|
||||||
|
|
||||||
export enum Textures {
|
export enum Textures {
|
||||||
@ -81,6 +83,9 @@ export class GameScene extends Phaser.Scene {
|
|||||||
pendingEvents: Queue<InitUserPositionEventInterface|AddPlayerEventInterface|RemovePlayerEventInterface|UserMovedEventInterface|GroupCreatedUpdatedEventInterface|DeleteGroupEventInterface> = new Queue<InitUserPositionEventInterface|AddPlayerEventInterface|RemovePlayerEventInterface|UserMovedEventInterface|GroupCreatedUpdatedEventInterface|DeleteGroupEventInterface>();
|
pendingEvents: Queue<InitUserPositionEventInterface|AddPlayerEventInterface|RemovePlayerEventInterface|UserMovedEventInterface|GroupCreatedUpdatedEventInterface|DeleteGroupEventInterface> = new Queue<InitUserPositionEventInterface|AddPlayerEventInterface|RemovePlayerEventInterface|UserMovedEventInterface|GroupCreatedUpdatedEventInterface|DeleteGroupEventInterface>();
|
||||||
private initPosition: PositionInterface|null = null;
|
private initPosition: PositionInterface|null = null;
|
||||||
private playersPositionInterpolator = new PlayersPositionInterpolator();
|
private playersPositionInterpolator = new PlayersPositionInterpolator();
|
||||||
|
private connection: Connection;
|
||||||
|
private simplePeer : SimplePeer;
|
||||||
|
private connectionPromise: Promise<Connection>
|
||||||
|
|
||||||
MapKey: string;
|
MapKey: string;
|
||||||
MapUrlFile: string;
|
MapUrlFile: string;
|
||||||
@ -99,8 +104,10 @@ export class GameScene extends Phaser.Scene {
|
|||||||
private PositionNextScene: Array<Array<{ key: string, hash: string }>> = new Array<Array<{ key: string, hash: string }>>();
|
private PositionNextScene: Array<Array<{ key: string, hash: string }>> = new Array<Array<{ key: string, hash: string }>>();
|
||||||
private startLayerName: string|undefined;
|
private startLayerName: string|undefined;
|
||||||
|
|
||||||
static createFromUrl(mapUrlFile: string, instance: string): GameScene {
|
static createFromUrl(mapUrlFile: string, instance: string, key: string|null = null): GameScene {
|
||||||
const key = GameScene.getMapKeyByUrl(mapUrlFile);
|
if (key === null) {
|
||||||
|
key = GameScene.getMapKeyByUrl(mapUrlFile);
|
||||||
|
}
|
||||||
return new GameScene(key, mapUrlFile, instance);
|
return new GameScene(key, mapUrlFile, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +124,7 @@ export class GameScene extends Phaser.Scene {
|
|||||||
this.MapKey = MapKey;
|
this.MapKey = MapKey;
|
||||||
this.MapUrlFile = MapUrlFile;
|
this.MapUrlFile = MapUrlFile;
|
||||||
this.RoomId = this.instance + '__' + this.MapKey;
|
this.RoomId = this.instance + '__' + this.MapKey;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//hook preload scene
|
//hook preload scene
|
||||||
@ -144,6 +152,49 @@ export class GameScene extends Phaser.Scene {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.load.bitmapFont('main_font', 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
this.load.bitmapFont('main_font', 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
||||||
|
|
||||||
|
this.connectionPromise = Connection.createConnection(gameManager.getPlayerName(), gameManager.getCharacterSelected()).then((connection : Connection) => {
|
||||||
|
this.connection = connection;
|
||||||
|
|
||||||
|
connection.onUserJoins((message: MessageUserJoined) => {
|
||||||
|
const userMessage: AddPlayerInterface = {
|
||||||
|
userId: message.userId,
|
||||||
|
character: message.character,
|
||||||
|
name: message.name,
|
||||||
|
position: message.position
|
||||||
|
}
|
||||||
|
this.addPlayer(userMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.onUserMoved((message: MessageUserMovedInterface) => {
|
||||||
|
this.updatePlayerPosition(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.onUserLeft((userId: string) => {
|
||||||
|
this.removePlayer(userId);
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.onGroupUpdatedOrCreated((groupPositionMessage: GroupCreatedUpdatedMessageInterface) => {
|
||||||
|
this.shareGroupPosition(groupPositionMessage);
|
||||||
|
})
|
||||||
|
|
||||||
|
connection.onGroupDeleted((groupId: string) => {
|
||||||
|
try {
|
||||||
|
this.deleteGroup(groupId);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// When connection is performed, let's connect SimplePeer
|
||||||
|
this.simplePeer = new SimplePeer(this.connection);
|
||||||
|
|
||||||
|
if (this.scene.isPaused()) {
|
||||||
|
this.scene.resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: we need to put a "unknown" instead of a "any" and validate the structure of the JSON we are receiving.
|
// FIXME: we need to put a "unknown" instead of a "any" and validate the structure of the JSON we are receiving.
|
||||||
@ -272,6 +323,11 @@ export class GameScene extends Phaser.Scene {
|
|||||||
path += '#'+this.startLayerName;
|
path += '#'+this.startLayerName;
|
||||||
}
|
}
|
||||||
window.history.pushState({}, 'WorkAdventure', path);
|
window.history.pushState({}, 'WorkAdventure', path);
|
||||||
|
|
||||||
|
// Let's pause the scene if the connection is not established yet
|
||||||
|
if (this.connection === undefined) {
|
||||||
|
this.scene.pause();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getExitSceneUrl(layer: ITiledMapLayer): string|undefined {
|
private getExitSceneUrl(layer: ITiledMapLayer): string|undefined {
|
||||||
@ -430,10 +486,14 @@ export class GameScene extends Phaser.Scene {
|
|||||||
this.createCollisionObject();
|
this.createCollisionObject();
|
||||||
|
|
||||||
//join room
|
//join room
|
||||||
this.GameManager.joinRoom(this.RoomId, this.startX, this.startY, PlayerAnimationNames.WalkDown, false);
|
this.connectionPromise.then((connection: Connection) => {
|
||||||
|
connection.joinARoom(this.RoomId, this.startX, this.startY, PlayerAnimationNames.WalkDown, false).then((userPositions: MessageUserPositionInterface[]) => {
|
||||||
|
this.initUsersPosition(userPositions);
|
||||||
|
});
|
||||||
|
|
||||||
//listen event to share position of user
|
//listen event to share position of user
|
||||||
this.CurrentPlayer.on(hasMovedEventName, this.pushPlayerPosition.bind(this))
|
this.CurrentPlayer.on(hasMovedEventName, this.pushPlayerPosition.bind(this))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pushPlayerPosition(event: HasMovedEvent) {
|
pushPlayerPosition(event: HasMovedEvent) {
|
||||||
@ -465,7 +525,7 @@ export class GameScene extends Phaser.Scene {
|
|||||||
private doPushPlayerPosition(event: HasMovedEvent): void {
|
private doPushPlayerPosition(event: HasMovedEvent): void {
|
||||||
this.lastMoveEventSent = event;
|
this.lastMoveEventSent = event;
|
||||||
this.lastSentTick = this.currentTick;
|
this.lastSentTick = this.currentTick;
|
||||||
this.GameManager.pushPlayerPosition(event);
|
this.connection.sharePosition(event.x, event.y, event.direction, event.moving);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventToClickOnTile(){
|
EventToClickOnTile(){
|
||||||
@ -525,6 +585,8 @@ export class GameScene extends Phaser.Scene {
|
|||||||
const nextSceneKey = this.checkToExit();
|
const nextSceneKey = this.checkToExit();
|
||||||
if(nextSceneKey){
|
if(nextSceneKey){
|
||||||
// We are completely destroying the current scene to avoid using a half-backed instance when coming back to the same map.
|
// 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.scene.stop();
|
||||||
this.scene.remove(this.scene.key);
|
this.scene.remove(this.scene.key);
|
||||||
this.scene.start(nextSceneKey.key, {
|
this.scene.start(nextSceneKey.key, {
|
||||||
startLayerName: nextSceneKey.hash
|
startLayerName: nextSceneKey.hash
|
||||||
@ -549,7 +611,7 @@ export class GameScene extends Phaser.Scene {
|
|||||||
/**
|
/**
|
||||||
* Called by the connexion when the full list of user position is received.
|
* Called by the connexion when the full list of user position is received.
|
||||||
*/
|
*/
|
||||||
public initUsersPosition(usersPosition: MessageUserPositionInterface[]): void {
|
private initUsersPosition(usersPosition: MessageUserPositionInterface[]): void {
|
||||||
this.pendingEvents.enqueue({
|
this.pendingEvents.enqueue({
|
||||||
type: "InitUserPositionEvent",
|
type: "InitUserPositionEvent",
|
||||||
event: usersPosition
|
event: usersPosition
|
||||||
@ -561,7 +623,7 @@ export class GameScene extends Phaser.Scene {
|
|||||||
* Put all the players on the map on map load.
|
* Put all the players on the map on map load.
|
||||||
*/
|
*/
|
||||||
private doInitUsersPosition(usersPosition: MessageUserPositionInterface[]): void {
|
private doInitUsersPosition(usersPosition: MessageUserPositionInterface[]): void {
|
||||||
const currentPlayerId = this.GameManager.getPlayerId();
|
const currentPlayerId = this.connection.userId;
|
||||||
|
|
||||||
// clean map
|
// clean map
|
||||||
this.MapPlayersByKey.forEach((player: RemotePlayer) => {
|
this.MapPlayersByKey.forEach((player: RemotePlayer) => {
|
||||||
|
@ -117,34 +117,31 @@ export class SelectCharacterScene extends Phaser.Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async login(name: string): Promise<StartMapInterface> {
|
private async login(name: string): Promise<StartMapInterface> {
|
||||||
return gameManager.connect(name, this.selectedPlayer.texture.key).then(() => {
|
gameManager.storePlayerDetails(name, this.selectedPlayer.texture.key);
|
||||||
// Do we have a start URL in the address bar? If so, let's redirect to this address
|
|
||||||
const instanceAndMapUrl = this.findMapUrl();
|
// Do we have a start URL in the address bar? If so, let's redirect to this address
|
||||||
if (instanceAndMapUrl !== null) {
|
const instanceAndMapUrl = this.findMapUrl();
|
||||||
const [mapUrl, instance] = instanceAndMapUrl;
|
if (instanceAndMapUrl !== null) {
|
||||||
const key = gameManager.loadMap(mapUrl, this.scene, instance);
|
const [mapUrl, instance] = instanceAndMapUrl;
|
||||||
this.scene.start(key, {
|
const key = gameManager.loadMap(mapUrl, this.scene, instance);
|
||||||
startLayerName: window.location.hash ? window.location.hash.substr(1) : undefined
|
this.scene.start(key, {
|
||||||
} as GameSceneInitInterface);
|
startLayerName: window.location.hash ? window.location.hash.substr(1) : undefined
|
||||||
return {
|
} as GameSceneInitInterface);
|
||||||
mapUrlStart: mapUrl,
|
return {
|
||||||
startInstance: instance
|
mapUrlStart: mapUrl,
|
||||||
};
|
startInstance: instance
|
||||||
} else {
|
};
|
||||||
// If we do not have a map address in the URL, let's ask the server for a start map.
|
} else {
|
||||||
return gameManager.loadStartMap().then((startMap: StartMapInterface) => {
|
// If we do not have a map address in the URL, let's ask the server for a start map.
|
||||||
const key = gameManager.loadMap(window.location.protocol + "//" + startMap.mapUrlStart, this.scene, startMap.startInstance);
|
return gameManager.loadStartMap().then((startMap: StartMapInterface) => {
|
||||||
this.scene.start(key);
|
const key = gameManager.loadMap(window.location.protocol + "//" + startMap.mapUrlStart, this.scene, startMap.startInstance);
|
||||||
return startMap;
|
this.scene.start(key);
|
||||||
}).catch((err) => {
|
return startMap;
|
||||||
console.error(err);
|
}).catch((err) => {
|
||||||
throw err;
|
console.error(err);
|
||||||
});
|
throw err;
|
||||||
}
|
});
|
||||||
}).catch((err) => {
|
}
|
||||||
console.error(err);
|
|
||||||
throw err;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
ConnectionInterface,
|
Connection,
|
||||||
WebRtcDisconnectMessageInterface,
|
WebRtcDisconnectMessageInterface,
|
||||||
WebRtcSignalMessageInterface,
|
WebRtcSignalMessageInterface,
|
||||||
WebRtcStartMessageInterface
|
WebRtcStartMessageInterface
|
||||||
@ -18,7 +18,7 @@ export interface UserSimplePeer{
|
|||||||
* This class manages connections to all the peers in the same group as me.
|
* This class manages connections to all the peers in the same group as me.
|
||||||
*/
|
*/
|
||||||
export class SimplePeer {
|
export class SimplePeer {
|
||||||
private Connection: ConnectionInterface;
|
private Connection: Connection;
|
||||||
private WebRtcRoomId: string;
|
private WebRtcRoomId: string;
|
||||||
private Users: Array<UserSimplePeer> = new Array<UserSimplePeer>();
|
private Users: Array<UserSimplePeer> = new Array<UserSimplePeer>();
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ export class SimplePeer {
|
|||||||
|
|
||||||
private PeerConnectionArray: Map<string, SimplePeerNamespace.Instance> = new Map<string, SimplePeerNamespace.Instance>();
|
private PeerConnectionArray: Map<string, SimplePeerNamespace.Instance> = new Map<string, SimplePeerNamespace.Instance>();
|
||||||
|
|
||||||
constructor(Connection: ConnectionInterface, WebRtcRoomId: string = "test-webrtc") {
|
constructor(Connection: Connection, WebRtcRoomId: string = "test-webrtc") {
|
||||||
this.Connection = Connection;
|
this.Connection = Connection;
|
||||||
this.WebRtcRoomId = WebRtcRoomId;
|
this.WebRtcRoomId = WebRtcRoomId;
|
||||||
this.MediaManager = new MediaManager((stream : MediaStream) => {
|
this.MediaManager = new MediaManager((stream : MediaStream) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user