from arcade.sprite import Sprite
from quest.helpers import scale
import arcade
import os
[docs]class QuestSprite(Sprite):
"""
The base class for sprites in Quest.
A :py:class:`QuestSprite` is a subclass of :py:class:`arcade.Sprite` with a
few additional methods to help integrate into the Quest framework.
Attributes:
description: A string description of the sprite.
strategy: If set, should be a :py:class:`quest.strategy.Strategy`, or another class
instance with a :py:meth:`choose_course` method.
speed: The sprite's speed.
Arguments:
filename: The only required argument is the name of the sprite's image file.
kwargs: There are many optional keyword arguments inherited from :py:class:`arcade.Sprite`.
"""
description = "quest sprite"
strategy = None
speed = 1
[docs] def set_course(self, vector):
"""Update the `change_x` and `change_y` properties using a vector.
Normally, sprites' intended movement is set using the `change_x` and `change_y`
properties. This method updates `change_x` and `change_y` based on an (x, y) vector
whose magnitude is scaled to the sprite's speed. This is helpful when you have an
(x, y) vector, for example a :py:class:`quest.helpers.Direction` or a vector to another
sprite, and want to have this sprite head that direction at its speed. For example, if you wanted
a sprite to always try to move down at its speed::
def on_update(self):
self.set_course(Direction.DOWN.to_vector())
"""
vx, vy = scale(vector, self.speed)
self.change_x = vx
self.change_y = vy
[docs] def stop(self):
"""Set the sprite's `change_x` and `change_y` to zero.
"""
self.change_x = 0
self.change_y = 0
[docs] def on_collision(self, other_sprite, game):
"""Called when the sprite collides with another sprite.
Override this method to change the sprite's collision behavior.
For example, an NPC sprite which represents an item that can be collected
by the player would probably call a method on `game` to update the inventory
and then call :py:meth:`self.remove()`.
"""
pass
[docs] def on_update(self, game):
"""Called on every tick, performs any needed updates.
By default, if the sprite has a strategy, it uses the strategy
to set its course.
"""
if self.strategy:
self.set_course(self.strategy.choose_course(self, game))
def __str__(self):
return "<{}>".format(self.description)
[docs]class Wall(QuestSprite):
"""Wall.
"""
description = "wall"
[docs]class Player(QuestSprite):
"""Player
"""
description = "player"
[docs]class NPC(QuestSprite):
"""Non-playable character
"""
description = "npc"
[docs]class Background(QuestSprite):
"""A sprite that does nothing.
"""
description = "background"
class EndMixIn:
def on_collision(self, sprite, game):
"""When the player collides with a Loot, it calls :py:meth:`quest.maze.MazeMap.on_loot_collected` to tell
the game to make needed updates. Then the Loot removes itself from the map.
"""
super().on_collision(sprite,game)
if game.game_over == False:
game.game_over = True
[docs]class End(EndMixIn,Background):
description = "end"