subtle changes in CameraManager in order to distinguish between setPosition and focusOn
This commit is contained in:
parent
5f26a39a5d
commit
4ebc55a429
@ -1,13 +1,22 @@
|
|||||||
import { Easing } from "../../types";
|
import { Easing } from "../../types";
|
||||||
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
|
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
|
||||||
import type { Box } from "../../WebRtc/LayoutManager";
|
import type { Box } from "../../WebRtc/LayoutManager";
|
||||||
import type { Player } from "../Player/Player";
|
import { hasMovedEventName, Player } from "../Player/Player";
|
||||||
import type { WaScaleManager } from "../Services/WaScaleManager";
|
import type { WaScaleManager } from "../Services/WaScaleManager";
|
||||||
import type { GameScene } from "./GameScene";
|
import type { GameScene } from "./GameScene";
|
||||||
|
|
||||||
export enum CameraMode {
|
export enum CameraMode {
|
||||||
Free = "Free",
|
/**
|
||||||
|
* Camera looks at certain point but is not locked and will start following the player on his movement
|
||||||
|
*/
|
||||||
|
Positioned = "Positioned",
|
||||||
|
/**
|
||||||
|
* Camera is actively following the player
|
||||||
|
*/
|
||||||
Follow = "Follow",
|
Follow = "Follow",
|
||||||
|
/**
|
||||||
|
* Camera is focusing on certain point and will not break this focus even on player movement
|
||||||
|
*/
|
||||||
Focus = "Focus",
|
Focus = "Focus",
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,12 +26,12 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||||||
private cameraBounds: { x: number; y: number };
|
private cameraBounds: { x: number; y: number };
|
||||||
private waScaleManager: WaScaleManager;
|
private waScaleManager: WaScaleManager;
|
||||||
|
|
||||||
private cameraMode: CameraMode = CameraMode.Free;
|
private cameraMode: CameraMode = CameraMode.Positioned;
|
||||||
|
|
||||||
private restoreZoomTween?: Phaser.Tweens.Tween;
|
private restoreZoomTween?: Phaser.Tweens.Tween;
|
||||||
private startFollowTween?: Phaser.Tweens.Tween;
|
private startFollowTween?: Phaser.Tweens.Tween;
|
||||||
|
|
||||||
private cameraFollowTarget?: { x: number; y: number };
|
private playerToFollow?: Player;
|
||||||
|
|
||||||
constructor(scene: GameScene, cameraBounds: { x: number; y: number }, waScaleManager: WaScaleManager) {
|
constructor(scene: GameScene, cameraBounds: { x: number; y: number }, waScaleManager: WaScaleManager) {
|
||||||
super();
|
super();
|
||||||
@ -47,6 +56,51 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||||||
return this.camera;
|
return this.camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set camera view to specific destination without changing current camera mode. Won't work if camera mode is set to Focus.
|
||||||
|
* @param setTo Viewport on which the camera should set the position
|
||||||
|
* @param duration Time for the transition im MS. If set to 0, transition will occur immediately
|
||||||
|
*/
|
||||||
|
public setPosition(setTo: { x: number; y: number; width: number; height: number }, duration: number = 1000): void {
|
||||||
|
if (this.cameraMode === CameraMode.Focus) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.setCameraMode(CameraMode.Positioned);
|
||||||
|
const currentZoomModifier = this.waScaleManager.zoomModifier;
|
||||||
|
const zoomModifierChange = this.getZoomModifierChange(setTo.width, setTo.height);
|
||||||
|
this.camera.stopFollow();
|
||||||
|
this.camera.pan(
|
||||||
|
setTo.x + setTo.width * 0.5,
|
||||||
|
setTo.y + setTo.height * 0.5,
|
||||||
|
duration,
|
||||||
|
Easing.SineEaseOut,
|
||||||
|
true,
|
||||||
|
(camera, progress, x, y) => {
|
||||||
|
if (this.cameraMode === CameraMode.Positioned) {
|
||||||
|
this.waScaleManager.zoomModifier = currentZoomModifier + progress * zoomModifierChange;
|
||||||
|
}
|
||||||
|
if (progress === 1) {
|
||||||
|
this.playerToFollow?.once(hasMovedEventName, () => {
|
||||||
|
if (this.playerToFollow) {
|
||||||
|
this.startFollowPlayer(this.playerToFollow, duration);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getZoomModifierChange(width: number, height: number): number {
|
||||||
|
const targetZoomModifier = this.waScaleManager.getTargetZoomModifierFor(width, height);
|
||||||
|
const currentZoomModifier = this.waScaleManager.zoomModifier;
|
||||||
|
return targetZoomModifier - currentZoomModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set camera to focus mode. As long as the camera is in the Focus mode, its view cannot be changed.
|
||||||
|
* @param setTo Viewport on which the camera should focus on
|
||||||
|
* @param duration Time for the transition im MS. If set to 0, transition will occur immediately
|
||||||
|
*/
|
||||||
public enterFocusMode(
|
public enterFocusMode(
|
||||||
focusOn: { x: number; y: number; width: number; height: number },
|
focusOn: { x: number; y: number; width: number; height: number },
|
||||||
margin: number = 0,
|
margin: number = 0,
|
||||||
@ -59,14 +113,10 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||||||
this.restoreZoomTween?.stop();
|
this.restoreZoomTween?.stop();
|
||||||
this.startFollowTween?.stop();
|
this.startFollowTween?.stop();
|
||||||
const marginMult = 1 + margin;
|
const marginMult = 1 + margin;
|
||||||
const targetZoomModifier = this.waScaleManager.getTargetZoomModifierFor(
|
|
||||||
focusOn.width * marginMult,
|
|
||||||
focusOn.height * marginMult
|
|
||||||
);
|
|
||||||
const currentZoomModifier = this.waScaleManager.zoomModifier;
|
const currentZoomModifier = this.waScaleManager.zoomModifier;
|
||||||
const zoomModifierChange = targetZoomModifier - currentZoomModifier;
|
const zoomModifierChange = this.getZoomModifierChange(focusOn.width * marginMult, focusOn.height * marginMult);
|
||||||
this.camera.stopFollow();
|
this.camera.stopFollow();
|
||||||
this.cameraFollowTarget = undefined;
|
this.playerToFollow = undefined;
|
||||||
this.camera.pan(
|
this.camera.pan(
|
||||||
focusOn.x + focusOn.width * 0.5 * marginMult,
|
focusOn.x + focusOn.width * 0.5 * marginMult,
|
||||||
focusOn.y + focusOn.height * 0.5 * marginMult,
|
focusOn.y + focusOn.height * 0.5 * marginMult,
|
||||||
@ -81,15 +131,15 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||||||
|
|
||||||
public leaveFocusMode(player: Player, duration: number = 1000): void {
|
public leaveFocusMode(player: Player, duration: number = 1000): void {
|
||||||
this.waScaleManager.setFocusTarget();
|
this.waScaleManager.setFocusTarget();
|
||||||
this.startFollow(player, duration);
|
this.startFollowPlayer(player, duration);
|
||||||
this.restoreZoom(duration);
|
this.restoreZoom(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public startFollow(target: object | Phaser.GameObjects.GameObject, duration: number = 0): void {
|
public startFollowPlayer(player: Player, duration: number = 0): void {
|
||||||
this.cameraFollowTarget = target as { x: number; y: number };
|
this.playerToFollow = player;
|
||||||
this.setCameraMode(CameraMode.Follow);
|
this.setCameraMode(CameraMode.Follow);
|
||||||
if (duration === 0) {
|
if (duration === 0) {
|
||||||
this.camera.startFollow(target, true);
|
this.camera.startFollow(player, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const oldPos = { x: this.camera.scrollX, y: this.camera.scrollY };
|
const oldPos = { x: this.camera.scrollX, y: this.camera.scrollY };
|
||||||
@ -99,17 +149,17 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||||||
duration,
|
duration,
|
||||||
ease: Easing.SineEaseOut,
|
ease: Easing.SineEaseOut,
|
||||||
onUpdate: (tween: Phaser.Tweens.Tween) => {
|
onUpdate: (tween: Phaser.Tweens.Tween) => {
|
||||||
if (!this.cameraFollowTarget) {
|
if (!this.playerToFollow) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const shiftX =
|
const shiftX =
|
||||||
(this.cameraFollowTarget.x - this.camera.worldView.width * 0.5 - oldPos.x) * tween.getValue();
|
(this.playerToFollow.x - this.camera.worldView.width * 0.5 - oldPos.x) * tween.getValue();
|
||||||
const shiftY =
|
const shiftY =
|
||||||
(this.cameraFollowTarget.y - this.camera.worldView.height * 0.5 - oldPos.y) * tween.getValue();
|
(this.playerToFollow.y - this.camera.worldView.height * 0.5 - oldPos.y) * tween.getValue();
|
||||||
this.camera.setScroll(oldPos.x + shiftX, oldPos.y + shiftY);
|
this.camera.setScroll(oldPos.x + shiftX, oldPos.y + shiftY);
|
||||||
},
|
},
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
this.camera.startFollow(target, true);
|
this.camera.startFollow(player, true);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -131,8 +181,8 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public isCameraLocked(): boolean {
|
public isCameraZoomLocked(): boolean {
|
||||||
return this.cameraMode === CameraMode.Focus;
|
return [CameraMode.Focus, CameraMode.Positioned].includes(this.cameraMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setCameraMode(mode: CameraMode): void {
|
private setCameraMode(mode: CameraMode): void {
|
||||||
|
@ -561,7 +561,7 @@ export class GameScene extends DirtyScene {
|
|||||||
waScaleManager
|
waScaleManager
|
||||||
);
|
);
|
||||||
biggestAvailableAreaStore.recompute();
|
biggestAvailableAreaStore.recompute();
|
||||||
this.cameraManager.startFollow(this.CurrentPlayer);
|
this.cameraManager.startFollowPlayer(this.CurrentPlayer);
|
||||||
|
|
||||||
this.animatedTiles.init(this.Map);
|
this.animatedTiles.init(this.Map);
|
||||||
this.events.on("tileanimationupdate", () => (this.dirty = true));
|
this.events.on("tileanimationupdate", () => (this.dirty = true));
|
||||||
@ -1072,8 +1072,7 @@ ${escapedMessage}
|
|||||||
|
|
||||||
this.iframeSubscriptionList.push(
|
this.iframeSubscriptionList.push(
|
||||||
iframeListener.cameraSetPositionStream.subscribe((cameraSetPositionEvent) => {
|
iframeListener.cameraSetPositionStream.subscribe((cameraSetPositionEvent) => {
|
||||||
// this.cameraManager.enterFocusMode({ ...cameraSetPositionEvent }, undefined, cameraSetPositionEvent.smooth ? 1000 : 0);
|
this.cameraManager.setPosition({ ...cameraSetPositionEvent }, cameraSetPositionEvent.smooth ? 1000 : 0);
|
||||||
console.log("camera set position");
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -2045,7 +2044,7 @@ ${escapedMessage}
|
|||||||
}
|
}
|
||||||
|
|
||||||
zoomByFactor(zoomFactor: number) {
|
zoomByFactor(zoomFactor: number) {
|
||||||
if (this.cameraManager.isCameraLocked()) {
|
if (this.cameraManager.isCameraZoomLocked()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
waScaleManager.zoomModifier *= zoomFactor;
|
waScaleManager.zoomModifier *= zoomFactor;
|
||||||
|
Loading…
Reference in New Issue
Block a user