Example #1
0
class Enemy(DirtySprite, TargetABC):
    def __init__(self, scene, position: Vector, player: 'Player'):
        super().__init__(scene.groups["interact"])
        self.image = image.load(path.join(path.dirname(__file__), "enemy.png"))
        self.rect = self.image.get_rect()
        self.rect.center = tuple(position)
        self._position = position
        self.direction = Vector(0, 1).rotate(random.randint(0, 359))
        self.dirty = 1
        self.scene = scene
        self.speed = 30
        self.reach = 20
        self.sense_limit = 200
        self.player = player

    @property
    def position(self):
        return self._position

    def interact(self, player: 'Player'):
        logging.getLogger(type(self).__name__).debug("Enemy killed.")
        self.kill()

    def update(self, time_delta):
        direction_to_player = self.player.position - self.position
        distance_to_player = direction_to_player.length
        if distance_to_player < self.reach:
            pass
        elif distance_to_player < self.sense_limit:
            self._position += direction_to_player.scale(self.speed *
                                                        time_delta)
        else:
            self.direction = self.direction.rotate(random.randint(-2, 2))
            self._position += self.direction.scale(self.speed * time_delta *
                                                   .5)
        self.rect.center = tuple(self.position)
        self.dirty = 1
Example #2
0
class BaseSprite(EventMixin):
    """
    The base Sprite class. All sprites should inherit from this (directly or
    indirectly).

    Attributes:
    * image (str): The image file
    * resource_path (pathlib.Path): The path that image is relative to
    * position: Location of the sprite
    * facing: The direction of the "top" of the sprite (rendering only)
    * size: The width/height of the sprite (sprites are square)
    """
    image = None
    resource_path = None
    position: Vector = Vector(0, 0)
    facing: Vector = Vector(0, -1)
    _size: Union[int, float] = 1
    _offset_value = None

    def __init__(self, **kwargs):
        super().__init__()

        # Make these instance properties with fresh instances
        # Don't use Vector.convert() because we need copying
        self.position = Vector(*self.position)
        self.facing = Vector(*self.facing)

        # Initialize things
        for k, v in kwargs.items():
            # Abbreviations
            if k == 'pos':
                k = 'position'
            # Castings
            if k in ('position', 'facing'):
                v = Vector(*v)  # Vector.convert() when that ships.
            setattr(self, k, v)

        # Trigger some calculations
        self.size = self.size

    @property
    def center(self) -> Vector:
        return self.position

    @center.setter
    def center(self, value: Sequence[float]):
        x = value[0]
        y = value[1]
        self.position.x = x
        self.position.y = y

    @property
    def left(self) -> Side:
        return Side(self, LEFT)

    @left.setter
    def left(self, value: float):
        self.position.x = value + self._offset_value

    @property
    def right(self) -> Side:
        return Side(self, RIGHT)

    @right.setter
    def right(self, value):
        self.position.x = value - self._offset_value

    @property
    def top(self):
        return Side(self, TOP)

    @top.setter
    def top(self, value):
        self.position.y = value + self._offset_value

    @property
    def bottom(self):
        return Side(self, BOTTOM)

    @bottom.setter
    def bottom(self, value):
        self.position.y = value - self._offset_value

    @property
    def size(self) -> Union[int, float]:
        return self._size

    @size.setter
    def size(self, value: Union[int, float]):
        self._size = value
        self._offset_value = self._size / 2

    def rotate(self, degrees: Number):
        self.facing.rotate(degrees)

    def __image__(self):
        if self.image is None:
            self.image = f"{type(self).__name__.lower()}.png"
        return self.image

    def __resource_path__(self):
        if self.resource_path is None:
            self.resource_path = Path(realpath(getfile(type(self)))).absolute().parent
        return self.resource_path