高级SpriteList技术#
本页提供了高级技术的概述。不能保证可运行的示例,因为读者应该能够将工作投入到实现它们中。
初学者应该注意以下几个部分。如果使用不当,其中一些技术可能会降低您的游戏速度或使其崩溃。
绘图顺序排序(&S)#
在某些情况下,您可以结合SpriteList的两个功能:
默认情况下,SpriteList从其最低索引开始绘制。
SpriteList
有一个sort()
方法几乎与list.sort()
。
首先,考虑其他选择#
在Python中,排序是一个很慢的、受CPU限制的函数。考虑使用以下技术来消除或最小化此成本:
使用多个精灵列表或
arcade.Scene
实现分层将你的游戏世界分成更小的区域,每个区域都有精灵列表,只有当里面的东西移动或变化时才排序
使用
Sprite.depth
具有的属性 shaders 在GPU上排序的步骤
有关商业2D游戏中使用的组块的概念性概述,请参阅以下内容:
排序SpriteList#
尽管上面列出的替代方法通常更好,但对精灵列表进行排序以控制绘制顺序仍然很有用。
就像Python的内置功能 list.sort()
,您可以传递一个 callable object 通过key参数指定如何排序,以及可选的 reverse
关键字来反转排序方向。
下面是一个如何使用排序来快速创建低效原型的示例:
import random
import arcade
# Warning: the bottom property is extra slow compared to other attributes!
def bottom_edge_as_sort_key(sprite):
return sprite.bottom
class InefficientTopDownGame(arcade.Window):
"""
Uses sorting to allow the player to move in front of & behind shrubs
For non-prototyping purposes, other approaches will be better.
"""
def __init__(self, num_shrubs=50):
super().__init__(800, 600, "Inefficient Top-Down Game")
self.background_color = arcade.color.SAND
self.shrubs = arcade.SpriteList()
self.drawable = arcade.SpriteList()
# Randomly place pale green shrubs around the screen
for i in range(num_shrubs):
shrub = arcade.SpriteSolidColor(20, 40, color=arcade.color.BUD_GREEN)
shrub.position = random.randrange(self.width), random.randrange(self.height)
self.shrubs.append(shrub)
self.drawable.append(shrub)
self.player = arcade.SpriteSolidColor(16, 30, color=arcade.color.RED)
self.drawable.append(self.player)
def on_mouse_motion(self, x, y, dx, dy):
# Update the player position
self.player.position = x, y
# Sort the sprites so the highest on the screen draw first
self.drawable.sort(key=bottom_edge_as_sort_key, reverse=True)
def on_draw(self):
self.clear()
self.drawable.draw()
game = InefficientTopDownGame()
game.run()
自定义纹理图集#
A TextureAtlas
表示 Texture
视频内存中并排打包的数据。随着纹理的添加,贴图集会增长以将它们全部放入您的GPU内存的同一部分。
默认情况下,每个 SpriteList
使用相同的默认地图集。使用 atlas
关键字参数指定实例的自定义地图集。
这对于防止在使用大纹理或形状奇怪的纹理时出现问题特别有用。
有关更多信息,请参阅以下内容:
这个
TextureAtlas
API文档
懒惰精灵列表#
您可以延迟为 SpriteList
通过路过 lazy=True
关于创作:
sprite_list = SpriteList(lazy=True)
SpriteList不会创建OpenGL资源,除非受到以下任一条件的强制:
第一
SpriteList.draw()
呼唤它GPU支持的冲突(如果已启用
此行为在以下情况下最有用:
案例 |
主要目的 |
---|---|
在窗口前创建SpriteList |
仅限CPU unit tests 永远不会抽签 |
并行化SpriteList创建 |
通过以下方式实现更快的加载和世界生成 |
并行加载#
为了提高加载速度并减少游戏过程中的卡顿,您可以并行运行游戏前任务,例如预先生成地图或将资源从磁盘预先加载到RAM中。
警告
只允许主线程访问OpenGL!
尝试从非主线程访问OpenGL将引发OpenGL错误!
为了安全地实现并行加载,在允许游戏开始之前,您需要使用以下一般方法:
经过
lazy=True
在创建时SpriteList
如上所述,在加载代码中添加加载完成后,将SpriteList数据同步回主线程或进程
在主线程内部,调用
Spritelist.initialize()
在每个精灵列表上,一旦它准备好分配GPU资源
非常高级的用户可以使用 subprocess
在另一个进程中创建SpriteList,并且 pickle
模块来帮助将数据传回主进程。
有关其他信息,请参阅以下内容:
Arcade's OpenGL notes 对于特定于街机的线程注意事项
Python 的
threading
文件Python 的
subprocess
和pickle
文件