added callback on playermove - gets quite delayed after walking for a few seconds
This commit is contained in:
parent
ce0c7ea3eb
commit
8e136cebe8
19
front/src/Api/Events/HasMovedEvent.ts
Normal file
19
front/src/Api/Events/HasMovedEvent.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import * as tg from "generic-type-guard";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const isHasMovedEvent =
|
||||||
|
new tg.IsInterface().withProperties({
|
||||||
|
direction: tg.isString,
|
||||||
|
moving: tg.isBoolean,
|
||||||
|
x: tg.isNumber,
|
||||||
|
y: tg.isNumber
|
||||||
|
}).get();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A message sent from the iFrame to the game to add a message in the chat.
|
||||||
|
*/
|
||||||
|
export type HasMovedEvent = tg.GuardedType<typeof isHasMovedEvent>;
|
||||||
|
|
||||||
|
|
||||||
|
export type HasMovedEventCallback = (event: HasMovedEvent) => void
|
@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
|
|
||||||
import { GameStateEvent } from './ApiGameStateEvent';
|
import { GameStateEvent } from './ApiGameStateEvent';
|
||||||
import { ButtonClickedEvent } from './ButtonClickedEvent';
|
import { ButtonClickedEvent } from './ButtonClickedEvent';
|
||||||
import { ChatEvent } from './ChatEvent';
|
import { ChatEvent } from './ChatEvent';
|
||||||
import { ClosePopupEvent } from './ClosePopupEvent';
|
import { ClosePopupEvent } from './ClosePopupEvent';
|
||||||
import { EnterLeaveEvent } from './EnterLeaveEvent';
|
import { EnterLeaveEvent } from './EnterLeaveEvent';
|
||||||
import { GoToPageEvent } from './GoToPageEvent';
|
import { GoToPageEvent } from './GoToPageEvent';
|
||||||
|
import { HasMovedEvent } from './HasMovedEvent';
|
||||||
import { OpenCoWebSiteEvent } from './OpenCoWebSiteEvent';
|
import { OpenCoWebSiteEvent } from './OpenCoWebSiteEvent';
|
||||||
import { OpenPopupEvent } from './OpenPopupEvent';
|
import { OpenPopupEvent } from './OpenPopupEvent';
|
||||||
import { OpenTabEvent } from './OpenTabEvent';
|
import { OpenTabEvent } from './OpenTabEvent';
|
||||||
@ -30,6 +30,7 @@ export type IframeEventMap = {
|
|||||||
restorePlayerControl: null
|
restorePlayerControl: null
|
||||||
displayBubble: null
|
displayBubble: null
|
||||||
removeBubble: null
|
removeBubble: null
|
||||||
|
enableMoveEvents: undefined
|
||||||
}
|
}
|
||||||
export interface IframeEvent<T extends keyof IframeEventMap> {
|
export interface IframeEvent<T extends keyof IframeEventMap> {
|
||||||
type: T;
|
type: T;
|
||||||
@ -46,6 +47,7 @@ export interface IframeResponseEventMap {
|
|||||||
leaveEvent: EnterLeaveEvent
|
leaveEvent: EnterLeaveEvent
|
||||||
buttonClickedEvent: ButtonClickedEvent
|
buttonClickedEvent: ButtonClickedEvent
|
||||||
gameState: GameStateEvent
|
gameState: GameStateEvent
|
||||||
|
hasMovedEvent: HasMovedEvent
|
||||||
}
|
}
|
||||||
export interface IframeResponseEvent<T extends keyof IframeResponseEventMap> {
|
export interface IframeResponseEvent<T extends keyof IframeResponseEventMap> {
|
||||||
type: T;
|
type: T;
|
||||||
|
@ -14,6 +14,7 @@ import { IframeEventMap, IframeEvent, IframeResponseEvent, IframeResponseEventMa
|
|||||||
import { UserInputChatEvent } from "./Events/UserInputChatEvent";
|
import { UserInputChatEvent } from "./Events/UserInputChatEvent";
|
||||||
import { GameStateEvent } from './Events/ApiGameStateEvent';
|
import { GameStateEvent } from './Events/ApiGameStateEvent';
|
||||||
import { deepFreezeClone as deepFreezeClone } from '../utility';
|
import { deepFreezeClone as deepFreezeClone } from '../utility';
|
||||||
|
import { HasMovedEvent } from './Events/HasMovedEvent';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,6 +22,7 @@ import { deepFreezeClone as deepFreezeClone } from '../utility';
|
|||||||
* Also allows to send messages to those iframes.
|
* Also allows to send messages to those iframes.
|
||||||
*/
|
*/
|
||||||
class IframeListener {
|
class IframeListener {
|
||||||
|
|
||||||
private readonly _chatStream: Subject<ChatEvent> = new Subject();
|
private readonly _chatStream: Subject<ChatEvent> = new Subject();
|
||||||
public readonly chatStream = this._chatStream.asObservable();
|
public readonly chatStream = this._chatStream.asObservable();
|
||||||
|
|
||||||
@ -60,6 +62,7 @@ class IframeListener {
|
|||||||
|
|
||||||
private readonly iframes = new Set<HTMLIFrameElement>();
|
private readonly iframes = new Set<HTMLIFrameElement>();
|
||||||
private readonly scripts = new Map<string, HTMLIFrameElement>();
|
private readonly scripts = new Map<string, HTMLIFrameElement>();
|
||||||
|
private sendMoveEvents: boolean = false;
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
window.addEventListener("message", (message: TypedMessageEvent<IframeEvent<keyof IframeEventMap>>) => {
|
window.addEventListener("message", (message: TypedMessageEvent<IframeEvent<keyof IframeEventMap>>) => {
|
||||||
@ -101,20 +104,18 @@ class IframeListener {
|
|||||||
}
|
}
|
||||||
else if (payload.type === 'closeCoWebSite') {
|
else if (payload.type === 'closeCoWebSite') {
|
||||||
scriptUtils.closeCoWebSite();
|
scriptUtils.closeCoWebSite();
|
||||||
}
|
} else if (payload.type === 'disablePlayerControl') {
|
||||||
else if (payload.type === 'disablePlayerControl') {
|
|
||||||
this._disablePlayerControlStream.next();
|
this._disablePlayerControlStream.next();
|
||||||
}
|
} else if (payload.type === 'restorePlayerControl') {
|
||||||
else if (payload.type === 'restorePlayerControl') {
|
|
||||||
this._enablePlayerControlStream.next();
|
this._enablePlayerControlStream.next();
|
||||||
}
|
} else if (payload.type === 'displayBubble') {
|
||||||
else if (payload.type === 'displayBubble') {
|
|
||||||
this._displayBubbleStream.next();
|
this._displayBubbleStream.next();
|
||||||
}
|
} else if (payload.type === 'removeBubble') {
|
||||||
else if (payload.type === 'removeBubble') {
|
|
||||||
this._removeBubbleStream.next();
|
this._removeBubbleStream.next();
|
||||||
} else if (payload.type == "getState") {
|
} else if (payload.type == "getState") {
|
||||||
this._gameStateStream.next();
|
this._gameStateStream.next();
|
||||||
|
} else if (payload.type == "enableMoveEvents") {
|
||||||
|
this.sendMoveEvents = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,6 +235,15 @@ class IframeListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasMovedEvent(event: HasMovedEvent) {
|
||||||
|
if (this.sendMoveEvents) {
|
||||||
|
this.postMessage({
|
||||||
|
'type': 'hasMovedEvent',
|
||||||
|
'data': event
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sendButtonClickedEvent(popupId: number, buttonId: number): void {
|
sendButtonClickedEvent(popupId: number, buttonId: number): void {
|
||||||
this.postMessage({
|
this.postMessage({
|
||||||
'type': 'buttonClickedEvent',
|
'type': 'buttonClickedEvent',
|
||||||
|
@ -8,12 +8,7 @@ import {SelectCharacterSceneName} from "../Login/SelectCharacterScene";
|
|||||||
import {EnableCameraSceneName} from "../Login/EnableCameraScene";
|
import {EnableCameraSceneName} from "../Login/EnableCameraScene";
|
||||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||||
|
|
||||||
export interface HasMovedEvent {
|
|
||||||
direction: string;
|
|
||||||
moving: boolean;
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class should be responsible for any scene starting/stopping
|
* This class should be responsible for any scene starting/stopping
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {gameManager, HasMovedEvent} from "./GameManager";
|
import { gameManager } from "./GameManager";
|
||||||
import {
|
import {
|
||||||
GroupCreatedUpdatedMessageInterface,
|
GroupCreatedUpdatedMessageInterface,
|
||||||
MessageUserJoined,
|
MessageUserJoined,
|
||||||
@ -92,6 +92,7 @@ import {PinchManager} from "../UserInput/PinchManager";
|
|||||||
import {joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey} from "../Components/MobileJoystick";
|
import {joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey} from "../Components/MobileJoystick";
|
||||||
import { PlayerStateObject } from '../../Api/Events/ApiGameStateEvent';
|
import { PlayerStateObject } from '../../Api/Events/ApiGameStateEvent';
|
||||||
import { waScaleManager } from "../Services/WaScaleManager";
|
import { waScaleManager } from "../Services/WaScaleManager";
|
||||||
|
import { HasMovedEvent } from '../../Api/Events/HasMovedEvent';
|
||||||
|
|
||||||
export interface GameSceneInitInterface {
|
export interface GameSceneInitInterface {
|
||||||
initPosition: PointInterface|null,
|
initPosition: PointInterface|null,
|
||||||
@ -631,6 +632,9 @@ export class GameScene extends DirtyScene implements CenterListener {
|
|||||||
|
|
||||||
//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))
|
||||||
|
this.CurrentPlayer.on(hasMovedEventName, (event: HasMovedEvent) => {
|
||||||
|
iframeListener.hasMovedEvent(event)
|
||||||
|
})
|
||||||
this.CurrentPlayer.on(hasMovedEventName, this.outlineItem.bind(this))
|
this.CurrentPlayer.on(hasMovedEventName, this.outlineItem.bind(this))
|
||||||
this.CurrentPlayer.on(hasMovedEventName, (event: HasMovedEvent) => {
|
this.CurrentPlayer.on(hasMovedEventName, (event: HasMovedEvent) => {
|
||||||
this.gameMap.setPosition(event.x, event.y);
|
this.gameMap.setPosition(event.x, event.y);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {HasMovedEvent} from "./GameManager";
|
|
||||||
import { MAX_EXTRAPOLATION_TIME } from "../../Enum/EnvironmentVariable";
|
import { MAX_EXTRAPOLATION_TIME } from "../../Enum/EnvironmentVariable";
|
||||||
import { PositionInterface } from "../../Connexion/ConnexionModels";
|
import { PositionInterface } from "../../Connexion/ConnexionModels";
|
||||||
|
import { HasMovedEvent } from '../../Api/Events/HasMovedEvent';
|
||||||
|
|
||||||
export class PlayerMovement {
|
export class PlayerMovement {
|
||||||
public constructor(private startPosition: PositionInterface, private startTick: number, private endPosition: HasMovedEvent, private endTick: number) {
|
public constructor(private startPosition: PositionInterface, private startTick: number, private endPosition: HasMovedEvent, private endTick: number) {
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
* This class is in charge of computing the position of all players.
|
* This class is in charge of computing the position of all players.
|
||||||
* Player movement is delayed by 200ms so position depends on ticks.
|
* Player movement is delayed by 200ms so position depends on ticks.
|
||||||
*/
|
*/
|
||||||
|
import { HasMovedEvent } from '../../Api/Events/HasMovedEvent';
|
||||||
import { PlayerMovement } from "./PlayerMovement";
|
import { PlayerMovement } from "./PlayerMovement";
|
||||||
import {HasMovedEvent} from "./GameManager";
|
|
||||||
|
|
||||||
export class PlayersPositionInterpolator {
|
export class PlayersPositionInterpolator {
|
||||||
playerMovements: Map<number, PlayerMovement> = new Map<number, PlayerMovement>();
|
playerMovements: Map<number, PlayerMovement> = new Map<number, PlayerMovement>();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ChatEvent } from "./Api/Events/ChatEvent";
|
import { ChatEvent } from "./Api/Events/ChatEvent";
|
||||||
import { isIframeResponseEventWrapper } from "./Api/Events/IframeEvent";
|
import { IframeEvent, IframeEventMap, isIframeResponseEventWrapper } from "./Api/Events/IframeEvent";
|
||||||
import { isUserInputChatEvent, UserInputChatEvent } from "./Api/Events/UserInputChatEvent";
|
import { isUserInputChatEvent, UserInputChatEvent } from "./Api/Events/UserInputChatEvent";
|
||||||
import { Subject } from "rxjs";
|
import { Subject } from "rxjs";
|
||||||
import { EnterLeaveEvent, isEnterLeaveEvent } from "./Api/Events/EnterLeaveEvent";
|
import { EnterLeaveEvent, isEnterLeaveEvent } from "./Api/Events/EnterLeaveEvent";
|
||||||
@ -10,6 +10,7 @@ import { OpenTabEvent } from "./Api/Events/OpenTabEvent";
|
|||||||
import { GoToPageEvent } from "./Api/Events/GoToPageEvent";
|
import { GoToPageEvent } from "./Api/Events/GoToPageEvent";
|
||||||
import { OpenCoWebSiteEvent } from "./Api/Events/OpenCoWebSiteEvent";
|
import { OpenCoWebSiteEvent } from "./Api/Events/OpenCoWebSiteEvent";
|
||||||
import { GameStateEvent, isGameStateEvent } from './Api/Events/ApiGameStateEvent';
|
import { GameStateEvent, isGameStateEvent } from './Api/Events/ApiGameStateEvent';
|
||||||
|
import { HasMovedEvent, HasMovedEventCallback, isHasMovedEvent } from './Api/Events/HasMovedEvent';
|
||||||
|
|
||||||
interface WorkAdventureApi {
|
interface WorkAdventureApi {
|
||||||
sendChatMessage(message: string, author: string): void;
|
sendChatMessage(message: string, author: string): void;
|
||||||
@ -25,7 +26,9 @@ interface WorkAdventureApi {
|
|||||||
restorePlayerControl(): void;
|
restorePlayerControl(): void;
|
||||||
displayBubble(): void;
|
displayBubble(): void;
|
||||||
removeBubble(): void;
|
removeBubble(): void;
|
||||||
getGameState():Promise<unknown>
|
getGameState(): Promise<GameStateEvent>
|
||||||
|
|
||||||
|
onMoveEvent(callback: (moveEvent: HasMovedEvent) => void): void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@ -75,13 +78,37 @@ class Popup {
|
|||||||
}, '*');
|
}, '*');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function uuidv4() {
|
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
||||||
|
const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const stateResolvers: Array<(event: GameStateEvent) => void> = []
|
const stateResolvers: Array<(event: GameStateEvent) => void> = []
|
||||||
|
|
||||||
|
const callbacks: { [type: string]: HasMovedEventCallback | ((arg?: HasMovedEvent | never) => void) } = {}
|
||||||
|
|
||||||
|
|
||||||
|
function postToParent(content: IframeEvent<keyof IframeEventMap>) {
|
||||||
|
window.parent.postMessage(content, "*")
|
||||||
|
}
|
||||||
|
let moveEventUuid: string | undefined;
|
||||||
|
|
||||||
window.WA = {
|
window.WA = {
|
||||||
|
|
||||||
|
onMoveEvent(callback: HasMovedEventCallback): void {
|
||||||
|
moveEventUuid = uuidv4();
|
||||||
|
callbacks[moveEventUuid] = callback;
|
||||||
|
postToParent({
|
||||||
|
type: "enableMoveEvents",
|
||||||
|
data: undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
window.parent.postMessage({
|
||||||
|
type: "enable"
|
||||||
|
}, "*")
|
||||||
|
},
|
||||||
|
|
||||||
getGameState() {
|
getGameState() {
|
||||||
return new Promise<GameStateEvent>((resolver, thrower) => {
|
return new Promise<GameStateEvent>((resolver, thrower) => {
|
||||||
@ -246,6 +273,8 @@ window.addEventListener('message', message => {
|
|||||||
stateResolvers.forEach(resolver => {
|
stateResolvers.forEach(resolver => {
|
||||||
resolver(payloadData);
|
resolver(payloadData);
|
||||||
})
|
})
|
||||||
|
} else if (payload.type == "hasMovedEvent" && isHasMovedEvent(payloadData) && moveEventUuid) {
|
||||||
|
callbacks[moveEventUuid](payloadData)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user