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