Source code for pygame_zer.driver

import enum

import pygame

from .camera import Camera
from .shape import Shape
from .types import Color, Rectf, Vec2f


[docs] class DriverFlags(enum.Flag): """ Flags to apply to a driver. These flags can be or'd together to combine various features. Attributes ---------- EMPTY A featureless flag. This only exists to create a starting state for building optional flag features. Disabled by default ZOOMABLE Allow zooming in and out. Enabled by default EXPLORABLE Allow panning up/down/left/right. Enabled by default NOCACHE Disable caching, may reduce performance. Disabled by default """ EMPTY = 1 ZOOMABLE = 2 EXPLORABLE = 4 NOCACHE = 8
DEFAULT_FLAGS = DriverFlags.ZOOMABLE | DriverFlags.EXPLORABLE """The default flags for a driver"""
[docs] class Driver: """ The driver for all pygame-zer functionality. Everything done using pygame-zer must happen through this driver. It contains a camera for point translation, a drawer to manage shapes, and any flags to modify behavior. Attributes ---------- camera : pygame_zer.Camera The driver camera. Should be modified directly using driver.camera flags : pygame_zer.DriverFlags The driver flags. Should not be modified after setting. Can be accessed by other classes in order to customize behavior Methods ------- draw() Draw to the camera/access the driver drawer. handle_event(event:pygame.event.Event) : bool Handle a pygame event. Returns true if handled. _insert_shape() Add a shape to the driver drawer. Only used by shape classes. """ def __init__(self, surface: pygame.Surface, flags: DriverFlags = DEFAULT_FLAGS): self.camera = Camera(surface, (0, 0), surface.get_size(), 1) self._drawer = DriverDrawer(self.camera) self.flags = flags @property def draw(self): """Draw to the camera/access the driver drawer. `Driver.draw()` is almost always used as a standalone called function to draw all registered shapes to the camera. However, it also returns a DriverDrawer that can perform immediate-mode drawing operations in camera space. This may incur performance hits. """ return self._drawer
[docs] def _insert_shape(self, shape: Shape): """Add a shape to the driver drawer. Unless you are making a custom shape class and adding self-registration, do not use this method directly. Add the driver to the shape's constructor. Parameters ---------- shape : pygame.Shape The shape to add to the driver """ self._drawer.shapes.append(shape)
[docs] def handle_event(self, event: pygame.event.Event) -> bool: """Handle a pygame event. Call this method in your pygame event loop. This handles all pygame events related to pygame-zer and returns true if the event applied to this driver. If the event does not apply to pygame-zer and should be handled separately, this method returns false. Parameters ---------- event : pygame.event.Event The event to attempt to handle """ if ( DriverFlags.EXPLORABLE in self.flags and event.type == pygame.MOUSEMOTION and event.buttons[0] ): self.camera.translate(event.rel) return True elif DriverFlags.ZOOMABLE in self.flags and event.type == pygame.MOUSEWHEEL: self.camera.zoom(event.y) return True return False
[docs] class DriverDrawer: """ The drawer for the driver. This class handles all drawing actions performed. This class should not be used directly other than for immediate-mode drawing. Methods ------- circle(color:pygame_zer.types.Color,center:pygame_zer.types.Vec2f,radius:float,width:float=0) Draw a circle immediately rect(color:pygame_zer.types.Color,rect:pygame_zer.types.Rectf,width:float=0) Draw a rectangle immediately line(color:pygame_zer.types.Color,start_pos:pygame_zer.types.Vec2f,end_pos:pygame_zer.types.Vec2f,width:float=1) Draw a line immediately """ def __init__(self, camera: Camera): self.shapes: list[Shape] = [] self.camera = camera def __call__(self): for shape in self.shapes: shape.draw(self.camera)
[docs] def circle(self, color: Color, center: Vec2f, radius: float, width: float = 0): """Draw a circle immediately""" center = self.camera.point_to_camera(center) radius = self.camera.distance_to_camera(radius) width = self.camera.distance_to_camera(width) radius += width # outlineRadius = ((self.outlineWidth + self.radius) / self.radius) * radius # if self.outline is not None: # pygame.draw.circle(camera.surface, self.outline, center, outlineRadius) pygame.draw.circle(self.camera.surface, color, center, radius, width=int(width))
[docs] def rect(self, color: Color, rect: Rectf, width: float = 0): """Draw a rectangle immediately""" topleft = self.camera.point_to_camera(rect[0:2]) size = [self.camera.distance_to_camera(x) for x in rect[2:]] width = self.camera.distance_to_camera(width) pygame.draw.rect( self.camera.surface, color, ( topleft[0] - width, topleft[1] - width, size[0] + width * 2, size[1] + width * 2, ), width=int(width), )
[docs] def line(self, color: Color, start_pos: Vec2f, end_pos: Vec2f, width: float = 1): """Draw a line immediately""" p1 = self.camera.point_to_camera(start_pos) p2 = self.camera.point_to_camera(end_pos) width = int(self.camera.distance_to_camera(1)) pygame.draw.line(self.camera.surface, color, p1, p2, width=width)