Merge pull request #1654 from thecodingmachine/feature-camera-management

Feature camera management
This commit is contained in:
David Négrier 2022-01-14 11:57:05 +01:00 committed by GitHub
commit 82c2d21423
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 639 additions and 131 deletions

View file

@ -0,0 +1,11 @@
import * as tg from "generic-type-guard";
export const isCameraFollowPlayerEvent = new tg.IsInterface()
.withProperties({
smooth: tg.isBoolean,
})
.get();
/**
* A message sent from the iFrame to the game to make the camera follow player.
*/
export type CameraFollowPlayerEvent = tg.GuardedType<typeof isCameraFollowPlayerEvent>;

View file

@ -0,0 +1,16 @@
import * as tg from "generic-type-guard";
export const isCameraSetEvent = new tg.IsInterface()
.withProperties({
x: tg.isNumber,
y: tg.isNumber,
width: tg.isOptional(tg.isNumber),
height: tg.isOptional(tg.isNumber),
lock: tg.isBoolean,
smooth: tg.isBoolean,
})
.get();
/**
* A message sent from the iFrame to the game to change the camera position.
*/
export type CameraSetEvent = tg.GuardedType<typeof isCameraSetEvent>;

View file

@ -9,8 +9,8 @@ export const isGameStateEvent = new tg.IsInterface()
startLayerName: tg.isUnion(tg.isString, tg.isNull),
tags: tg.isArray(tg.isString),
variables: tg.isObject,
userRoomToken: tg.isUnion(tg.isString, tg.isUndefined),
playerVariables: tg.isObject,
userRoomToken: tg.isUnion(tg.isString, tg.isUndefined),
})
.get();
/**

View file

@ -28,10 +28,12 @@ import type { MessageReferenceEvent } from "./ui/TriggerActionMessageEvent";
import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent";
import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent";
import type { ChangeLayerEvent } from "./ChangeLayerEvent";
import type { ChangeZoneEvent } from "./ChangeZoneEvent";
import { isColorEvent } from "./ColorEvent";
import { isPlayerPosition } from "./PlayerPosition";
import type { WasCameraUpdatedEvent } from "./WasCameraUpdatedEvent";
import type { ChangeZoneEvent } from "./ChangeZoneEvent";
import type { CameraSetEvent } from "./CameraSetEvent";
import type { CameraFollowPlayerEvent } from "./CameraFollowPlayerEvent";
import { isColorEvent } from "./ColorEvent";
export interface TypedMessageEvent<T> extends MessageEvent {
data: T;
@ -43,6 +45,8 @@ export interface TypedMessageEvent<T> extends MessageEvent {
export type IframeEventMap = {
loadPage: LoadPageEvent;
chat: ChatEvent;
cameraFollowPlayer: CameraFollowPlayerEvent;
cameraSet: CameraSetEvent;
openPopup: OpenPopupEvent;
closePopup: ClosePopupEvent;
openTab: OpenTabEvent;

View file

@ -33,6 +33,8 @@ import { handleMenuRegistrationEvent, handleMenuUnregisterEvent } from "../Store
import type { ChangeLayerEvent } from "./Events/ChangeLayerEvent";
import type { WasCameraUpdatedEvent } from "./Events/WasCameraUpdatedEvent";
import type { ChangeZoneEvent } from "./Events/ChangeZoneEvent";
import { CameraSetEvent, isCameraSetEvent } from "./Events/CameraSetEvent";
import { CameraFollowPlayerEvent, isCameraFollowPlayerEvent } from "./Events/CameraFollowPlayerEvent";
type AnswererCallback<T extends keyof IframeQueryMap> = (
query: IframeQueryMap[T]["query"],
@ -56,6 +58,12 @@ class IframeListener {
private readonly _disablePlayerControlStream: Subject<void> = new Subject();
public readonly disablePlayerControlStream = this._disablePlayerControlStream.asObservable();
private readonly _cameraSetStream: Subject<CameraSetEvent> = new Subject();
public readonly cameraSetStream = this._cameraSetStream.asObservable();
private readonly _cameraFollowPlayerStream: Subject<CameraFollowPlayerEvent> = new Subject();
public readonly cameraFollowPlayerStream = this._cameraFollowPlayerStream.asObservable();
private readonly _enablePlayerControlStream: Subject<void> = new Subject();
public readonly enablePlayerControlStream = this._enablePlayerControlStream.asObservable();
@ -202,6 +210,10 @@ class IframeListener {
this._hideLayerStream.next(payload.data);
} else if (payload.type === "setProperty" && isSetPropertyEvent(payload.data)) {
this._setPropertyStream.next(payload.data);
} else if (payload.type === "cameraSet" && isCameraSetEvent(payload.data)) {
this._cameraSetStream.next(payload.data);
} else if (payload.type === "cameraFollowPlayer" && isCameraFollowPlayerEvent(payload.data)) {
this._cameraFollowPlayerStream.next(payload.data);
} else if (payload.type === "chat" && isChatEvent(payload.data)) {
scriptUtils.sendAnonymousChat(payload.data);
} else if (payload.type === "openPopup" && isOpenPopupEvent(payload.data)) {

View file

@ -17,6 +17,27 @@ export class WorkAdventureCameraCommands extends IframeApiContribution<WorkAdven
}),
];
public set(
x: number,
y: number,
width?: number,
height?: number,
lock: boolean = false,
smooth: boolean = false
): void {
sendToWorkadventure({
type: "cameraSet",
data: { x, y, width, height, lock, smooth },
});
}
public followPlayer(smooth: boolean = false): void {
sendToWorkadventure({
type: "cameraFollowPlayer",
data: { smooth },
});
}
onCameraUpdate(): Subject<WasCameraUpdatedEvent> {
sendToWorkadventure({
type: "onCameraUpdate",

View file

@ -1,4 +1,3 @@
import type { ChatEvent } from "../Events/ChatEvent";
import { isUserInputChatEvent, UserInputChatEvent } from "../Events/UserInputChatEvent";
import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution";
import { apiCallback } from "./registeredCallbacks";