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