Adds the camera to available APIs with retrieving of the worldView
This commit is contained in:
parent
99dfd77600
commit
5b6a8ca4d7
@ -69,7 +69,7 @@ You need to wait for the end of the initialization before calling `WA.player.get
|
||||
|
||||
```typescript
|
||||
WA.onInit().then(() => {
|
||||
console.log('Tags: ', WA.player.getPosition());
|
||||
console.log('Position: ', WA.player.getPosition());
|
||||
})
|
||||
```
|
||||
|
||||
|
18
front/src/Api/Events/HasCameraMovedEvent.ts
Normal file
18
front/src/Api/Events/HasCameraMovedEvent.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import * as tg from "generic-type-guard";
|
||||
|
||||
export const isHasCameraMovedEvent = new tg.IsInterface()
|
||||
.withProperties({
|
||||
x: tg.isNumber,
|
||||
y: tg.isNumber,
|
||||
width: tg.isNumber,
|
||||
height: tg.isNumber,
|
||||
})
|
||||
.get();
|
||||
|
||||
/**
|
||||
* A message sent from the game to the iFrame to notify a movement from the camera.
|
||||
*/
|
||||
|
||||
export type HasCameraMovedEvent = tg.GuardedType<typeof isHasCameraMovedEvent>;
|
||||
|
||||
export type HasCameraMovedEventCallback = (event: HasCameraMovedEvent) => void;
|
@ -30,6 +30,7 @@ import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEv
|
||||
import type { ChangeLayerEvent } from "./ChangeLayerEvent";
|
||||
import { isPlayerPropertyEvent } from "./PlayerPropertyEvent";
|
||||
import { isPlayerPosition } from "./PlayerPosition";
|
||||
import type { HasCameraMovedEvent } from "./HasCameraMovedEvent";
|
||||
|
||||
export interface TypedMessageEvent<T> extends MessageEvent {
|
||||
data: T;
|
||||
@ -50,6 +51,7 @@ export type IframeEventMap = {
|
||||
displayBubble: null;
|
||||
removeBubble: null;
|
||||
onPlayerMove: undefined;
|
||||
onCameraMove: undefined;
|
||||
showLayer: LayerEvent;
|
||||
hideLayer: LayerEvent;
|
||||
setProperty: SetPropertyEvent;
|
||||
@ -80,6 +82,7 @@ export interface IframeResponseEventMap {
|
||||
leaveLayerEvent: ChangeLayerEvent;
|
||||
buttonClickedEvent: ButtonClickedEvent;
|
||||
hasPlayerMoved: HasPlayerMovedEvent;
|
||||
hasCameraMoved: HasCameraMovedEvent;
|
||||
menuItemClicked: MenuItemClickedEvent;
|
||||
setVariable: SetVariableEvent;
|
||||
messageTriggered: MessageReferenceEvent;
|
||||
|
@ -31,6 +31,7 @@ import type { SetVariableEvent } from "./Events/SetVariableEvent";
|
||||
import { ModifyEmbeddedWebsiteEvent, isEmbeddedWebsiteEvent } from "./Events/EmbeddedWebsiteEvent";
|
||||
import { handleMenuRegistrationEvent, handleMenuUnregisterEvent } from "../Stores/MenuStore";
|
||||
import type { ChangeLayerEvent } from "./Events/ChangeLayerEvent";
|
||||
import type { HasCameraMovedEvent } from "./Events/HasCameraMovedEvent";
|
||||
|
||||
type AnswererCallback<T extends keyof IframeQueryMap> = (
|
||||
query: IframeQueryMap[T]["query"],
|
||||
@ -94,6 +95,7 @@ class IframeListener {
|
||||
private readonly iframeCloseCallbacks = new Map<HTMLIFrameElement, (() => void)[]>();
|
||||
private readonly scripts = new Map<string, HTMLIFrameElement>();
|
||||
private sendPlayerMove: boolean = false;
|
||||
private sendCameraMove: boolean = false;
|
||||
|
||||
// Note: we are forced to type this in unknown and later cast with "as" because of https://github.com/microsoft/TypeScript/issues/31904
|
||||
private answerers: {
|
||||
@ -225,6 +227,8 @@ class IframeListener {
|
||||
this._removeBubbleStream.next();
|
||||
} else if (payload.type == "onPlayerMove") {
|
||||
this.sendPlayerMove = true;
|
||||
} else if (payload.type == "onCameraMove") {
|
||||
this.sendCameraMove = true;
|
||||
} else if (payload.type == "setTiles" && isSetTilesEvent(payload.data)) {
|
||||
this._setTilesStream.next(payload.data);
|
||||
} else if (payload.type == "modifyEmbeddedWebsite" && isEmbeddedWebsiteEvent(payload.data)) {
|
||||
@ -423,6 +427,15 @@ class IframeListener {
|
||||
}
|
||||
}
|
||||
|
||||
hasCameraMoved(event: HasCameraMovedEvent) {
|
||||
if (this.sendCameraMove) {
|
||||
this.postMessage({
|
||||
type: "hasCameraMoved",
|
||||
data: event,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
sendButtonClickedEvent(popupId: number, buttonId: number): void {
|
||||
this.postMessage({
|
||||
type: "buttonClickedEvent",
|
||||
|
@ -13,7 +13,7 @@ export class EmbeddedWebsite {
|
||||
private _allowApi: boolean;
|
||||
private _position: Rectangle;
|
||||
private readonly origin: "map" | "player" | undefined;
|
||||
private _scale: number | undefined;
|
||||
private _scale: number;
|
||||
|
||||
constructor(private config: CreateEmbeddedWebsiteEvent) {
|
||||
this.name = config.name;
|
||||
@ -23,7 +23,7 @@ export class EmbeddedWebsite {
|
||||
this._allowApi = config.allowApi ?? false;
|
||||
this._position = config.position;
|
||||
this.origin = config.origin;
|
||||
this._scale = config.scale;
|
||||
this._scale = config.scale ?? 1;
|
||||
}
|
||||
|
||||
public get url() {
|
||||
@ -116,7 +116,7 @@ export class EmbeddedWebsite {
|
||||
});
|
||||
}
|
||||
|
||||
public get scale() {
|
||||
public get scale(): number {
|
||||
return this._scale;
|
||||
}
|
||||
|
||||
|
29
front/src/Api/iframe/camera.ts
Normal file
29
front/src/Api/iframe/camera.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution";
|
||||
import { Subject } from "rxjs";
|
||||
import type { HasCameraMovedEvent, HasCameraMovedEventCallback } from "../Events/HasCameraMovedEvent";
|
||||
import { apiCallback } from "./registeredCallbacks";
|
||||
import { isHasCameraMovedEvent } from "../Events/HasCameraMovedEvent";
|
||||
|
||||
const moveStream = new Subject<HasCameraMovedEvent>();
|
||||
|
||||
export class WorkAdventureCameraCommands extends IframeApiContribution<WorkAdventureCameraCommands> {
|
||||
callbacks = [
|
||||
apiCallback({
|
||||
type: "hasCameraMoved",
|
||||
typeChecker: isHasCameraMovedEvent,
|
||||
callback: (payloadData) => {
|
||||
moveStream.next(payloadData);
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
onCameraMove(callback: HasCameraMovedEventCallback): void {
|
||||
moveStream.subscribe(callback);
|
||||
sendToWorkadventure({
|
||||
type: "onCameraMove",
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new WorkAdventureCameraCommands();
|
@ -30,6 +30,7 @@ export class EmbeddedWebsiteManager {
|
||||
height: rect["height"],
|
||||
},
|
||||
origin: website.origin,
|
||||
scale: website.scale,
|
||||
};
|
||||
});
|
||||
|
||||
@ -144,9 +145,9 @@ export class EmbeddedWebsiteManager {
|
||||
name,
|
||||
url,
|
||||
/*x,
|
||||
y,
|
||||
width,
|
||||
height,*/
|
||||
y,
|
||||
width,
|
||||
height,*/
|
||||
allow,
|
||||
allowApi,
|
||||
visible,
|
||||
|
@ -89,6 +89,8 @@ import { get } from "svelte/store";
|
||||
import { contactPageStore } from "../../Stores/MenuStore";
|
||||
import { GameMapProperties } from "./GameMapProperties";
|
||||
import SpriteSheetFile = Phaser.Loader.FileTypes.SpriteSheetFile;
|
||||
import Camera = Phaser.Cameras.Scene2D.Camera;
|
||||
import type { HasCameraMovedEvent } from "../../Api/Events/HasCameraMovedEvent";
|
||||
|
||||
export interface GameSceneInitInterface {
|
||||
initPosition: PointInterface | null;
|
||||
@ -750,6 +752,17 @@ export class GameScene extends DirtyScene {
|
||||
this.gameMap.setPosition(event.x, event.y);
|
||||
});
|
||||
|
||||
//listen event to share the actual worldView when the camera is updated
|
||||
this.cameras.main.on("followupdate", (camera: Camera) => {
|
||||
const worldView: HasCameraMovedEvent = {
|
||||
x: camera.worldView.x,
|
||||
y: camera.worldView.y,
|
||||
width: camera.worldView.width,
|
||||
height: camera.worldView.height,
|
||||
};
|
||||
iframeListener.hasCameraMoved(worldView);
|
||||
});
|
||||
|
||||
// Set up variables manager
|
||||
this.sharedVariablesManager = new SharedVariablesManager(
|
||||
this.connection,
|
||||
|
@ -20,6 +20,7 @@ import type { ButtonDescriptor } from "./Api/iframe/Ui/ButtonDescriptor";
|
||||
import type { Popup } from "./Api/iframe/Ui/Popup";
|
||||
import type { Sound } from "./Api/iframe/Sound/Sound";
|
||||
import { answerPromises, queryWorkadventure } from "./Api/iframe/IframeApiContribution";
|
||||
import camera from "./Api/iframe/camera";
|
||||
|
||||
const globalState = createState("global");
|
||||
|
||||
@ -45,6 +46,7 @@ const wa = {
|
||||
sound,
|
||||
room,
|
||||
player,
|
||||
camera,
|
||||
state: globalState,
|
||||
|
||||
onInit(): Promise<void> {
|
||||
|
Loading…
Reference in New Issue
Block a user