Making groups part of zones
This commit is contained in:
parent
3ca2a5bf68
commit
f5f9dcac04
@ -7,7 +7,7 @@ import Jwt, {JsonWebTokenError} from "jsonwebtoken";
|
|||||||
import {SECRET_KEY, MINIMUM_DISTANCE, GROUP_RADIUS, ALLOW_ARTILLERY} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
|
import {SECRET_KEY, MINIMUM_DISTANCE, GROUP_RADIUS, ALLOW_ARTILLERY} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
|
||||||
import {World} from "../Model/World";
|
import {World} from "../Model/World";
|
||||||
import {Group} from "../Model/Group";
|
import {Group} from "../Model/Group";
|
||||||
import {UserInterface} from "../Model/UserInterface";
|
import {User} from "../Model/User";
|
||||||
import {isSetPlayerDetailsMessage,} from "../Model/Websocket/SetPlayerDetailsMessage";
|
import {isSetPlayerDetailsMessage,} from "../Model/Websocket/SetPlayerDetailsMessage";
|
||||||
import {MessageUserJoined} from "../Model/Websocket/MessageUserJoined";
|
import {MessageUserJoined} from "../Model/Websocket/MessageUserJoined";
|
||||||
import {MessageUserMoved} from "../Model/Websocket/MessageUserMoved";
|
import {MessageUserMoved} from "../Model/Websocket/MessageUserMoved";
|
||||||
@ -22,6 +22,8 @@ import {isItemEventMessageInterface} from "../Model/Websocket/ItemEventMessage";
|
|||||||
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";
|
import {isViewport} from "../Model/Websocket/ViewportMessage";
|
||||||
|
import {GroupUpdateInterface} from "_Model/Websocket/GroupUpdateInterface";
|
||||||
|
import {Movable} from "../Model/Movable";
|
||||||
|
|
||||||
enum SockerIoEvent {
|
enum SockerIoEvent {
|
||||||
CONNECTION = "connection",
|
CONNECTION = "connection",
|
||||||
@ -159,7 +161,7 @@ export class IoSocketController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private sendDeleteGroupEvent(uuid: string, lastUser: UserInterface): void {
|
private sendDeleteGroupEvent(uuid: string, lastUser: User): void {
|
||||||
// Let's get the room of the group. To do this, let's get anyone in the group and find its room.
|
// Let's get the room of the group. To do this, let's get anyone in the group and find its room.
|
||||||
const userId = lastUser.id;
|
const userId = lastUser.id;
|
||||||
const client: ExSocketInterface = this.searchClientByIdOrFail(userId);
|
const client: ExSocketInterface = this.searchClientByIdOrFail(userId);
|
||||||
@ -215,15 +217,29 @@ 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);
|
||||||
|
|
||||||
const users = world.setViewport(Client, message.viewport);
|
const things = world.setViewport(Client, message.viewport);
|
||||||
const listOfUsers = users.map((user: UserInterface) => {
|
|
||||||
const player: ExSocketInterface|undefined = this.sockets.get(user.id);
|
const listOfUsers: Array<MessageUserPosition> = [];
|
||||||
if (player === undefined) {
|
const listOfGroups: Array<GroupUpdateInterface> = [];
|
||||||
console.warn('Something went wrong. The World contains a user "'+user.id+"' but this user does not exist in the sockets list!");
|
|
||||||
return null;
|
for (const thing of things) {
|
||||||
|
if (thing instanceof User) {
|
||||||
|
const player: ExSocketInterface|undefined = this.sockets.get(thing.id);
|
||||||
|
if (player === undefined) {
|
||||||
|
console.warn('Something went wrong. The World contains a user "'+thing.id+"' but this user does not exist in the sockets list!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
listOfUsers.push(new MessageUserPosition(thing.id, player.name, player.characterLayers, player.position));
|
||||||
|
} else if (thing instanceof Group) {
|
||||||
|
listOfGroups.push({
|
||||||
|
groupId: thing.getId(),
|
||||||
|
position: thing.getPosition(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error("Unexpected type for Movable returned by setViewport");
|
||||||
}
|
}
|
||||||
return new MessageUserPosition(user.id, player.name, player.characterLayers, player.position);
|
}
|
||||||
}, users);
|
|
||||||
|
|
||||||
const listOfItems: {[itemId: string]: unknown} = {};
|
const listOfItems: {[itemId: string]: unknown} = {};
|
||||||
for (const [itemId, item] of world.getItemsState().entries()) {
|
for (const [itemId, item] of world.getItemsState().entries()) {
|
||||||
@ -232,15 +248,13 @@ export class IoSocketController {
|
|||||||
|
|
||||||
//console.warn('ANSWER PLAYER POSITIONS', listOfUsers);
|
//console.warn('ANSWER PLAYER POSITIONS', listOfUsers);
|
||||||
if (answerFn === undefined && ALLOW_ARTILLERY === true) {
|
if (answerFn === undefined && ALLOW_ARTILLERY === true) {
|
||||||
/*console.error("TYPEOF answerFn", typeof(answerFn));
|
|
||||||
console.error("answerFn", answerFn);
|
|
||||||
process.exit(1)*/
|
|
||||||
// For some reason, answerFn can be undefined if we use Artillery (?)
|
// For some reason, answerFn can be undefined if we use Artillery (?)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
answerFn({
|
answerFn({
|
||||||
users: listOfUsers,
|
users: listOfUsers,
|
||||||
|
groups: listOfGroups,
|
||||||
items: listOfItems
|
items: listOfItems
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -485,28 +499,51 @@ export class IoSocketController {
|
|||||||
}, (user1: string, group: Group) => {
|
}, (user1: string, group: Group) => {
|
||||||
this.disConnectedUser(user1, group);
|
this.disConnectedUser(user1, group);
|
||||||
}, MINIMUM_DISTANCE, GROUP_RADIUS, (group: Group) => {
|
}, MINIMUM_DISTANCE, GROUP_RADIUS, (group: Group) => {
|
||||||
this.sendUpdateGroupEvent(group);
|
//this.sendUpdateGroupEvent(group);
|
||||||
}, (groupUuid: string, lastUser: UserInterface) => {
|
}, (groupUuid: string, lastUser: User) => {
|
||||||
this.sendDeleteGroupEvent(groupUuid, lastUser);
|
//this.sendDeleteGroupEvent(groupUuid, lastUser);
|
||||||
}, (user, listener) => {
|
}, (thing: Movable, listener: User) => {
|
||||||
const clientUser = this.searchClientByIdOrFail(user.id);
|
|
||||||
const clientListener = this.searchClientByIdOrFail(listener.id);
|
const clientListener = this.searchClientByIdOrFail(listener.id);
|
||||||
const messageUserJoined = new MessageUserJoined(clientUser.userId, clientUser.name, clientUser.characterLayers, clientUser.position);
|
if (thing instanceof User) {
|
||||||
|
const clientUser = this.searchClientByIdOrFail(thing.id);
|
||||||
|
const messageUserJoined = new MessageUserJoined(clientUser.userId, clientUser.name, clientUser.characterLayers, clientUser.position);
|
||||||
|
|
||||||
clientListener.emit(SockerIoEvent.JOIN_ROOM, messageUserJoined);
|
clientListener.emit(SockerIoEvent.JOIN_ROOM, messageUserJoined);
|
||||||
//console.log("Sending JOIN_ROOM event");
|
} else if (thing instanceof Group) {
|
||||||
}, (user, position, listener) => {
|
clientListener.emit(SockerIoEvent.GROUP_CREATE_UPDATE, {
|
||||||
const clientUser = this.searchClientByIdOrFail(user.id);
|
position: thing.getPosition(),
|
||||||
|
groupId: thing.getId()
|
||||||
|
} as GroupUpdateInterface);
|
||||||
|
} else {
|
||||||
|
console.error('Unexpected type for Movable.');
|
||||||
|
}
|
||||||
|
}, (thing: Movable, position, listener) => {
|
||||||
const clientListener = this.searchClientByIdOrFail(listener.id);
|
const clientListener = this.searchClientByIdOrFail(listener.id);
|
||||||
|
if (thing instanceof User) {
|
||||||
|
const clientUser = this.searchClientByIdOrFail(thing.id);
|
||||||
|
|
||||||
clientListener.emitInBatch(SockerIoEvent.USER_MOVED, new MessageUserMoved(clientUser.userId, clientUser.position));
|
clientListener.emitInBatch(SockerIoEvent.USER_MOVED, new MessageUserMoved(clientUser.userId, clientUser.position));
|
||||||
//console.log("Sending USER_MOVED event");
|
//console.log("Sending USER_MOVED event");
|
||||||
}, (user, listener) => {
|
} else if (thing instanceof Group) {
|
||||||
const clientUser = this.searchClientByIdOrFail(user.id);
|
clientListener.emit(SockerIoEvent.GROUP_CREATE_UPDATE, {
|
||||||
|
position: thing.getPosition(),
|
||||||
|
groupId: thing.getId()
|
||||||
|
} as GroupUpdateInterface);
|
||||||
|
} else {
|
||||||
|
console.error('Unexpected type for Movable.');
|
||||||
|
}
|
||||||
|
}, (thing: Movable, listener) => {
|
||||||
const clientListener = this.searchClientByIdOrFail(listener.id);
|
const clientListener = this.searchClientByIdOrFail(listener.id);
|
||||||
|
if (thing instanceof User) {
|
||||||
|
const clientUser = this.searchClientByIdOrFail(thing.id);
|
||||||
|
clientListener.emit(SockerIoEvent.USER_LEFT, clientUser.userId);
|
||||||
|
//console.log("Sending USER_LEFT event");
|
||||||
|
} else if (thing instanceof Group) {
|
||||||
|
clientListener.emit(SockerIoEvent.GROUP_DELETE, thing.getId());
|
||||||
|
} else {
|
||||||
|
console.error('Unexpected type for Movable.');
|
||||||
|
}
|
||||||
|
|
||||||
clientListener.emit(SockerIoEvent.USER_LEFT, clientUser.userId);
|
|
||||||
//console.log("Sending USER_LEFT event");
|
|
||||||
});
|
});
|
||||||
this.Worlds.set(roomId, world);
|
this.Worlds.set(roomId, world);
|
||||||
}
|
}
|
||||||
@ -516,7 +553,7 @@ export class IoSocketController {
|
|||||||
Client.emit(SockerIoEvent.GROUP_CREATE_UPDATE, {
|
Client.emit(SockerIoEvent.GROUP_CREATE_UPDATE, {
|
||||||
position: group.getPosition(),
|
position: group.getPosition(),
|
||||||
groupId: group.getId()
|
groupId: group.getId()
|
||||||
});
|
} as GroupUpdateInterface);
|
||||||
});
|
});
|
||||||
//join world
|
//join world
|
||||||
world.join(Client, Client.position);
|
world.join(Client, Client.position);
|
||||||
|
@ -1,29 +1,30 @@
|
|||||||
import { World, ConnectCallback, DisconnectCallback } from "./World";
|
import { World, ConnectCallback, DisconnectCallback } from "./World";
|
||||||
import { UserInterface } from "./UserInterface";
|
import { User } from "./User";
|
||||||
import {PositionInterface} from "_Model/PositionInterface";
|
import {PositionInterface} from "_Model/PositionInterface";
|
||||||
import {uuid} from "uuidv4";
|
import {uuid} from "uuidv4";
|
||||||
|
import {Movable} from "_Model/Movable";
|
||||||
|
|
||||||
export class Group {
|
export class Group implements Movable {
|
||||||
static readonly MAX_PER_GROUP = 4;
|
static readonly MAX_PER_GROUP = 4;
|
||||||
|
|
||||||
private id: string;
|
private id: string;
|
||||||
private users: Set<UserInterface>;
|
private users: Set<User>;
|
||||||
private connectCallback: ConnectCallback;
|
private connectCallback: ConnectCallback;
|
||||||
private disconnectCallback: DisconnectCallback;
|
private disconnectCallback: DisconnectCallback;
|
||||||
|
|
||||||
|
|
||||||
constructor(users: UserInterface[], connectCallback: ConnectCallback, disconnectCallback: DisconnectCallback) {
|
constructor(users: User[], connectCallback: ConnectCallback, disconnectCallback: DisconnectCallback) {
|
||||||
this.users = new Set<UserInterface>();
|
this.users = new Set<User>();
|
||||||
this.connectCallback = connectCallback;
|
this.connectCallback = connectCallback;
|
||||||
this.disconnectCallback = disconnectCallback;
|
this.disconnectCallback = disconnectCallback;
|
||||||
this.id = uuid();
|
this.id = uuid();
|
||||||
|
|
||||||
users.forEach((user: UserInterface) => {
|
users.forEach((user: User) => {
|
||||||
this.join(user);
|
this.join(user);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getUsers(): UserInterface[] {
|
getUsers(): User[] {
|
||||||
return Array.from(this.users.values());
|
return Array.from(this.users.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ export class Group {
|
|||||||
let x = 0;
|
let x = 0;
|
||||||
let y = 0;
|
let y = 0;
|
||||||
// Let's compute the barycenter of all users.
|
// Let's compute the barycenter of all users.
|
||||||
this.users.forEach((user: UserInterface) => {
|
this.users.forEach((user: User) => {
|
||||||
x += user.position.x;
|
x += user.position.x;
|
||||||
y += user.position.y;
|
y += user.position.y;
|
||||||
});
|
});
|
||||||
@ -58,7 +59,7 @@ export class Group {
|
|||||||
return this.users.size <= 1;
|
return this.users.size <= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
join(user: UserInterface): void
|
join(user: User): void
|
||||||
{
|
{
|
||||||
// Broadcast on the right event
|
// Broadcast on the right event
|
||||||
this.connectCallback(user.id, this);
|
this.connectCallback(user.id, this);
|
||||||
@ -66,7 +67,7 @@ export class Group {
|
|||||||
user.group = this;
|
user.group = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave(user: UserInterface): void
|
leave(user: User): void
|
||||||
{
|
{
|
||||||
const success = this.users.delete(user);
|
const success = this.users.delete(user);
|
||||||
if (success === false) {
|
if (success === false) {
|
||||||
|
8
back/src/Model/Movable.ts
Normal file
8
back/src/Model/Movable.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import {PositionInterface} from "_Model/PositionInterface";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A physical object that can be placed into a Zone
|
||||||
|
*/
|
||||||
|
export interface Movable {
|
||||||
|
getPosition(): PositionInterface
|
||||||
|
}
|
@ -8,10 +8,12 @@
|
|||||||
* The PositionNotifier is important for performance. It allows us to send the position of players only to a restricted
|
* The PositionNotifier is important for performance. It allows us to send the position of players only to a restricted
|
||||||
* number of players around the current player.
|
* number of players around the current player.
|
||||||
*/
|
*/
|
||||||
import {UserEntersCallback, UserLeavesCallback, UserMovesCallback, Zone} from "./Zone";
|
import {EntersCallback, LeavesCallback, MovesCallback, Zone} from "./Zone";
|
||||||
import {PointInterface} from "_Model/Websocket/PointInterface";
|
import {PointInterface} from "_Model/Websocket/PointInterface";
|
||||||
import {UserInterface} from "_Model/UserInterface";
|
import {User} from "_Model/User";
|
||||||
import {ViewportInterface} from "_Model/Websocket/ViewportMessage";
|
import {ViewportInterface} from "_Model/Websocket/ViewportMessage";
|
||||||
|
import {Movable} from "_Model/Movable";
|
||||||
|
import {PositionInterface} from "_Model/PositionInterface";
|
||||||
|
|
||||||
interface ZoneDescriptor {
|
interface ZoneDescriptor {
|
||||||
i: number;
|
i: number;
|
||||||
@ -24,7 +26,7 @@ export class PositionNotifier {
|
|||||||
|
|
||||||
private zones: Zone[][] = [];
|
private zones: Zone[][] = [];
|
||||||
|
|
||||||
constructor(private zoneWidth: number, private zoneHeight: number, private onUserEnters: UserEntersCallback, private onUserMoves: UserMovesCallback, private onUserLeaves: UserLeavesCallback) {
|
constructor(private zoneWidth: number, private zoneHeight: number, private onUserEnters: EntersCallback, private onUserMoves: MovesCallback, private onUserLeaves: LeavesCallback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private getZoneDescriptorFromCoordinates(x: number, y: number): ZoneDescriptor {
|
private getZoneDescriptorFromCoordinates(x: number, y: number): ZoneDescriptor {
|
||||||
@ -38,7 +40,7 @@ export class PositionNotifier {
|
|||||||
* Sets the viewport coordinates.
|
* Sets the viewport coordinates.
|
||||||
* Returns the list of new users to add
|
* Returns the list of new users to add
|
||||||
*/
|
*/
|
||||||
public setViewport(user: UserInterface, viewport: ViewportInterface): UserInterface[] {
|
public setViewport(user: User, viewport: ViewportInterface): Movable[] {
|
||||||
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 [];
|
||||||
@ -60,43 +62,46 @@ export class PositionNotifier {
|
|||||||
const removedZones = [...oldZones].filter(x => !newZones.has(x));
|
const removedZones = [...oldZones].filter(x => !newZones.has(x));
|
||||||
|
|
||||||
|
|
||||||
let users: UserInterface[] = [];
|
let things: Movable[] = [];
|
||||||
for (const zone of addedZones) {
|
for (const zone of addedZones) {
|
||||||
zone.startListening(user);
|
zone.startListening(user);
|
||||||
users = users.concat(Array.from(zone.getPlayers()))
|
things = things.concat(Array.from(zone.getThings()))
|
||||||
}
|
}
|
||||||
for (const zone of removedZones) {
|
for (const zone of removedZones) {
|
||||||
zone.stopListening(user);
|
zone.stopListening(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
return users;
|
return things;
|
||||||
}
|
}
|
||||||
|
|
||||||
public updatePosition(user: UserInterface, userPosition: PointInterface): void {
|
public updatePosition(thing: Movable, newPosition: PositionInterface, oldPosition: PositionInterface): void {
|
||||||
// Did we change zone?
|
// Did we change zone?
|
||||||
const oldZoneDesc = this.getZoneDescriptorFromCoordinates(user.position.x, user.position.y);
|
const oldZoneDesc = this.getZoneDescriptorFromCoordinates(oldPosition.x, oldPosition.y);
|
||||||
const newZoneDesc = this.getZoneDescriptorFromCoordinates(userPosition.x, userPosition.y);
|
const newZoneDesc = this.getZoneDescriptorFromCoordinates(newPosition.x, newPosition.y);
|
||||||
|
|
||||||
if (oldZoneDesc.i != newZoneDesc.i || oldZoneDesc.j != newZoneDesc.j) {
|
if (oldZoneDesc.i != newZoneDesc.i || oldZoneDesc.j != newZoneDesc.j) {
|
||||||
const oldZone = this.getZone(oldZoneDesc.i, oldZoneDesc.j);
|
const oldZone = this.getZone(oldZoneDesc.i, oldZoneDesc.j);
|
||||||
const newZone = this.getZone(newZoneDesc.i, newZoneDesc.j);
|
const newZone = this.getZone(newZoneDesc.i, newZoneDesc.j);
|
||||||
|
|
||||||
// Leave old zone
|
// Leave old zone
|
||||||
oldZone.leave(user, newZone);
|
oldZone.leave(thing, newZone);
|
||||||
|
|
||||||
// Enter new zone
|
// Enter new zone
|
||||||
newZone.enter(user, oldZone, userPosition);
|
newZone.enter(thing, oldZone, newPosition);
|
||||||
} else {
|
} else {
|
||||||
const zone = this.getZone(oldZoneDesc.i, oldZoneDesc.j);
|
const zone = this.getZone(oldZoneDesc.i, oldZoneDesc.j);
|
||||||
zone.move(user, userPosition);
|
zone.move(thing, newPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public leave(user: UserInterface): void {
|
public leave(thing: Movable): void {
|
||||||
const oldZoneDesc = this.getZoneDescriptorFromCoordinates(user.position.x, user.position.y);
|
const oldPosition = thing.getPosition();
|
||||||
|
const oldZoneDesc = this.getZoneDescriptorFromCoordinates(oldPosition.x, oldPosition.y);
|
||||||
const oldZone = this.getZone(oldZoneDesc.i, oldZoneDesc.j);
|
const oldZone = this.getZone(oldZoneDesc.i, oldZoneDesc.j);
|
||||||
oldZone.leave(user, null);
|
oldZone.leave(thing, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeViewport(user: User): void {
|
||||||
// Also, let's stop listening on viewports
|
// Also, let's stop listening on viewports
|
||||||
for (const zone of user.listenedZones) {
|
for (const zone of user.listenedZones) {
|
||||||
zone.stopListening(user);
|
zone.stopListening(user);
|
||||||
|
23
back/src/Model/User.ts
Normal file
23
back/src/Model/User.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { Group } from "./Group";
|
||||||
|
import { PointInterface } from "./Websocket/PointInterface";
|
||||||
|
import {Zone} from "_Model/Zone";
|
||||||
|
import {Movable} from "_Model/Movable";
|
||||||
|
import {PositionInterface} from "_Model/PositionInterface";
|
||||||
|
|
||||||
|
export class User implements Movable {
|
||||||
|
public listenedZones: Set<Zone>;
|
||||||
|
public group?: Group;
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
public id: string,
|
||||||
|
public position: PointInterface,
|
||||||
|
public silent: boolean,
|
||||||
|
|
||||||
|
) {
|
||||||
|
this.listenedZones = new Set<Zone>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPosition(): PositionInterface {
|
||||||
|
return this.position;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
import { Group } from "./Group";
|
|
||||||
import { PointInterface } from "./Websocket/PointInterface";
|
|
||||||
import {Zone} from "_Model/Zone";
|
|
||||||
|
|
||||||
export interface UserInterface {
|
|
||||||
id: string,
|
|
||||||
group?: Group,
|
|
||||||
position: PointInterface,
|
|
||||||
silent: boolean,
|
|
||||||
listenedZones: Set<Zone>
|
|
||||||
}
|
|
6
back/src/Model/Websocket/GroupUpdateInterface.ts
Normal file
6
back/src/Model/Websocket/GroupUpdateInterface.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import {PositionInterface} from "_Model/PositionInterface";
|
||||||
|
|
||||||
|
export interface GroupUpdateInterface {
|
||||||
|
position: PositionInterface,
|
||||||
|
groupId: string,
|
||||||
|
}
|
@ -2,27 +2,28 @@ import {MessageUserPosition, Point} from "./Websocket/MessageUserPosition";
|
|||||||
import {PointInterface} from "./Websocket/PointInterface";
|
import {PointInterface} from "./Websocket/PointInterface";
|
||||||
import {Group} from "./Group";
|
import {Group} from "./Group";
|
||||||
import {Distance} from "./Distance";
|
import {Distance} from "./Distance";
|
||||||
import {UserInterface} from "./UserInterface";
|
import {User} from "./User";
|
||||||
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 {UserEntersCallback, UserLeavesCallback, UserMovesCallback, Zone} from "_Model/Zone";
|
import {EntersCallback, LeavesCallback, MovesCallback, Zone} from "_Model/Zone";
|
||||||
import {PositionNotifier} from "./PositionNotifier";
|
import {PositionNotifier} from "./PositionNotifier";
|
||||||
import {ViewportInterface} from "_Model/Websocket/ViewportMessage";
|
import {ViewportInterface} from "_Model/Websocket/ViewportMessage";
|
||||||
|
import {Movable} from "_Model/Movable";
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
// callback called when a group is created or moved or changes users
|
// callback called when a group is created or moved or changes users
|
||||||
export type GroupUpdatedCallback = (group: Group) => void;
|
export type GroupUpdatedCallback = (group: Group) => void;
|
||||||
export type GroupDeletedCallback = (uuid: string, lastUser: UserInterface) => void;
|
export type GroupDeletedCallback = (uuid: string, lastUser: User) => void;
|
||||||
|
|
||||||
export class World {
|
export class World {
|
||||||
private readonly minDistance: number;
|
private readonly minDistance: number;
|
||||||
private readonly groupRadius: number;
|
private readonly groupRadius: number;
|
||||||
|
|
||||||
// Users, sorted by ID
|
// Users, sorted by ID
|
||||||
private readonly users: Map<string, UserInterface>;
|
private readonly users: Map<string, User>;
|
||||||
private readonly groups: Set<Group>;
|
private readonly groups: Set<Group>;
|
||||||
|
|
||||||
private readonly connectCallback: ConnectCallback;
|
private readonly connectCallback: ConnectCallback;
|
||||||
@ -40,11 +41,11 @@ export class World {
|
|||||||
groupRadius: number,
|
groupRadius: number,
|
||||||
groupUpdatedCallback: GroupUpdatedCallback,
|
groupUpdatedCallback: GroupUpdatedCallback,
|
||||||
groupDeletedCallback: GroupDeletedCallback,
|
groupDeletedCallback: GroupDeletedCallback,
|
||||||
onUserEnters: UserEntersCallback,
|
onEnters: EntersCallback,
|
||||||
onUserMoves: UserMovesCallback,
|
onMoves: MovesCallback,
|
||||||
onUserLeaves: UserLeavesCallback)
|
onLeaves: LeavesCallback)
|
||||||
{
|
{
|
||||||
this.users = new Map<string, UserInterface>();
|
this.users = new Map<string, User>();
|
||||||
this.groups = new Set<Group>();
|
this.groups = new Set<Group>();
|
||||||
this.connectCallback = connectCallback;
|
this.connectCallback = connectCallback;
|
||||||
this.disconnectCallback = disconnectCallback;
|
this.disconnectCallback = disconnectCallback;
|
||||||
@ -53,24 +54,19 @@ export class World {
|
|||||||
this.groupUpdatedCallback = groupUpdatedCallback;
|
this.groupUpdatedCallback = groupUpdatedCallback;
|
||||||
this.groupDeletedCallback = groupDeletedCallback;
|
this.groupDeletedCallback = groupDeletedCallback;
|
||||||
// A zone is 10 sprites wide.
|
// A zone is 10 sprites wide.
|
||||||
this.positionNotifier = new PositionNotifier(320, 320, onUserEnters, onUserMoves, onUserLeaves);
|
this.positionNotifier = new PositionNotifier(320, 320, onEnters, onMoves, onLeaves);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getGroups(): Group[] {
|
public getGroups(): Group[] {
|
||||||
return Array.from(this.groups.values());
|
return Array.from(this.groups.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUsers(): Map<string, UserInterface> {
|
public getUsers(): Map<string, User> {
|
||||||
return this.users;
|
return this.users;
|
||||||
}
|
}
|
||||||
|
|
||||||
public join(socket : Identificable, userPosition: PointInterface): void {
|
public join(socket : Identificable, userPosition: PointInterface): void {
|
||||||
this.users.set(socket.userId, {
|
this.users.set(socket.userId, new User(socket.userId, userPosition, false));
|
||||||
id: socket.userId,
|
|
||||||
position: userPosition,
|
|
||||||
silent: false, // FIXME: silent should be set at the correct value when joining a room.
|
|
||||||
listenedZones: new Set<Zone>()
|
|
||||||
});
|
|
||||||
// Let's call update position to trigger the join / leave room
|
// Let's call update position to trigger the join / leave room
|
||||||
this.updatePosition(socket, userPosition);
|
this.updatePosition(socket, userPosition);
|
||||||
}
|
}
|
||||||
@ -87,6 +83,7 @@ export class World {
|
|||||||
|
|
||||||
if (userObj !== undefined) {
|
if (userObj !== undefined) {
|
||||||
this.positionNotifier.leave(userObj);
|
this.positionNotifier.leave(userObj);
|
||||||
|
this.positionNotifier.removeViewport(userObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +97,9 @@ export class World {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.positionNotifier.updatePosition(user, userPosition);
|
this.positionNotifier.updatePosition(user, userPosition, user.position);
|
||||||
|
|
||||||
|
const oldGroupPosition = user.group?.getPosition();
|
||||||
|
|
||||||
user.position = userPosition;
|
user.position = userPosition;
|
||||||
|
|
||||||
@ -108,17 +107,17 @@ export class World {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof user.group === 'undefined') {
|
if (user.group === undefined) {
|
||||||
// If the user is not part of a group:
|
// If the user is not part of a group:
|
||||||
// should he join a group?
|
// should he join a group?
|
||||||
const closestItem: UserInterface|Group|null = this.searchClosestAvailableUserOrGroup(user);
|
const closestItem: User|Group|null = this.searchClosestAvailableUserOrGroup(user);
|
||||||
|
|
||||||
if (closestItem !== null) {
|
if (closestItem !== null) {
|
||||||
if (closestItem instanceof Group) {
|
if (closestItem instanceof Group) {
|
||||||
// Let's join the group!
|
// Let's join the group!
|
||||||
closestItem.join(user);
|
closestItem.join(user);
|
||||||
} else {
|
} else {
|
||||||
const closestUser : UserInterface = closestItem;
|
const closestUser : User = closestItem;
|
||||||
const group: Group = new Group([
|
const group: Group = new Group([
|
||||||
user,
|
user,
|
||||||
closestUser
|
closestUser
|
||||||
@ -138,7 +137,8 @@ export class World {
|
|||||||
|
|
||||||
// At the very end, if the user is part of a group, let's call the callback to update group position
|
// At the very end, if the user is part of a group, let's call the callback to update group position
|
||||||
if (typeof user.group !== 'undefined') {
|
if (typeof user.group !== 'undefined') {
|
||||||
this.groupUpdatedCallback(user.group);
|
this.positionNotifier.updatePosition(user.group, user.group.getPosition(), oldGroupPosition ? oldGroupPosition : user.group.getPosition());
|
||||||
|
//this.groupUpdatedCallback(user.group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,21 +167,23 @@ export class World {
|
|||||||
*
|
*
|
||||||
* @param user
|
* @param user
|
||||||
*/
|
*/
|
||||||
private leaveGroup(user: UserInterface): void {
|
private leaveGroup(user: User): void {
|
||||||
const group = user.group;
|
const group = user.group;
|
||||||
if (typeof group === 'undefined') {
|
if (typeof group === 'undefined') {
|
||||||
throw new Error("The user is part of no group");
|
throw new Error("The user is part of no group");
|
||||||
}
|
}
|
||||||
group.leave(user);
|
group.leave(user);
|
||||||
if (group.isEmpty()) {
|
if (group.isEmpty()) {
|
||||||
this.groupDeletedCallback(group.getId(), user);
|
//this.groupDeletedCallback(group.getId(), user);
|
||||||
|
this.positionNotifier.leave(group);
|
||||||
group.destroy();
|
group.destroy();
|
||||||
if (!this.groups.has(group)) {
|
if (!this.groups.has(group)) {
|
||||||
throw new Error("Could not find group "+group.getId()+" referenced by user "+user.id+" in World.");
|
throw new Error("Could not find group "+group.getId()+" referenced by user "+user.id+" in World.");
|
||||||
}
|
}
|
||||||
this.groups.delete(group);
|
this.groups.delete(group);
|
||||||
} else {
|
} else {
|
||||||
this.groupUpdatedCallback(group);
|
this.positionNotifier.updatePosition(group, group.getPosition(), group.getPosition());
|
||||||
|
//this.groupUpdatedCallback(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,10 +195,10 @@ export class World {
|
|||||||
* OR
|
* OR
|
||||||
* - close enough to a group (distance <= groupRadius)
|
* - close enough to a group (distance <= groupRadius)
|
||||||
*/
|
*/
|
||||||
private searchClosestAvailableUserOrGroup(user: UserInterface): UserInterface|Group|null
|
private searchClosestAvailableUserOrGroup(user: User): User|Group|null
|
||||||
{
|
{
|
||||||
let minimumDistanceFound: number = Math.max(this.minDistance, this.groupRadius);
|
let minimumDistanceFound: number = Math.max(this.minDistance, this.groupRadius);
|
||||||
let matchingItem: UserInterface | Group | null = null;
|
let matchingItem: User | Group | null = null;
|
||||||
this.users.forEach((currentUser, userId) => {
|
this.users.forEach((currentUser, userId) => {
|
||||||
// Let's only check users that are not part of a group
|
// Let's only check users that are not part of a group
|
||||||
if (typeof currentUser.group !== 'undefined') {
|
if (typeof currentUser.group !== 'undefined') {
|
||||||
@ -265,7 +267,7 @@ export class World {
|
|||||||
return matchingItem;
|
return matchingItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static computeDistance(user1: UserInterface, user2: UserInterface): number
|
public static computeDistance(user1: User, user2: User): number
|
||||||
{
|
{
|
||||||
return Math.sqrt(Math.pow(user2.position.x - user1.position.x, 2) + Math.pow(user2.position.y - user1.position.y, 2));
|
return Math.sqrt(Math.pow(user2.position.x - user1.position.x, 2) + Math.pow(user2.position.y - user1.position.y, 2));
|
||||||
}
|
}
|
||||||
@ -343,7 +345,7 @@ export class World {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}*/
|
}*/
|
||||||
setViewport(socket : Identificable, viewport: ViewportInterface): UserInterface[] {
|
setViewport(socket : Identificable, viewport: ViewportInterface): Movable[] {
|
||||||
const user = this.users.get(socket.userId);
|
const user = this.users.get(socket.userId);
|
||||||
if(typeof user === 'undefined') {
|
if(typeof user === 'undefined') {
|
||||||
console.warn('In setViewport, could not find user with ID "'+socket.userId+'" in world.');
|
console.warn('In setViewport, could not find user with ID "'+socket.userId+'" in world.');
|
||||||
|
@ -1,77 +1,77 @@
|
|||||||
import {UserInterface} from "./UserInterface";
|
import {User} from "./User";
|
||||||
import {PointInterface} from "_Model/Websocket/PointInterface";
|
|
||||||
import {PositionInterface} from "_Model/PositionInterface";
|
import {PositionInterface} from "_Model/PositionInterface";
|
||||||
|
import {Movable} from "_Model/Movable";
|
||||||
|
|
||||||
export type UserEntersCallback = (user: UserInterface, listener: UserInterface) => void;
|
export type EntersCallback = (thing: Movable, listener: User) => void;
|
||||||
export type UserMovesCallback = (user: UserInterface, position: PointInterface, listener: UserInterface) => void;
|
export type MovesCallback = (thing: Movable, position: PositionInterface, listener: User) => void;
|
||||||
export type UserLeavesCallback = (user: UserInterface, listener: UserInterface) => void;
|
export type LeavesCallback = (thing: Movable, listener: User) => void;
|
||||||
|
|
||||||
export class Zone {
|
export class Zone {
|
||||||
private players: Set<UserInterface> = new Set<UserInterface>();
|
private things: Set<Movable> = new Set<Movable>();
|
||||||
private listeners: Set<UserInterface> = new Set<UserInterface>();
|
private listeners: Set<User> = new Set<User>();
|
||||||
|
|
||||||
constructor(private onUserEnters: UserEntersCallback, private onUserMoves: UserMovesCallback, private onUserLeaves: UserLeavesCallback) {
|
constructor(private onEnters: EntersCallback, private onMoves: MovesCallback, private onLeaves: LeavesCallback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A user leaves the zone
|
* A user/thing leaves the zone
|
||||||
*/
|
*/
|
||||||
public leave(user: UserInterface, newZone: Zone|null) {
|
public leave(thing: Movable, newZone: Zone|null) {
|
||||||
this.players.delete(user);
|
this.things.delete(thing);
|
||||||
this.notifyUserLeft(user, newZone);
|
this.notifyLeft(thing, newZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify listeners of this zone that this user left
|
* Notify listeners of this zone that this user/thing left
|
||||||
*/
|
*/
|
||||||
private notifyUserLeft(user: UserInterface, newZone: Zone|null) {
|
private notifyLeft(thing: Movable, 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 !== thing && (newZone === null || !listener.listenedZones.has(newZone))) {
|
||||||
this.onUserLeaves(user, listener);
|
this.onLeaves(thing, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enter(user: UserInterface, oldZone: Zone|null, position: PointInterface) {
|
public enter(thing: Movable, oldZone: Zone|null, position: PositionInterface) {
|
||||||
this.players.add(user);
|
this.things.add(thing);
|
||||||
this.notifyUserEnter(user, oldZone, position);
|
this.notifyUserEnter(thing, oldZone, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify listeners of this zone that this user entered
|
* Notify listeners of this zone that this user entered
|
||||||
*/
|
*/
|
||||||
private notifyUserEnter(user: UserInterface, oldZone: Zone|null, position: PointInterface) {
|
private notifyUserEnter(thing: Movable, oldZone: Zone|null, position: PositionInterface) {
|
||||||
for (const listener of this.listeners) {
|
for (const listener of this.listeners) {
|
||||||
if (listener === user) {
|
if (listener === thing) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (oldZone === null || !listener.listenedZones.has(oldZone)) {
|
if (oldZone === null || !listener.listenedZones.has(oldZone)) {
|
||||||
this.onUserEnters(user, listener);
|
this.onEnters(thing, listener);
|
||||||
} else {
|
} else {
|
||||||
this.onUserMoves(user, position, listener);
|
this.onMoves(thing, position, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public move(user: UserInterface, position: PointInterface) {
|
public move(thing: Movable, position: PositionInterface) {
|
||||||
if (!this.players.has(user)) {
|
if (!this.things.has(thing)) {
|
||||||
this.players.add(user);
|
this.things.add(thing);
|
||||||
const foo = this.players;
|
const foo = this.things;
|
||||||
this.notifyUserEnter(user, null, position);
|
this.notifyUserEnter(thing, null, position);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const listener of this.listeners) {
|
for (const listener of this.listeners) {
|
||||||
if (listener !== user) {
|
if (listener !== thing) {
|
||||||
this.onUserMoves(user,position, listener);
|
this.onMoves(thing,position, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public startListening(listener: UserInterface): void {
|
public startListening(listener: User): void {
|
||||||
for (const player of this.players) {
|
for (const thing of this.things) {
|
||||||
if (player !== listener) {
|
if (thing !== listener) {
|
||||||
this.onUserEnters(player, listener);
|
this.onEnters(thing, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,10 +79,10 @@ export class Zone {
|
|||||||
listener.listenedZones.add(this);
|
listener.listenedZones.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public stopListening(listener: UserInterface): void {
|
public stopListening(listener: User): void {
|
||||||
for (const player of this.players) {
|
for (const thing of this.things) {
|
||||||
if (player !== listener) {
|
if (thing !== listener) {
|
||||||
this.onUserLeaves(player, listener);
|
this.onLeaves(thing, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ export class Zone {
|
|||||||
listener.listenedZones.delete(this);
|
listener.listenedZones.delete(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPlayers(): Set<UserInterface> {
|
public getThings(): Set<Movable> {
|
||||||
return this.players;
|
return this.things;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,16 @@ import {World, ConnectCallback, DisconnectCallback } from "../src/Model/World";
|
|||||||
import {Point} from "../src/Model/Websocket/MessageUserPosition";
|
import {Point} from "../src/Model/Websocket/MessageUserPosition";
|
||||||
import { Group } from "../src/Model/Group";
|
import { Group } from "../src/Model/Group";
|
||||||
import {PositionNotifier} from "../src/Model/PositionNotifier";
|
import {PositionNotifier} from "../src/Model/PositionNotifier";
|
||||||
import {UserInterface} from "../src/Model/UserInterface";
|
import {User} from "../src/Model/User";
|
||||||
import {PointInterface} from "../src/Model/Websocket/PointInterface";
|
import {PointInterface} from "../src/Model/Websocket/PointInterface";
|
||||||
import {Zone} from "_Model/Zone";
|
import {Zone} from "_Model/Zone";
|
||||||
|
import {Movable} from "_Model/Movable";
|
||||||
|
|
||||||
function move(user: UserInterface, x: number, y: number, positionNotifier: PositionNotifier): void {
|
function move(user: User, x: number, y: number, positionNotifier: PositionNotifier): void {
|
||||||
positionNotifier.updatePosition(user, {
|
positionNotifier.updatePosition(user, {
|
||||||
x,
|
x,
|
||||||
y,
|
y
|
||||||
moving: false,
|
}, user.position);
|
||||||
direction: 'down'
|
|
||||||
});
|
|
||||||
user.position.x = x;
|
user.position.x = x;
|
||||||
user.position.y = y;
|
user.position.y = y;
|
||||||
}
|
}
|
||||||
@ -24,35 +23,27 @@ describe("PositionNotifier", () => {
|
|||||||
let moveTriggered = false;
|
let moveTriggered = false;
|
||||||
let leaveTriggered = false;
|
let leaveTriggered = false;
|
||||||
|
|
||||||
const positionNotifier = new PositionNotifier(300, 300, (user: UserInterface) => {
|
const positionNotifier = new PositionNotifier(300, 300, (thing: Movable) => {
|
||||||
enterTriggered = true;
|
enterTriggered = true;
|
||||||
}, (user: UserInterface, position: PointInterface) => {
|
}, (thing: Movable, position: PointInterface) => {
|
||||||
moveTriggered = true;
|
moveTriggered = true;
|
||||||
}, (user: UserInterface) => {
|
}, (thing: Movable) => {
|
||||||
leaveTriggered = true;
|
leaveTriggered = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const user1 = {
|
const user1 = new User("1", {
|
||||||
id: "1",
|
x: 500,
|
||||||
position: {
|
y: 500,
|
||||||
x: 500,
|
moving: false,
|
||||||
y: 500,
|
direction: 'down'
|
||||||
moving: false,
|
}, false);
|
||||||
direction: 'down'
|
|
||||||
},
|
|
||||||
listenedZones: new Set<Zone>(),
|
|
||||||
} as UserInterface;
|
|
||||||
|
|
||||||
const user2 = {
|
const user2 = new User("2", {
|
||||||
id: "2",
|
x: -9999,
|
||||||
position: {
|
y: -9999,
|
||||||
x: -9999,
|
moving: false,
|
||||||
y: -9999,
|
direction: 'down'
|
||||||
moving: false,
|
}, false);
|
||||||
direction: 'down'
|
|
||||||
},
|
|
||||||
listenedZones: new Set<Zone>(),
|
|
||||||
} as UserInterface;
|
|
||||||
|
|
||||||
positionNotifier.setViewport(user1, {
|
positionNotifier.setViewport(user1, {
|
||||||
left: 200,
|
left: 200,
|
||||||
@ -98,6 +89,7 @@ describe("PositionNotifier", () => {
|
|||||||
|
|
||||||
// Leave the room
|
// Leave the room
|
||||||
positionNotifier.leave(user2);
|
positionNotifier.leave(user2);
|
||||||
|
positionNotifier.removeViewport(user2);
|
||||||
expect(enterTriggered).toBe(false);
|
expect(enterTriggered).toBe(false);
|
||||||
expect(moveTriggered).toBe(false);
|
expect(moveTriggered).toBe(false);
|
||||||
expect(leaveTriggered).toBe(true);
|
expect(leaveTriggered).toBe(true);
|
||||||
@ -109,35 +101,27 @@ describe("PositionNotifier", () => {
|
|||||||
let moveTriggered = false;
|
let moveTriggered = false;
|
||||||
let leaveTriggered = false;
|
let leaveTriggered = false;
|
||||||
|
|
||||||
const positionNotifier = new PositionNotifier(300, 300, (user: UserInterface) => {
|
const positionNotifier = new PositionNotifier(300, 300, (thing: Movable) => {
|
||||||
enterTriggered = true;
|
enterTriggered = true;
|
||||||
}, (user: UserInterface, position: PointInterface) => {
|
}, (thing: Movable, position: PointInterface) => {
|
||||||
moveTriggered = true;
|
moveTriggered = true;
|
||||||
}, (user: UserInterface) => {
|
}, (thing: Movable) => {
|
||||||
leaveTriggered = true;
|
leaveTriggered = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const user1 = {
|
const user1 = new User("1", {
|
||||||
id: "1",
|
x: 500,
|
||||||
position: {
|
y: 500,
|
||||||
x: 500,
|
moving: false,
|
||||||
y: 500,
|
direction: 'down'
|
||||||
moving: false,
|
}, false);
|
||||||
direction: 'down'
|
|
||||||
},
|
|
||||||
listenedZones: new Set<Zone>(),
|
|
||||||
} as UserInterface;
|
|
||||||
|
|
||||||
const user2 = {
|
const user2 = new User("2", {
|
||||||
id: "2",
|
x: -9999,
|
||||||
position: {
|
y: -9999,
|
||||||
x: -9999,
|
moving: false,
|
||||||
y: -9999,
|
direction: 'down'
|
||||||
moving: false,
|
}, false);
|
||||||
direction: 'down'
|
|
||||||
},
|
|
||||||
listenedZones: new Set<Zone>(),
|
|
||||||
} as UserInterface;
|
|
||||||
|
|
||||||
let newUsers = positionNotifier.setViewport(user1, {
|
let newUsers = positionNotifier.setViewport(user1, {
|
||||||
left: 200,
|
left: 200,
|
||||||
|
@ -123,7 +123,8 @@ export interface ItemEventMessageInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface RoomJoinedMessageInterface {
|
export interface RoomJoinedMessageInterface {
|
||||||
users: MessageUserPositionInterface[]
|
users: MessageUserPositionInterface[],
|
||||||
|
groups: GroupCreatedUpdatedMessageInterface[],
|
||||||
items: { [itemId: number] : unknown }
|
items: { [itemId: number] : unknown }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -780,6 +780,7 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
this.initUsersPosition(roomJoinedMessage.users);
|
this.initUsersPosition(roomJoinedMessage.users);
|
||||||
this.connectionAnswerPromiseResolve(roomJoinedMessage);
|
this.connectionAnswerPromiseResolve(roomJoinedMessage);
|
||||||
});
|
});
|
||||||
|
// FIXME: weirdly enough we don't use the result of joinARoom !!!!!!
|
||||||
|
|
||||||
//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))
|
||||||
|
Loading…
Reference in New Issue
Block a user