Platformer With Enemies

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()