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()