Move with a Sprite Animation

sprite_move_animation.py
1"""
2Move with a Sprite Animation
3
4Simple program to show basic sprite usage.
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.sprite_move_animation
10"""
11import arcade
12import random
13
14WINDOW_WIDTH = 1280
15WINDOW_HEIGHT = 720
16WINDOW_TITLE = "Move with a Sprite Animation Example"
17
18COIN_SCALE = 0.5
19COIN_COUNT = 50
20CHARACTER_SCALING = 1
21
22# How fast to move, and how fast to run the animation
23MOVEMENT_SPEED = 5
24UPDATES_PER_FRAME = 5
25
26# Constants used to track if the player is facing left or right
27RIGHT_FACING = 0
28LEFT_FACING = 1
29
30
31class PlayerCharacter(arcade.Sprite):
32 def __init__(self, idle_texture_pair, walk_texture_pairs):
33 # Default to face-right
34 self.character_face_direction = RIGHT_FACING
35
36 # Used for flipping between image sequences
37 self.cur_texture = 0
38 self.idle_texture_pair = idle_texture_pair
39 self.walk_textures = walk_texture_pairs
40
41 # Adjust the collision box. Default includes too much empty space
42 # side-to-side. Box is centered at sprite center, (0, 0)
43 self.points = [[-22, -64], [22, -64], [22, 28], [-22, 28]]
44 # Set up parent class
45 super().__init__(self.idle_texture_pair[0], scale=CHARACTER_SCALING)
46
47
48 def update_animation(self, delta_time: float = 1 / 60):
49
50 # Figure out if we need to flip face left or right
51 if self.change_x < 0 and self.character_face_direction == RIGHT_FACING:
52 self.character_face_direction = LEFT_FACING
53 elif self.change_x > 0 and self.character_face_direction == LEFT_FACING:
54 self.character_face_direction = RIGHT_FACING
55
56 # Idle animation
57 if self.change_x == 0 and self.change_y == 0:
58 self.texture = self.idle_texture_pair[self.character_face_direction]
59 return
60
61 # Walking animation
62 self.cur_texture += 1
63 if self.cur_texture > 7 * UPDATES_PER_FRAME:
64 self.cur_texture = 0
65 frame = self.cur_texture // UPDATES_PER_FRAME
66 direction = self.character_face_direction
67 self.texture = self.walk_textures[frame][direction]
68
69
70class GameView(arcade.View):
71 """ Main application class. """
72
73 def __init__(self):
74 """ Set up the game and initialize the variables. """
75 super().__init__()
76
77 # Sprite lists
78 self.player_list = None
79 self.coin_list = None
80
81 # Set up the player
82 self.score = 0
83 self.score_text = arcade.Text("Score: 0", 10, 20, arcade.color.WHITE, 14)
84 self.player = None
85
86 # --- Load Textures for the player ---
87 # Images from Kenney.nl's Asset Pack 3. We pick one randomly
88 character_types = [
89 ":resources:images/animated_characters/female_adventurer/femaleAdventurer",
90 ":resources:images/animated_characters/female_person/femalePerson",
91 ":resources:images/animated_characters/male_person/malePerson",
92 ":resources:images/animated_characters/male_adventurer/maleAdventurer",
93 ":resources:images/animated_characters/zombie/zombie",
94 ":resources:images/animated_characters/robot/robot",
95 ]
96 chosen_character = random.choice(character_types)
97
98 # Load textures for idle standing
99 idle_texture = arcade.load_texture(f"{chosen_character}_idle.png")
100 self.idle_texture_pair = idle_texture, idle_texture.flip_left_right()
101
102 # Load textures for walking
103 self.walk_texture_pairs = []
104 for i in range(8):
105 texture = arcade.load_texture(f"{chosen_character}_walk{i}.png")
106 self.walk_texture_pairs.append((texture, texture.flip_left_right()))
107
108 def setup(self):
109 self.player_list = arcade.SpriteList()
110 self.coin_list = arcade.SpriteList()
111
112 # Set up the player
113 self.score = 0
114 self.player = PlayerCharacter(self.idle_texture_pair, self.walk_texture_pairs)
115 self.player.position = self.center
116 self.player.scale = 0.8
117
118 self.player_list.append(self.player)
119
120 for i in range(COIN_COUNT):
121 coin = arcade.Sprite(":resources:images/items/gold_1.png", scale=0.5)
122 coin.center_x = random.randrange(WINDOW_WIDTH)
123 coin.center_y = random.randrange(WINDOW_HEIGHT)
124
125 self.coin_list.append(coin)
126
127 # Set the background color
128 self.background_color = arcade.color.AMAZON
129
130 def on_draw(self):
131 """
132 Render the screen.
133 """
134
135 # This command has to happen before we start drawing
136 self.clear()
137
138 # Draw all the sprites.
139 self.coin_list.draw()
140 self.player_list.draw()
141
142 # Put the text on the screen.
143 self.score_text.text = f"Score: {self.score}"
144 self.score_text.draw()
145
146 def on_key_press(self, key, modifiers):
147 """
148 Called whenever a key is pressed.
149 """
150 # Player controls for movement using arrow keys and WASD
151 if key in (arcade.key.UP, arcade.key.W):
152 self.player.change_y = MOVEMENT_SPEED
153 elif key in (arcade.key.DOWN, arcade.key.S):
154 self.player.change_y = -MOVEMENT_SPEED
155 elif key in (arcade.key.LEFT, arcade.key.A):
156 self.player.change_x = -MOVEMENT_SPEED
157 elif key in (arcade.key.RIGHT, arcade.key.D):
158 self.player.change_x = MOVEMENT_SPEED
159 # Quit
160 elif key in (arcade.key.ESCAPE, arcade.key.Q):
161 arcade.close_window()
162
163 def on_key_release(self, key, modifiers):
164 """
165 Called when the user releases a key.
166 """
167 if key in (arcade.key.UP, arcade.key.DOWN, arcade.key.W, arcade.key.S):
168 self.player.change_y = 0
169 elif key in (arcade.key.LEFT, arcade.key.RIGHT, arcade.key.A, arcade.key.D):
170 self.player.change_x = 0
171
172 def on_update(self, delta_time):
173 """ Movement and game logic """
174
175 # Move the player
176 self.player_list.update()
177
178 # Update the players animation
179 self.player_list.update_animation()
180
181 # Generate a list of all sprites that collided with the player.
182 hit_list = arcade.check_for_collision_with_list(self.player, self.coin_list)
183
184 # Loop through each colliding sprite, remove it, and add to the score.
185 for coin in hit_list:
186 coin.remove_from_sprite_lists()
187 self.score += 1
188
189
190def main():
191 """ Main function """
192 # Create a window class. This is what actually shows up on screen
193 window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
194
195 # Create and setup the GameView
196 game = GameView()
197 game.setup()
198
199 # Show GameView on screen
200 window.show_view(game)
201
202 # Start the arcade game loop
203 arcade.run()
204
205
206if __name__ == "__main__":
207 main()