Platformer With Enemies

../../_images/sprite_enemies_in_platformer1.png
sprite_enemies_in_platformer.py
  1"""
  2Show how to do enemies in a platformer
  3
  4Artwork from: https://kenney.nl
  5Tiled available from: https://www.mapeditor.org/
  6
  7If Python and Arcade are installed, this example can be run from the command line with:
  8python -m arcade.examples.sprite_enemies_in_platformer
  9"""
 10
 11import arcade
 12
 13SPRITE_SCALING = 0.5
 14SPRITE_NATIVE_SIZE = 128
 15SPRITE_SIZE = int(SPRITE_NATIVE_SIZE * SPRITE_SCALING)
 16
 17SCREEN_WIDTH = 800
 18SCREEN_HEIGHT = 600
 19SCREEN_TITLE = "Sprite Enemies in a Platformer Example"
 20
 21# How many pixels to keep as a minimum margin between the character
 22# and the edge of the screen.
 23VIEWPORT_MARGIN = 40
 24RIGHT_MARGIN = 150
 25
 26# Physics
 27MOVEMENT_SPEED = 5
 28JUMP_SPEED = 14
 29GRAVITY = 0.5
 30
 31
 32class MyGame(arcade.Window):
 33    """ Main application class. """
 34
 35    def __init__(self):
 36        """
 37        Initializer
 38        """
 39        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
 40
 41        # Sprite lists
 42        self.wall_list = None
 43        self.enemy_list = None
 44        self.player_list = None
 45
 46        # Set up the player
 47        self.player_sprite = None
 48        self.physics_engine = None
 49        self.view_left = 0
 50        self.view_bottom = 0
 51        self.game_over = False
 52
 53    def setup(self):
 54        """ Set up the game and initialize the variables. """
 55
 56        # Sprite lists
 57        self.wall_list = arcade.SpriteList()
 58        self.enemy_list = arcade.SpriteList()
 59        self.player_list = arcade.SpriteList()
 60
 61        # Draw the walls on the bottom
 62        for x in range(0, SCREEN_WIDTH, SPRITE_SIZE):
 63            wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=SPRITE_SCALING)
 64
 65            wall.bottom = 0
 66            wall.left = x
 67            self.wall_list.append(wall)
 68
 69        # Draw the platform
 70        for x in range(SPRITE_SIZE * 3, SPRITE_SIZE * 8, SPRITE_SIZE):
 71            wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=SPRITE_SCALING)
 72
 73            wall.bottom = SPRITE_SIZE * 3
 74            wall.left = x
 75            self.wall_list.append(wall)
 76
 77        # Draw the crates
 78        for x in range(0, SCREEN_WIDTH, SPRITE_SIZE * 5):
 79            wall = arcade.Sprite(":resources:images/tiles/boxCrate_double.png", scale=SPRITE_SCALING)
 80
 81            wall.bottom = SPRITE_SIZE
 82            wall.left = x
 83            self.wall_list.append(wall)
 84
 85        # -- Draw an enemy on the ground
 86        enemy = arcade.Sprite(":resources:images/enemies/wormGreen.png", scale=SPRITE_SCALING)
 87
 88        enemy.bottom = SPRITE_SIZE
 89        enemy.left = SPRITE_SIZE * 2
 90
 91        # Set enemy initial speed
 92        enemy.change_x = 2
 93        self.enemy_list.append(enemy)
 94
 95        # -- Draw a enemy on the platform
 96        enemy = arcade.Sprite(":resources:images/enemies/wormGreen.png", scale=SPRITE_SCALING)
 97
 98        enemy.bottom = SPRITE_SIZE * 4
 99        enemy.left = SPRITE_SIZE * 4
100
101        # Set boundaries on the left/right the enemy can't cross
102        enemy.boundary_right = SPRITE_SIZE * 8
103        enemy.boundary_left = SPRITE_SIZE * 3
104        enemy.change_x = 2
105        self.enemy_list.append(enemy)
106
107        # -- Set up the player
108        self.player_sprite = arcade.Sprite(":resources:images/animated_characters/female_person/femalePerson_idle.png",
109                                           scale=SPRITE_SCALING)
110        self.player_list.append(self.player_sprite)
111
112        # Starting position of the player
113        self.player_sprite.center_x = 64
114        self.player_sprite.center_y = 270
115
116        self.physics_engine = arcade.PhysicsEnginePlatformer(self.player_sprite,
117                                                             self.wall_list,
118                                                             gravity_constant=GRAVITY)
119
120        # Set the background color
121        self.background_color = arcade.color.AMAZON
122
123    def on_draw(self):
124        """
125        Render the screen.
126        """
127
128        # This command has to happen before we start drawing
129        self.clear()
130
131        # Draw all the sprites.
132        self.player_list.draw()
133        self.wall_list.draw()
134        self.enemy_list.draw()
135
136    def on_key_press(self, key, modifiers):
137        """
138        Called whenever the mouse moves.
139        """
140        if key == arcade.key.UP:
141            if self.physics_engine.can_jump():
142                self.player_sprite.change_y = JUMP_SPEED
143        elif key == arcade.key.LEFT:
144            self.player_sprite.change_x = -MOVEMENT_SPEED
145        elif key == arcade.key.RIGHT:
146            self.player_sprite.change_x = MOVEMENT_SPEED
147
148    def on_key_release(self, key, modifiers):
149        """
150        Called when the user presses a mouse button.
151        """
152        if key == arcade.key.LEFT or key == arcade.key.RIGHT:
153            self.player_sprite.change_x = 0
154
155    def on_update(self, delta_time):
156        """ Movement and game logic """
157
158        # Update the player based on the physics engine
159        if not self.game_over:
160            # Move the enemies
161            self.enemy_list.update()
162
163            # Check each enemy
164            for enemy in self.enemy_list:
165                # If the enemy hit a wall, reverse
166                if len(arcade.check_for_collision_with_list(enemy, self.wall_list)) > 0:
167                    enemy.change_x *= -1
168                # If the enemy hit the left boundary, reverse
169                elif enemy.boundary_left is not None and enemy.left < enemy.boundary_left:
170                    enemy.change_x *= -1
171                # If the enemy hit the right boundary, reverse
172                elif enemy.boundary_right is not None and enemy.right > enemy.boundary_right:
173                    enemy.change_x *= -1
174
175            # Update the player using the physics engine
176            self.physics_engine.update()
177
178            # See if the player hit a worm. If so, game over.
179            if len(arcade.check_for_collision_with_list(self.player_sprite, self.enemy_list)) > 0:
180                self.game_over = True
181
182
183def main():
184    window = MyGame()
185    window.setup()
186    arcade.run()
187
188
189if __name__ == "__main__":
190    main()