Implement on enter/leave layer events

This commit is contained in:
Alexis Faizeau 2021-10-29 16:44:51 +02:00
parent 0b08d9251e
commit 934e24f837
14 changed files with 222 additions and 18 deletions

View File

@ -14,6 +14,7 @@ The list of functions below is **deprecated**. You should not use those but. use
- Method `WA.goToRoom` is deprecated. It has been renamed to `WA.nav.goToRoom`. - Method `WA.goToRoom` is deprecated. It has been renamed to `WA.nav.goToRoom`.
- Method `WA.openCoWebSite` is deprecated. It has been renamed to `WA.nav.openCoWebSite`. - Method `WA.openCoWebSite` is deprecated. It has been renamed to `WA.nav.openCoWebSite`.
- Method `WA.closeCoWebSite` is deprecated. It has been renamed to `WA.nav.closeCoWebSite`. - Method `WA.closeCoWebSite` is deprecated. It has been renamed to `WA.nav.closeCoWebSite`.
- Method `WA.closeCoWebsite` is deprecated. It has been renamed to `WA.nav.closeCoWebsite`.
- Method `WA.openPopup` is deprecated. It has been renamed to `WA.ui.openPopup`. - Method `WA.openPopup` is deprecated. It has been renamed to `WA.ui.openPopup`.
- Method `WA.onChatMessage` is deprecated. It has been renamed to `WA.chat.onChatMessage`. - Method `WA.onChatMessage` is deprecated. It has been renamed to `WA.chat.onChatMessage`.
- Method `WA.onEnterZone` is deprecated. It has been renamed to `WA.room.onEnterZone`. - Method `WA.onEnterZone` is deprecated. It has been renamed to `WA.room.onEnterZone`.

View File

@ -68,7 +68,9 @@ The event has the following attributes :
* **moving (boolean):** **true** when the current player is moving, **false** otherwise. * **moving (boolean):** **true** when the current player is moving, **false** otherwise.
* **direction (string):** **"right"** | **"left"** | **"down"** | **"top"** the direction where the current player is moving. * **direction (string):** **"right"** | **"left"** | **"down"** | **"top"** the direction where the current player is moving.
* **x (number):** coordinate X of the current player. * **x (number):** coordinate X of the current player.
* **y (number):** coordinate Y of the current player. * **y (number):** coordinate Y of the current player.
* **oldX (number):** old coordinate X of the current player.
* **oldY (number):** old coordinate Y of the current player.
**callback:** the function that will be called when the current player is moving. It contains the event. **callback:** the function that will be called when the current player is moving. It contains the event.

View File

@ -0,0 +1,11 @@
import * as tg from "generic-type-guard";
export const isChangeLayerEvent = new tg.IsInterface()
.withProperties({
name: tg.isString,
})
.get();
/**
* A message sent from the game to the iFrame when a user enters or leaves a layer.
*/
export type ChangeLayerEvent = tg.GuardedType<typeof isChangeLayerEvent>;

View File

@ -6,6 +6,8 @@ export const isHasPlayerMovedEvent = new tg.IsInterface()
moving: tg.isBoolean, moving: tg.isBoolean,
x: tg.isNumber, x: tg.isNumber,
y: tg.isNumber, y: tg.isNumber,
oldX: tg.isOptional(tg.isNumber),
oldY: tg.isOptional(tg.isNumber),
}) })
.get(); .get();

View File

@ -29,6 +29,7 @@ import type {
} from "./ui/TriggerActionMessageEvent"; } from "./ui/TriggerActionMessageEvent";
import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent"; import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent";
import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent"; import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent";
import type { ChangeLayerEvent } from "./ChangeLayerEvent";
export interface TypedMessageEvent<T> extends MessageEvent { export interface TypedMessageEvent<T> extends MessageEvent {
data: T; data: T;
@ -75,6 +76,8 @@ export interface IframeResponseEventMap {
userInputChat: UserInputChatEvent; userInputChat: UserInputChatEvent;
enterEvent: EnterLeaveEvent; enterEvent: EnterLeaveEvent;
leaveEvent: EnterLeaveEvent; leaveEvent: EnterLeaveEvent;
enterLayerEvent: ChangeLayerEvent;
leaveLayerEvent: ChangeLayerEvent;
buttonClickedEvent: ButtonClickedEvent; buttonClickedEvent: ButtonClickedEvent;
hasPlayerMoved: HasPlayerMovedEvent; hasPlayerMoved: HasPlayerMovedEvent;
menuItemClicked: MenuItemClickedEvent; menuItemClicked: MenuItemClickedEvent;

View File

@ -30,6 +30,7 @@ import { SetTilesEvent, isSetTilesEvent } from "./Events/SetTilesEvent";
import type { SetVariableEvent } from "./Events/SetVariableEvent"; import type { SetVariableEvent } from "./Events/SetVariableEvent";
import { ModifyEmbeddedWebsiteEvent, isEmbeddedWebsiteEvent } from "./Events/EmbeddedWebsiteEvent"; import { ModifyEmbeddedWebsiteEvent, isEmbeddedWebsiteEvent } from "./Events/EmbeddedWebsiteEvent";
import { handleMenuRegistrationEvent, handleMenuUnregisterEvent } from "../Stores/MenuStore"; import { handleMenuRegistrationEvent, handleMenuUnregisterEvent } from "../Stores/MenuStore";
import type { ChangeLayerEvent } from "./Events/ChangeLayerEvent";
type AnswererCallback<T extends keyof IframeQueryMap> = ( type AnswererCallback<T extends keyof IframeQueryMap> = (
query: IframeQueryMap[T]["query"], query: IframeQueryMap[T]["query"],
@ -395,6 +396,24 @@ class IframeListener {
}); });
} }
sendEnterLayerEvent(layerName: string) {
this.postMessage({
type: "enterLayerEvent",
data: {
name: layerName,
} as ChangeLayerEvent,
});
}
sendLeaveLayerEvent(layerName: string) {
this.postMessage({
type: "leaveLayerEvent",
data: {
name: layerName,
} as ChangeLayerEvent,
});
}
hasPlayerMoved(event: HasPlayerMovedEvent) { hasPlayerMoved(event: HasPlayerMovedEvent) {
if (this.sendPlayerMove) { if (this.sendPlayerMove) {
this.postMessage({ this.postMessage({

View File

@ -1,6 +1,7 @@
import { Subject } from "rxjs"; import { Subject } from "rxjs";
import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent"; import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent";
import { ChangeLayerEvent, isChangeLayerEvent } from "../Events/ChangeLayerEvent";
import { IframeApiContribution, queryWorkadventure, sendToWorkadventure } from "./IframeApiContribution"; import { IframeApiContribution, queryWorkadventure, sendToWorkadventure } from "./IframeApiContribution";
import { apiCallback } from "./registeredCallbacks"; import { apiCallback } from "./registeredCallbacks";
@ -12,6 +13,9 @@ import website from "./website";
const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>(); const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>(); const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
const enterLayerStreams: Map<string, Subject<void>> = new Map<string, Subject<void>>();
const leaveLayerStreams: Map<string, Subject<void>> = new Map<string, Subject<void>>();
interface TileDescriptor { interface TileDescriptor {
x: number; x: number;
y: number; y: number;
@ -47,8 +51,25 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
leaveStreams.get(payloadData.name)?.next(); leaveStreams.get(payloadData.name)?.next();
}, },
}), }),
apiCallback({
type: "enterLayerEvent",
typeChecker: isChangeLayerEvent,
callback: (payloadData: ChangeLayerEvent) => {
enterLayerStreams.get(payloadData.name)?.next();
},
}),
apiCallback({
type: "leaveLayerEvent",
typeChecker: isChangeLayerEvent,
callback: (payloadData) => {
leaveLayerStreams.get(payloadData.name)?.next();
},
}),
]; ];
/**
* @deprecated Use onEnterLayer instead
*/
onEnterZone(name: string, callback: () => void): void { onEnterZone(name: string, callback: () => void): void {
let subject = enterStreams.get(name); let subject = enterStreams.get(name);
if (subject === undefined) { if (subject === undefined) {
@ -57,6 +78,10 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
} }
subject.subscribe(callback); subject.subscribe(callback);
} }
/**
* @deprecated Use onLeaveLayer instead
*/
onLeaveZone(name: string, callback: () => void): void { onLeaveZone(name: string, callback: () => void): void {
let subject = leaveStreams.get(name); let subject = leaveStreams.get(name);
if (subject === undefined) { if (subject === undefined) {
@ -65,12 +90,35 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
} }
subject.subscribe(callback); subject.subscribe(callback);
} }
onEnterLayer(layerName: string): Subject<void> {
let subject = enterLayerStreams.get(layerName);
if (subject === undefined) {
subject = new Subject<ChangeLayerEvent>();
enterLayerStreams.set(layerName, subject);
}
return subject;
}
onLeaveLayer(layerName: string): Subject<void> {
let subject = leaveLayerStreams.get(layerName);
if (subject === undefined) {
subject = new Subject<ChangeLayerEvent>();
leaveLayerStreams.set(layerName, subject);
}
return subject;
}
showLayer(layerName: string): void { showLayer(layerName: string): void {
sendToWorkadventure({ type: "showLayer", data: { name: layerName } }); sendToWorkadventure({ type: "showLayer", data: { name: layerName } });
} }
hideLayer(layerName: string): void { hideLayer(layerName: string): void {
sendToWorkadventure({ type: "hideLayer", data: { name: layerName } }); sendToWorkadventure({ type: "hideLayer", data: { name: layerName } });
} }
setProperty(layerName: string, propertyName: string, propertyValue: string | number | boolean | undefined): void { setProperty(layerName: string, propertyName: string, propertyValue: string | number | boolean | undefined): void {
sendToWorkadventure({ sendToWorkadventure({
type: "setProperty", type: "setProperty",
@ -81,10 +129,12 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
}, },
}); });
} }
async getTiledMap(): Promise<ITiledMap> { async getTiledMap(): Promise<ITiledMap> {
const event = await queryWorkadventure({ type: "getMapData", data: undefined }); const event = await queryWorkadventure({ type: "getMapData", data: undefined });
return event.data as ITiledMap; return event.data as ITiledMap;
} }
setTiles(tiles: TileDescriptor[]) { setTiles(tiles: TileDescriptor[]) {
sendToWorkadventure({ sendToWorkadventure({
type: "setTiles", type: "setTiles",

View File

@ -2,6 +2,7 @@ import type { ITiledMap, ITiledMapLayer, ITiledMapProperty } from "../Map/ITiled
import { flattenGroupLayersMap } from "../Map/LayersFlattener"; import { flattenGroupLayersMap } from "../Map/LayersFlattener";
import TilemapLayer = Phaser.Tilemaps.TilemapLayer; import TilemapLayer = Phaser.Tilemaps.TilemapLayer;
import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes"; import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes";
import { iframeListener } from "../../Api/IframeListener";
export type PropertyChangeCallback = ( export type PropertyChangeCallback = (
newValue: string | number | boolean | undefined, newValue: string | number | boolean | undefined,
@ -9,14 +10,25 @@ export type PropertyChangeCallback = (
allProps: Map<string, string | boolean | number> allProps: Map<string, string | boolean | number>
) => void; ) => void;
export type layerChangeCallback = (
layersChangedByAction: Array<ITiledMapLayer>,
allLayersOnNewPosition: Array<ITiledMapLayer>,
) => void;
/** /**
* A wrapper around a ITiledMap interface to provide additional capabilities. * A wrapper around a ITiledMap interface to provide additional capabilities.
* It is used to handle layer properties. * It is used to handle layer properties.
*/ */
export class GameMap { export class GameMap {
// oldKey is the index of the previous tile.
private oldKey: number | undefined;
// key is the index of the current tile.
private key: number | undefined; private key: number | undefined;
private lastProperties = new Map<string, string | boolean | number>(); private lastProperties = new Map<string, string | boolean | number>();
private callbacks = new Map<string, Array<PropertyChangeCallback>>(); private propertiesChangeCallbacks = new Map<string, Array<PropertyChangeCallback>>();
private enterLayerCallbacks = Array<layerChangeCallback>();
private leaveLayerCallbacks = Array<layerChangeCallback>();
private tileNameMap = new Map<string, number>(); private tileNameMap = new Map<string, number>();
private tileSetPropertyMap: { [tile_index: number]: Array<ITiledMapProperty> } = {}; private tileSetPropertyMap: { [tile_index: number]: Array<ITiledMapProperty> } = {};
@ -68,22 +80,32 @@ export class GameMap {
return []; return [];
} }
private getLayersByKey(key: number): Array<ITiledMapLayer> {
return this.flatLayers.filter(flatLayer => flatLayer.type === 'tilelayer' && flatLayer.data[key] !== 0);
}
/** /**
* Sets the position of the current player (in pixels) * Sets the position of the current player (in pixels)
* This will trigger events if properties are changing. * This will trigger events if properties are changing.
*/ */
public setPosition(x: number, y: number) { public setPosition(x: number, y: number) {
this.oldKey = this.key;
const xMap = Math.floor(x / this.map.tilewidth); const xMap = Math.floor(x / this.map.tilewidth);
const yMap = Math.floor(y / this.map.tileheight); const yMap = Math.floor(y / this.map.tileheight);
const key = xMap + yMap * this.map.width; const key = xMap + yMap * this.map.width;
if (key === this.key) { if (key === this.key) {
return; return;
} }
this.key = key; this.key = key;
this.triggerAll();
this.triggerAllProperties();
this.triggerLayersChange();
} }
private triggerAll(): void { private triggerAllProperties(): void {
const newProps = this.getProperties(this.key ?? 0); const newProps = this.getProperties(this.key ?? 0);
const oldProps = this.lastProperties; const oldProps = this.lastProperties;
this.lastProperties = newProps; this.lastProperties = newProps;
@ -105,6 +127,36 @@ export class GameMap {
} }
} }
private triggerLayersChange() {
const layersByOldKey = this.oldKey ? this.getLayersByKey(this.oldKey) : [];
const layersByNewKey = this.key ? this.getLayersByKey(this.key) : [];
const enterLayers = new Set(layersByNewKey);
const leaveLayers = new Set(layersByOldKey);
enterLayers.forEach(layer => {
if (leaveLayers.has(layer)) {
leaveLayers.delete(layer);
enterLayers.delete(layer);
}
});
if (enterLayers.size > 0) {
const layerArray = Array.from(enterLayers);
for (const callback of this.enterLayerCallbacks) {
callback(layerArray, layersByNewKey);
}
}
if (leaveLayers.size > 0) {
const layerArray = Array.from(leaveLayers);
for (const callback of this.leaveLayerCallbacks) {
callback(layerArray, layersByNewKey);
}
}
}
public getCurrentProperties(): Map<string, string | boolean | number> { public getCurrentProperties(): Map<string, string | boolean | number> {
return this.lastProperties; return this.lastProperties;
} }
@ -167,7 +219,7 @@ export class GameMap {
newValue: string | number | boolean | undefined, newValue: string | number | boolean | undefined,
allProps: Map<string, string | boolean | number> allProps: Map<string, string | boolean | number>
) { ) {
const callbacksArray = this.callbacks.get(propName); const callbacksArray = this.propertiesChangeCallbacks.get(propName);
if (callbacksArray !== undefined) { if (callbacksArray !== undefined) {
for (const callback of callbacksArray) { for (const callback of callbacksArray) {
callback(newValue, oldValue, allProps); callback(newValue, oldValue, allProps);
@ -179,14 +231,28 @@ export class GameMap {
* Registers a callback called when the user moves to a tile where the property propName is different from the last tile the user was on. * Registers a callback called when the user moves to a tile where the property propName is different from the last tile the user was on.
*/ */
public onPropertyChange(propName: string, callback: PropertyChangeCallback) { public onPropertyChange(propName: string, callback: PropertyChangeCallback) {
let callbacksArray = this.callbacks.get(propName); let callbacksArray = this.propertiesChangeCallbacks.get(propName);
if (callbacksArray === undefined) { if (callbacksArray === undefined) {
callbacksArray = new Array<PropertyChangeCallback>(); callbacksArray = new Array<PropertyChangeCallback>();
this.callbacks.set(propName, callbacksArray); this.propertiesChangeCallbacks.set(propName, callbacksArray);
} }
callbacksArray.push(callback); callbacksArray.push(callback);
} }
/**
* Registers a callback called when the user moves inside another layer.
*/
public onEnterLayer(callback: layerChangeCallback) {
this.enterLayerCallbacks.push(callback);
}
/**
* Registers a callback called when the user moves outside another layer.
*/
public onLeaveLayer(callback: layerChangeCallback) {
this.leaveLayerCallbacks.push(callback);
}
public findLayer(layerName: string): ITiledMapLayer | undefined { public findLayer(layerName: string): ITiledMapLayer | undefined {
return this.flatLayers.find((layer) => layer.name === layerName); return this.flatLayers.find((layer) => layer.name === layerName);
} }
@ -284,7 +350,8 @@ export class GameMap {
} }
property.value = propertyValue; property.value = propertyValue;
this.triggerAll(); this.triggerAllProperties();
this.triggerLayersChange();
} }
/** /**

View File

@ -186,6 +186,8 @@ export class GameScene extends DirtyScene {
moving: false, moving: false,
x: -1000, x: -1000,
y: -1000, y: -1000,
oldX: -1000,
oldY: -1000,
}; };
private gameMap!: GameMap; private gameMap!: GameMap;
@ -764,6 +766,19 @@ export class GameScene extends DirtyScene {
//init user position and play trigger to check layers properties //init user position and play trigger to check layers properties
this.gameMap.setPosition(this.CurrentPlayer.x, this.CurrentPlayer.y); this.gameMap.setPosition(this.CurrentPlayer.x, this.CurrentPlayer.y);
// Init layer change listener
this.gameMap.onEnterLayer(layers => {
layers.forEach(layer => {
iframeListener.sendEnterLayerEvent(layer.name);
});
});
this.gameMap.onLeaveLayer(layers => {
layers.forEach(layer => {
iframeListener.sendLeaveLayerEvent(layer.name);
});
});
}); });
} }
@ -895,6 +910,7 @@ export class GameScene extends DirtyScene {
audioManagerVisibilityStore.set(!(newValue === undefined)); audioManagerVisibilityStore.set(!(newValue === undefined));
}); });
// TODO: Legacy functionnality replace by layer change
this.gameMap.onPropertyChange("zone", (newValue, oldValue) => { this.gameMap.onPropertyChange("zone", (newValue, oldValue) => {
if (oldValue) { if (oldValue) {
iframeListener.sendLeaveEvent(oldValue as string); iframeListener.sendLeaveEvent(oldValue as string);
@ -1749,7 +1765,11 @@ ${escapedMessage}
const playerMovement = new PlayerMovement( const playerMovement = new PlayerMovement(
{ x: player.x, y: player.y }, { x: player.x, y: player.y },
this.currentTick, this.currentTick,
message.position, {
...message.position,
oldX: undefined,
oldY: undefined,
},
this.currentTick + POSITION_DELAY this.currentTick + POSITION_DELAY
); );
this.playersPositionInterpolator.updatePlayerPosition(player.userId, playerMovement); this.playersPositionInterpolator.updatePlayerPosition(player.userId, playerMovement);

View File

@ -38,6 +38,8 @@ export class PlayerMovement {
return { return {
x, x,
y, y,
oldX: this.startPosition.x,
oldY: this.startPosition.y,
direction: this.endPosition.direction, direction: this.endPosition.direction,
moving: true, moving: true,
}; };

View File

@ -64,14 +64,14 @@ export class Player extends Character {
if (x !== 0 || y !== 0) { if (x !== 0 || y !== 0) {
this.move(x, y); this.move(x, y);
this.emit(hasMovedEventName, { moving, direction, x: this.x, y: this.y }); this.emit(hasMovedEventName, { moving, direction, x: this.x, y: this.y, oldX: x, oldY: y });
} else if (this.wasMoving && moving) { } else if (this.wasMoving && moving) {
// slow joystick movement // slow joystick movement
this.move(0, 0); this.move(0, 0);
this.emit(hasMovedEventName, { moving, direction: this.previousDirection, x: this.x, y: this.y }); this.emit(hasMovedEventName, { moving, direction: this.previousDirection, x: this.x, y: this.y, oldX: x, oldY: y });
} else if (this.wasMoving && !moving) { } else if (this.wasMoving && !moving) {
this.stop(); this.stop();
this.emit(hasMovedEventName, { moving, direction: this.previousDirection, x: this.x, y: this.y }); this.emit(hasMovedEventName, { moving, direction: this.previousDirection, x: this.x, y: this.y, oldX: x, oldY: y });
} }
if (direction !== null) { if (direction !== null) {

View File

@ -9,7 +9,9 @@ export interface LayoutManagerAction {
userInputManager: UserInputManager | undefined; userInputManager: UserInputManager | undefined;
} }
function createLayoutManagerAction() { function createLayoutManagerAction() {
const { subscribe, set, update } = writable<LayoutManagerAction[]>([]); const { subscribe, set, update } = writable<LayoutManagerAction[]>([]);
return { return {

View File

@ -7,7 +7,12 @@ describe("Interpolation / Extrapolation", () => {
x: 100, y: 200 x: 100, y: 200
}, 42000, }, 42000,
{ {
x: 200, y: 100, moving: true, direction: "up" x: 200,
y: 100,
oldX: undefined,
oldY: undefined,
moving: true,
direction: "up"
}, },
42200 42200
); );
@ -19,6 +24,8 @@ describe("Interpolation / Extrapolation", () => {
expect(playerMovement.getPosition(42100)).toEqual({ expect(playerMovement.getPosition(42100)).toEqual({
x: 150, x: 150,
y: 150, y: 150,
oldX: undefined,
oldY: undefined,
direction: 'up', direction: 'up',
moving: true moving: true
}); });
@ -26,6 +33,8 @@ describe("Interpolation / Extrapolation", () => {
expect(playerMovement.getPosition(42200)).toEqual({ expect(playerMovement.getPosition(42200)).toEqual({
x: 200, x: 200,
y: 100, y: 100,
oldX: undefined,
oldY: undefined,
direction: 'up', direction: 'up',
moving: true moving: true
}); });
@ -33,6 +42,8 @@ describe("Interpolation / Extrapolation", () => {
expect(playerMovement.getPosition(42300)).toEqual({ expect(playerMovement.getPosition(42300)).toEqual({
x: 250, x: 250,
y: 50, y: 50,
oldX: undefined,
oldY: undefined,
direction: 'up', direction: 'up',
moving: true moving: true
}); });
@ -43,7 +54,12 @@ describe("Interpolation / Extrapolation", () => {
x: 100, y: 200 x: 100, y: 200
}, 42000, }, 42000,
{ {
x: 200, y: 100, moving: false, direction: "up" x: 200,
y: 100,
oldX: undefined,
oldY: undefined,
moving: false,
direction: "up"
}, },
42200 42200
); );
@ -51,6 +67,8 @@ describe("Interpolation / Extrapolation", () => {
expect(playerMovement.getPosition(42300)).toEqual({ expect(playerMovement.getPosition(42300)).toEqual({
x: 200, x: 200,
y: 100, y: 100,
oldX: undefined,
oldY: undefined,
direction: 'up', direction: 'up',
moving: false moving: false
}); });
@ -61,7 +79,12 @@ describe("Interpolation / Extrapolation", () => {
x: 100, y: 200 x: 100, y: 200
}, 42000, }, 42000,
{ {
x: 200, y: 100, moving: false, direction: "up" x: 200,
y: 100,
oldX: undefined,
oldY: undefined,
moving: false,
direction: "up"
}, },
42200 42200
); );
@ -69,6 +92,8 @@ describe("Interpolation / Extrapolation", () => {
expect(playerMovement.getPosition(42100)).toEqual({ expect(playerMovement.getPosition(42100)).toEqual({
x: 150, x: 150,
y: 150, y: 150,
oldX: undefined,
oldY: undefined,
direction: 'up', direction: 'up',
moving: true moving: true
}); });

View File

@ -231,12 +231,12 @@ export class SocketManager implements ZoneEventListener {
try { try {
client.viewport = viewport; client.viewport = viewport;
const world = this.rooms.get(client.roomId); const room = this.rooms.get(client.roomId);
if (!world) { if (!room) {
console.error("In SET_VIEWPORT, could not find world with id '", client.roomId, "'"); console.error("In SET_VIEWPORT, could not find world with id '", client.roomId, "'");
return; return;
} }
world.setViewport(client, client.viewport); room.setViewport(client, client.viewport);
} catch (e) { } catch (e) {
console.error('An error occurred on "SET_VIEWPORT" event'); console.error('An error occurred on "SET_VIEWPORT" event');
console.error(e); console.error(e);