pymunk_demo_platformer_08.py Diff

pymunk_demo_platformer_08.py
--- /home/docs/checkouts/readthedocs.org/user_builds/arcade-library/checkouts/2.6.8/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_07.py
+++ /home/docs/checkouts/readthedocs.org/user_builds/arcade-library/checkouts/2.6.8/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_08.py
@@ -55,6 +55,101 @@
 # Strength of a jump
 PLAYER_JUMP_IMPULSE = 1800
 
+# Close enough to not-moving to have the animation go to idle.
+DEAD_ZONE = 0.1
+
+# Constants used to track if the player is facing left or right
+RIGHT_FACING = 0
+LEFT_FACING = 1
+
+# How many pixels to move before we change the texture in the walking animation
+DISTANCE_TO_CHANGE_TEXTURE = 20
+
+
+class PlayerSprite(arcade.Sprite):
+    """ Player Sprite """
+    def __init__(self):
+        """ Init """
+        # Let parent initialize
+        super().__init__()
+
+        # Set our scale
+        self.scale = SPRITE_SCALING_PLAYER
+
+        # Images from Kenney.nl's Character pack
+        # main_path = ":resources:images/animated_characters/female_adventurer/femaleAdventurer"
+        main_path = ":resources:images/animated_characters/female_person/femalePerson"
+        # main_path = ":resources:images/animated_characters/male_person/malePerson"
+        # main_path = ":resources:images/animated_characters/male_adventurer/maleAdventurer"
+        # main_path = ":resources:images/animated_characters/zombie/zombie"
+        # main_path = ":resources:images/animated_characters/robot/robot"
+
+        # Load textures for idle standing
+        self.idle_texture_pair = arcade.load_texture_pair(f"{main_path}_idle.png")
+        self.jump_texture_pair = arcade.load_texture_pair(f"{main_path}_jump.png")
+        self.fall_texture_pair = arcade.load_texture_pair(f"{main_path}_fall.png")
+
+        # Load textures for walking
+        self.walk_textures = []
+        for i in range(8):
+            texture = arcade.load_texture_pair(f"{main_path}_walk{i}.png")
+            self.walk_textures.append(texture)
+
+        # Set the initial texture
+        self.texture = self.idle_texture_pair[0]
+
+        # Hit box will be set based on the first image used.
+        self.hit_box = self.texture.hit_box_points
+
+        # Default to face-right
+        self.character_face_direction = RIGHT_FACING
+
+        # Index of our current texture
+        self.cur_texture = 0
+
+        # How far have we traveled horizontally since changing the texture
+        self.x_odometer = 0
+
+    def pymunk_moved(self, physics_engine, dx, dy, d_angle):
+        """ Handle being moved by the pymunk engine """
+        # Figure out if we need to face left or right
+        if dx < -DEAD_ZONE and self.character_face_direction == RIGHT_FACING:
+            self.character_face_direction = LEFT_FACING
+        elif dx > DEAD_ZONE and self.character_face_direction == LEFT_FACING:
+            self.character_face_direction = RIGHT_FACING
+
+        # Are we on the ground?
+        is_on_ground = physics_engine.is_on_ground(self)
+
+        # Add to the odometer how far we've moved
+        self.x_odometer += dx
+
+        # Jumping animation
+        if not is_on_ground:
+            if dy > DEAD_ZONE:
+                self.texture = self.jump_texture_pair[self.character_face_direction]
+                return
+            elif dy < -DEAD_ZONE:
+                self.texture = self.fall_texture_pair[self.character_face_direction]
+                return
+
+        # Idle animation
+        if abs(dx) <= DEAD_ZONE:
+            self.texture = self.idle_texture_pair[self.character_face_direction]
+            return
+
+        # Have we moved far enough to change the texture?
+        if abs(self.x_odometer) > DISTANCE_TO_CHANGE_TEXTURE:
+
+            # Reset the odometer
+            self.x_odometer = 0
+
+            # Advance the walking animation
+            self.cur_texture += 1
+            if self.cur_texture > 7:
+                self.cur_texture = 0
+            self.texture = self.walk_textures[self.cur_texture][self.character_face_direction]
+
 
 class GameWindow(arcade.Window):
     """ Main Window """
@@ -66,7 +161,7 @@
         super().__init__(width, height, title)
 
         # Player sprite
-        self.player_sprite: Optional[arcade.Sprite] = None
+        self.player_sprite: Optional[PlayerSprite] = None
 
         # Sprite lists we need
         self.player_list: Optional[arcade.SpriteList] = None
@@ -102,8 +197,8 @@
         self.item_list = tile_map.sprite_lists["Dynamic Items"]
 
         # Create player sprite
-        self.player_sprite = arcade.Sprite(":resources:images/animated_characters/female_person/femalePerson_idle.png",
-                                           SPRITE_SCALING_PLAYER)
+        self.player_sprite = PlayerSprite()
+
         # Set player location
         grid_x = 1
         grid_y = 1