Add your description here
Project description
Pygame Visor
Camera/Viewport library.
Currently only works with pygame-ce, as it's using pygame.FRect in some parts.
License
MIT © 2025 Sani (https://github.com/nitori)
Camera/Viewport System – Feature Overview
- Translate between world and screen coordinates (
world_to_screen,screen_to_world)- Needed for input mapping (e.g.
screen_to_world(surface_rect, mouse_pos))
- Needed for input mapping (e.g.
- Support multiple view modes:
- Fixed world area (scales with screen), with or without padding
-
Fixed zoom level (screen res affects visible area)
- Camera movement via external control (
move_to(pos)) - Optional clamping to world bounds / limits (camera can't move past edges)
- Multiple views supported via independent instances (multi-camera/minimap/splitscreen)
- Support lerping/smooth movement to a target position (or perhaps have the user do it themselves?)
- Can probably get some more love, but a basic lerp already works.
- Expose
get_bounding_box(surface_rect)for rendering logic- Camera "requests" world region using the bounding box method above; game provides matching surfaces
- Accept surface size/rect for bounding box calculations (for the different view modes above)
- Handle zooming, including fractional zoom
- UX: Optional zoom-to-cursor behavior (maintains world point under cursor)
Optional stuff for now
- debug helpers (draw bounding box, show mouse world pos, etc.)
- Overscan/margin support for effects, camera shake, etc.
View/Visor Modes
1. Fixed Region (letterbox)
- A specific world size (e.g. 400x300 units) is always shown.
- If the screen's aspect ratio differs, black bars (letterboxing) fill the space.
- Scaling happens to fit the screen, preserving aspect ratio.
2. Fixed Region (extended view)
- A specific world size (e.g. 400x300) is the minimum shown.
- If the screen is larger/wider, more of the world is revealed (i.e. expands the visible region).
- No letterboxing; fills the screen with as much world as possible.
Basic Usage
# get a surface the view can draw on. Could also be screen directly.
surf = pygame.Surface(400, 300)
# Create a Visor instance
visor = Visor(
VisorMode.RegionLetterbox, # One of two modes (see above)
initial_region=(0, 0, 400, 300), # world region to "view"
limits=[-2000, -2000, 2000, 2000], # Optional min/max x,y coords to constrain the visor to.
)
while True:
# ...
# Get the world bounding box (it's a pygame.FRect, indicating the area of
# the world that is currently visible)
bbox = visor.get_bounding_box(surf.get_rect())
# Get iterable of surfaces, that cover the bounding box
# This you need to implement yourself!
# Return an iterable of tuples: ((world_x, world_y), tile_surface)
# Where tile_surface (at the moment) must have world coords width/height. Surfaces are expected to be
# pre-rendered at world-scale (1 unit = 1 pixel in world space). The Visor system will scale them
# appropriately based on screen resolution and visor mode.
tiles = world.get_tiles_iterable(bbox)
# render tiles to surface, the visor will autoscale them to the correct size.
visor.render(surf, tiles)
# optional (if you don't use the screen directly), blit to screen:
screen.blit(surf, (0, 0))
# ...
If you have a player, that needs to be rendered on top of the map. Assuming player.surf holds
your players surface, and player.rect holds the players position:
while True:
# ...
# update visor based on player position *before* getting the bbox
visor.move_to(player.rect.center) # visor.lerp_to(...) is also possible
bbox = visor.get_bounding_box(surf.get_rect())
# ... get tiles etc.
# render map
visor.render(surf, tiles)
# render the player using visor.render, so it will be scaled correctly
visor.render(surf, [
(player.rect.topleft, player.surf)
])
# ...
Examples
See example_map.py for a full working example of a main visor and a minimap using two independent cameras.
See example_modes.py to demonstrate the difference between VisorMode.RegionLetterbox and VisorMode.RegionExpand.
See example_zoom.py to demonstrate a simple way to zoom your visor in and out.
See example_mouse.py for a demonstration of tracking mouse screen pos to world tile position.
See example_ui.py for a simple UI example, of how to position them in the "active" area, in any VisorMode.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pygame_visor-0.1.1.tar.gz.
File metadata
- Download URL: pygame_visor-0.1.1.tar.gz
- Upload date:
- Size: 69.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c32fa12fac45bb392d8aafe437307878147cf795929699c2470cfe36d7b9bb57
|
|
| MD5 |
68b0edd6ddc55b49eabda6d96a474e7e
|
|
| BLAKE2b-256 |
d6fcd061c87352a54369588880d641223db1d7800d924f43dce0adb4f4550e55
|
File details
Details for the file pygame_visor-0.1.1-py3-none-any.whl.
File metadata
- Download URL: pygame_visor-0.1.1-py3-none-any.whl
- Upload date:
- Size: 7.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c8fb08995099c8cd73c51f94252bba4fbfc13a1c7ffeb4e6b5d2085002f8069e
|
|
| MD5 |
cfcc70ae4b9e55c3a8b3d3fb402c864d
|
|
| BLAKE2b-256 |
6ddc7b5078ddf1c744486a5fbdbd43367d7813a5ee57370bed0142662d00aa1d
|