The sprite system handles loading, managing, and rendering game sprites and animations.
class Sprite:
def __init__(
self,
sprite_sheet: SpriteSheet,
config: Optional[SpriteConfig] = None
):
"""Initialize a sprite with the given sprite sheet and configuration."""
def set_frame(self, frame_index: int) -> None
Set the current frame of the sprite.
def draw(self, surface: pygame.Surface) -> None
Draw the sprite to the given surface.
class SpriteSheet:
def __init__(self, texture_path: str):
"""Load a sprite sheet from the given image file."""
def add_frame(self, frame: SpriteFrame) -> int
Add a frame to the sprite sheet. Returns the frame index.
def add_frames_grid(
self,
frame_width: int,
frame_height: int,
margin: int = 0,
spacing: int = 0
) -> None
Add frames from a grid layout. Useful for uniform sprite sheets.
Configuration for a single frame in a sprite sheet.
@dataclass
class SpriteFrame:
x: int
y: int
width: int
height: int
x
: X position of the frame in the sprite sheety
: Y position of the frame in the sprite sheetwidth
: Width of the frameheight
: Height of the frame
Configuration for sprite rendering.
@dataclass
class SpriteConfig:
x: float = 0.0
y: float = 0.0
scale_x: float = 1.0
scale_y: float = 1.0
rotation: int = 0 # Degrees, must be multiple of 90
flip_x: bool = False
flip_y: bool = False
alpha: int = 255
z_index: int = 0
x
: X position for renderingy
: Y position for renderingscale_x
: Horizontal scale factorscale_y
: Vertical scale factorrotation
: Rotation in degrees (must be multiple of 90)flip_x
: Horizontally flip the spriteflip_y
: Vertically flip the spritealpha
: Transparency (0-255)z_index
: Rendering order
from src.core.sprite import SpriteSheet, SpriteFrame
# Load sprite sheet
sheet = SpriteSheet("player.png")
# Add individual frames
sheet.add_frame(SpriteFrame(0, 0, 32, 32)) # Idle
sheet.add_frame(SpriteFrame(32, 0, 32, 32)) # Walk 1
sheet.add_frame(SpriteFrame(64, 0, 32, 32)) # Walk 2
# Or add frames from a grid
sheet.add_frames_grid(
frame_width=32,
frame_height=32,
margin=1,
spacing=1
)
from src.core.sprite import Sprite, SpriteConfig
# Create sprite configuration
config = SpriteConfig(
x=100,
y=100,
scale_x=2.0,
scale_y=2.0,
flip_x=False
)
# Create sprite
sprite = Sprite(sheet, config)
# Set current frame
sprite.set_frame(1) # Show walking frame
# Draw sprite
sprite.draw(window.surface)
-
Sprite Sheet Organization:
- Group related frames together
- Use consistent frame sizes when possible
- Add padding to prevent bleeding
- Consider power-of-two textures for compatibility
-
Memory Management:
- Share sprite sheets between similar sprites
- Unload unused sprite sheets
- Use texture atlases for small sprites
-
Animation:
- Use frame indices for animation sequences
- Consider frame timing in animation loops
- Implement state machines for complex animations
-
Performance:
- Batch similar sprites together
- Use sprite culling for off-screen objects
- Minimize sprite sheet switches
- Add padding between frames
- Use texture coordinates slightly inset from edges
- Ensure power-of-two textures when required
- Too many individual sprites
- Frequent sprite sheet switching
- Excessive scaling or rotation
- Large sprite sheets
- Duplicate sprite sheet loading
- Unused frames in memory
- Incorrect transparency
- Scaling artifacts
- Rotation limitations