Add zoom and drag to move camera
This commit is contained in:
@@ -33,6 +33,7 @@ export class GameScene extends Phaser.Scene {
|
||||
|
||||
private playerPath: Vec2[] = [];
|
||||
private awaitingPlayer = false;
|
||||
private followPlayer = true;
|
||||
|
||||
// Sub-systems
|
||||
private dungeonRenderer!: DungeonRenderer;
|
||||
@@ -144,8 +145,66 @@ export class GameScene extends Phaser.Scene {
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Zoom Control
|
||||
this.input.on(
|
||||
"wheel",
|
||||
(
|
||||
_pointer: Phaser.Input.Pointer,
|
||||
_gameObjects: any,
|
||||
_deltaX: number,
|
||||
deltaY: number,
|
||||
_deltaZ: number
|
||||
) => {
|
||||
if (this.isMenuOpen || this.isInventoryOpen || this.dungeonRenderer.isMinimapVisible()) return;
|
||||
|
||||
const zoomDir = deltaY > 0 ? -1 : 1;
|
||||
const newZoom = Phaser.Math.Clamp(
|
||||
this.cameras.main.zoom + zoomDir * GAME_CONFIG.rendering.zoomStep,
|
||||
GAME_CONFIG.rendering.minZoom,
|
||||
GAME_CONFIG.rendering.maxZoom
|
||||
);
|
||||
this.cameras.main.setZoom(newZoom);
|
||||
}
|
||||
);
|
||||
|
||||
// Disable context menu for right-click panning
|
||||
this.input.mouse?.disableContextMenu();
|
||||
|
||||
// Camera Panning
|
||||
this.input.on("pointermove", (p: Phaser.Input.Pointer) => {
|
||||
if (!p.isDown) return;
|
||||
if (this.isMenuOpen || this.isInventoryOpen || this.dungeonRenderer.isMinimapVisible()) return;
|
||||
|
||||
// Pan with Middle Click or Right Click
|
||||
// Note: p.button is not always reliable in move events for holding,
|
||||
// so we use specific button down checks or the shift key modifier.
|
||||
const isRightDrag = p.rightButtonDown();
|
||||
const isMiddleDrag = p.middleButtonDown();
|
||||
const isShiftDrag = p.isDown && p.event.shiftKey;
|
||||
|
||||
if (isRightDrag || isMiddleDrag || isShiftDrag) {
|
||||
const { x, y } = p.position;
|
||||
const { x: prevX, y: prevY } = p.prevPosition;
|
||||
|
||||
const dx = (x - prevX) / this.cameras.main.zoom;
|
||||
const dy = (y - prevY) / this.cameras.main.zoom;
|
||||
|
||||
this.cameras.main.scrollX -= dx;
|
||||
this.cameras.main.scrollY -= dy;
|
||||
|
||||
this.followPlayer = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Mouse click -> compute path (only during player turn, and not while menu/minimap is open)
|
||||
this.input.on("pointerdown", (p: Phaser.Input.Pointer) => {
|
||||
// Only allow Left Click (0) for movement
|
||||
if (p.button !== 0) return;
|
||||
|
||||
this.followPlayer = true;
|
||||
|
||||
|
||||
if (!this.awaitingPlayer) return;
|
||||
if (this.isMenuOpen || this.isInventoryOpen || this.dungeonRenderer.isMinimapVisible()) return;
|
||||
|
||||
@@ -258,6 +317,7 @@ export class GameScene extends Phaser.Scene {
|
||||
|
||||
private commitPlayerAction(action: Action) {
|
||||
this.awaitingPlayer = false;
|
||||
this.followPlayer = true;
|
||||
|
||||
const playerEvents = applyAction(this.world, this.playerId, action, this.entityManager);
|
||||
const enemyStep = stepUntilPlayerTurn(this.world, this.playerId, this.entityManager);
|
||||
@@ -328,13 +388,16 @@ export class GameScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
this.dungeonRenderer.computeFov(this.playerId);
|
||||
this.centerCameraOnPlayer();
|
||||
if (this.followPlayer) {
|
||||
this.centerCameraOnPlayer();
|
||||
}
|
||||
this.dungeonRenderer.render(this.playerPath);
|
||||
this.emitUIUpdate();
|
||||
}
|
||||
|
||||
private loadFloor(floor: number) {
|
||||
this.floorIndex = floor;
|
||||
this.followPlayer = true;
|
||||
|
||||
const { world, playerId } = generateWorld(floor, this.runState);
|
||||
this.world = world;
|
||||
|
||||
Reference in New Issue
Block a user