diff options
Diffstat (limited to 'html/rogue/js/camera.js')
-rw-r--r-- | html/rogue/js/camera.js | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/html/rogue/js/camera.js b/html/rogue/js/camera.js new file mode 100644 index 0000000..05e0f28 --- /dev/null +++ b/html/rogue/js/camera.js @@ -0,0 +1,93 @@ +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); + }, + + 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)); + } +}; \ No newline at end of file |