versión inicial del juego
This commit is contained in:
150
src/view/CameraManager.js
Normal file
150
src/view/CameraManager.js
Normal file
@@ -0,0 +1,150 @@
|
||||
import * as THREE from 'three';
|
||||
import { DIRECTIONS } from '../engine/dungeon/Constants.js';
|
||||
|
||||
export class CameraManager {
|
||||
constructor(renderer) {
|
||||
this.renderer = renderer; // Reference to GameRenderer to access scenes/resize if needed
|
||||
|
||||
// Configuration
|
||||
this.zoomLevel = 20; // Orthographic zoom factor
|
||||
this.aspect = window.innerWidth / window.innerHeight;
|
||||
|
||||
// Isometric Setup: Orthographic Camera
|
||||
// Left, Right, Top, Bottom, Near, Far
|
||||
// Dimensions determined by zoomLevel and aspect
|
||||
this.camera = new THREE.OrthographicCamera(
|
||||
-this.zoomLevel * this.aspect,
|
||||
this.zoomLevel * this.aspect,
|
||||
this.zoomLevel,
|
||||
-this.zoomLevel,
|
||||
1,
|
||||
1000
|
||||
);
|
||||
|
||||
// Initial Position: Isometric View
|
||||
// Looking from "High Corner"
|
||||
this.camera.position.set(20, 20, 20);
|
||||
this.camera.lookAt(0, 0, 0);
|
||||
|
||||
// --- Controls State ---
|
||||
this.isDragging = false;
|
||||
this.lastMouseX = 0;
|
||||
this.lastMouseY = 0;
|
||||
this.panSpeed = 0.5;
|
||||
|
||||
// Current Snap View (North, East, South, West)
|
||||
// We'll define View Angles relative to "Target"
|
||||
this.currentViewAngle = 0; // 0 = North? We'll refine mapping.
|
||||
|
||||
this.setupInputListeners();
|
||||
}
|
||||
|
||||
getCamera() {
|
||||
return this.camera;
|
||||
}
|
||||
|
||||
setupInputListeners() {
|
||||
// Zoom (Mouse Wheel)
|
||||
window.addEventListener('wheel', (e) => {
|
||||
e.preventDefault();
|
||||
// Adjust Zoom Level property
|
||||
if (e.deltaY < 0) this.zoomLevel = Math.max(5, this.zoomLevel - 1);
|
||||
else this.zoomLevel = Math.min(50, this.zoomLevel + 1);
|
||||
|
||||
this.updateProjection();
|
||||
}, { passive: false });
|
||||
|
||||
// Pan Listeners (Middle Click)
|
||||
window.addEventListener('mousedown', (e) => {
|
||||
if (e.button === 1) { // Middle Mouse
|
||||
this.isDragging = true;
|
||||
this.lastMouseX = e.clientX;
|
||||
this.lastMouseY = e.clientY;
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('mouseup', () => {
|
||||
this.isDragging = false;
|
||||
});
|
||||
|
||||
window.addEventListener('mousemove', (e) => {
|
||||
if (this.isDragging) {
|
||||
const dx = e.clientX - this.lastMouseX;
|
||||
const dy = e.clientY - this.lastMouseY;
|
||||
this.lastMouseX = e.clientX;
|
||||
this.lastMouseY = e.clientY;
|
||||
|
||||
this.pan(-dx, dy); // Invert X usually feels natural (drag ground)
|
||||
}
|
||||
});
|
||||
|
||||
// Resize Listener linkage
|
||||
window.addEventListener('resize', () => {
|
||||
this.aspect = window.innerWidth / window.innerHeight;
|
||||
this.updateProjection();
|
||||
});
|
||||
}
|
||||
|
||||
updateProjection() {
|
||||
this.camera.left = -this.zoomLevel * this.aspect;
|
||||
this.camera.right = this.zoomLevel * this.aspect;
|
||||
this.camera.top = this.zoomLevel;
|
||||
this.camera.bottom = -this.zoomLevel;
|
||||
this.camera.updateProjectionMatrix();
|
||||
}
|
||||
|
||||
pan(dx, dy) {
|
||||
// Panning moves the camera position relative to its local axes
|
||||
// X movement moves Right/Left
|
||||
// Y movement moves Up/Down (in screen space)
|
||||
|
||||
// Since we are isometric, "Up/Down" on screen means moving along the projected Z axis basically.
|
||||
|
||||
// Simple implementation: Translate on X and Z (Ground Plane)
|
||||
// We need to convert screen delta to world delta based on current rotation?
|
||||
// For 'Fixed' views, it's easier.
|
||||
|
||||
const moveSpeed = this.panSpeed * 0.1 * (this.zoomLevel / 10);
|
||||
|
||||
// Basic Pan relative to world for now:
|
||||
// We really want to move camera.translateX/Y?
|
||||
this.camera.translateX(dx * moveSpeed);
|
||||
this.camera.translateY(dy * moveSpeed);
|
||||
}
|
||||
|
||||
// --- Fixed Orbit Logic ---
|
||||
// N, S, E, W
|
||||
setIsoView(direction) {
|
||||
// Standard Isometric look from corner
|
||||
// Distance
|
||||
const dist = 40;
|
||||
const height = 30; // 35 degrees up approx?
|
||||
|
||||
let x, z;
|
||||
switch (direction) {
|
||||
case DIRECTIONS.NORTH: // Looking North means camera is at South?
|
||||
// Or Looking FROM North?
|
||||
// Usually "North View" means "Top of map is North".
|
||||
// In 3D Iso, standard is X=Right, Z=Down(South).
|
||||
// "Normal" view: Camera at +X, +Z looking at origin?
|
||||
x = dist; z = dist;
|
||||
break;
|
||||
case DIRECTIONS.SOUTH:
|
||||
x = -dist; z = -dist;
|
||||
break;
|
||||
case DIRECTIONS.EAST:
|
||||
x = dist; z = -dist;
|
||||
break;
|
||||
case DIRECTIONS.WEST:
|
||||
x = -dist; z = dist;
|
||||
break;
|
||||
default:
|
||||
x = dist; z = dist;
|
||||
}
|
||||
|
||||
this.camera.position.set(x, height, z);
|
||||
this.camera.lookAt(0, 0, 0); // Need to orbit around a pivot actually if we want to pan...
|
||||
// If we pan, camera.lookAt overrides position logic unless we move the visual target.
|
||||
// TODO: Implement OrbitControls-like logic with a target.
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user