transmit companion to remote players

This commit is contained in:
Johannes Berthel 2021-04-02 21:21:11 +02:00
parent 2ad712807b
commit c07079051a
19 changed files with 96 additions and 40 deletions

View file

@ -88,9 +88,9 @@ class ConnectionManager {
this.localUser = new LocalUser('', 'test', []);
}
public connectToRoomSocket(roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface): Promise<OnConnectInterface> {
public connectToRoomSocket(roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface, companion: string|null): Promise<OnConnectInterface> {
return new Promise<OnConnectInterface>((resolve, reject) => {
const connection = new RoomConnection(this.localUser.jwtToken, roomId, name, characterLayers, position, viewport);
const connection = new RoomConnection(this.localUser.jwtToken, roomId, name, characterLayers, position, viewport, companion);
connection.onConnectError((error: object) => {
console.log('An error occurred while connecting to socket server. Retrying');
reject(error);
@ -111,7 +111,7 @@ class ConnectionManager {
this.reconnectingTimeout = setTimeout(() => {
//todo: allow a way to break recursion?
//todo: find a way to avoid recursive function. Otherwise, the call stack will grow indefinitely.
this.connectToRoomSocket(roomId, name, characterLayers, position, viewport).then((connection) => resolve(connection));
this.connectToRoomSocket(roomId, name, characterLayers, position, viewport, companion).then((connection) => resolve(connection));
}, 4000 + Math.floor(Math.random() * 2000) );
});
});

View file

@ -47,6 +47,7 @@ export interface MessageUserPositionInterface {
name: string;
characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface;
companion: string|null;
}
export interface MessageUserMovedInterface {
@ -58,7 +59,8 @@ export interface MessageUserJoined {
userId: number;
name: string;
characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface
position: PointInterface;
companion: string|null;
}
export interface PositionInterface {

View file

@ -4,6 +4,7 @@ const playerNameKey = 'playerName';
const selectedPlayerKey = 'selectedPlayer';
const customCursorPositionKey = 'customCursorPosition';
const characterLayersKey = 'characterLayers';
const companionKey = 'companion';
const gameQualityKey = 'gameQuality';
const videoQualityKey = 'videoQuality';
const audioPlayerVolumeKey = 'audioVolume';
@ -47,6 +48,13 @@ class LocalUserStore {
return JSON.parse(localStorage.getItem(characterLayersKey) || "null");
}
setCompanion(companion: string): void {
localStorage.setItem(companionKey, companion);
}
getCompanion(): string|null {
return localStorage.getItem(companionKey);
}
setGameQualityValue(value: number): void {
localStorage.setItem(gameQualityKey, '' + value);
}

View file

@ -66,7 +66,7 @@ export class RoomConnection implements RoomConnection {
* @param token A JWT token containing the UUID of the user
* @param roomId The ID of the room in the form "_/[instance]/[map_url]" or "@/[org]/[event]/[map]"
*/
public constructor(token: string|null, roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface) {
public constructor(token: string|null, roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface, companion: string|null) {
let url = API_URL.replace('http://', 'ws://').replace('https://', 'wss://');
url += '/room';
url += '?roomId='+(roomId ?encodeURIComponent(roomId):'');
@ -81,6 +81,10 @@ export class RoomConnection implements RoomConnection {
url += '&bottom='+Math.floor(viewport.bottom);
url += '&left='+Math.floor(viewport.left);
url += '&right='+Math.floor(viewport.right);
if (typeof companion === 'string') {
url += '&companion='+encodeURIComponent(companion);
}
if (RoomConnection.websocketFactory) {
this.socket = RoomConnection.websocketFactory(url);
@ -316,11 +320,14 @@ export class RoomConnection implements RoomConnection {
}
})
const companion = message.getCompanion();
return {
userId: message.getUserid(),
name: message.getName(),
characterLayers,
position: ProtobufClientUtils.toPointInterface(position)
position: ProtobufClientUtils.toPointInterface(position),
companion: companion ? companion.getName() : null
}
}

View file

@ -22,11 +22,7 @@ export class Companion extends Container {
private direction: PlayerAnimationDirections;
private animationType: PlayerAnimationTypes;
constructor(
scene: Phaser.Scene,
x: number,
y: number
) {
constructor(scene: Phaser.Scene, x: number, y: number, name: string) {
super(scene, x + 8, y + 8);
this.sprites = new Map<string, Sprite>();
@ -38,11 +34,7 @@ export class Companion extends Container {
this.direction = PlayerAnimationDirections.Down;
this.animationType = PlayerAnimationTypes.Idle;
// select random animal
const animal = ["dog1", "dog2", "dog3", "cat1", "cat2", "cat3"];
const random = Math.floor(Math.random() * animal.length);
this.companionName = animal[random];
this.companionName = name;
lazyLoadResource(this.scene.load, this.companionName).then(resource => {
this.addResource(resource);
@ -59,14 +51,16 @@ export class Companion extends Container {
this.setDepth(-1);
scene.add.existing(this);
this.scene.events.addListener('update', this.step, this);
this.scene.add.existing(this);
}
public setTarget(x: number, y: number, direction: PlayerAnimationDirections) {
this.target = { x, y, direction };
}
public step(delta: number) {
public step(time: number, delta: number) {
if (typeof this.target === 'undefined') return;
this.delta += delta;
@ -216,6 +210,8 @@ export class Companion extends Container {
}
}
this.scene.events.removeListener('update', this.step, this);
super.destroy();
}
}

View file

@ -71,8 +71,8 @@ export abstract class Character extends Container {
this.playAnimation(direction, moving);
}
public addCompanion(): void {
this.companion = new Companion(this.scene, this.x, this.y);
public addCompanion(name: string): void {
this.companion = new Companion(this.scene, this.x, this.y, name);
}
public addTextures(textures: string[], frame?: string | number): void {

View file

@ -17,12 +17,17 @@ export class RemotePlayer extends Character {
name: string,
texturesPromise: Promise<string[]>,
direction: PlayerAnimationDirections,
moving: boolean
moving: boolean,
companion: string|null
) {
super(Scene, x, y, texturesPromise, name, direction, moving, 1);
//set data
this.userId = userId;
if (typeof companion === 'string') {
this.addCompanion(companion);
}
}
updatePosition(position: PointInterface): void {

View file

@ -6,4 +6,5 @@ export interface AddPlayerInterface {
name: string;
characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface;
companion: string|null;
}

View file

@ -21,12 +21,14 @@ export interface HasMovedEvent {
export class GameManager {
private playerName: string|null;
private characterLayers: string[]|null;
private companion: string|null;
private startRoom!:Room;
currentGameSceneName: string|null = null;
constructor() {
this.playerName = localUserStore.getName();
this.characterLayers = localUserStore.getCharacterLayers();
this.companion = localUserStore.getCompanion();
}
public async init(scenePlugin: Phaser.Scenes.ScenePlugin): Promise<string> {
@ -63,6 +65,9 @@ export class GameManager {
return this.characterLayers;
}
getCompanion(): string|null {
return this.companion;
}
public async loadMap(room: Room, scenePlugin: Phaser.Scenes.ScenePlugin): Promise<void> {
const roomID = room.id;

View file

@ -159,6 +159,7 @@ export class GameScene extends ResizableScene implements CenterListener {
private openChatIcon!: OpenChatIcon;
private playerName!: string;
private characterLayers!: string[];
private companion!: string|null;
private messageSubscription: Subscription|null = null;
private popUpElements : Map<number, DOMElement> = new Map<number, Phaser.GameObjects.DOMElement>();
@ -335,7 +336,7 @@ export class GameScene extends ResizableScene implements CenterListener {
}
this.playerName = playerName;
this.characterLayers = gameManager.getCharacterLayers();
this.companion = gameManager.getCompanion();
//initalise map
this.Map = this.add.tilemap(this.MapUrlFile);
@ -459,7 +460,9 @@ export class GameScene extends ResizableScene implements CenterListener {
top: camera.scrollY,
right: camera.scrollX + camera.width,
bottom: camera.scrollY + camera.height,
}).then((onConnect: OnConnectInterface) => {
},
this.companion
).then((onConnect: OnConnectInterface) => {
this.connection = onConnect.connection;
this.connection.onUserJoins((message: MessageUserJoined) => {
@ -467,7 +470,8 @@ export class GameScene extends ResizableScene implements CenterListener {
userId: message.userId,
characterLayers: message.characterLayers,
name: message.name,
position: message.position
position: message.position,
companion: message.companion
}
this.addPlayer(userMessage);
});
@ -1019,7 +1023,8 @@ ${escapedMessage}
texturesPromise,
PlayerAnimationDirections.Down,
false,
this.userInputManager
this.userInputManager,
this.companion
);
}catch (err){
if(err instanceof TextureError) {
@ -1211,7 +1216,8 @@ ${escapedMessage}
addPlayerData.name,
texturesPromise,
addPlayerData.position.direction as PlayerAnimationDirections,
addPlayerData.position.moving
addPlayerData.position.moving,
addPlayerData.companion
);
this.MapPlayers.add(player);
this.MapPlayersByKey.set(player.userId, player);

View file

@ -21,14 +21,17 @@ export class Player extends Character implements CurrentGamerInterface {
texturesPromise: Promise<string[]>,
direction: PlayerAnimationDirections,
moving: boolean,
private userInputManager: UserInputManager
private userInputManager: UserInputManager,
companion: string|null
) {
super(Scene, x, y, texturesPromise, name, direction, moving, 1);
//the current player model should be push away by other players to prevent conflict
this.getBody().setImmovable(false);
this.addCompanion();
if (typeof companion === 'string') {
this.addCompanion(companion);
}
}
moveUser(delta: number): void {
@ -61,10 +64,6 @@ export class Player extends Character implements CurrentGamerInterface {
moving = true;
}
if (this.companion) {
this.companion.step(delta);
}
if (x !== 0 || y !== 0) {
this.move(x, y);
this.emit(hasMovedEventName, {moving, direction, x: this.x, y: this.y});