Files
pixel_tower_defense/game/camera.py
T
2026-07-13 21:33:23 +02:00

51 lines
1.7 KiB
Python

"""Camera module - manages zoom and pan for a 2D viewport."""
import pygame as pg
class Camera:
"""2D camera with zoom and world/screen coordinate conversion.
Attributes:
zoom (float): Current zoom multiplier, clamped to [0.5, 4.0].
offset (pg.math.Vector2): Top-left world position currently in view.
"""
def __init__(self):
self.zoom = 2
self.offset = pg.math.Vector2(0, 0)
def world_to_screen(self, pos):
"""Convert a world-space position to screen pixels."""
return (
int((pos[0] - self.offset.x) * self.zoom),
int((pos[1] - self.offset.y) * self.zoom),
)
def screen_to_world(self, pos):
"""Convert a screen pixel position to world-space coordinates."""
return (
pos[0] / self.zoom + self.offset.x,
pos[1] / self.zoom + self.offset.y,
)
def move(self, dx, dy):
"""Pan the camera by (dx, dy) in world-space units."""
self.offset.x += dx
self.offset.y += dy
def change_zoom(self, amount):
"""Adjust zoom by amount, clamped to [0.5, 4.0]."""
self.zoom += amount
self.zoom = max(0.5, min(self.zoom, 4.0))
def zoom_offset(self, screen_pos, zoom_factor):
"""Zoom toward screen_pos, keeping the world point under it stationary."""
world_before = self.screen_to_world(screen_pos)
self.change_zoom(zoom_factor)
world_after = self.screen_to_world(screen_pos)
# Compensate offset so the point under the cursor doesn't shift
self.offset.x += world_before[0] - world_after[0]
self.offset.y += world_before[1] - world_after[1]