Plugin PositionNotifier into the main application.
This commit is contained in:
parent
f8d462b0d7
commit
d24ec0bd75
@ -20,6 +20,7 @@ import {isWebRtcSignalMessageInterface} from "../Model/Websocket/WebRtcSignalMes
|
|||||||
import {UserInGroupInterface} from "../Model/Websocket/UserInGroupInterface";
|
import {UserInGroupInterface} from "../Model/Websocket/UserInGroupInterface";
|
||||||
import {uuid} from 'uuidv4';
|
import {uuid} from 'uuidv4';
|
||||||
import {isUserMovesInterface} from "../Model/Websocket/UserMovesMessage";
|
import {isUserMovesInterface} from "../Model/Websocket/UserMovesMessage";
|
||||||
|
import {isViewport} from "../Model/Websocket/ViewportMessage";
|
||||||
|
|
||||||
enum SockerIoEvent {
|
enum SockerIoEvent {
|
||||||
CONNECTION = "connection",
|
CONNECTION = "connection",
|
||||||
@ -212,22 +213,16 @@ export class IoSocketController {
|
|||||||
//join new previous room
|
//join new previous room
|
||||||
const world = this.joinRoom(Client, roomId, message.position);
|
const world = this.joinRoom(Client, roomId, message.position);
|
||||||
|
|
||||||
//add function to refresh position user in real time.
|
const users = world.setViewport(Client, message.viewport);
|
||||||
//this.refreshUserPosition(Client);
|
const listOfUsers = users.map((user: UserInterface) => {
|
||||||
|
|
||||||
const messageUserJoined = new MessageUserJoined(Client.userId, Client.name, Client.characterLayers, Client.position);
|
|
||||||
|
|
||||||
socket.to(roomId).emit(SockerIoEvent.JOIN_ROOM, messageUserJoined);
|
|
||||||
|
|
||||||
// The answer shall contain the list of all users of the room with their positions:
|
|
||||||
const listOfUsers = Array.from(world.getUsers(), ([key, user]) => {
|
|
||||||
const player: ExSocketInterface|undefined = this.sockets.get(user.id);
|
const player: ExSocketInterface|undefined = this.sockets.get(user.id);
|
||||||
if (player === undefined) {
|
if (player === undefined) {
|
||||||
console.warn('Something went wrong. The World contains a user "'+user.id+"' but this user does not exist in the sockets list!");
|
console.warn('Something went wrong. The World contains a user "'+user.id+"' but this user does not exist in the sockets list!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new MessageUserPosition(user.id, player.name, player.characterLayers, player.position);
|
return new MessageUserPosition(user.id, player.name, player.characterLayers, player.position);
|
||||||
}).filter((item: MessageUserPosition|null) => item !== null);
|
}, users);
|
||||||
|
|
||||||
answerFn(listOfUsers);
|
answerFn(listOfUsers);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('An error occurred on "join_room" event');
|
console.error('An error occurred on "join_room" event');
|
||||||
@ -235,6 +230,30 @@ export class IoSocketController {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on(SockerIoEvent.SET_VIEWPORT, (message: unknown): void => {
|
||||||
|
try {
|
||||||
|
//console.log('SET_VIEWPORT')
|
||||||
|
if (!isViewport(message)) {
|
||||||
|
socket.emit(SockerIoEvent.MESSAGE_ERROR, {message: 'Invalid SET_VIEWPORT message.'});
|
||||||
|
console.warn('Invalid SET_VIEWPORT message received: ', message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Client = (socket as ExSocketInterface);
|
||||||
|
Client.viewport = message;
|
||||||
|
|
||||||
|
const world = this.Worlds.get(Client.roomId);
|
||||||
|
if (!world) {
|
||||||
|
console.error("Could not find world with id '", Client.roomId, "'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
world.setViewport(Client, Client.viewport);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('An error occurred on "SET_VIEWPORT" event');
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
socket.on(SockerIoEvent.USER_POSITION, (userMovesMessage: unknown): void => {
|
socket.on(SockerIoEvent.USER_POSITION, (userMovesMessage: unknown): void => {
|
||||||
console.log(SockerIoEvent.USER_POSITION, userMovesMessage);
|
console.log(SockerIoEvent.USER_POSITION, userMovesMessage);
|
||||||
try {
|
try {
|
||||||
@ -257,19 +276,7 @@ export class IoSocketController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
world.updatePosition(Client, Client.position);
|
world.updatePosition(Client, Client.position);
|
||||||
|
world.setViewport(Client, Client.viewport);
|
||||||
const clientsInRoom = this.Io.sockets.adapter.rooms[Client.roomId];
|
|
||||||
console.log('clientsInRoom', clientsInRoom);
|
|
||||||
for (const clientId in clientsInRoom.sockets) {
|
|
||||||
console.log('client: %s', clientId);
|
|
||||||
const targetSocket = this.Io.sockets.connected[clientId] as ExSocketInterface;
|
|
||||||
if (socket === targetSocket) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//targetSocket.emit(SockerIoEvent.USER_MOVED, new MessageUserMoved(Client.userId, Client.position));
|
|
||||||
targetSocket.emitInBatch(SockerIoEvent.USER_MOVED, new MessageUserMoved(Client.userId, Client.position));
|
|
||||||
}
|
|
||||||
//socket.to(Client.roomId).emit(SockerIoEvent.USER_MOVED, new MessageUserMoved(Client.userId, Client.position));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('An error occurred on "user_position" event');
|
console.error('An error occurred on "user_position" event');
|
||||||
console.error(e);
|
console.error(e);
|
||||||
@ -404,8 +411,6 @@ export class IoSocketController {
|
|||||||
// leave previous room and world
|
// leave previous room and world
|
||||||
if(Client.roomId){
|
if(Client.roomId){
|
||||||
try {
|
try {
|
||||||
Client.to(Client.roomId).emit(SockerIoEvent.USER_LEFT, Client.userId);
|
|
||||||
|
|
||||||
//user leave previous world
|
//user leave previous world
|
||||||
const world: World | undefined = this.Worlds.get(Client.roomId);
|
const world: World | undefined = this.Worlds.get(Client.roomId);
|
||||||
if (world) {
|
if (world) {
|
||||||
@ -441,6 +446,25 @@ export class IoSocketController {
|
|||||||
this.sendUpdateGroupEvent(group);
|
this.sendUpdateGroupEvent(group);
|
||||||
}, (groupUuid: string, lastUser: UserInterface) => {
|
}, (groupUuid: string, lastUser: UserInterface) => {
|
||||||
this.sendDeleteGroupEvent(groupUuid, lastUser);
|
this.sendDeleteGroupEvent(groupUuid, lastUser);
|
||||||
|
}, (user, listener) => {
|
||||||
|
const clientUser = this.searchClientByIdOrFail(user.id);
|
||||||
|
const clientListener = this.searchClientByIdOrFail(listener.id);
|
||||||
|
const messageUserJoined = new MessageUserJoined(clientUser.userId, clientUser.name, clientUser.characterLayers, clientUser.position);
|
||||||
|
|
||||||
|
clientListener.emit(SockerIoEvent.JOIN_ROOM, messageUserJoined);
|
||||||
|
//console.log("Sending JOIN_ROOM event");
|
||||||
|
}, (user, position, listener) => {
|
||||||
|
const clientUser = this.searchClientByIdOrFail(user.id);
|
||||||
|
const clientListener = this.searchClientByIdOrFail(listener.id);
|
||||||
|
|
||||||
|
clientListener.emitInBatch(SockerIoEvent.USER_MOVED, new MessageUserMoved(clientUser.userId, clientUser.position));
|
||||||
|
//console.log("Sending USER_MOVED event");
|
||||||
|
}, (user, listener) => {
|
||||||
|
const clientUser = this.searchClientByIdOrFail(user.id);
|
||||||
|
const clientListener = this.searchClientByIdOrFail(listener.id);
|
||||||
|
|
||||||
|
clientListener.emit(SockerIoEvent.USER_LEFT, clientUser.userId);
|
||||||
|
//console.log("Sending USER_LEFT event");
|
||||||
});
|
});
|
||||||
this.Worlds.set(roomId, world);
|
this.Worlds.set(roomId, world);
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,14 @@ export class PositionNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public setViewport(user: UserInterface, viewport: ViewportInterface): void {
|
/**
|
||||||
|
* Sets the viewport coordinates.
|
||||||
|
* Returns the list of new users to add
|
||||||
|
*/
|
||||||
|
public setViewport(user: UserInterface, viewport: ViewportInterface): UserInterface[] {
|
||||||
if (viewport.left > viewport.right || viewport.top > viewport.bottom) {
|
if (viewport.left > viewport.right || viewport.top > viewport.bottom) {
|
||||||
console.warn('Invalid viewport received: ', viewport);
|
console.warn('Invalid viewport received: ', viewport);
|
||||||
return;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldZones = user.listenedZones;
|
const oldZones = user.listenedZones;
|
||||||
@ -55,12 +59,17 @@ export class PositionNotifier {
|
|||||||
const addedZones = [...newZones].filter(x => !oldZones.has(x));
|
const addedZones = [...newZones].filter(x => !oldZones.has(x));
|
||||||
const removedZones = [...oldZones].filter(x => !newZones.has(x));
|
const removedZones = [...oldZones].filter(x => !newZones.has(x));
|
||||||
|
|
||||||
|
|
||||||
|
let users: UserInterface[] = [];
|
||||||
for (const zone of addedZones) {
|
for (const zone of addedZones) {
|
||||||
zone.startListening(user);
|
zone.startListening(user);
|
||||||
|
users = users.concat(Array.from(zone.getPlayers()))
|
||||||
}
|
}
|
||||||
for (const zone of removedZones) {
|
for (const zone of removedZones) {
|
||||||
zone.stopListening(user);
|
zone.stopListening(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return users;
|
||||||
}
|
}
|
||||||
|
|
||||||
public updatePosition(user: UserInterface, userPosition: PointInterface): void {
|
public updatePosition(user: UserInterface, userPosition: PointInterface): void {
|
||||||
@ -87,6 +96,11 @@ export class PositionNotifier {
|
|||||||
const oldZoneDesc = this.getZoneDescriptorFromCoordinates(user.position.x, user.position.y);
|
const oldZoneDesc = this.getZoneDescriptorFromCoordinates(user.position.x, user.position.y);
|
||||||
const oldZone = this.getZone(oldZoneDesc.i, oldZoneDesc.j);
|
const oldZone = this.getZone(oldZoneDesc.i, oldZoneDesc.j);
|
||||||
oldZone.leave(user, null);
|
oldZone.leave(user, null);
|
||||||
|
|
||||||
|
// Also, let's stop listening on viewports
|
||||||
|
for (const zone of user.listenedZones) {
|
||||||
|
zone.stopListening(user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getZone(i: number, j: number): Zone {
|
private getZone(i: number, j: number): Zone {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import * as tg from "generic-type-guard";
|
import * as tg from "generic-type-guard";
|
||||||
import {isPointInterface} from "./PointInterface";
|
import {isPointInterface} from "./PointInterface";
|
||||||
|
import {isViewport} from "./ViewportMessage";
|
||||||
|
|
||||||
export const isJoinRoomMessageInterface =
|
export const isJoinRoomMessageInterface =
|
||||||
new tg.IsInterface().withProperties({
|
new tg.IsInterface().withProperties({
|
||||||
roomId: tg.isString,
|
roomId: tg.isString,
|
||||||
position: isPointInterface,
|
position: isPointInterface,
|
||||||
|
viewport: isViewport
|
||||||
}).get();
|
}).get();
|
||||||
export type JoinRoomMessageInterface = tg.GuardedType<typeof isJoinRoomMessageInterface>;
|
export type JoinRoomMessageInterface = tg.GuardedType<typeof isJoinRoomMessageInterface>;
|
||||||
|
@ -6,7 +6,9 @@ import {UserInterface} from "./UserInterface";
|
|||||||
import {ExSocketInterface} from "_Model/Websocket/ExSocketInterface";
|
import {ExSocketInterface} from "_Model/Websocket/ExSocketInterface";
|
||||||
import {PositionInterface} from "_Model/PositionInterface";
|
import {PositionInterface} from "_Model/PositionInterface";
|
||||||
import {Identificable} from "_Model/Websocket/Identificable";
|
import {Identificable} from "_Model/Websocket/Identificable";
|
||||||
import {Zone} from "_Model/Zone";
|
import {UserEntersCallback, UserLeavesCallback, UserMovesCallback, Zone} from "_Model/Zone";
|
||||||
|
import {PositionNotifier} from "./PositionNotifier";
|
||||||
|
import {ViewportInterface} from "_Model/Websocket/ViewportMessage";
|
||||||
|
|
||||||
export type ConnectCallback = (user: string, group: Group) => void;
|
export type ConnectCallback = (user: string, group: Group) => void;
|
||||||
export type DisconnectCallback = (user: string, group: Group) => void;
|
export type DisconnectCallback = (user: string, group: Group) => void;
|
||||||
@ -28,12 +30,17 @@ export class World {
|
|||||||
private readonly groupUpdatedCallback: GroupUpdatedCallback;
|
private readonly groupUpdatedCallback: GroupUpdatedCallback;
|
||||||
private readonly groupDeletedCallback: GroupDeletedCallback;
|
private readonly groupDeletedCallback: GroupDeletedCallback;
|
||||||
|
|
||||||
|
private readonly positionNotifier: PositionNotifier;
|
||||||
|
|
||||||
constructor(connectCallback: ConnectCallback,
|
constructor(connectCallback: ConnectCallback,
|
||||||
disconnectCallback: DisconnectCallback,
|
disconnectCallback: DisconnectCallback,
|
||||||
minDistance: number,
|
minDistance: number,
|
||||||
groupRadius: number,
|
groupRadius: number,
|
||||||
groupUpdatedCallback: GroupUpdatedCallback,
|
groupUpdatedCallback: GroupUpdatedCallback,
|
||||||
groupDeletedCallback: GroupDeletedCallback)
|
groupDeletedCallback: GroupDeletedCallback,
|
||||||
|
onUserEnters: UserEntersCallback,
|
||||||
|
onUserMoves: UserMovesCallback,
|
||||||
|
onUserLeaves: UserLeavesCallback)
|
||||||
{
|
{
|
||||||
this.users = new Map<string, UserInterface>();
|
this.users = new Map<string, UserInterface>();
|
||||||
this.groups = new Set<Group>();
|
this.groups = new Set<Group>();
|
||||||
@ -43,6 +50,8 @@ export class World {
|
|||||||
this.groupRadius = groupRadius;
|
this.groupRadius = groupRadius;
|
||||||
this.groupUpdatedCallback = groupUpdatedCallback;
|
this.groupUpdatedCallback = groupUpdatedCallback;
|
||||||
this.groupDeletedCallback = groupDeletedCallback;
|
this.groupDeletedCallback = groupDeletedCallback;
|
||||||
|
// A zone is 10 sprites wide.
|
||||||
|
this.positionNotifier = new PositionNotifier(320, 320, onUserEnters, onUserMoves, onUserLeaves);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getGroups(): Group[] {
|
public getGroups(): Group[] {
|
||||||
@ -73,6 +82,10 @@ export class World {
|
|||||||
this.leaveGroup(userObj);
|
this.leaveGroup(userObj);
|
||||||
}
|
}
|
||||||
this.users.delete(user.userId);
|
this.users.delete(user.userId);
|
||||||
|
|
||||||
|
if (userObj !== undefined) {
|
||||||
|
this.positionNotifier.leave(userObj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public isEmpty(): boolean {
|
public isEmpty(): boolean {
|
||||||
@ -85,6 +98,8 @@ export class World {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.positionNotifier.updatePosition(user, userPosition);
|
||||||
|
|
||||||
user.position = userPosition;
|
user.position = userPosition;
|
||||||
|
|
||||||
if (user.silent) {
|
if (user.silent) {
|
||||||
@ -318,4 +333,12 @@ export class World {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}*/
|
}*/
|
||||||
|
setViewport(socket : Identificable, viewport: ViewportInterface): UserInterface[] {
|
||||||
|
const user = this.users.get(socket.userId);
|
||||||
|
if(typeof user === 'undefined') {
|
||||||
|
console.warn('In setViewport, could not find user with ID "'+socket.userId+'" in world.');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.positionNotifier.setViewport(user, viewport);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@ import {UserInterface} from "./UserInterface";
|
|||||||
import {PointInterface} from "_Model/Websocket/PointInterface";
|
import {PointInterface} from "_Model/Websocket/PointInterface";
|
||||||
import {PositionInterface} from "_Model/PositionInterface";
|
import {PositionInterface} from "_Model/PositionInterface";
|
||||||
|
|
||||||
export type UserEntersCallback = (user: UserInterface) => void;
|
export type UserEntersCallback = (user: UserInterface, listener: UserInterface) => void;
|
||||||
export type UserMovesCallback = (user: UserInterface, position: PointInterface) => void;
|
export type UserMovesCallback = (user: UserInterface, position: PointInterface, listener: UserInterface) => void;
|
||||||
export type UserLeavesCallback = (user: UserInterface) => void;
|
export type UserLeavesCallback = (user: UserInterface, listener: UserInterface) => void;
|
||||||
|
|
||||||
export class Zone {
|
export class Zone {
|
||||||
private players: Set<UserInterface> = new Set<UserInterface>();
|
private players: Set<UserInterface> = new Set<UserInterface>();
|
||||||
@ -27,7 +27,7 @@ export class Zone {
|
|||||||
private notifyUserLeft(user: UserInterface, newZone: Zone|null) {
|
private notifyUserLeft(user: UserInterface, newZone: Zone|null) {
|
||||||
for (const listener of this.listeners) {
|
for (const listener of this.listeners) {
|
||||||
if (listener !== user && (newZone === null || !listener.listenedZones.has(newZone))) {
|
if (listener !== user && (newZone === null || !listener.listenedZones.has(newZone))) {
|
||||||
this.onUserLeaves(user);
|
this.onUserLeaves(user, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,40 +46,51 @@ export class Zone {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (oldZone === null || !listener.listenedZones.has(oldZone)) {
|
if (oldZone === null || !listener.listenedZones.has(oldZone)) {
|
||||||
this.onUserEnters(user);
|
this.onUserEnters(user, listener);
|
||||||
} else {
|
} else {
|
||||||
this.onUserMoves(user, position);
|
this.onUserMoves(user, position, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public move(user: UserInterface, position: PointInterface) {
|
public move(user: UserInterface, position: PointInterface) {
|
||||||
|
if (!this.players.has(user)) {
|
||||||
|
this.players.add(user);
|
||||||
|
const foo = this.players;
|
||||||
|
this.notifyUserEnter(user, null, position);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const listener of this.listeners) {
|
for (const listener of this.listeners) {
|
||||||
if (listener !== user) {
|
if (listener !== user) {
|
||||||
this.onUserMoves(user,position);
|
this.onUserMoves(user,position, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public startListening(user: UserInterface): void {
|
public startListening(listener: UserInterface): void {
|
||||||
for (const player of this.players) {
|
for (const player of this.players) {
|
||||||
if (player !== user) {
|
if (player !== listener) {
|
||||||
this.onUserEnters(user);
|
this.onUserEnters(player, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.listeners.add(user);
|
this.listeners.add(listener);
|
||||||
user.listenedZones.add(this);
|
listener.listenedZones.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public stopListening(user: UserInterface): void {
|
public stopListening(listener: UserInterface): void {
|
||||||
for (const player of this.players) {
|
for (const player of this.players) {
|
||||||
if (player !== user) {
|
if (player !== listener) {
|
||||||
this.onUserLeaves(user);
|
this.onUserLeaves(player, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.listeners.delete(user);
|
this.listeners.delete(listener);
|
||||||
user.listenedZones.delete(this);
|
listener.listenedZones.delete(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPlayers(): Set<UserInterface> {
|
||||||
|
return this.players;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,13 +139,15 @@ describe("PositionNotifier", () => {
|
|||||||
listenedZones: new Set<Zone>(),
|
listenedZones: new Set<Zone>(),
|
||||||
} as UserInterface;
|
} as UserInterface;
|
||||||
|
|
||||||
positionNotifier.setViewport(user1, {
|
let newUsers = positionNotifier.setViewport(user1, {
|
||||||
left: 200,
|
left: 200,
|
||||||
right: 600,
|
right: 600,
|
||||||
top: 100,
|
top: 100,
|
||||||
bottom: 500
|
bottom: 500
|
||||||
});
|
});
|
||||||
|
|
||||||
|
expect(newUsers.length).toBe(0);
|
||||||
|
|
||||||
move(user2, 500, 500, positionNotifier);
|
move(user2, 500, 500, positionNotifier);
|
||||||
|
|
||||||
expect(enterTriggered).toBe(true);
|
expect(enterTriggered).toBe(true);
|
||||||
@ -178,7 +180,7 @@ describe("PositionNotifier", () => {
|
|||||||
leaveTriggered = false;
|
leaveTriggered = false;
|
||||||
|
|
||||||
// Move the viewport back on the user.
|
// Move the viewport back on the user.
|
||||||
positionNotifier.setViewport(user1, {
|
newUsers = positionNotifier.setViewport(user1, {
|
||||||
left: 200,
|
left: 200,
|
||||||
right: 600,
|
right: 600,
|
||||||
top: 100,
|
top: 100,
|
||||||
@ -189,5 +191,6 @@ describe("PositionNotifier", () => {
|
|||||||
expect(moveTriggered).toBe(false);
|
expect(moveTriggered).toBe(false);
|
||||||
expect(leaveTriggered).toBe(false);
|
expect(leaveTriggered).toBe(false);
|
||||||
enterTriggered = false;
|
enterTriggered = false;
|
||||||
|
expect(newUsers.length).toBe(1);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -13,7 +13,7 @@ describe("World", () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const world = new World(connect, disconnect, 160, 160, () => {}, () => {});
|
const world = new World(connect, disconnect, 160, 160, () => {}, () => {}, () => {}, () => {}, () => {});
|
||||||
|
|
||||||
world.join({ userId: "foo" }, new Point(100, 100));
|
world.join({ userId: "foo" }, new Point(100, 100));
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ describe("World", () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const world = new World(connect, disconnect, 160, 160, () => {}, () => {});
|
const world = new World(connect, disconnect, 160, 160, () => {}, () => {}, () => {}, () => {}, () => {});
|
||||||
|
|
||||||
world.join({ userId: "foo" }, new Point(100, 100));
|
world.join({ userId: "foo" }, new Point(100, 100));
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ describe("World", () => {
|
|||||||
disconnectCallNumber++;
|
disconnectCallNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
const world = new World(connect, disconnect, 160, 160, () => {}, () => {});
|
const world = new World(connect, disconnect, 160, 160, () => {}, () => {}, () => {}, () => {}, () => {});
|
||||||
|
|
||||||
world.join({ userId: "foo" }, new Point(100, 100));
|
world.join({ userId: "foo" }, new Point(100, 100));
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
"sourceMap": true, /* Generates corresponding '.map' file. */
|
||||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||||
"outDir": "./dist", /* Redirect output structure to the directory. */
|
"outDir": "./dist", /* Redirect output structure to the directory. */
|
||||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||||
|
@ -182,9 +182,13 @@ export class Connection implements Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public joinARoom(roomId: string, startX: number, startY: number, direction: string, moving: boolean): Promise<MessageUserPositionInterface[]> {
|
public joinARoom(roomId: string, startX: number, startY: number, direction: string, moving: boolean, viewport: ViewportInterface): Promise<MessageUserPositionInterface[]> {
|
||||||
const promise = new Promise<MessageUserPositionInterface[]>((resolve, reject) => {
|
const promise = new Promise<MessageUserPositionInterface[]>((resolve, reject) => {
|
||||||
this.socket.emit(EventMessage.JOIN_ROOM, { roomId, position: {x: startX, y: startY, direction, moving }}, (userPositions: MessageUserPositionInterface[]) => {
|
this.socket.emit(EventMessage.JOIN_ROOM, {
|
||||||
|
roomId,
|
||||||
|
position: {x: startX, y: startY, direction, moving },
|
||||||
|
viewport,
|
||||||
|
}, (userPositions: MessageUserPositionInterface[]) => {
|
||||||
resolve(userPositions);
|
resolve(userPositions);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -203,6 +207,10 @@ export class Connection implements Connection {
|
|||||||
this.socket.emit(EventMessage.SET_SILENT, silent);
|
this.socket.emit(EventMessage.SET_SILENT, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setViewport(viewport: ViewportInterface): void {
|
||||||
|
this.socket.emit(EventMessage.SET_VIEWPORT, viewport);
|
||||||
|
}
|
||||||
|
|
||||||
public onUserJoins(callback: (message: MessageUserJoined) => void): void {
|
public onUserJoins(callback: (message: MessageUserJoined) => void): void {
|
||||||
this.socket.on(EventMessage.JOIN_ROOM, callback);
|
this.socket.on(EventMessage.JOIN_ROOM, callback);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
private startLayerName: string|undefined;
|
private startLayerName: string|undefined;
|
||||||
private presentationModeSprite!: Sprite;
|
private presentationModeSprite!: Sprite;
|
||||||
private chatModeSprite!: Sprite;
|
private chatModeSprite!: Sprite;
|
||||||
private repositionCallback!: (this: Window, ev: UIEvent) => void;
|
private onResizeCallback!: (this: Window, ev: UIEvent) => void;
|
||||||
private gameMap!: GameMap;
|
private gameMap!: GameMap;
|
||||||
|
|
||||||
static createFromUrl(mapUrlFile: string, instance: string, key: string|null = null): GameScene {
|
static createFromUrl(mapUrlFile: string, instance: string, key: string|null = null): GameScene {
|
||||||
@ -226,7 +226,7 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
|
|
||||||
this.scene.stop(this.scene.key);
|
this.scene.stop(this.scene.key);
|
||||||
this.scene.remove(this.scene.key);
|
this.scene.remove(this.scene.key);
|
||||||
window.removeEventListener('resize', this.repositionCallback);
|
window.removeEventListener('resize', this.onResizeCallback);
|
||||||
})
|
})
|
||||||
|
|
||||||
// When connection is performed, let's connect SimplePeer
|
// When connection is performed, let's connect SimplePeer
|
||||||
@ -412,8 +412,8 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
this.switchLayoutMode();
|
this.switchLayoutMode();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.repositionCallback = this.reposition.bind(this);
|
this.onResizeCallback = this.onResize.bind(this);
|
||||||
window.addEventListener('resize', this.repositionCallback);
|
window.addEventListener('resize', this.onResizeCallback);
|
||||||
this.reposition();
|
this.reposition();
|
||||||
|
|
||||||
// From now, this game scene will be notified of reposition events
|
// From now, this game scene will be notified of reposition events
|
||||||
@ -636,7 +636,17 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
|
|
||||||
//join room
|
//join room
|
||||||
this.connectionPromise.then((connection: Connection) => {
|
this.connectionPromise.then((connection: Connection) => {
|
||||||
connection.joinARoom(this.RoomId, this.startX, this.startY, PlayerAnimationNames.WalkDown, false).then((userPositions: MessageUserPositionInterface[]) => {
|
const camera = this.cameras.main;
|
||||||
|
connection.joinARoom(this.RoomId,
|
||||||
|
this.startX,
|
||||||
|
this.startY,
|
||||||
|
PlayerAnimationNames.WalkDown,
|
||||||
|
false, {
|
||||||
|
left: camera.scrollX,
|
||||||
|
top: camera.scrollY,
|
||||||
|
right: camera.scrollX + camera.width,
|
||||||
|
bottom: camera.scrollY + camera.height,
|
||||||
|
}).then((userPositions: MessageUserPositionInterface[]) => {
|
||||||
this.initUsersPosition(userPositions);
|
this.initUsersPosition(userPositions);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -747,7 +757,7 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
this.simplePeer.unregister();
|
this.simplePeer.unregister();
|
||||||
this.scene.stop();
|
this.scene.stop();
|
||||||
this.scene.remove(this.scene.key);
|
this.scene.remove(this.scene.key);
|
||||||
window.removeEventListener('resize', this.repositionCallback);
|
window.removeEventListener('resize', this.onResizeCallback);
|
||||||
this.scene.start(nextSceneKey.key, {
|
this.scene.start(nextSceneKey.key, {
|
||||||
startLayerName: nextSceneKey.hash
|
startLayerName: nextSceneKey.hash
|
||||||
});
|
});
|
||||||
@ -936,6 +946,19 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
return mapUrlStart.substring(startPos, endPos);
|
return mapUrlStart.substring(startPos, endPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onResize(): void {
|
||||||
|
this.reposition();
|
||||||
|
|
||||||
|
// Send new viewport to server
|
||||||
|
const camera = this.cameras.main;
|
||||||
|
this.connection.setViewport({
|
||||||
|
left: camera.scrollX,
|
||||||
|
top: camera.scrollY,
|
||||||
|
right: camera.scrollX + camera.width,
|
||||||
|
bottom: camera.scrollY + camera.height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private reposition(): void {
|
private reposition(): void {
|
||||||
this.presentationModeSprite.setY(this.game.renderer.height - 2);
|
this.presentationModeSprite.setY(this.game.renderer.height - 2);
|
||||||
this.chatModeSprite.setY(this.game.renderer.height - 2);
|
this.chatModeSprite.setY(this.game.renderer.height - 2);
|
||||||
|
Loading…
Reference in New Issue
Block a user