Merge pull request #150 from thecodingmachine/strict_mode_front
Enabling Typescript strict mode on the front
This commit is contained in:
commit
7223c1804d
front
@ -98,10 +98,10 @@ export interface GroupCreatedUpdatedMessageInterface {
|
||||
}
|
||||
|
||||
export interface ConnectionInterface {
|
||||
socket: any;
|
||||
token: string;
|
||||
name: string;
|
||||
userId: string;
|
||||
socket: Socket|null;
|
||||
token: string|null;
|
||||
name: string|null;
|
||||
userId: string|null;
|
||||
|
||||
createConnection(name: string, characterSelected: string): Promise<any>;
|
||||
|
||||
@ -112,7 +112,7 @@ export interface ConnectionInterface {
|
||||
sharePosition(x: number, y: number, direction: string, moving: boolean): void;
|
||||
|
||||
/*webrtc*/
|
||||
sendWebrtcSignal(signal: any, roomId: string, userId?: string, receiverId?: string): void;
|
||||
sendWebrtcSignal(signal: any, roomId: string, userId?: string|null, receiverId?: string): void;
|
||||
|
||||
receiveWebrtcSignal(callBack: Function): void;
|
||||
|
||||
@ -122,15 +122,15 @@ export interface ConnectionInterface {
|
||||
}
|
||||
|
||||
export class Connection implements ConnectionInterface {
|
||||
socket: Socket;
|
||||
token: string;
|
||||
name: string; // TODO: drop "name" storage here
|
||||
character: string;
|
||||
userId: string;
|
||||
socket: Socket|null = null;
|
||||
token: string|null = null;
|
||||
name: string|null = null; // TODO: drop "name" storage here
|
||||
character: string|null = null;
|
||||
userId: string|null = null;
|
||||
|
||||
GameManager: GameManager;
|
||||
|
||||
lastPositionShared: PointInterface = null;
|
||||
lastPositionShared: PointInterface|null = null;
|
||||
lastRoom: string|null = null;
|
||||
|
||||
constructor(GameManager: GameManager) {
|
||||
@ -156,6 +156,13 @@ export class Connection implements ConnectionInterface {
|
||||
});
|
||||
}
|
||||
|
||||
private getSocket(): Socket {
|
||||
if (this.socket === null) {
|
||||
throw new Error('Socket not initialized while using Connection')
|
||||
}
|
||||
return this.socket;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param character
|
||||
@ -171,7 +178,7 @@ export class Connection implements ConnectionInterface {
|
||||
this.onUserLeft();
|
||||
|
||||
return new Promise<ConnectionInterface>((resolve, reject) => {
|
||||
this.socket.emit(EventMessage.SET_PLAYER_DETAILS, {
|
||||
this.getSocket().emit(EventMessage.SET_PLAYER_DETAILS, {
|
||||
name: this.name,
|
||||
character: this.character
|
||||
} as SetPlayerDetailsMessage, (id: string) => {
|
||||
@ -215,7 +222,7 @@ export class Connection implements ConnectionInterface {
|
||||
}
|
||||
|
||||
joinARoom(roomId: string, startX: number, startY: number, direction: string, moving: boolean): void {
|
||||
this.socket.emit(EventMessage.JOIN_ROOM, { roomId, position: {x: startX, y: startY, direction, moving }}, (userPositions: MessageUserPositionInterface[]) => {
|
||||
this.getSocket().emit(EventMessage.JOIN_ROOM, { roomId, position: {x: startX, y: startY, direction, moving }}, (userPositions: MessageUserPositionInterface[]) => {
|
||||
this.GameManager.initUsersPosition(userPositions);
|
||||
});
|
||||
this.lastRoom = roomId;
|
||||
@ -227,42 +234,42 @@ export class Connection implements ConnectionInterface {
|
||||
}
|
||||
let point = new Point(x, y, direction, moving);
|
||||
this.lastPositionShared = point;
|
||||
this.socket.emit(EventMessage.USER_POSITION, point);
|
||||
this.getSocket().emit(EventMessage.USER_POSITION, point);
|
||||
}
|
||||
|
||||
private onUserJoins(): void {
|
||||
this.socket.on(EventMessage.JOIN_ROOM, (message: MessageUserJoined) => {
|
||||
this.getSocket().on(EventMessage.JOIN_ROOM, (message: MessageUserJoined) => {
|
||||
this.GameManager.onUserJoins(message);
|
||||
});
|
||||
}
|
||||
|
||||
private onUserMoved(): void {
|
||||
this.socket.on(EventMessage.USER_MOVED, (message: MessageUserMovedInterface) => {
|
||||
this.getSocket().on(EventMessage.USER_MOVED, (message: MessageUserMovedInterface) => {
|
||||
this.GameManager.onUserMoved(message);
|
||||
});
|
||||
}
|
||||
|
||||
private onUserLeft(): void {
|
||||
this.socket.on(EventMessage.USER_LEFT, (userId: string) => {
|
||||
this.getSocket().on(EventMessage.USER_LEFT, (userId: string) => {
|
||||
this.GameManager.onUserLeft(userId);
|
||||
});
|
||||
}
|
||||
|
||||
private groupUpdatedOrCreated(): void {
|
||||
this.socket.on(EventMessage.GROUP_CREATE_UPDATE, (groupCreateUpdateMessage: GroupCreatedUpdatedMessageInterface) => {
|
||||
this.getSocket().on(EventMessage.GROUP_CREATE_UPDATE, (groupCreateUpdateMessage: GroupCreatedUpdatedMessageInterface) => {
|
||||
//console.log('Group ', groupCreateUpdateMessage.groupId, " position :", groupCreateUpdateMessage.position.x, groupCreateUpdateMessage.position.y)
|
||||
this.GameManager.shareGroupPosition(groupCreateUpdateMessage);
|
||||
})
|
||||
}
|
||||
|
||||
private groupDeleted(): void {
|
||||
this.socket.on(EventMessage.GROUP_DELETE, (groupId: string) => {
|
||||
this.getSocket().on(EventMessage.GROUP_DELETE, (groupId: string) => {
|
||||
this.GameManager.deleteGroup(groupId);
|
||||
})
|
||||
}
|
||||
|
||||
sendWebrtcSignal(signal: any, roomId: string, userId? : string, receiverId? : string) {
|
||||
return this.socket.emit(EventMessage.WEBRTC_SIGNAL, {
|
||||
sendWebrtcSignal(signal: any, roomId: string, userId? : string|null, receiverId? : string) {
|
||||
return this.getSocket().emit(EventMessage.WEBRTC_SIGNAL, {
|
||||
userId: userId ? userId : this.userId,
|
||||
receiverId: receiverId ? receiverId : this.userId,
|
||||
roomId: roomId,
|
||||
@ -271,31 +278,34 @@ export class Connection implements ConnectionInterface {
|
||||
}
|
||||
|
||||
receiveWebrtcStart(callback: Function) {
|
||||
this.socket.on(EventMessage.WEBRTC_START, callback);
|
||||
this.getSocket().on(EventMessage.WEBRTC_START, callback);
|
||||
}
|
||||
|
||||
receiveWebrtcSignal(callback: Function) {
|
||||
return this.socket.on(EventMessage.WEBRTC_SIGNAL, callback);
|
||||
return this.getSocket().on(EventMessage.WEBRTC_SIGNAL, callback);
|
||||
}
|
||||
|
||||
private errorMessage(): void {
|
||||
this.socket.on(EventMessage.MESSAGE_ERROR, (message: string) => {
|
||||
this.getSocket().on(EventMessage.MESSAGE_ERROR, (message: string) => {
|
||||
console.error(EventMessage.MESSAGE_ERROR, message);
|
||||
})
|
||||
}
|
||||
|
||||
private disconnectServer(): void {
|
||||
this.socket.on(EventMessage.CONNECT_ERROR, () => {
|
||||
this.getSocket().on(EventMessage.CONNECT_ERROR, () => {
|
||||
this.GameManager.switchToDisconnectedScene();
|
||||
});
|
||||
|
||||
this.socket.on(EventMessage.RECONNECT, () => {
|
||||
this.getSocket().on(EventMessage.RECONNECT, () => {
|
||||
this.connectSocketServer();
|
||||
if (this.lastPositionShared === null) {
|
||||
throw new Error('No last position shared found while reconnecting');
|
||||
}
|
||||
this.GameManager.reconnectToGameScene(this.lastPositionShared);
|
||||
});
|
||||
}
|
||||
|
||||
disconnectMessage(callback: Function): void {
|
||||
this.socket.on(EventMessage.WEBRTC_DISCONNECT, callback);
|
||||
this.getSocket().on(EventMessage.WEBRTC_DISCONNECT, callback);
|
||||
}
|
||||
}
|
||||
|
@ -3,18 +3,18 @@ export class MessageUI {
|
||||
static warningMessage(text: string){
|
||||
this.removeMessage();
|
||||
let body = document.getElementById("body");
|
||||
body.insertAdjacentHTML('afterbegin', `
|
||||
body?.insertAdjacentHTML('afterbegin', `
|
||||
<div id="message-reconnect" class="message-info warning">
|
||||
${text}
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
|
||||
static removeMessage(id : string = null) {
|
||||
static removeMessage(id : string|null = null) {
|
||||
if(!id){
|
||||
let messages = document.getElementsByClassName("message-info");
|
||||
for (let i = 0; i < messages.length; i++){
|
||||
messages.item(i).remove();
|
||||
messages.item(i)?.remove();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -24,14 +24,31 @@ export const PLAYER_RESOURCES: Array<any> = [
|
||||
{name: "Female8", img: "resources/characters/pipoya/Female 16-4.png"/*, x: 128, y: 128*/}
|
||||
];
|
||||
|
||||
export class PlayableCaracter extends Phaser.Physics.Arcade.Sprite {
|
||||
private bubble: SpeechBubble;
|
||||
interface AnimationData {
|
||||
key: string;
|
||||
frameRate: number;
|
||||
repeat: number;
|
||||
frameModel: string; //todo use an enum
|
||||
frameStart: number;
|
||||
frameEnd: number;
|
||||
}
|
||||
|
||||
export abstract class Character extends Phaser.Physics.Arcade.Sprite {
|
||||
private bubble: SpeechBubble|null = null;
|
||||
private readonly playerName: BitmapText;
|
||||
public PlayerValue: string;
|
||||
public PlayerTexture: string;
|
||||
|
||||
|
||||
constructor(scene: Phaser.Scene, x: number, y: number, texture: string, name: string, frame?: string | number) {
|
||||
constructor(scene: Phaser.Scene,
|
||||
x: number,
|
||||
y: number,
|
||||
texture: string,
|
||||
name: string,
|
||||
direction: string,
|
||||
moving: boolean,
|
||||
frame?: string | number
|
||||
) {
|
||||
super(scene, x, y, texture, frame);
|
||||
|
||||
this.PlayerValue = name;
|
||||
@ -51,6 +68,64 @@ export class PlayableCaracter extends Phaser.Physics.Arcade.Sprite {
|
||||
this.setDepth(-1);
|
||||
|
||||
this.scene.events.on('postupdate', this.postupdate.bind(this));
|
||||
|
||||
this.initAnimation();
|
||||
this.playAnimation(direction, moving);
|
||||
}
|
||||
|
||||
private initAnimation(): void {
|
||||
this.getPlayerAnimations(this.PlayerTexture).forEach(d => {
|
||||
this.scene.anims.create({
|
||||
key: d.key,
|
||||
frames: this.scene.anims.generateFrameNumbers(d.frameModel, {start: d.frameStart, end: d.frameEnd}),
|
||||
frameRate: d.frameRate,
|
||||
repeat: d.repeat
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
private getPlayerAnimations(name: string): AnimationData[] {
|
||||
return [{
|
||||
key: `${name}-${PlayerAnimationNames.WalkDown}`,
|
||||
frameModel: name,
|
||||
frameStart: 0,
|
||||
frameEnd: 2,
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationNames.WalkLeft}`,
|
||||
frameModel: name,
|
||||
frameStart: 3,
|
||||
frameEnd: 5,
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationNames.WalkRight}`,
|
||||
frameModel: name,
|
||||
frameStart: 6,
|
||||
frameEnd: 8,
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationNames.WalkUp}`,
|
||||
frameModel: name,
|
||||
frameStart: 9,
|
||||
frameEnd: 11,
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}];
|
||||
}
|
||||
|
||||
protected playAnimation(direction : string, moving: boolean): void {
|
||||
if (moving && (!this.anims.currentAnim || this.anims.currentAnim.key !== direction)) {
|
||||
this.play(this.PlayerTexture+'-'+direction, true);
|
||||
} else if (!moving) {
|
||||
/*if (this.anims.currentAnim) {
|
||||
this.anims.stop();
|
||||
}*/
|
||||
this.play(this.PlayerTexture+'-'+direction, true);
|
||||
this.stop();
|
||||
}
|
||||
}
|
||||
|
||||
move(x: number, y: number) {
|
||||
@ -91,8 +166,10 @@ export class PlayableCaracter extends Phaser.Physics.Arcade.Sprite {
|
||||
this.bubble = new SpeechBubble(this.scene, this, text)
|
||||
//todo make the bubble destroy on player movement?
|
||||
setTimeout(() => {
|
||||
this.bubble.destroy();
|
||||
this.bubble = null;
|
||||
if (this.bubble !== null) {
|
||||
this.bubble.destroy();
|
||||
this.bubble = null;
|
||||
}
|
||||
}, 3000)
|
||||
}
|
||||
|
38
front/src/Phaser/Entity/RemotePlayer.ts
Normal file
38
front/src/Phaser/Entity/RemotePlayer.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import {GameScene} from "../Game/GameScene";
|
||||
import {PointInterface} from "../../Connection";
|
||||
import {Character} from "../Entity/Character";
|
||||
|
||||
/**
|
||||
* Class representing the sprite of a remote player (a player that plays on another computer)
|
||||
*/
|
||||
export class RemotePlayer extends Character {
|
||||
userId: string;
|
||||
previousDirection: string;
|
||||
wasMoving: boolean;
|
||||
|
||||
constructor(
|
||||
userId: string,
|
||||
Scene: GameScene,
|
||||
x: number,
|
||||
y: number,
|
||||
name: string,
|
||||
PlayerTexture: string,
|
||||
direction: string,
|
||||
moving: boolean
|
||||
) {
|
||||
super(Scene, x, y, PlayerTexture, name, direction, moving, 1);
|
||||
|
||||
//set data
|
||||
this.userId = userId;
|
||||
|
||||
//the current player model should be push away by other players to prevent conflict
|
||||
//this.setImmovable(false);
|
||||
}
|
||||
|
||||
updatePosition(position: PointInterface): void {
|
||||
this.playAnimation(position.direction, position.moving);
|
||||
this.setX(position.x);
|
||||
this.setY(position.y);
|
||||
this.setDepth(position.y);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import Scene = Phaser.Scene;
|
||||
import {PlayableCaracter} from "./PlayableCaracter";
|
||||
import {Character} from "./Character";
|
||||
|
||||
export class SpeechBubble {
|
||||
private bubble: Phaser.GameObjects.Graphics;
|
||||
@ -11,7 +11,7 @@ export class SpeechBubble {
|
||||
* @param player
|
||||
* @param text
|
||||
*/
|
||||
constructor(scene: Scene, player: PlayableCaracter, text: string = "") {
|
||||
constructor(scene: Scene, player: Character, text: string = "") {
|
||||
|
||||
let bubbleHeight = 50;
|
||||
let bubblePadding = 10;
|
||||
@ -80,9 +80,6 @@ export class SpeechBubble {
|
||||
destroy(): void {
|
||||
this.bubble.setVisible(false) //todo find a better way
|
||||
this.bubble.destroy();
|
||||
this.bubble = null;
|
||||
this.content.destroy();
|
||||
this.content = null;
|
||||
}
|
||||
|
||||
}
|
@ -9,7 +9,7 @@ import {
|
||||
Point,
|
||||
PointInterface
|
||||
} from "../../Connection";
|
||||
import {SimplePeerInterface, SimplePeer} from "../../WebRtc/SimplePeer";
|
||||
import {SimplePeer} from "../../WebRtc/SimplePeer";
|
||||
import {AddPlayerInterface} from "./AddPlayerInterface";
|
||||
import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
|
||||
|
||||
@ -35,7 +35,7 @@ export class GameManager {
|
||||
private ConnectionInstance: Connection;
|
||||
private currentGameScene: GameScene;
|
||||
private playerName: string;
|
||||
SimplePeer : SimplePeerInterface;
|
||||
SimplePeer : SimplePeer;
|
||||
private characterUserSelected: string;
|
||||
|
||||
constructor() {
|
||||
@ -139,7 +139,7 @@ export class GameManager {
|
||||
return this.playerName;
|
||||
}
|
||||
|
||||
getPlayerId(): string {
|
||||
getPlayerId(): string|null {
|
||||
return this.ConnectionInstance.userId;
|
||||
}
|
||||
|
||||
@ -155,9 +155,8 @@ export class GameManager {
|
||||
let sceneKey = GameScene.getMapKeyByUrl(mapUrl);
|
||||
|
||||
let gameIndex = scene.getIndex(sceneKey);
|
||||
let game : Phaser.Scene = null;
|
||||
if(gameIndex === -1){
|
||||
game = GameScene.createFromUrl(mapUrl, instance);
|
||||
let game : Phaser.Scene = GameScene.createFromUrl(mapUrl, instance);
|
||||
scene.add(sceneKey, game, false);
|
||||
}
|
||||
return sceneKey;
|
||||
|
@ -4,10 +4,10 @@ import {
|
||||
MessageUserMovedInterface,
|
||||
MessageUserPositionInterface, PointInterface, PositionInterface
|
||||
} from "../../Connection";
|
||||
import {CurrentGamerInterface, GamerInterface, hasMovedEventName, Player} from "../Player/Player";
|
||||
import {CurrentGamerInterface, hasMovedEventName, Player} from "../Player/Player";
|
||||
import { DEBUG_MODE, ZOOM_LEVEL, POSITION_DELAY } from "../../Enum/EnvironmentVariable";
|
||||
import {ITiledMap, ITiledMapLayer, ITiledTileSet} from "../Map/ITiledMap";
|
||||
import {PLAYER_RESOURCES} from "../Entity/PlayableCaracter";
|
||||
import {PLAYER_RESOURCES} from "../Entity/Character";
|
||||
import Texture = Phaser.Textures.Texture;
|
||||
import Sprite = Phaser.GameObjects.Sprite;
|
||||
import CanvasTexture = Phaser.Textures.CanvasTexture;
|
||||
@ -15,6 +15,7 @@ import {AddPlayerInterface} from "./AddPlayerInterface";
|
||||
import {PlayerAnimationNames} from "../Player/Animation";
|
||||
import {PlayerMovement} from "./PlayerMovement";
|
||||
import {PlayersPositionInterpolator} from "./PlayersPositionInterpolator";
|
||||
import {RemotePlayer} from "../Entity/RemotePlayer";
|
||||
|
||||
export enum Textures {
|
||||
Player = "male1"
|
||||
@ -29,16 +30,16 @@ export class GameScene extends Phaser.Scene {
|
||||
Terrains : Array<Phaser.Tilemaps.Tileset>;
|
||||
CurrentPlayer: CurrentGamerInterface;
|
||||
MapPlayers : Phaser.Physics.Arcade.Group;
|
||||
MapPlayersByKey : Map<string, GamerInterface> = new Map<string, GamerInterface>();
|
||||
MapPlayersByKey : Map<string, RemotePlayer> = new Map<string, RemotePlayer>();
|
||||
Map: Phaser.Tilemaps.Tilemap;
|
||||
Layers : Array<Phaser.Tilemaps.StaticTilemapLayer>;
|
||||
Objects : Array<Phaser.Physics.Arcade.Sprite>;
|
||||
map: ITiledMap;
|
||||
mapFile: ITiledMap;
|
||||
groups: Map<string, Sprite>;
|
||||
startX = 704;// 22 case
|
||||
startY = 32; // 1 case
|
||||
circleTexture: CanvasTexture;
|
||||
initPosition: PositionInterface;
|
||||
private initPosition: PositionInterface|null = null;
|
||||
private playersPositionInterpolator = new PlayersPositionInterpolator();
|
||||
|
||||
MapKey: string;
|
||||
@ -107,9 +108,9 @@ export class GameScene extends Phaser.Scene {
|
||||
private onMapLoad(data: any): void {
|
||||
// Triggered when the map is loaded
|
||||
// Load tiles attached to the map recursively
|
||||
this.map = data.data;
|
||||
this.mapFile = data.data;
|
||||
let url = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/'));
|
||||
this.map.tilesets.forEach((tileset) => {
|
||||
this.mapFile.tilesets.forEach((tileset) => {
|
||||
if (typeof tileset.name === 'undefined' || typeof tileset.image === 'undefined') {
|
||||
console.warn("Don't know how to handle tileset ", tileset)
|
||||
return;
|
||||
@ -121,14 +122,16 @@ export class GameScene extends Phaser.Scene {
|
||||
|
||||
//hook initialisation
|
||||
init(initData : GameSceneInitInterface) {
|
||||
this.initPosition = initData.initPosition;
|
||||
if (initData.initPosition !== undefined) {
|
||||
this.initPosition = initData.initPosition;
|
||||
}
|
||||
}
|
||||
|
||||
//hook create scene
|
||||
create(): void {
|
||||
//initalise map
|
||||
this.Map = this.add.tilemap(this.MapKey);
|
||||
this.map.tilesets.forEach((tileset: ITiledTileSet) => {
|
||||
this.mapFile.tilesets.forEach((tileset: ITiledTileSet) => {
|
||||
this.Terrains.push(this.Map.addTilesetImage(tileset.name, tileset.name));
|
||||
});
|
||||
|
||||
@ -138,12 +141,12 @@ export class GameScene extends Phaser.Scene {
|
||||
//add layer on map
|
||||
this.Layers = new Array<Phaser.Tilemaps.StaticTilemapLayer>();
|
||||
let depth = -2;
|
||||
this.map.layers.forEach((layer : ITiledMapLayer) => {
|
||||
this.mapFile.layers.forEach((layer : ITiledMapLayer) => {
|
||||
if (layer.type === 'tilelayer') {
|
||||
this.addLayer(this.Map.createStaticLayer(layer.name, this.Terrains, 0, 0).setDepth(depth));
|
||||
}
|
||||
if (layer.type === 'tilelayer' && this.getExitSceneUrl(layer) !== undefined) {
|
||||
this.loadNextGame(layer, this.map.width, this.map.tilewidth, this.map.tileheight);
|
||||
this.loadNextGame(layer, this.mapFile.width, this.mapFile.tilewidth, this.mapFile.tileheight);
|
||||
}
|
||||
if (layer.type === 'tilelayer' && layer.name === "start") {
|
||||
let startPosition = this.startUser(layer);
|
||||
@ -196,7 +199,7 @@ export class GameScene extends Phaser.Scene {
|
||||
// FIXME: entry should be dictated by a property passed to init()
|
||||
path += '#'+url.hash;
|
||||
}
|
||||
window.history.pushState({}, null, path);
|
||||
window.history.pushState({}, 'WorkAdventure', path);
|
||||
}
|
||||
|
||||
private getExitSceneUrl(layer: ITiledMapLayer): string|undefined {
|
||||
@ -232,6 +235,9 @@ export class GameScene extends Phaser.Scene {
|
||||
*/
|
||||
private loadNextGame(layer: ITiledMapLayer, mapWidth: number, tileWidth: number, tileHeight: number){
|
||||
let 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;
|
||||
@ -265,7 +271,7 @@ export class GameScene extends Phaser.Scene {
|
||||
* @param layer
|
||||
*/
|
||||
private startUser(layer: ITiledMapLayer): PositionInterface {
|
||||
if (this.initPosition !== undefined) {
|
||||
if (this.initPosition !== null) {
|
||||
this.startX = this.initPosition.x;
|
||||
this.startY = this.initPosition.y;
|
||||
return {
|
||||
@ -338,7 +344,6 @@ export class GameScene extends Phaser.Scene {
|
||||
//initialise player
|
||||
//TODO create animation moving between exit and start
|
||||
this.CurrentPlayer = new Player(
|
||||
null, // The current player is not has no id (because the id can change if connection is lost and we should check that id using the GameManager.
|
||||
this,
|
||||
this.startX,
|
||||
this.startY,
|
||||
@ -413,7 +418,7 @@ export class GameScene extends Phaser.Scene {
|
||||
// Let's move all users
|
||||
let updatedPlayersPositions = this.playersPositionInterpolator.getUpdatedPositions(time);
|
||||
updatedPlayersPositions.forEach((moveEvent: HasMovedEvent, userId: string) => {
|
||||
let player : GamerInterface | undefined = this.MapPlayersByKey.get(userId);
|
||||
let player : RemotePlayer | undefined = this.MapPlayersByKey.get(userId);
|
||||
if (player === undefined) {
|
||||
throw new Error('Cannot find player with ID "' + userId +'"');
|
||||
}
|
||||
@ -450,11 +455,11 @@ export class GameScene extends Phaser.Scene {
|
||||
let currentPlayerId = this.GameManager.getPlayerId();
|
||||
|
||||
// clean map
|
||||
this.MapPlayersByKey.forEach((player: GamerInterface) => {
|
||||
this.MapPlayersByKey.forEach((player: RemotePlayer) => {
|
||||
player.destroy();
|
||||
this.MapPlayers.remove(player);
|
||||
});
|
||||
this.MapPlayersByKey = new Map<string, GamerInterface>();
|
||||
this.MapPlayersByKey = new Map<string, RemotePlayer>();
|
||||
|
||||
// load map
|
||||
usersPosition.forEach((userPosition : MessageUserPositionInterface) => {
|
||||
@ -478,7 +483,7 @@ export class GameScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
//initialise player
|
||||
let player = new Player(
|
||||
let player = new RemotePlayer(
|
||||
addPlayerData.userId,
|
||||
this,
|
||||
addPlayerData.position.x,
|
||||
@ -503,15 +508,16 @@ export class GameScene extends Phaser.Scene {
|
||||
let player = this.MapPlayersByKey.get(userId);
|
||||
if (player === undefined) {
|
||||
console.error('Cannot find user with id ', userId);
|
||||
} else {
|
||||
player.destroy();
|
||||
this.MapPlayers.remove(player);
|
||||
}
|
||||
player.destroy();
|
||||
this.MapPlayers.remove(player);
|
||||
this.MapPlayersByKey.delete(userId);
|
||||
this.playersPositionInterpolator.removePlayer(userId);
|
||||
}
|
||||
|
||||
updatePlayerPosition(message: MessageUserMovedInterface): void {
|
||||
let player : GamerInterface | undefined = this.MapPlayersByKey.get(message.userId);
|
||||
let player : RemotePlayer | undefined = this.MapPlayersByKey.get(message.userId);
|
||||
if (player === undefined) {
|
||||
throw new Error('Cannot find player with ID "' + message.userId +'"');
|
||||
}
|
||||
@ -525,8 +531,9 @@ export class GameScene extends Phaser.Scene {
|
||||
shareGroupPosition(groupPositionMessage: GroupCreatedUpdatedMessageInterface) {
|
||||
let groupId = groupPositionMessage.groupId;
|
||||
|
||||
if (this.groups.has(groupId)) {
|
||||
this.groups.get(groupId).setPosition(Math.round(groupPositionMessage.position.x), Math.round(groupPositionMessage.position.y));
|
||||
let group = this.groups.get(groupId);
|
||||
if (group !== undefined) {
|
||||
group.setPosition(Math.round(groupPositionMessage.position.x), Math.round(groupPositionMessage.position.y));
|
||||
} else {
|
||||
// TODO: circle radius should not be hard stored
|
||||
let sprite = new Sprite(
|
||||
@ -541,10 +548,11 @@ export class GameScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
deleteGroup(groupId: string): void {
|
||||
if(!this.groups.get(groupId)){
|
||||
let group = this.groups.get(groupId);
|
||||
if(!group){
|
||||
return;
|
||||
}
|
||||
this.groups.get(groupId).destroy();
|
||||
group.destroy();
|
||||
this.groups.delete(groupId);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import {TextInput} from "../Components/TextInput";
|
||||
import {ClickButton} from "../Components/ClickButton";
|
||||
import Image = Phaser.GameObjects.Image;
|
||||
import Rectangle = Phaser.GameObjects.Rectangle;
|
||||
import {PLAYER_RESOURCES} from "../Entity/PlayableCaracter";
|
||||
import {PLAYER_RESOURCES} from "../Entity/Character";
|
||||
import {cypressAsserter} from "../../Cypress/CypressAsserter";
|
||||
import {SelectCharacterSceneInitDataInterface, SelectCharacterSceneName} from "./SelectCharacterScene";
|
||||
|
||||
@ -16,12 +16,12 @@ enum LoginTextures {
|
||||
}
|
||||
|
||||
export class LoginScene extends Phaser.Scene {
|
||||
private nameInput: TextInput;
|
||||
private textField: TextField;
|
||||
private infoTextField: TextField;
|
||||
private pressReturnField: TextField;
|
||||
private logo: Image;
|
||||
private name: string;
|
||||
private nameInput: TextInput|null = null;
|
||||
private textField: TextField|null = null;
|
||||
private infoTextField: TextField|null = null;
|
||||
private pressReturnField: TextField|null = null;
|
||||
private logo: Image|null = null;
|
||||
private name: string = '';
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
@ -82,9 +82,9 @@ export class LoginScene extends Phaser.Scene {
|
||||
|
||||
update(time: number, delta: number): void {
|
||||
if (this.name == '') {
|
||||
this.pressReturnField.setVisible(false);
|
||||
this.pressReturnField?.setVisible(false);
|
||||
} else {
|
||||
this.pressReturnField.setVisible(!!(Math.floor(time / 500) % 2));
|
||||
this.pressReturnField?.setVisible(!!(Math.floor(time / 500) % 2));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ import {TextField} from "../Components/TextField";
|
||||
import {ClickButton} from "../Components/ClickButton";
|
||||
import Image = Phaser.GameObjects.Image;
|
||||
import Rectangle = Phaser.GameObjects.Rectangle;
|
||||
import {PLAYER_RESOURCES} from "../Entity/PlayableCaracter";
|
||||
import {PLAYER_RESOURCES} from "../Entity/Character";
|
||||
|
||||
//todo: put this constants in a dedicated file
|
||||
export const SelectCharacterSceneName = "SelectCharacterScene";
|
||||
|
@ -2,39 +2,21 @@ import {PlayerAnimationNames} from "./Animation";
|
||||
import {GameScene, Textures} from "../Game/GameScene";
|
||||
import {MessageUserPositionInterface, PointInterface} from "../../Connection";
|
||||
import {ActiveEventList, UserInputEvent, UserInputManager} from "../UserInput/UserInputManager";
|
||||
import {PlayableCaracter} from "../Entity/PlayableCaracter";
|
||||
import {Character} from "../Entity/Character";
|
||||
|
||||
|
||||
export const hasMovedEventName = "hasMoved";
|
||||
export interface CurrentGamerInterface extends PlayableCaracter{
|
||||
export interface CurrentGamerInterface extends Character{
|
||||
moveUser(delta: number) : void;
|
||||
say(text : string) : void;
|
||||
}
|
||||
|
||||
export interface GamerInterface extends PlayableCaracter{
|
||||
userId : string;
|
||||
updatePosition(position: PointInterface): void;
|
||||
say(text : string) : void;
|
||||
}
|
||||
|
||||
interface AnimationData {
|
||||
key: string;
|
||||
frameRate: number;
|
||||
repeat: number;
|
||||
frameModel: string; //todo use an enum
|
||||
frameStart: number;
|
||||
frameEnd: number;
|
||||
}
|
||||
|
||||
|
||||
export class Player extends PlayableCaracter implements CurrentGamerInterface, GamerInterface {
|
||||
userId: string;
|
||||
export class Player extends Character implements CurrentGamerInterface {
|
||||
userInputManager: UserInputManager;
|
||||
previousDirection: string;
|
||||
wasMoving: boolean;
|
||||
|
||||
constructor(
|
||||
userId: string,
|
||||
Scene: GameScene,
|
||||
x: number,
|
||||
y: number,
|
||||
@ -43,62 +25,13 @@ export class Player extends PlayableCaracter implements CurrentGamerInterface, G
|
||||
direction: string,
|
||||
moving: boolean
|
||||
) {
|
||||
super(Scene, x, y, PlayerTexture, name, 1);
|
||||
super(Scene, x, y, PlayerTexture, name, direction, moving, 1);
|
||||
|
||||
//create input to move
|
||||
this.userInputManager = new UserInputManager(Scene);
|
||||
|
||||
//set data
|
||||
this.userId = userId;
|
||||
|
||||
//the current player model should be push away by other players to prevent conflict
|
||||
this.setImmovable(false);
|
||||
this.initAnimation();
|
||||
|
||||
this.playAnimation(direction, moving);
|
||||
}
|
||||
|
||||
private initAnimation(): void {
|
||||
this.getPlayerAnimations(this.PlayerTexture).forEach(d => {
|
||||
this.scene.anims.create({
|
||||
key: d.key,
|
||||
frames: this.scene.anims.generateFrameNumbers(d.frameModel, {start: d.frameStart, end: d.frameEnd}),
|
||||
frameRate: d.frameRate,
|
||||
repeat: d.repeat
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
private getPlayerAnimations(name: string): AnimationData[] {
|
||||
return [{
|
||||
key: `${name}-${PlayerAnimationNames.WalkDown}`,
|
||||
frameModel: name,
|
||||
frameStart: 0,
|
||||
frameEnd: 2,
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationNames.WalkLeft}`,
|
||||
frameModel: name,
|
||||
frameStart: 3,
|
||||
frameEnd: 5,
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationNames.WalkRight}`,
|
||||
frameModel: name,
|
||||
frameStart: 6,
|
||||
frameEnd: 8,
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationNames.WalkUp}`,
|
||||
frameModel: name,
|
||||
frameStart: 9,
|
||||
frameEnd: 11,
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}];
|
||||
}
|
||||
|
||||
moveUser(delta: number): void {
|
||||
@ -146,24 +79,4 @@ export class Player extends PlayableCaracter implements CurrentGamerInterface, G
|
||||
}
|
||||
this.wasMoving = moving;
|
||||
}
|
||||
|
||||
//todo: put this method into the NonPlayer class instead
|
||||
updatePosition(position: PointInterface): void {
|
||||
this.playAnimation(position.direction, position.moving);
|
||||
this.setX(position.x);
|
||||
this.setY(position.y);
|
||||
this.setDepth(position.y);
|
||||
}
|
||||
|
||||
private playAnimation(direction : string, moving: boolean): void {
|
||||
if (moving && (!this.anims.currentAnim || this.anims.currentAnim.key !== direction)) {
|
||||
this.play(this.PlayerTexture+'-'+direction, true);
|
||||
} else if (!moving) {
|
||||
/*if (this.anims.currentAnim) {
|
||||
this.anims.stop();
|
||||
}*/
|
||||
this.play(this.PlayerTexture+'-'+direction, true);
|
||||
this.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import {TextInput} from "../Components/TextInput";
|
||||
import {ClickButton} from "../Components/ClickButton";
|
||||
import Image = Phaser.GameObjects.Image;
|
||||
import Rectangle = Phaser.GameObjects.Rectangle;
|
||||
import {PLAYER_RESOURCES} from "../Entity/PlayableCaracter";
|
||||
import {PLAYER_RESOURCES} from "../Entity/Character";
|
||||
import {cypressAsserter} from "../../Cypress/CypressAsserter";
|
||||
import Sprite = Phaser.GameObjects.Sprite;
|
||||
|
||||
|
@ -2,7 +2,6 @@ import Map = Phaser.Structs.Map;
|
||||
import {GameScene} from "../Game/GameScene";
|
||||
|
||||
interface UserInputManagerDatum {
|
||||
keyCode: number;
|
||||
keyInstance: Phaser.Input.Keyboard.Key;
|
||||
event: UserInputEvent
|
||||
}
|
||||
@ -33,27 +32,26 @@ export class ActiveEventList {
|
||||
|
||||
//this class is responsible for catching user inputs and listing all active user actions at every game tick events.
|
||||
export class UserInputManager {
|
||||
private KeysCode: UserInputManagerDatum[] = [
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.Z, event: UserInputEvent.MoveUp, keyInstance: null},
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.Q, event: UserInputEvent.MoveLeft, keyInstance: null},
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.S, event: UserInputEvent.MoveDown, keyInstance: null},
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.D, event: UserInputEvent.MoveRight, keyInstance: null},
|
||||
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.UP, event: UserInputEvent.MoveUp, keyInstance: null},
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.LEFT, event: UserInputEvent.MoveLeft, keyInstance: null},
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.DOWN, event: UserInputEvent.MoveDown, keyInstance: null},
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.RIGHT, event: UserInputEvent.MoveRight, keyInstance: null},
|
||||
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.SHIFT, event: UserInputEvent.SpeedUp, keyInstance: null},
|
||||
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.E, event: UserInputEvent.Interact, keyInstance: null},
|
||||
{keyCode: Phaser.Input.Keyboard.KeyCodes.F, event: UserInputEvent.Shout, keyInstance: null},
|
||||
];
|
||||
private KeysCode: UserInputManagerDatum[];
|
||||
|
||||
constructor(Scene : GameScene) {
|
||||
this.KeysCode.forEach(d => {
|
||||
d.keyInstance = Scene.input.keyboard.addKey(d.keyCode);
|
||||
});
|
||||
|
||||
this.KeysCode = [
|
||||
{event: UserInputEvent.MoveUp, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Z) },
|
||||
{event: UserInputEvent.MoveLeft, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q) },
|
||||
{event: UserInputEvent.MoveDown, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S) },
|
||||
{event: UserInputEvent.MoveRight, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D) },
|
||||
|
||||
{event: UserInputEvent.MoveUp, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.UP) },
|
||||
{event: UserInputEvent.MoveLeft, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.LEFT) },
|
||||
{event: UserInputEvent.MoveDown, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.DOWN) },
|
||||
{event: UserInputEvent.MoveRight, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT) },
|
||||
|
||||
{event: UserInputEvent.SpeedUp, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SHIFT) },
|
||||
|
||||
{event: UserInputEvent.Interact, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E) },
|
||||
{event: UserInputEvent.Shout, keyInstance: Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.F) },
|
||||
];
|
||||
}
|
||||
|
||||
getEventListForGameTick(): ActiveEventList {
|
||||
|
@ -4,26 +4,25 @@ const videoConstraint: {width : any, height: any, facingMode : string} = {
|
||||
facingMode: "user"
|
||||
};
|
||||
export class MediaManager {
|
||||
localStream: MediaStream;
|
||||
localStream: MediaStream|null = null;
|
||||
remoteVideo: Array<any> = new Array<any>();
|
||||
myCamVideo: any;
|
||||
myCamVideo: HTMLVideoElement;
|
||||
cinemaClose: any = null;
|
||||
cinema: any = null;
|
||||
microphoneClose: any = null;
|
||||
microphone: any = null;
|
||||
webrtcInAudio: any;
|
||||
webrtcInAudio: HTMLAudioElement;
|
||||
constraintsMedia : {audio : any, video : any} = {
|
||||
audio: true,
|
||||
video: videoConstraint
|
||||
};
|
||||
getCameraPromise : Promise<any> = null;
|
||||
updatedLocalStreamCallBack : Function;
|
||||
|
||||
constructor(updatedLocalStreamCallBack : Function) {
|
||||
this.updatedLocalStreamCallBack = updatedLocalStreamCallBack;
|
||||
|
||||
this.myCamVideo = document.getElementById('myCamVideo');
|
||||
this.webrtcInAudio = document.getElementById('audio-webrtc-in');
|
||||
this.myCamVideo = this.getElementByIdOrFail<HTMLVideoElement>('myCamVideo');
|
||||
this.webrtcInAudio = this.getElementByIdOrFail<HTMLAudioElement>('audio-webrtc-in');
|
||||
this.webrtcInAudio.volume = 0.2;
|
||||
|
||||
this.microphoneClose = document.getElementById('microphone-close');
|
||||
@ -56,7 +55,7 @@ export class MediaManager {
|
||||
}
|
||||
|
||||
activeVisio(){
|
||||
let webRtc = document.getElementById('webRtc');
|
||||
let webRtc = this.getElementByIdOrFail('webRtc');
|
||||
webRtc.classList.add('active');
|
||||
}
|
||||
|
||||
@ -130,7 +129,7 @@ export class MediaManager {
|
||||
} catch (e) {
|
||||
promise = Promise.reject(false);
|
||||
}
|
||||
return this.getCameraPromise = promise;
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +138,7 @@ export class MediaManager {
|
||||
*/
|
||||
addActiveVideo(userId : string, userName: string = ""){
|
||||
this.webrtcInAudio.play();
|
||||
let elementRemoteVideo = document.getElementById("activeCam");
|
||||
let elementRemoteVideo = this.getElementByIdOrFail("activeCam");
|
||||
userName = userName.toUpperCase();
|
||||
let color = this.getColorByString(userName);
|
||||
elementRemoteVideo.insertAdjacentHTML('beforeend', `
|
||||
@ -247,4 +246,14 @@ export class MediaManager {
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
private getElementByIdOrFail<T extends HTMLElement>(id: string): T {
|
||||
let elem = document.getElementById(id);
|
||||
if (elem === null) {
|
||||
throw new Error("Cannot find HTML element with id '"+id+"'");
|
||||
}
|
||||
// FIXME: does not check the type of the returned type
|
||||
return elem as T;
|
||||
}
|
||||
|
||||
}
|
@ -1,21 +1,21 @@
|
||||
import {ConnectionInterface} from "../Connection";
|
||||
import {MediaManager} from "./MediaManager";
|
||||
let Peer = require('simple-peer');
|
||||
import * as SimplePeerNamespace from "simple-peer";
|
||||
let Peer: SimplePeerNamespace.SimplePeer = require('simple-peer');
|
||||
|
||||
class UserSimplePear{
|
||||
class UserSimplePeer{
|
||||
userId: string;
|
||||
name?: string;
|
||||
initiator?: boolean;
|
||||
}
|
||||
export class SimplePeerInterface {}
|
||||
export class SimplePeer implements SimplePeerInterface{
|
||||
export class SimplePeer {
|
||||
private Connection: ConnectionInterface;
|
||||
private WebRtcRoomId: string;
|
||||
private Users: Array<UserSimplePear> = new Array<UserSimplePear>();
|
||||
private Users: Array<UserSimplePeer> = new Array<UserSimplePeer>();
|
||||
|
||||
private MediaManager: MediaManager;
|
||||
|
||||
private PeerConnectionArray: Map<string, any> = new Map<string, any>();
|
||||
private PeerConnectionArray: Map<string, SimplePeerNamespace.Instance> = new Map<string, SimplePeerNamespace.Instance>();
|
||||
|
||||
constructor(Connection: ConnectionInterface, WebRtcRoomId: string = "test-webrtc") {
|
||||
this.Connection = Connection;
|
||||
@ -66,7 +66,7 @@ export class SimplePeer implements SimplePeerInterface{
|
||||
* server has two person connected, start the meet
|
||||
*/
|
||||
private startWebRtc() {
|
||||
this.Users.forEach((user: UserSimplePear) => {
|
||||
this.Users.forEach((user: UserSimplePeer) => {
|
||||
//if it's not an initiator, peer connection will be created when gamer will receive offer signal
|
||||
if(!user.initiator){
|
||||
return;
|
||||
@ -78,14 +78,14 @@ export class SimplePeer implements SimplePeerInterface{
|
||||
/**
|
||||
* create peer connection to bind users
|
||||
*/
|
||||
private createPeerConnection(user : UserSimplePear) {
|
||||
private createPeerConnection(user : UserSimplePeer) {
|
||||
if(this.PeerConnectionArray.has(user.userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let name = user.name;
|
||||
if(!name){
|
||||
let userSearch = this.Users.find((userSearch: UserSimplePear) => userSearch.userId === user.userId);
|
||||
let userSearch = this.Users.find((userSearch: UserSimplePeer) => userSearch.userId === user.userId);
|
||||
if(userSearch) {
|
||||
name = userSearch.name;
|
||||
}
|
||||
@ -112,11 +112,11 @@ export class SimplePeer implements SimplePeerInterface{
|
||||
this.PeerConnectionArray.set(user.userId, peer);
|
||||
|
||||
//start listen signal for the peer connection
|
||||
this.PeerConnectionArray.get(user.userId).on('signal', (data: any) => {
|
||||
peer.on('signal', (data: any) => {
|
||||
this.sendWebrtcSignal(data, user.userId);
|
||||
});
|
||||
|
||||
this.PeerConnectionArray.get(user.userId).on('stream', (stream: MediaStream) => {
|
||||
peer.on('stream', (stream: MediaStream) => {
|
||||
let videoActive = false;
|
||||
let microphoneActive = false;
|
||||
stream.getTracks().forEach((track : MediaStreamTrack) => {
|
||||
@ -141,23 +141,23 @@ export class SimplePeer implements SimplePeerInterface{
|
||||
this.stream(user.userId, stream);
|
||||
});
|
||||
|
||||
/*this.PeerConnectionArray.get(user.userId).on('track', (track: MediaStreamTrack, stream: MediaStream) => {
|
||||
/*peer.on('track', (track: MediaStreamTrack, stream: MediaStream) => {
|
||||
this.stream(user.userId, stream);
|
||||
});*/
|
||||
|
||||
this.PeerConnectionArray.get(user.userId).on('close', () => {
|
||||
peer.on('close', () => {
|
||||
this.closeConnection(user.userId);
|
||||
});
|
||||
|
||||
this.PeerConnectionArray.get(user.userId).on('error', (err: any) => {
|
||||
peer.on('error', (err: any) => {
|
||||
console.error(`error => ${user.userId} => ${err.code}`, err);
|
||||
});
|
||||
|
||||
this.PeerConnectionArray.get(user.userId).on('connect', () => {
|
||||
peer.on('connect', () => {
|
||||
console.info(`connect => ${user.userId}`);
|
||||
});
|
||||
|
||||
this.PeerConnectionArray.get(user.userId).on('data', (chunk: Buffer) => {
|
||||
peer.on('data', (chunk: Buffer) => {
|
||||
let data = JSON.parse(chunk.toString('utf8'));
|
||||
if(data.type === "stream"){
|
||||
this.stream(user.userId, data.stream);
|
||||
@ -174,7 +174,7 @@ export class SimplePeer implements SimplePeerInterface{
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
this.PeerConnectionArray.get(userId).destroy();
|
||||
this.PeerConnectionArray.get(userId)?.destroy();
|
||||
this.PeerConnectionArray.delete(userId)
|
||||
} catch (err) {
|
||||
console.error("closeConnection", err)
|
||||
@ -200,7 +200,12 @@ export class SimplePeer implements SimplePeerInterface{
|
||||
if(data.signal.type === "offer"){
|
||||
this.createPeerConnection(data);
|
||||
}
|
||||
this.PeerConnectionArray.get(data.userId).signal(data.signal);
|
||||
let peer = this.PeerConnectionArray.get(data.userId);
|
||||
if (peer !== undefined) {
|
||||
peer.signal(data.signal);
|
||||
} else {
|
||||
console.error('Could not find peer whose ID is "'+data.userId+'" in PeerConnectionArray');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`receiveWebrtcSignal => ${data.userId}`, e);
|
||||
}
|
||||
@ -227,27 +232,32 @@ export class SimplePeer implements SimplePeerInterface{
|
||||
private addMedia (userId : any = null) {
|
||||
try {
|
||||
let transceiver : any = null;
|
||||
if(!this.MediaManager.localStream){
|
||||
let localStream: MediaStream|null = this.MediaManager.localStream;
|
||||
let peer = this.PeerConnectionArray.get(userId);
|
||||
if(localStream === null) {
|
||||
//send fake signal
|
||||
if(!this.PeerConnectionArray.has(userId)){
|
||||
if(peer === undefined){
|
||||
return;
|
||||
}
|
||||
this.PeerConnectionArray.get(userId).write(new Buffer(JSON.stringify({
|
||||
peer.write(new Buffer(JSON.stringify({
|
||||
type: "stream",
|
||||
stream: null
|
||||
})));
|
||||
return;
|
||||
}
|
||||
this.MediaManager.localStream.getTracks().forEach(
|
||||
transceiver = (track: MediaStreamTrack) => this.PeerConnectionArray.get(userId).addTrack(track, this.MediaManager.localStream)
|
||||
)
|
||||
if (peer === undefined) {
|
||||
throw new Error('While adding media, cannot find user with ID '+userId);
|
||||
}
|
||||
for (const track of localStream.getTracks()) {
|
||||
peer.addTrack(track, localStream);
|
||||
}
|
||||
}catch (e) {
|
||||
console.error(`addMedia => addMedia => ${userId}`, e);
|
||||
}
|
||||
}
|
||||
|
||||
updatedLocalStream(){
|
||||
this.Users.forEach((user: UserSimplePear) => {
|
||||
this.Users.forEach((user: UserSimplePeer) => {
|
||||
this.addMedia(user.userId);
|
||||
})
|
||||
}
|
||||
|
@ -7,6 +7,18 @@
|
||||
"module": "CommonJS",
|
||||
"target": "es5",
|
||||
"jsx": "react",
|
||||
"allowJs": true
|
||||
"allowJs": true,
|
||||
|
||||
"strict": false, /* Enable all strict type-checking options. */
|
||||
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
"strictNullChecks": true, /* Enable strict null checks. */
|
||||
"strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
"strictPropertyInitialization": false, /* Enable strict checking of property initialization in classes. */
|
||||
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user