Moving Platforms
sprite_moving_platforms.py
1"""
2Sprite with Moving Platforms
3
4Artwork from https://kenney.nl
5
6If Python and Arcade are installed, this example can be run from the command line with:
7python -m arcade.examples.sprite_moving_platforms
8"""
9import arcade
10
11SPRITE_SCALING = 0.5
12
13WINDOW_WIDTH = 1289
14WINDOW_HEIGHT = 720
15WINDOW_TITLE = "Sprite with Moving Platforms Example"
16SPRITE_PIXEL_SIZE = 128
17GRID_PIXEL_SIZE = (SPRITE_PIXEL_SIZE * SPRITE_SCALING)
18
19# How many pixels to keep as a minimum margin between the character
20# and the edge of the screen.
21VIEWPORT_MARGIN = SPRITE_PIXEL_SIZE * SPRITE_SCALING
22RIGHT_MARGIN = 4 * SPRITE_PIXEL_SIZE * SPRITE_SCALING
23
24# Physics
25MOVEMENT_SPEED = 10 * SPRITE_SCALING
26JUMP_SPEED = 28 * SPRITE_SCALING
27GRAVITY = .9 * SPRITE_SCALING
28
29# How fast the camera pans to the player. 1.0 is instant.
30CAMERA_SPEED = 0.1
31
32
33class GameView(arcade.View):
34 """ Main application class. """
35
36 def __init__(self):
37 """ Initializer """
38
39 # Call the parent init
40 super().__init__()
41
42 # Sprite lists
43
44 # Drawing non-moving walls separate from moving walls improves performance.
45 self.static_wall_list = None
46 self.moving_platform_list = None
47
48 self.player_list = None
49
50 # Set up the player
51 self.player_sprite = None
52 self.physics_engine = None
53 self.game_over = False
54
55 # Create the cameras. One for the GUI, one for the sprites.
56 # We scroll the 'sprite world' but not the GUI.
57 self.camera_sprites = arcade.camera.Camera2D()
58 self.camera_gui = arcade.camera.Camera2D()
59
60 self.left_down = False
61 self.right_down = False
62
63 def setup(self):
64 """ Set up the game and initialize the variables. """
65
66 # Sprite lists
67 self.static_wall_list = arcade.SpriteList()
68 self.moving_platform_list = arcade.SpriteList()
69 self.player_list = arcade.SpriteList()
70
71 # Set up the player
72 self.player_sprite = arcade.Sprite(
73 ":resources:images/animated_characters/female_person/femalePerson_idle.png",
74 scale=SPRITE_SCALING,
75 )
76 self.player_sprite.center_x = 2 * GRID_PIXEL_SIZE
77 self.player_sprite.center_y = 3 * GRID_PIXEL_SIZE
78 self.player_list.append(self.player_sprite)
79
80 # Create floor
81 for i in range(50):
82 wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=SPRITE_SCALING)
83 wall.bottom = 0
84 wall.center_x = - 1000 + i * GRID_PIXEL_SIZE
85 self.static_wall_list.append(wall)
86
87 # Create platform side to side
88 wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=SPRITE_SCALING)
89 wall.center_y = 3 * GRID_PIXEL_SIZE
90 wall.center_x = 3 * GRID_PIXEL_SIZE
91 wall.boundary_left = 2 * GRID_PIXEL_SIZE
92 wall.boundary_right = 5 * GRID_PIXEL_SIZE
93 wall.change_x = 2 * SPRITE_SCALING
94 self.moving_platform_list.append(wall)
95
96 # Create platform side to side
97 wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=SPRITE_SCALING)
98 wall.center_y = 3 * GRID_PIXEL_SIZE
99 wall.center_x = 7 * GRID_PIXEL_SIZE
100 wall.boundary_left = 5 * GRID_PIXEL_SIZE
101 wall.boundary_right = 9 * GRID_PIXEL_SIZE
102 wall.change_x = -2 * SPRITE_SCALING
103 self.moving_platform_list.append(wall)
104
105 # Create platform moving up and down
106 wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=SPRITE_SCALING)
107 wall.center_y = 5 * GRID_PIXEL_SIZE
108 wall.center_x = 5 * GRID_PIXEL_SIZE
109 wall.boundary_top = 8 * GRID_PIXEL_SIZE
110 wall.boundary_bottom = 4 * GRID_PIXEL_SIZE
111 wall.change_y = 2 * SPRITE_SCALING
112 self.moving_platform_list.append(wall)
113
114 # Create platform moving diagonally
115 wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=SPRITE_SCALING)
116 wall.center_y = 5 * GRID_PIXEL_SIZE
117 wall.center_x = 8 * GRID_PIXEL_SIZE
118 wall.boundary_left = 7 * GRID_PIXEL_SIZE
119 wall.boundary_right = 9 * GRID_PIXEL_SIZE
120 wall.boundary_top = 8 * GRID_PIXEL_SIZE
121 wall.boundary_bottom = 4 * GRID_PIXEL_SIZE
122 wall.change_x = 2 * SPRITE_SCALING
123 wall.change_y = 2 * SPRITE_SCALING
124 self.moving_platform_list.append(wall)
125
126 # Create our physics engine
127 self.physics_engine = arcade.PhysicsEnginePlatformer(
128 self.player_sprite,
129 platforms=self.moving_platform_list,
130 walls=self.static_wall_list,
131 gravity_constant=GRAVITY
132 )
133
134 # Set the background color
135 self.background_color = arcade.color.AMAZON
136
137 self.game_over = False
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 # Select the camera we'll use to draw all our sprites
148 with self.camera_sprites.activate():
149 # Draw the sprites
150 self.static_wall_list.draw()
151 self.moving_platform_list.draw()
152 self.player_list.draw()
153
154 # Update & draw our text to the screen
155 with self.camera_gui.activate():
156 distance = self.player_sprite.right
157 output = f"Distance: {distance}"
158 arcade.draw_text(output, 10, 20, arcade.color.WHITE, 14)
159
160 def set_x_speed(self):
161 if self.left_down and not self.right_down:
162 self.player_sprite.change_x = -MOVEMENT_SPEED
163 elif self.right_down and not self.left_down:
164 self.player_sprite.change_x = MOVEMENT_SPEED
165 else:
166 self.player_sprite.change_x = 0
167
168 def on_key_press(self, key, modifiers):
169 """ Called whenever the mouse moves. """
170 if key == arcade.key.UP:
171 if self.physics_engine.can_jump():
172 self.player_sprite.change_y = JUMP_SPEED
173 elif key == arcade.key.LEFT:
174 self.left_down = True
175 self.set_x_speed()
176 elif key == arcade.key.RIGHT:
177 self.right_down = True
178 self.set_x_speed()
179
180 def on_key_release(self, key, modifiers):
181 """ Called when the user presses a mouse button. """
182 if key == arcade.key.LEFT:
183 self.left_down = False
184 self.set_x_speed()
185 elif key == arcade.key.RIGHT:
186 self.right_down = False
187 self.set_x_speed()
188
189 def on_update(self, delta_time):
190 """ Movement and game logic """
191
192 # Call update on all sprites
193 self.physics_engine.update()
194
195 # Scroll the screen to the player
196 self.scroll_to_player()
197
198 def scroll_to_player(self):
199 """
200 Scroll the window to the player.
201
202 if CAMERA_SPEED is 1, the camera will immediately move to the desired position.
203 Anything between 0 and 1 will have the camera move to the location with a smoother
204 pan.
205 """
206
207 position = (self.player_sprite.center_x, self.player_sprite.center_y)
208 self.camera_sprites.position = arcade.math.lerp_2d(
209 self.camera_sprites.position,
210 position,
211 CAMERA_SPEED,
212 )
213
214
215def main():
216 """ Main function """
217 # Create a window class. This is what actually shows up on screen
218 window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
219
220 # Create and setup the GameView
221 game = GameView()
222 game.setup()
223
224 # Show GameView on screen
225 window.show_view(game)
226
227 # Start the arcade game loop
228 arcade.run()
229
230
231if __name__ == "__main__":
232 main()