使用级别和切片地图#

sprite_tiled_map_with_levels.py#
1"""
2Load a Tiled map file with Levels
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_tiled_map_with_levels
9"""
10import time
11
12import arcade
13
14TILE_SPRITE_SCALING = 0.5
15PLAYER_SCALING = 0.6
16
17SCREEN_WIDTH = 800
18SCREEN_HEIGHT = 600
19SCREEN_TITLE = "Sprite Tiled Map with Levels Example"
20SPRITE_PIXEL_SIZE = 128
21GRID_PIXEL_SIZE = SPRITE_PIXEL_SIZE * TILE_SPRITE_SCALING
22
23# How many pixels to keep as a minimum margin between the character
24# and the edge of the screen.
25VIEWPORT_MARGIN_TOP = 60
26VIEWPORT_MARGIN_BOTTOM = 60
27VIEWPORT_MARGIN_RIGHT = 270
28VIEWPORT_MARGIN_LEFT = 270
29
30# Physics
31MOVEMENT_SPEED = 5
32JUMP_SPEED = 23
33GRAVITY = 1.1
34
35
36class MyGame(arcade.Window):
37 """Main application class."""
38
39 def __init__(self):
40 """
41 Initializer
42 """
43 super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
44
45 # Tilemap Object
46 self.tile_map = None
47
48 # Sprite lists
49 self.player_list = None
50
51 # Set up the player
52 self.score = 0
53 self.player_sprite = None
54
55 self.physics_engine = None
56 self.cam = None
57 self.end_of_map = 0
58 self.game_over = False
59 self.last_time = None
60 self.frame_count = 0
61 self.fps_message = None
62
63 self.level = 1
64 self.max_level = 2
65
66 def setup(self):
67 """Set up the game and initialize the variables."""
68
69 # Sprite lists
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=PLAYER_SCALING,
76 )
77
78 # Starting position of the player
79 self.player_sprite.center_x = 128
80 self.player_sprite.center_y = 64
81 self.player_list.append(self.player_sprite)
82
83 self.load_level(self.level)
84
85 self.game_over = False
86
87 def load_level(self, level):
88 # layer_options = {"Platforms": {"use_spatial_hash": True}}
89
90 # Read in the tiled map
91 self.tile_map = arcade.load_tilemap(
92 f":resources:tiled_maps/level_{level}.json", scaling=TILE_SPRITE_SCALING
93 )
94
95 # --- Walls ---
96
97 # Calculate the right edge of the my_map in pixels
98 self.end_of_map = self.tile_map.width * GRID_PIXEL_SIZE
99
100 self.physics_engine = arcade.PhysicsEnginePlatformer(
101 self.player_sprite,
102 self.tile_map.sprite_lists["Platforms"],
103 gravity_constant=GRAVITY,
104 )
105
106 # --- Other stuff
107 # Set the background color
108 if self.tile_map.background_color:
109 self.background_color = self.tile_map.background_color
110
111 # Reset cam
112 self.cam = arcade.camera.Camera2D()
113
114 def on_draw(self):
115 """
116 Render the screen.
117 """
118
119 self.frame_count += 1
120
121 # This command has to happen before we start drawing
122 self.clear()
123
124 # Draw all the sprites.
125 self.player_list.draw()
126 self.tile_map.sprite_lists["Platforms"].draw()
127
128 if self.last_time and self.frame_count % 60 == 0:
129 fps = 1.0 / (time.time() - self.last_time) * 60
130 self.fps_message = f"FPS: {fps:5.0f}"
131
132 if self.fps_message:
133 arcade.draw_text(
134 self.fps_message,
135 self.cam.left + 10,
136 self.cam.bottom + 40,
137 arcade.color.BLACK,
138 14,
139 )
140
141 if self.frame_count % 60 == 0:
142 self.last_time = time.time()
143
144 # Put the text on the screen.
145 # Adjust the text position based on the view port so that we don't
146 # scroll the text too.
147 distance = self.player_sprite.right
148 output = f"Distance: {distance:.0f}"
149 arcade.draw_text(
150 output, self.cam.left + 10, self.cam.bottom + 20, arcade.color.BLACK, 14
151 )
152
153 if self.game_over:
154 arcade.draw_text(
155 "Game Over",
156 self.cam.left + 200,
157 self.cam.bottom + 200,
158 arcade.color.BLACK,
159 30,
160 )
161
162 def on_key_press(self, key, modifiers):
163 """
164 Called whenever the mouse moves.
165 """
166 if key == arcade.key.UP:
167 if self.physics_engine.can_jump():
168 self.player_sprite.change_y = JUMP_SPEED
169 elif key == arcade.key.LEFT:
170 self.player_sprite.change_x = -MOVEMENT_SPEED
171 elif key == arcade.key.RIGHT:
172 self.player_sprite.change_x = MOVEMENT_SPEED
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 if self.player_sprite.right >= self.end_of_map:
185 if self.level < self.max_level:
186 self.level += 1
187 self.load_level(self.level)
188 self.player_sprite.center_x = 128
189 self.player_sprite.center_y = 64
190 self.player_sprite.change_x = 0
191 self.player_sprite.change_y = 0
192 else:
193 self.game_over = True
194
195 # Call update on all sprites (The sprites don't do much in this
196 # example though.)
197 if not self.game_over:
198 self.physics_engine.update()
199
200 # --- Manage Scrolling ---
201
202 # Track if we need to change the viewport
203
204 changed = False
205
206 # Scroll left
207 left_bndry = self.cam.left + VIEWPORT_MARGIN_LEFT
208 if self.player_sprite.left < left_bndry:
209 self.cam.left -= left_bndry - self.player_sprite.left
210 changed = True
211
212 # Scroll right
213 right_bndry = self.cam.right - VIEWPORT_MARGIN_RIGHT
214 if self.player_sprite.right > right_bndry:
215 self.cam.left += self.player_sprite.right - right_bndry
216 changed = True
217
218 # Scroll up
219 top_bndry = self.cam.top - VIEWPORT_MARGIN_TOP
220 if self.player_sprite.top > top_bndry:
221 self.cam.bottom += self.player_sprite.top - top_bndry
222 changed = True
223
224 # Scroll down
225 bottom_bndry = self.cam.bottom + VIEWPORT_MARGIN_BOTTOM
226 if self.player_sprite.bottom < bottom_bndry:
227 self.cam.bottom -= bottom_bndry - self.player_sprite.bottom
228 changed = True
229
230 if changed:
231 self.cam.use()
232
233
234def main():
235 window = MyGame()
236 window.setup()
237 arcade.run()
238
239
240if __name__ == "__main__":
241 main()