第3步-多款雪碧和SpriteList#
到目前为止,我们的游戏进行得很顺利,我们有一个角色出现在屏幕上!如果我们的角色有一个可以生活的世界,那不是很好吗?为了做到这一点,我们需要画更多的精灵。在本章中,我们将探索SpriteList,这是Arade提供的一次绘制大量Sprite的类。
最后,我们会得到这样的结果:

SpriteList#
arcade.SpriteList
存在以一次绘制所有精灵的集合。例如,假设您要绘制100,000个长方体雪碧。如果没有SpriteList,您将不得不将所有Sprite放到一个列表中,然后对调用 draw()
在每一个精灵身上。
这种方法表现得极为糟糕。相反,您可以将所有框添加到 arcade.SpriteList
然后绘制SpriteList。这样做,您可以绘制所有100,000个精灵,其成本与绘制一个精灵的成本大致相同。
备注
这是因为Arade是一个大量基于GPU的库。GPU真的很擅长分批处理。这意味着我们可以将有关精灵的所有信息发送到GPU,然后告诉它一次绘制所有精灵。然而,如果我们一次只画一个精灵,那么我们每次都必须从我们的CPU到我们的GPU进行往返。
即使只绘制一个Sprite,也应该为其创建SpriteList。除了小调试之外,绘制单个Sprite永远不会比将其添加到SpriteList更好。事实上,打电话给 draw()
在Sprite上,只需在内部创建一个SpriteList来绘制该Sprite。
让我们继续为我们的玩家在我们的 __init__
函数,并将玩家添加到其中。
self.player_list = arcade.SpriteList()
self.player_list.append(self.player_sprite)
然后在我们的 on_draw
函数,我们可以为角色绘制SpriteList,而不是直接绘制Sprite:
self.player_list.draw()
现在,让我们尝试为我们的角色构建一个世界。为此,我们将为要绘制的对象创建一个新的SpriteList,我们可以在 __init__
功能。
self.wall_list = arcade.SpriteList(use_spatial_hash=True)
在这段代码中有一些需要解包的地方。让我们来解决每个问题:
为什么不使用与我们的播放器相同的SpriteList,为什么将其命名为WALLS?
最终,我们需要在角色和这些对象之间进行碰撞检测。除了绘制之外,SpriteList还用作碰撞检测的实用程序。例如,您可以检查两个SpriteList之间的冲突,或将SpriteList传递到几个物理引擎中。我们将在后面的章节中探讨这些主题。
是什么
use_spatial_hash
?这也用于碰撞检测。空间散列是一种特殊的算法,它将使其性能更高,代价是移动精灵的成本更高。您经常会在预计不会移动太多的SpriteList上看到此选项,例如墙或楼板。
使用新创建的SpriteList,让我们继续向其中添加一些对象。我们可以将这些行添加到我们的 __init__
功能。
for x in range(0, 1250, 64):
wall = arcade.Sprite(":resources:images/tiles/grassMid.png", TILE_SCALING)
wall.center_x = x
wall.center_y = 32
self.wall_list.append(wall)
coordinate_list = [[512, 96], [256, 96], [768, 96]]
for coordinate in coordinate_list:
wall = arcade.Sprite(
":resources:images/tiles/boxCrate_double.png", scale=0.5
)
wall.position = coordinate
self.wall_list.append(wall)
在这些行中,我们将一些草和一些板条箱添加到SpriteList中。
对于地面,我们使用的是Python的 range
函数在X位置列表上迭代,这将给我们一条水平线的Sprite。对于这些框,我们将它们插入列表中的指定坐标。
我们还在做一些新的事情 arcade.Sprite
创造。首先,我们直接传递图像文件,而不是首先创建纹理。这最终是做同样的事情,我们只是不是自己管理纹理,而是让Arade来处理它。我们还为这些精灵增加了一个比例。为了好玩,你可以去掉刻度,看看图像会变得更大。
最后,为了绘制我们的新世界,我们所需要做的就是绘制墙的SpriteList on_draw
:
self.wall_list.draw()
源代码#
1"""
2Platformer Game
3
4python -m arcade.examples.platform_tutorial.03_more_sprites
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
15
16
17class MyGame(arcade.Window):
18 """
19 Main application class.
20 """
21
22 def __init__(self):
23
24 # Call the parent class and set up the window
25 super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
26
27 # Variable to hold our texture for our player
28 self.player_texture = arcade.load_texture(":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png")
29
30 # Separate variable that holds the player sprite
31 self.player_sprite = arcade.Sprite(self.player_texture)
32 self.player_sprite.center_x = 64
33 self.player_sprite.center_y = 128
34
35 # SpriteList for our player
36 self.player_list = arcade.SpriteList()
37 self.player_list.append(self.player_sprite)
38
39 # SpriteList for our boxes and ground
40 # Putting our ground and box Sprites in the same SpriteList
41 # will make it easier to perform collision detection against
42 # them later on. Setting the spatial hash to True will make
43 # collision detection much faster if the objects in this
44 # SpriteList do not move.
45 self.wall_list = arcade.SpriteList(use_spatial_hash=True)
46
47 # Create the ground
48 # This shows using a loop to place multiple sprites horizontally
49 for x in range(0, 1250, 64):
50 wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=0.5)
51 wall.center_x = x
52 wall.center_y = 32
53 self.wall_list.append(wall)
54
55 # Put some crates on the ground
56 # This shows using a coordinate list to place sprites
57 coordinate_list = [[512, 96], [256, 96], [768, 96]]
58
59 for coordinate in coordinate_list:
60 # Add a crate on the ground
61 wall = arcade.Sprite(
62 ":resources:images/tiles/boxCrate_double.png", scale=0.5
63 )
64 wall.position = coordinate
65 self.wall_list.append(wall)
66
67 self.background_color = arcade.csscolor.CORNFLOWER_BLUE
68
69 def setup(self):
70 """Set up the game here. Call this function to restart the game."""
71 pass
72
73 def on_draw(self):
74 """Render the screen."""
75
76 # Clear the screen to the background color
77 self.clear()
78
79 # Draw our sprites
80 self.player_list.draw()
81 self.wall_list.draw()
82
83
84def main():
85 """Main function"""
86 window = MyGame()
87 window.setup()
88 arcade.run()
89
90
91if __name__ == "__main__":
92 main()
的文档
arcade.SpriteList
班级
备注
一旦您准备好并运行了代码,请尝试以下操作:
看看是否可以使用SpriteList更改所有框和地面的颜色
尝试使SpriteList不可见
运行本章#
python -m arcade.examples.platform_tutorial.03_more_sprites