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"""
 11from __future__ import annotations
 12
 13import arcade
 14import random
 15
 16SCREEN_WIDTH = 800
 17SCREEN_HEIGHT = 600
 18SCREEN_TITLE = "Move with a Sprite Animation Example"
 19
 20COIN_SCALE = 0.5
 21COIN_COUNT = 50
 22CHARACTER_SCALING = 1
 23
 24# How fast to move, and how fast to run the animation
 25MOVEMENT_SPEED = 5
 26UPDATES_PER_FRAME = 5
 27
 28# Constants used to track if the player is facing left or right
 29RIGHT_FACING = 0
 30LEFT_FACING = 1
 31
 32
 33class PlayerCharacter(arcade.Sprite):
 34    def __init__(self):
 35        # Default to face-right
 36        self.character_face_direction = RIGHT_FACING
 37
 38        # Used for flipping between image sequences
 39        self.cur_texture = 0
 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
 45        # --- Load Textures ---
 46
 47        # Images from Kenney.nl's Asset Pack 3
 48        main_path = ":resources:images/animated_characters/female_adventurer/femaleAdventurer"
 49        # main_path = ":resources:images/animated_characters/female_person/femalePerson"
 50        # main_path = ":resources:images/animated_characters/male_person/malePerson"
 51        # main_path = ":resources:images/animated_characters/male_adventurer/maleAdventurer"
 52        # main_path = ":resources:images/animated_characters/zombie/zombie"
 53        # main_path = ":resources:images/animated_characters/robot/robot"
 54
 55        # Load textures for idle standing
 56        self.idle_texture_pair = arcade.load_texture_pair(f"{main_path}_idle.png")
 57        # Set up parent class
 58        super().__init__(self.idle_texture_pair[0], scale=CHARACTER_SCALING)
 59
 60        # Load textures for walking
 61        self.walk_textures = []
 62        for i in range(8):
 63            texture = arcade.load_texture_pair(f"{main_path}_walk{i}.png")
 64            self.walk_textures.append(texture)
 65
 66    def update_animation(self, delta_time: float = 1 / 60):
 67
 68        # Figure out if we need to flip face left or right
 69        if self.change_x < 0 and self.character_face_direction == RIGHT_FACING:
 70            self.character_face_direction = LEFT_FACING
 71        elif self.change_x > 0 and self.character_face_direction == LEFT_FACING:
 72            self.character_face_direction = RIGHT_FACING
 73
 74        # Idle animation
 75        if self.change_x == 0 and self.change_y == 0:
 76            self.texture = self.idle_texture_pair[self.character_face_direction]
 77            return
 78
 79        # Walking animation
 80        self.cur_texture += 1
 81        if self.cur_texture > 7 * UPDATES_PER_FRAME:
 82            self.cur_texture = 0
 83        frame = self.cur_texture // UPDATES_PER_FRAME
 84        direction = self.character_face_direction
 85        self.texture = self.walk_textures[frame][direction]
 86
 87
 88class MyGame(arcade.Window):
 89    """ Main application class. """
 90
 91    def __init__(self, width, height, title):
 92        """ Set up the game and initialize the variables. """
 93        super().__init__(width, height, title)
 94
 95        # Sprite lists
 96        self.player_list = None
 97        self.coin_list = None
 98
 99        # Set up the player
100        self.score = 0
101        self.player = None
102
103    def setup(self):
104        self.player_list = arcade.SpriteList()
105        self.coin_list = arcade.SpriteList()
106
107        # Set up the player
108        self.score = 0
109        self.player = PlayerCharacter()
110
111        self.player.center_x = SCREEN_WIDTH // 2
112        self.player.center_y = SCREEN_HEIGHT // 2
113        self.player.scale = 0.8
114
115        self.player_list.append(self.player)
116
117        for i in range(COIN_COUNT):
118            coin = arcade.Sprite(":resources:images/items/gold_1.png",
119                                 scale=0.5)
120            coin.center_x = random.randrange(SCREEN_WIDTH)
121            coin.center_y = random.randrange(SCREEN_HEIGHT)
122
123            self.coin_list.append(coin)
124
125        # Set the background color
126        self.background_color = arcade.color.AMAZON
127
128    def on_draw(self):
129        """
130        Render the screen.
131        """
132
133        # This command has to happen before we start drawing
134        self.clear()
135
136        # Draw all the sprites.
137        self.coin_list.draw()
138        self.player_list.draw()
139
140        # Put the text on the screen.
141        output = f"Score: {self.score}"
142        arcade.draw_text(output, 10, 20, arcade.color.WHITE, 14)
143
144    def on_key_press(self, key, modifiers):
145        """
146        Called whenever a key is pressed.
147        """
148        if key == arcade.key.UP:
149            self.player.change_y = MOVEMENT_SPEED
150        elif key == arcade.key.DOWN:
151            self.player.change_y = -MOVEMENT_SPEED
152        elif key == arcade.key.LEFT:
153            self.player.change_x = -MOVEMENT_SPEED
154        elif key == arcade.key.RIGHT:
155            self.player.change_x = MOVEMENT_SPEED
156
157    def on_key_release(self, key, modifiers):
158        """
159        Called when the user releases a key.
160        """
161        if key == arcade.key.UP or key == arcade.key.DOWN:
162            self.player.change_y = 0
163        elif key == arcade.key.LEFT or key == arcade.key.RIGHT:
164            self.player.change_x = 0
165
166    def on_update(self, delta_time):
167        """ Movement and game logic """
168
169        # Move the player
170        self.player_list.update()
171
172        # Update the players animation
173        self.player_list.update_animation()
174
175        # Generate a list of all sprites that collided with the player.
176        hit_list = arcade.check_for_collision_with_list(self.player, self.coin_list)
177
178        # Loop through each colliding sprite, remove it, and add to the score.
179        for coin in hit_list:
180            coin.remove_from_sprite_lists()
181            self.score += 1
182
183
184def main():
185    """ Main function """
186    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
187    window.setup()
188    arcade.run()
189
190
191if __name__ == "__main__":
192    main()