第八步--收集硬币#
现在我们可以在比赛中完全移动了,我们需要给球员一个目标。电子游戏的一个经典目标是收集硬币,所以让我们继续添加这一点。
在这一章中,你将学习如何检查与我们的玩家的碰撞,并找出他们到底是什么碰撞,并对它做一些事情。现在我们只会在他们收集硬币的时候从屏幕上移除硬币,但在后面的章节中,我们会给角色一个分数,当他们收集硬币时,我们会增加分数。我们还将在稍后开始播放声音。
首先,我们将创建一个新的SpriteList来存放我们的硬币。就像我们的另一个墙精灵列表一样,继续向 __init__
函数来存储它,然后在 setup
功能。目前,我们希望为此列表启用空间散列。如果你决定使用移动硬币,你会想要关掉它。
# Inside __init__
self.coin_list = None
# Inside setup
self.coin_list = arcade.SpriteList(use_spatial_hash=True)
看看你能不能用我们已经学到的东西把硬币添加到SpriteList中。为他们提供的内置资源是 :resources:images/items/coinGold.png
。提示:就像我们处理盒子和地面一样,你会想要缩放这些东西。如果你被卡住了,你可以查看下面的完整源代码,看看我们是如何按照我们在地面上使用的相同模式放置它们的。
一旦您放置了硬币并将它们添加到 coin_list
,不要忘记将它们添加到 on_draw
。
self.coin_list.draw()
现在我们正在将硬币画到屏幕上,我们如何让它们与玩家交互?当玩家击球时,我们希望将其从屏幕上移除。要做到这一点,我们将使用 arcade.check_for_collision_with_list()
功能。该函数接受一个Sprite,在本例中是我们的玩家,还有一个SpriteList,对于我们来说是硬币。它将返回一个列表,其中包含给定SpriteList中与Sprite发生冲突的所有Sprite。
我们可以使用for循环迭代该列表,以对发生冲突的每个精灵执行某些操作。这意味着,如果我们将多个硬币放在一起,我们可以检测到用户一次点击多个硬币。
为了做到这一点,并在玩家击中硬币精灵时将其移除,我们将把这个添加到 on_update
功能。
coin_hit_list = arcade.check_for_collision_with_list(
self.player_sprite, self.coin_list
)
for coin in coin_hit_list:
coin.remove_from_sprite_lists()
我们用这个 arcade.BasicSprite.remove_from_sprite_lists()
函数,以确保我们的Sprite从它所属的所有SpriteList中完全删除。
源代码#
1"""
2Platformer Game
3
4python -m arcade.examples.platform_tutorial.08_coins
5"""
6import arcade
7
8# Constants
9SCREEN_WIDTH = 800
10SCREEN_HEIGHT = 600
11SCREEN_TITLE = "Platformer"
12
13# Constants used to scale our sprites from their original size
14TILE_SCALING = 0.5
15COIN_SCALING = 0.5
16
17# Movement speed of player, in pixels per frame
18PLAYER_MOVEMENT_SPEED = 5
19GRAVITY = 1
20PLAYER_JUMP_SPEED = 20
21
22
23class MyGame(arcade.Window):
24 """
25 Main application class.
26 """
27
28 def __init__(self):
29
30 # Call the parent class and set up the window
31 super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
32
33 # Variable to hold our texture for our player
34 self.player_texture = None
35
36 # Separate variable that holds the player sprite
37 self.player_sprite = None
38
39 # SpriteList for our player
40 self.player_list = None
41
42 # SpriteList for our boxes and ground
43 # Putting our ground and box Sprites in the same SpriteList
44 # will make it easier to perform collision detection against
45 # them later on. Setting the spatial hash to True will make
46 # collision detection much faster if the objects in this
47 # SpriteList do not move.
48 self.wall_list = None
49
50 # SpriteList for coins the player can collect
51 self.coin_list = None
52
53 # A variable to store our camera object
54 self.camera = None
55
56 def setup(self):
57 """Set up the game here. Call this function to restart the game."""
58 self.player_texture = arcade.load_texture(":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png")
59
60 self.player_sprite = arcade.Sprite(self.player_texture)
61 self.player_sprite.center_x = 64
62 self.player_sprite.center_y = 128
63
64 self.player_list = arcade.SpriteList()
65 self.player_list.append(self.player_sprite)
66
67 self.wall_list = arcade.SpriteList(use_spatial_hash=True)
68 self.coin_list = arcade.SpriteList(use_spatial_hash=True)
69
70 # Create the ground
71 # This shows using a loop to place multiple sprites horizontally
72 for x in range(0, 1250, 64):
73 wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=TILE_SCALING)
74 wall.center_x = x
75 wall.center_y = 32
76 self.wall_list.append(wall)
77
78 # Put some crates on the ground
79 # This shows using a coordinate list to place sprites
80 coordinate_list = [[512, 96], [256, 96], [768, 96]]
81
82 for coordinate in coordinate_list:
83 # Add a crate on the ground
84 wall = arcade.Sprite(
85 ":resources:images/tiles/boxCrate_double.png", scale=TILE_SCALING
86 )
87 wall.position = coordinate
88 self.wall_list.append(wall)
89
90 # Add coins to the world
91 for x in range(128, 1250, 256):
92 coin = arcade.Sprite(":resources:images/items/coinGold.png", scale=COIN_SCALING)
93 coin.center_x = x
94 coin.center_y = 96
95 self.coin_list.append(coin)
96
97 # Create a Platformer Physics Engine, this will handle moving our
98 # player as well as collisions between the player sprite and
99 # whatever SpriteList we specify for the walls.
100 # It is important to supply static to the walls parameter. There is a
101 # platforms parameter that is intended for moving platforms.
102 # If a platform is supposed to move, and is added to the walls list,
103 # it will not be moved.
104 self.physics_engine = arcade.PhysicsEnginePlatformer(
105 self.player_sprite, walls=self.wall_list, gravity_constant=GRAVITY
106 )
107
108 # Initialize our camera, setting a viewport the size of our window.
109 self.camera = arcade.camera.Camera2D()
110
111 self.background_color = arcade.csscolor.CORNFLOWER_BLUE
112
113 def on_draw(self):
114 """Render the screen."""
115
116 # Clear the screen to the background color
117 self.clear()
118
119 # Activate our camera before drawing
120 self.camera.use()
121
122 # Draw our sprites
123 self.player_list.draw()
124 self.wall_list.draw()
125 self.coin_list.draw()
126
127 def on_update(self, delta_time):
128 """Movement and Game Logic"""
129
130 # Move the player using our physics engine
131 self.physics_engine.update()
132
133 # See if we hit any coins
134 coin_hit_list = arcade.check_for_collision_with_list(
135 self.player_sprite, self.coin_list
136 )
137
138 # Loop through each coin we hit (if any) and remove it
139 for coin in coin_hit_list:
140 # Remove the coin
141 coin.remove_from_sprite_lists()
142
143 # Center our camera on the player
144 self.camera.position = self.player_sprite.position
145
146 def on_key_press(self, key, modifiers):
147 """Called whenever a key is pressed."""
148
149 if key == arcade.key.ESCAPE:
150 self.setup()
151
152 if key == arcade.key.UP or key == arcade.key.W:
153 if self.physics_engine.can_jump():
154 self.player_sprite.change_y = PLAYER_JUMP_SPEED
155
156 if key == arcade.key.LEFT or key == arcade.key.A:
157 self.player_sprite.change_x = -PLAYER_MOVEMENT_SPEED
158 elif key == arcade.key.RIGHT or key == arcade.key.D:
159 self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED
160
161 def on_key_release(self, key, modifiers):
162 """Called whenever a key is released."""
163
164 if key == arcade.key.LEFT or key == arcade.key.A:
165 self.player_sprite.change_x = 0
166 elif key == arcade.key.RIGHT or key == arcade.key.D:
167 self.player_sprite.change_x = 0
168
169
170def main():
171 """Main function"""
172 window = MyGame()
173 window.setup()
174 arcade.run()
175
176
177if __name__ == "__main__":
178 main()
运行本章#
python -m arcade.examples.platform_tutorial.08_coins