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
 17WINDOW_WIDTH = 1280
 18WINDOW_HEIGHT = 720
 19WINDOW_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 GameView(arcade.View):
 33    """Main application class."""
 34
 35    def __init__(self):
 36        """Initializer"""
 37        super().__init__()
 38
 39        # Sprite lists
 40        self.wall_list = None
 41        self.enemy_list = None
 42        self.player_list = None
 43
 44        # Set up the player
 45        self.player_sprite = None
 46        self.physics_engine = None
 47        self.view_left = 0
 48        self.view_bottom = 0
 49        self.game_over = False
 50
 51    def setup(self):
 52        """Set up the game and initialize the variables."""
 53        # Sprite lists
 54        self.wall_list = arcade.SpriteList()
 55        self.enemy_list = arcade.SpriteList()
 56        self.player_list = arcade.SpriteList()
 57
 58        # Draw the walls on the bottom
 59        for x in range(0, WINDOW_WIDTH, SPRITE_SIZE):
 60            wall = arcade.Sprite(
 61                ":resources:images/tiles/grassMid.png",
 62                scale=SPRITE_SCALING,
 63            )
 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(
 72                ":resources:images/tiles/grassMid.png",
 73                scale=SPRITE_SCALING,
 74            )
 75
 76            wall.bottom = SPRITE_SIZE * 3
 77            wall.left = x
 78            self.wall_list.append(wall)
 79
 80        # Draw the crates
 81        for x in range(0, WINDOW_WIDTH, SPRITE_SIZE * 5):
 82            wall = arcade.Sprite(
 83                ":resources:images/tiles/boxCrate_double.png",
 84                scale=SPRITE_SCALING,
 85            )
 86
 87            wall.bottom = SPRITE_SIZE
 88            wall.left = x
 89            self.wall_list.append(wall)
 90
 91        # -- Draw an enemy on the ground
 92        enemy = arcade.Sprite(
 93            ":resources:images/enemies/wormGreen.png",
 94            scale=SPRITE_SCALING,
 95        )
 96
 97        enemy.bottom = SPRITE_SIZE
 98        enemy.left = SPRITE_SIZE * 2
 99
100        # Set enemy initial speed
101        enemy.change_x = 2
102        self.enemy_list.append(enemy)
103
104        # -- Draw a enemy on the platform
105        enemy = arcade.Sprite(
106            ":resources:images/enemies/wormGreen.png",
107            scale=SPRITE_SCALING,
108        )
109
110        enemy.bottom = SPRITE_SIZE * 4
111        enemy.left = SPRITE_SIZE * 4
112
113        # Set boundaries on the left/right the enemy can't cross
114        enemy.boundary_right = SPRITE_SIZE * 8
115        enemy.boundary_left = SPRITE_SIZE * 3
116        enemy.change_x = 2
117        self.enemy_list.append(enemy)
118
119        # -- Set up the player
120        self.player_sprite = arcade.Sprite(
121            ":resources:images/animated_characters/female_person/femalePerson_idle.png",
122            scale=SPRITE_SCALING,
123        )
124        self.player_list.append(self.player_sprite)
125
126        # Starting position of the player
127        self.player_sprite.center_x = 64
128        self.player_sprite.center_y = 270
129
130        self.physics_engine = arcade.PhysicsEnginePlatformer(
131            self.player_sprite,
132            self.wall_list,
133            gravity_constant=GRAVITY,
134        )
135
136        # Set the background color
137        self.background_color = arcade.color.AMAZON
138
139    def on_draw(self):
140        """
141        Render the screen.
142        """
143
144        # This command has to happen before we start drawing
145        self.clear()
146
147        # Draw all the sprites.
148        self.player_list.draw()
149        self.wall_list.draw()
150        self.enemy_list.draw()
151
152        if self.game_over:
153            arcade.draw_text(
154                "GAME OVER, Press R to reset",
155                self.center_x, self.center_y,
156                font_size=30, anchor_x='center'
157            )
158
159    def on_key_press(self, key, modifiers):
160        """
161        Called whenever the mouse moves.
162        """
163        if key == arcade.key.UP:
164            if self.physics_engine.can_jump():
165                self.player_sprite.change_y = JUMP_SPEED
166        elif key == arcade.key.LEFT:
167            self.player_sprite.change_x = -MOVEMENT_SPEED
168        elif key == arcade.key.RIGHT:
169            self.player_sprite.change_x = MOVEMENT_SPEED
170        elif key == arcade.key.R:
171            self.setup()
172            self.game_over = False
173
174    def on_key_release(self, key, modifiers):
175        """
176        Called when the user presses a mouse button.
177        """
178        if key == arcade.key.LEFT or key == arcade.key.RIGHT:
179            self.player_sprite.change_x = 0
180
181    def on_update(self, delta_time):
182        """ Movement and game logic """
183
184        # Update the player based on the physics engine
185        if not self.game_over:
186            # Move the enemies
187            self.enemy_list.update()
188
189            # Check each enemy
190            for enemy in self.enemy_list:
191                # If the enemy hit a wall, reverse
192                if len(arcade.check_for_collision_with_list(enemy, self.wall_list)) > 0:
193                    enemy.change_x *= -1
194                # If the enemy hit the left boundary, reverse
195                elif enemy.boundary_left is not None and enemy.left < enemy.boundary_left:
196                    enemy.change_x *= -1
197                # If the enemy hit the right boundary, reverse
198                elif enemy.boundary_right is not None and enemy.right > enemy.boundary_right:
199                    enemy.change_x *= -1
200
201            # Update the player using the physics engine
202            self.physics_engine.update()
203
204            # See if the player hit a worm. If so, game over.
205            if len(arcade.check_for_collision_with_list(
206                self.player_sprite,
207                self.enemy_list,
208            )) > 0:
209                self.game_over = True
210
211
212def main():
213    """ Main function """
214    window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
215    game = GameView()
216    game.setup()
217
218    window.show_view(game)
219    arcade.run()
220
221
222if __name__ == "__main__":
223    main()