Sprites That Follow The Player 2#

Screen shot of using sprites to collect coins
sprite_follow_simple_2.py#
  1"""
  2Sprite Follow Player 2
  3
  4This calculates a 'vector' towards the player and randomly updates it based
  5on the player's location. This is a bit more complex, but more interesting
  6way of following the player.
  7
  8Artwork from https://kenney.nl
  9
 10If Python and Arcade are installed, this example can be run from the command line with:
 11python -m arcade.examples.sprite_follow_simple_2
 12"""
 13
 14from __future__ import annotations
 15
 16import random
 17import arcade
 18import math
 19
 20# --- Constants ---
 21SPRITE_SCALING_PLAYER = 0.5
 22SPRITE_SCALING_COIN = 0.2
 23COIN_COUNT = 5
 24COIN_SPEED = 0.5
 25
 26SCREEN_WIDTH = 800
 27SCREEN_HEIGHT = 600
 28SCREEN_TITLE = "Sprite Follow Player Simple Example 2"
 29
 30SPRITE_SPEED = 0.5
 31
 32
 33class Coin(arcade.Sprite):
 34    """
 35    This class represents the coins on our screen. It is a child class of
 36    the arcade library's "Sprite" class.
 37    """
 38
 39    def follow_sprite(self, player_sprite):
 40        """
 41        This function will move the current sprite towards whatever
 42        other sprite is specified as a parameter.
 43
 44        We use the 'min' function here to get the sprite to line up with
 45        the target sprite, and not jump around if the sprite is not off
 46        an exact multiple of SPRITE_SPEED.
 47        """
 48
 49        self.center_x += self.change_x
 50        self.center_y += self.change_y
 51
 52        # Random 1 in 100 chance that we'll change from our old direction and
 53        # then re-aim toward the player
 54        if random.randrange(100) == 0:
 55            start_x = self.center_x
 56            start_y = self.center_y
 57
 58            # Get the destination location for the bullet
 59            dest_x = player_sprite.center_x
 60            dest_y = player_sprite.center_y
 61
 62            # Do math to calculate how to get the bullet to the destination.
 63            # Calculation the angle in radians between the start points
 64            # and end points. This is the angle the bullet will travel.
 65            x_diff = dest_x - start_x
 66            y_diff = dest_y - start_y
 67            angle = math.atan2(y_diff, x_diff)
 68
 69            # Taking into account the angle, calculate our change_x
 70            # and change_y. Velocity is how fast the bullet travels.
 71            self.change_x = math.cos(angle) * COIN_SPEED
 72            self.change_y = math.sin(angle) * COIN_SPEED
 73
 74
 75class MyGame(arcade.Window):
 76    """ Our custom Window Class"""
 77
 78    def __init__(self):
 79        """ Initializer """
 80        # Call the parent class initializer
 81        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
 82
 83        # Variables that will hold sprite lists
 84        self.player_list = None
 85        self.coin_list = None
 86
 87        # Set up the player info
 88        self.player_sprite = None
 89        self.score = 0
 90
 91        # Don't show the mouse cursor
 92        self.set_mouse_visible(False)
 93
 94        self.background_color = arcade.color.AMAZON
 95
 96    def setup(self):
 97        """ Set up the game and initialize the variables. """
 98
 99        # Sprite lists
100        self.player_list = arcade.SpriteList()
101        self.coin_list = arcade.SpriteList()
102
103        # Score
104        self.score = 0
105
106        # Set up the player
107        # Character image from kenney.nl
108        self.player_sprite = arcade.Sprite(":resources:images/animated_characters/female_person/femalePerson_idle.png",
109                                           scale=SPRITE_SCALING_PLAYER)
110        self.player_sprite.center_x = 50
111        self.player_sprite.center_y = 50
112        self.player_list.append(self.player_sprite)
113
114        # Create the coins
115        for i in range(COIN_COUNT):
116            # Create the coin instance
117            # Coin image from kenney.nl
118            coin = Coin(":resources:images/items/coinGold.png", scale=SPRITE_SCALING_COIN)
119
120            # Position the coin
121            coin.center_x = random.randrange(SCREEN_WIDTH)
122            coin.center_y = random.randrange(SCREEN_HEIGHT)
123
124            # Add the coin to the lists
125            self.coin_list.append(coin)
126
127    def on_draw(self):
128        """ Draw everything """
129        self.clear()
130        self.coin_list.draw()
131        self.player_list.draw()
132
133        # Put the text on the screen.
134        output = f"Score: {self.score}"
135        arcade.draw_text(output, 10, 20, arcade.color.WHITE, 14)
136
137    def on_mouse_motion(self, x, y, dx, dy):
138        """ Handle Mouse Motion """
139
140        # Move the center of the player sprite to match the mouse x, y
141        self.player_sprite.center_x = x
142        self.player_sprite.center_y = y
143
144    def on_update(self, delta_time):
145        """ Movement and game logic """
146
147        for coin in self.coin_list:
148            coin.follow_sprite(self.player_sprite)
149
150        # Generate a list of all sprites that collided with the player.
151        hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.coin_list)
152
153        # Loop through each colliding sprite, remove it, and add to the score.
154        for coin in hit_list:
155            coin.kill()
156            self.score += 1
157
158
159def main():
160    """ Main function """
161    window = MyGame()
162    window.setup()
163    arcade.run()
164
165
166if __name__ == "__main__":
167    main()