Source code for visualiser.util

'''Utility functions and classes'''
import os
from enum import Enum
import pygame

SPRITE_DIR = os.path.dirname(__file__) +'/../sprites'
OBSTACLE_SPRITE_PREFIX = 'obstacles/'

_spriteCache = {}

[docs]class Actions(Enum): '''Enumerations of the actions that the simulator can receive''' #: No action NONE = 1 #: Move into the lane to the left LEFT = 2 #: Move into the lane to the right RIGHT = 3 #: Toggle the pause state of the simulator PAUSE = 4
[docs]def loadSprite(path, scale=1): '''Load an image as a :class:`pygame.Surface`. Automatically caches loaded images in the background :param path: (:class:`str`) Path to desired image, relative to the sprites/ directory :param scale: (:class:`float`) Multiplied against the size of the image in order to scale as desired ''' if path in _spriteCache: img = _spriteCache[path].copy() else: src = os.path.join(SPRITE_DIR, path) img = pygame.image.load(src).convert_alpha() _spriteCache[path] = img size = img.get_size() return pygame.transform.scale( img, tuple(map(lambda x: int(x *scale), size)))
[docs]class Vector: '''A 2D vector, with arithmetic magic methods implemented''' def __init__(self, x=0, y=0): #: The x component of the vector self.x = x #: The y component of the vector self.y = y def __add__(self, val): vec = hasattr(val, 'x') return Vector( self.x + (val.x if vec else val), self.y + (val.y if vec else val)) def __sub__(self, val): vec = hasattr(val, 'x') return Vector( self.x - (val.x if vec else val), self.y - (val.y if vec else val)) def __mul__(self, val): vec = hasattr(val, 'x') return Vector( self.x * (val.x if vec else val), self.y * (val.y if vec else val)) def __div__(self, val): vec = hasattr(val, 'x') return Vector( self.x / (val.x if vec else val), self.y / (val.y if vec else val)) def __repr__(self): return 'Vector'+ str((self.x, self.y))
[docs]class Pos(Vector): '''2D vector that automatically updates its vehicle's rect position''' def __init__(self, vehicle, x=0, y=0): # pylint: disable=super-init-not-called # Vector's init is undesireable because it would override attributes self._x = 0 self._y = 0 self._vehicle = vehicle self.x = x self.y = y @property def x(self): '''The x component of the vector :getter: Return x value :setter: Set x value, rounded to nearest :class:`int`''' return self._x @x.setter def x(self, val): if not self._vehicle.rect is None: self._vehicle.rect.x = round(val) self._x = val @property def y(self): '''The y component of the vector :getter: Return y value :setter: Set y value, rounded to nearest :class:`int`''' return self._y @y.setter def y(self, val): if not self._vehicle.rect is None: self._vehicle.rect.y = round(val) self._y = val