some more tweaks with smooth zooming control

This commit is contained in:
Hanusiak Piotr 2021-12-02 14:44:13 +01:00
parent 092daa245f
commit ddaa81a7ac
3 changed files with 54 additions and 18 deletions

View file

@ -1,16 +1,26 @@
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 type { WaScaleManager } from '../Services/WaScaleManager'; import type { WaScaleManager } from '../Services/WaScaleManager';
import type { GameScene } from './GameScene'; import type { GameScene } from './GameScene';
export enum CameraMode {
Free = 'Free',
Follow = 'Follow',
Focus = 'Focus',
}
export class CameraManager extends Phaser.Events.EventEmitter { export class CameraManager extends Phaser.Events.EventEmitter {
private scene: GameScene; private scene: GameScene;
private camera: Phaser.Cameras.Scene2D.Camera; private camera: Phaser.Cameras.Scene2D.Camera;
private cameraBounds: { x: number, y: number };
private waScaleManager: WaScaleManager; private waScaleManager: WaScaleManager;
private cameraBounds: { x: number, y: number }; private cameraMode: CameraMode = CameraMode.Free;
private restoreZoomTween?: Phaser.Tweens.Tween;
constructor(scene: GameScene, cameraBounds: { x: number, y: number }, waScaleManager: WaScaleManager) { constructor(scene: GameScene, cameraBounds: { x: number, y: number }, waScaleManager: WaScaleManager) {
super(); super();
@ -28,11 +38,13 @@ export class CameraManager extends Phaser.Events.EventEmitter {
return this.camera; return this.camera;
} }
public changeCameraFocus( public enterFocusMode(
focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000, focusOn: { x: number, y: number, width: number, height: number }, duration: number = 1000,
): void { ): void {
this.setCameraMode(CameraMode.Focus);
this.waScaleManager.saveZoom(); this.waScaleManager.saveZoom();
this.waScaleManager.lockZoomingViaPlayerInput();
this.restoreZoomTween?.stop();
const maxZoomModifier = 2.84; // How to get max zoom value? const maxZoomModifier = 2.84; // How to get max zoom value?
const currentZoomModifier = this.waScaleManager.zoomModifier; const currentZoomModifier = this.waScaleManager.zoomModifier;
const zoomModifierChange = maxZoomModifier - currentZoomModifier; const zoomModifierChange = maxZoomModifier - currentZoomModifier;
@ -46,9 +58,15 @@ export class CameraManager extends Phaser.Events.EventEmitter {
}); });
} }
public leaveFocusMode(player: Player): void {
// We are forcing camera.pan to kill previous pan animation on EnterFocusMode
this.camera.pan(player.x, player.y, 1, Easing.SineEaseOut, true);
this.startFollow(player);
this.restoreZoom();
}
public startFollow(target: object | Phaser.GameObjects.GameObject): void { public startFollow(target: object | Phaser.GameObjects.GameObject): void {
this.waScaleManager.lockZoomingViaPlayerInput(false); this.setCameraMode(CameraMode.Follow);
this.waScaleManager.restoreZoom();
this.camera.startFollow(target, true); this.camera.startFollow(target, true);
} }
@ -69,6 +87,30 @@ export class CameraManager extends Phaser.Events.EventEmitter {
); );
} }
public isCameraLocked(): boolean {
return this.cameraMode === CameraMode.Focus;
}
private setCameraMode(mode: CameraMode): void {
if (this.cameraMode === mode) {
return;
}
this.cameraMode = mode;
}
private restoreZoom(): void {
this.restoreZoomTween?.stop();
this.restoreZoomTween = this.scene.tweens.addCounter({
from: this.waScaleManager.zoomModifier,
to: this.waScaleManager.getSaveZoom(),
duration: 1000,
ease: Easing.SineEaseOut,
onUpdate: (tween: Phaser.Tweens.Tween) => {
this.waScaleManager.zoomModifier = tween.getValue();
}
});
}
private initCamera() { private initCamera() {
this.camera = this.scene.cameras.main; this.camera = this.scene.cameras.main;
this.camera.setBounds(0, 0, this.cameraBounds.x, this.cameraBounds.y); this.camera.setBounds(0, 0, this.cameraBounds.x, this.cameraBounds.y);

View file

@ -788,7 +788,7 @@ export class GameScene extends DirtyScene {
for (const zone of zones) { for (const zone of zones) {
for (const property of zone.properties ?? []) { for (const property of zone.properties ?? []) {
if (property.name === 'focusable' && property.value === true) { if (property.name === 'focusable' && property.value === true) {
this.cameraManager.changeCameraFocus(zone); this.cameraManager.enterFocusMode(zone);
break; break;
} }
} }
@ -802,7 +802,7 @@ export class GameScene extends DirtyScene {
for (const zone of zones) { for (const zone of zones) {
for (const property of zone.properties ?? []) { for (const property of zone.properties ?? []) {
if (property.name === 'focusable' && property.value === true) { if (property.name === 'focusable' && property.value === true) {
this.cameraManager.startFollow(this.CurrentPlayer); this.cameraManager.leaveFocusMode(this.CurrentPlayer);
break; break;
} }
} }
@ -1954,7 +1954,7 @@ ${escapedMessage}
} }
zoomByFactor(zoomFactor: number) { zoomByFactor(zoomFactor: number) {
if (waScaleManager.isZoomingViaPlayerInputLocked()) { if (this.cameraManager.isCameraLocked()) {
return; return;
} }
waScaleManager.zoomModifier *= zoomFactor; waScaleManager.zoomModifier *= zoomFactor;

View file

@ -12,8 +12,6 @@ export class WaScaleManager {
private actualZoom: number = 1; private actualZoom: number = 1;
private _saveZoom: number = 1; private _saveZoom: number = 1;
private zoomingViaPlayerInputLocked: boolean = false;
public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) { public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) {
this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber); this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber);
} }
@ -23,14 +21,6 @@ export class WaScaleManager {
this.game = game; this.game = game;
} }
public isZoomingViaPlayerInputLocked(): boolean {
return this.zoomingViaPlayerInputLocked;
}
public lockZoomingViaPlayerInput(lock: boolean = true): void {
this.zoomingViaPlayerInputLocked = lock;
}
public applyNewSize() { public applyNewSize() {
const { width, height } = coWebsiteManager.getGameSize(); const { width, height } = coWebsiteManager.getGameSize();
@ -82,6 +72,10 @@ export class WaScaleManager {
this._saveZoom = this.hdpiManager.zoomModifier; this._saveZoom = this.hdpiManager.zoomModifier;
} }
public getSaveZoom(): number {
return this._saveZoom;
}
public restoreZoom(): void { public restoreZoom(): void {
this.hdpiManager.zoomModifier = this._saveZoom; this.hdpiManager.zoomModifier = this._saveZoom;
this.applyNewSize(); this.applyNewSize();