diff options
Diffstat (limited to 'html/rogue/js/camera.js')
-rw-r--r-- | html/rogue/js/camera.js | 145 |
1 files changed, 91 insertions, 54 deletions
diff --git a/html/rogue/js/camera.js b/html/rogue/js/camera.js index e5d5d14..05e0f28 100644 --- a/html/rogue/js/camera.js +++ b/html/rogue/js/camera.js @@ -1,56 +1,93 @@ -const createCamera = (x, y) => ({ - x, - y, - width: window.innerWidth, - height: window.innerHeight, - // Define the dead zone (the area where camera won't move) - deadZone: { - x: window.innerWidth * 0.3, // 30% of screen width - y: window.innerHeight * 0.3, // 30% of screen height - } -}); - -const updateCamera = (camera, target) => { - // Calculate the center point of the screen - const screenCenterX = camera.x + camera.width / 2; - const screenCenterY = camera.y + camera.height / 2; - - // Calculate the distance from the target to the screen center - const distanceX = target.x - screenCenterX; - const distanceY = target.y - screenCenterY; - - // Calculate the dead zone boundaries - const deadZoneLeft = -camera.deadZone.x / 2; - const deadZoneRight = camera.deadZone.x / 2; - const deadZoneTop = -camera.deadZone.y / 2; - const deadZoneBottom = camera.deadZone.y / 2; - - // Calculate new camera position with smooth following - let newX = camera.x; - let newY = camera.y; +const Camera = { + x: 0, + y: 0, + + centerOn(hex) { + const pixelCoord = HexGrid.toPixel(hex); + + // Calculate desired camera position + this.x = pixelCoord.x - state.canvas.width / 2; + this.y = pixelCoord.y - state.canvas.height / 2; + + // Calculate grid dimensions + const gridPixelWidth = Config.hex.GRID_SIZE * Config.hex.WIDTH; + const gridPixelHeight = Config.hex.GRID_SIZE * Config.hex.HEIGHT; + + // Calculate grid bounds (accounting for centered grid) + const minX = -gridPixelWidth / 2; + const maxX = gridPixelWidth / 2 - state.canvas.width; + const minY = -gridPixelHeight / 2; + const maxY = gridPixelHeight / 2 - state.canvas.height; + + // Keep camera within grid bounds + this.x = Math.max(minX, Math.min(this.x, maxX)); + this.y = Math.max(minY, Math.min(this.y, maxY)); + + // Round to prevent sub-pixel rendering + this.x = Math.round(this.x); + this.y = Math.round(this.y); + }, - // Horizontal camera movement - if (distanceX < deadZoneLeft) { - newX += distanceX - deadZoneLeft; - } else if (distanceX > deadZoneRight) { - newX += distanceX - deadZoneRight; + smoothFollow(target) { + const targetPixel = HexGrid.toPixel(target); + const screenX = Math.round(targetPixel.x - this.x); + const screenY = Math.round(targetPixel.y - this.y); + + const centerX = state.canvas.width / 2; + const centerY = state.canvas.height / 2; + + // Determine if we're on a narrow screen + const isNarrowScreen = state.canvas.width <= Config.camera.NARROW_SCREEN_THRESHOLD; + + // Calculate dynamic deadzones based on screen size + const deadzoneX = Math.min( + Math.max( + state.canvas.width * ( + isNarrowScreen ? + Config.camera.DEADZONE_RATIO_X.NARROW : + Config.camera.DEADZONE_RATIO_X.WIDE + ), + Config.camera.MIN_DEADZONE + ), + Config.camera.MAX_DEADZONE + ); + + const deadzoneY = Math.min( + Math.max(state.canvas.height * Config.camera.DEADZONE_RATIO_Y, + Config.camera.MIN_DEADZONE + ), + Config.camera.MAX_DEADZONE + ); + + const deltaX = screenX - centerX; + const deltaY = screenY - centerY; + + // Use more aggressive follow speed for narrow screens + const followSpeed = isNarrowScreen ? + Config.camera.FOLLOW_SPEED * 1.5 : + Config.camera.FOLLOW_SPEED; + + // Ensure camera moves if player is near screen edges + if (Math.abs(deltaX) > deadzoneX) { + const adjustX = deltaX - (deltaX > 0 ? deadzoneX : -deadzoneX); + this.x += Math.round(adjustX * followSpeed); + } + + if (Math.abs(deltaY) > deadzoneY) { + const adjustY = deltaY - (deltaY > 0 ? deadzoneY : -deadzoneY); + this.y += Math.round(adjustY * followSpeed); + } + + // Calculate grid bounds (accounting for centered grid) + const gridPixelWidth = Config.hex.GRID_SIZE * Config.hex.WIDTH; + const gridPixelHeight = Config.hex.GRID_SIZE * Config.hex.HEIGHT; + const minX = -gridPixelWidth / 2; + const maxX = gridPixelWidth / 2 - state.canvas.width; + const minY = -gridPixelHeight / 2; + const maxY = gridPixelHeight / 2 - state.canvas.height; + + // Keep camera within grid bounds + this.x = Math.max(minX, Math.min(this.x, maxX)); + this.y = Math.max(minY, Math.min(this.y, maxY)); } - - // Vertical camera movement - if (distanceY < deadZoneTop) { - newY += distanceY - deadZoneTop; - } else if (distanceY > deadZoneBottom) { - newY += distanceY - deadZoneBottom; - } - - // Add subtle smoothing to camera movement - const smoothing = 0.1; - newX = camera.x + (newX - camera.x) * smoothing; - newY = camera.y + (newY - camera.y) * smoothing; - - return { - ...camera, - x: newX, - y: newY - }; -}; +}; \ No newline at end of file |