Sprites That Follow a Path#

Screen shot of a sprite following a path
follow_path.py#
  1"""
  2Sprite Follow Path
  3
  4This example has enemy sprites follow a set path.
  5
  6Artwork from https://kenney.nl
  7
  8If Python and Arcade are installed, this example can be run from the command line with:
  9python -m arcade.examples.follow_path
 10"""
 11
 12import arcade
 13import math
 14
 15# --- Constants ---
 16SPRITE_SCALING_PLAYER = 0.5
 17SPRITE_SCALING_ENEMY = 0.5
 18ENEMY_SPEED = 3.0
 19
 20SCREEN_WIDTH = 800
 21SCREEN_HEIGHT = 600
 22SCREEN_TITLE = "Sprite Follow Path Simple Example"
 23
 24
 25class Enemy(arcade.Sprite):
 26    """
 27    This class represents the Enemy on our screen.
 28    """
 29
 30    def __init__(self, image, scale, position_list):
 31        super().__init__(image, scale=scale)
 32        self.position_list = position_list
 33        self.cur_position = 0
 34        self.speed = ENEMY_SPEED
 35
 36    def update(self):
 37        """ Have a sprite follow a path """
 38
 39        # Where are we
 40        start_x = self.center_x
 41        start_y = self.center_y
 42
 43        # Where are we going
 44        dest_x = self.position_list[self.cur_position][0]
 45        dest_y = self.position_list[self.cur_position][1]
 46
 47        # X and Y diff between the two
 48        x_diff = dest_x - start_x
 49        y_diff = dest_y - start_y
 50
 51        # Calculate angle to get there
 52        angle = math.atan2(y_diff, x_diff)
 53
 54        # How far are we?
 55        distance = math.sqrt((self.center_x - dest_x) ** 2 + (self.center_y - dest_y) ** 2)
 56
 57        # How fast should we go? If we are close to our destination,
 58        # lower our speed so we don't overshoot.
 59        speed = min(self.speed, distance)
 60
 61        # Calculate vector to travel
 62        change_x = math.cos(angle) * speed
 63        change_y = math.sin(angle) * speed
 64
 65        # Update our location
 66        self.center_x += change_x
 67        self.center_y += change_y
 68
 69        # How far are we?
 70        distance = math.sqrt((self.center_x - dest_x) ** 2 + (self.center_y - dest_y) ** 2)
 71
 72        # If we are there, head to the next point.
 73        if distance <= self.speed:
 74            self.cur_position += 1
 75
 76            # Reached the end of the list, start over.
 77            if self.cur_position >= len(self.position_list):
 78                self.cur_position = 0
 79
 80
 81class MyGame(arcade.Window):
 82    """ Our custom Window Class"""
 83
 84    def __init__(self):
 85        """ Initializer """
 86        # Call the parent class initializer
 87        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
 88
 89        # Variables that will hold sprite lists
 90        self.player_list = None
 91        self.enemy_list = None
 92
 93        # Set up the player info
 94        self.player_sprite = None
 95        self.score = 0
 96
 97        # Don't show the mouse cursor
 98        self.set_mouse_visible(False)
 99
100        self.background_color = arcade.color.AMAZON
101
102    def setup(self):
103        """ Set up the game and initialize the variables. """
104
105        # Sprite lists
106        self.player_list = arcade.SpriteList()
107        self.enemy_list = arcade.SpriteList()
108
109        # Score
110        self.score = 0
111
112        # Set up the player
113        # Character image from kenney.nl
114        self.player_sprite = arcade.Sprite(
115            ":resources:images/animated_characters/female_person/femalePerson_idle.png",
116            scale=SPRITE_SCALING_PLAYER)
117        self.player_sprite.center_x = 50
118        self.player_sprite.center_y = 50
119        self.player_list.append(self.player_sprite)
120
121        # List of points the enemy will travel too.
122        position_list = [[50, 50],
123                         [700, 50],
124                         [700, 500],
125                         [50, 500]]
126
127        # Create the enemy
128        enemy = Enemy(":resources:images/animated_characters/robot/robot_idle.png",
129                      SPRITE_SCALING_ENEMY,
130                      position_list)
131
132        # Set initial location of the enemy at the first point
133        enemy.center_x = position_list[0][0]
134        enemy.center_x = position_list[0][1]
135
136        # Add the enemy to the enemy list
137        self.enemy_list.append(enemy)
138
139    def on_draw(self):
140        """ Draw everything """
141        self.clear()
142        self.enemy_list.draw()
143        self.player_list.draw()
144
145    def on_mouse_motion(self, x, y, dx, dy):
146        """ Handle Mouse Motion """
147
148        # Move the center of the player sprite to match the mouse x, y
149        self.player_sprite.center_x = x
150        self.player_sprite.center_y = y
151
152    def on_update(self, delta_time):
153        """ Movement and game logic """
154        self.enemy_list.update()
155
156
157def main():
158    """ Main function """
159    window = MyGame()
160    window.setup()
161    arcade.run()
162
163
164if __name__ == "__main__":
165    main()