The window system handles the game's display and provides basic rendering functionality.
class Window:
def __init__(self, config: WindowConfig):
"""Initialize the window with the given configuration."""
def clear(self, color: Tuple[int, int, int] = (0, 0, 0)) -> None
Clear the window with the specified color (default: black).
def present(self) -> None
Scale and present the internal surface to the display.
def set_title(self, title: str) -> None
Set the window title.
def toggle_fullscreen(self) -> None
Toggle fullscreen mode.
@property
def surface(self) -> pygame.Surface
Get the internal rendering surface.
@property
def display_surface(self) -> pygame.Surface
Get the scaled display surface.
Configuration options for the game window.
@dataclass
class WindowConfig:
title: str
width: int
height: int
scale: int = 1
vsync: bool = True
fullscreen: bool = False
title
: Window titlewidth
: Window width in pixelsheight
: Window height in pixelsscale
: Integer scaling factor (default: 1)vsync
: Enable vertical synchronization (default: True)fullscreen
: Start in fullscreen mode (default: False)
from src.core import Window, WindowConfig
# Create window configuration
config = WindowConfig(
title="My Game",
width=320,
height=240,
scale=2,
vsync=True
)
# Create window
window = Window(config)
# Game loop
while True:
# Clear window
window.clear((100, 149, 237)) # Cornflower blue
# Draw game objects to window.surface
# ...
# Update display
window.present()
-
Resolution: Choose a base resolution that matches your game's style:
- 256×224: NES/Master System style
- 320×240: SNES/Genesis style
- 640×480: Early PC style
-
Scaling: Use integer scaling to maintain pixel-perfect rendering:
config = WindowConfig(
width=320,
height=240,
scale=2 # Creates a 640×480 window
)
- VSync: Enable VSync to prevent screen tearing:
config = WindowConfig(
# ...
vsync=True
)
- Surface Management: Draw to the internal surface, not the display surface:
# Correct
window.surface.blit(sprite, position)
# Incorrect
window.display_surface.blit(sprite, position)
- Ensure you're using integer scaling values
- Draw to the internal surface, not the display surface
- Avoid floating-point positions for sprites
- Use hardware acceleration when available
- Batch similar draw operations
- Minimize surface locking/unlocking
- Consider using display lists for static elements
- Handle window resize events properly
- Save/restore window state when toggling fullscreen
- Consider different scaling modes for fullscreen