使用在切片 Mapfile 中加载#
下面是一个使用平铺地图的快速示例。有关详细信息,请参阅:

sprite_tiled_map.py#
1"""
2Load a Tiled map file
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
9"""
10
11import time
12
13import arcade
14
15TILE_SCALING = 0.5
16PLAYER_SCALING = 1
17
18SCREEN_WIDTH = 800
19SCREEN_HEIGHT = 600
20SCREEN_TITLE = "Sprite Tiled Map Example"
21SPRITE_PIXEL_SIZE = 128
22GRID_PIXEL_SIZE = SPRITE_PIXEL_SIZE * TILE_SCALING
23
24# How many pixels to keep as a minimum margin between the character
25# and the edge of the screen.
26VIEWPORT_MARGIN_TOP = 60
27VIEWPORT_MARGIN_BOTTOM = 60
28VIEWPORT_RIGHT_MARGIN = 270
29VIEWPORT_LEFT_MARGIN = 270
30
31# Physics
32MOVEMENT_SPEED = 5
33JUMP_SPEED = 23
34GRAVITY = 1.1
35
36
37class MyGame(arcade.Window):
38 """Main application class."""
39
40 def __init__(self):
41 """
42 Initializer
43 """
44 super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
45
46 # Tilemap Object
47 self.tile_map = None
48
49 # Sprite lists
50 self.player_list = None
51 self.wall_list = None
52 self.coin_list = None
53
54 # Set up the player
55 self.score = 0
56 self.player_sprite = None
57
58 self.physics_engine = None
59 self.end_of_map = 0
60 self.game_over = False
61 self.last_time = None
62 self.frame_count = 0
63
64 # Cameras
65 self.camera = None
66 self.gui_camera = None
67
68 # Text
69 self.fps_text = arcade.Text(
70 "",
71 x=10,
72 y=40,
73 color=arcade.color.BLACK,
74 font_size=14
75 )
76 self.distance_text = arcade.Text(
77 "0.0",
78 x=10,
79 y=20,
80 color=arcade.color.BLACK,
81 font_size=14,
82 )
83
84 def setup(self):
85 """Set up the game and initialize the variables."""
86
87 # Sprite lists
88 self.player_list = arcade.SpriteList()
89
90 # Set up the player
91 self.player_sprite = arcade.Sprite(
92 ":resources:images/animated_characters/female_person/femalePerson_idle.png",
93 scale=PLAYER_SCALING,
94 )
95
96 # Starting position of the player
97 self.player_sprite.center_x = 196
98 self.player_sprite.center_y = 270
99 self.player_list.append(self.player_sprite)
100
101 map_name = ":resources:/tiled_maps/map.json"
102
103 layer_options = {
104 "Platforms": {"use_spatial_hash": True},
105 "Coins": {"use_spatial_hash": True},
106 }
107
108 # Read in the tiled map
109 self.tile_map = arcade.load_tilemap(
110 map_name, layer_options=layer_options, scaling=TILE_SCALING
111 )
112 self.end_of_map = self.tile_map.width * GRID_PIXEL_SIZE
113
114 # Set wall and coin SpriteLists
115 self.wall_list = self.tile_map.sprite_lists["Platforms"]
116 self.coin_list = self.tile_map.sprite_lists["Coins"]
117
118 # --- Other stuff
119 # Set the background color
120 if self.tile_map.background_color:
121 self.background_color = self.tile_map.background_color
122
123 # Keep player from running through the wall_list layer
124 walls = [self.wall_list, ]
125 self.physics_engine = arcade.PhysicsEnginePlatformer(
126 self.player_sprite, walls, gravity_constant=GRAVITY
127 )
128
129 self.camera = arcade.camera.Camera2D()
130 self.gui_camera = arcade.camera.Camera2D()
131
132 # Center camera on user
133 self.pan_camera_to_user()
134
135 self.game_over = False
136
137 def on_draw(self):
138 """
139 Render the screen.
140 """
141
142 # This command has to happen before we start drawing
143 self.camera.use()
144 self.clear()
145
146 # Start counting frames
147 self.frame_count += 1
148
149 # Draw all the sprites.
150 self.player_list.draw()
151 self.wall_list.draw()
152 self.coin_list.draw()
153
154 # Activate GUI camera for FPS, distance and hit boxes
155 # This will adjust text position based on viewport
156 self.gui_camera.use()
157
158 # Calculate FPS if conditions are met
159 if self.last_time and self.frame_count % 60 == 0:
160 fps = round(1.0 / (time.time() - self.last_time) * 60)
161 self.fps_text.text = f"FPS: {fps:3d}"
162
163 # Draw FPS text
164 self.fps_text.draw()
165
166 # Get time for every 60 frames
167 if self.frame_count % 60 == 0:
168 self.last_time = time.time()
169
170 # Enable to draw hit boxes
171 # self.wall_list.draw_hit_boxes()
172 # self.wall_list_objects.draw_hit_boxes()
173
174 # Get distance and draw text
175 distance = self.player_sprite.right
176 self.distance_text.text = f"Distance: {distance}"
177 self.distance_text.draw()
178
179 # Draw game over text if condition met
180 if self.game_over:
181 arcade.draw_text(
182 "Game Over",
183 200,
184 200,
185 arcade.color.BLACK,
186 30,
187 )
188
189 def on_key_press(self, key, modifiers):
190 """
191 Called whenever a key is pressed.
192 """
193 if key == arcade.key.UP:
194 if self.physics_engine.can_jump():
195 self.player_sprite.change_y = JUMP_SPEED
196 elif key == arcade.key.LEFT:
197 self.player_sprite.change_x = -MOVEMENT_SPEED
198 elif key == arcade.key.RIGHT:
199 self.player_sprite.change_x = MOVEMENT_SPEED
200
201 def on_key_release(self, key, modifiers):
202 """
203 Called when the user presses a mouse button.
204 """
205 if key == arcade.key.LEFT or key == arcade.key.RIGHT:
206 self.player_sprite.change_x = 0
207
208 def on_update(self, delta_time):
209 """Movement and game logic"""
210
211 if self.player_sprite.right >= self.end_of_map:
212 self.game_over = True
213
214 # Call update on all sprites
215 if not self.game_over:
216 self.physics_engine.update()
217
218 coins_hit = arcade.check_for_collision_with_list(
219 self.player_sprite, self.coin_list
220 )
221 for coin in coins_hit:
222 coin.remove_from_sprite_lists()
223 self.score += 1
224
225 # Pan to the user
226 self.pan_camera_to_user(panning_fraction=0.12)
227
228 def pan_camera_to_user(self, panning_fraction: float = 1.0):
229 """ Manage Scrolling """
230
231 # This spot would center on the user
232 screen_center_x = self.player_sprite.center_x
233 screen_center_y = self.player_sprite.center_y
234 if screen_center_x - self.width/2 < 0:
235 screen_center_x = self.width/2
236 if screen_center_y - self.height/2 < 0:
237 screen_center_y = self.height/2
238 user_centered = screen_center_x, screen_center_y
239
240 self.camera.position = arcade.math.lerp_2d(self.camera.position, user_centered, panning_fraction)
241
242
243def main():
244 window = MyGame()
245 window.setup()
246 arcade.run()
247
248
249if __name__ == "__main__":
250 main()