Move with a Sprite Animation

GIF animation of animated walking character.
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()