优化实体是分层策略的核心。对实体进行分层,使得渲染策略可以被采用。通常,优化技术会试图消除开销。正如表 1所述,由于引入了层,您已经增加了内存开销。这里讨论的优化技术将减少处理器为了加快游戏而必须执行的大量工作。我们的目标是寻找一种减少要渲染的空间量的方法,并尽可能多地删除每一步中出现的渲染和清除调用。
第一个优化方法针对的是清除空间,通过只清除组成该实体的屏幕子集来加快处理。首先减少与区域的各实体周围的透明像素重叠的重绘区域量。使用此技术的包括相对较小的实体,它们填充了视区的小区域。
第一个目标是球和障碍物实体。单一实体清除技术涉及到在将实体渲染到新位置之前清除前一帧渲染该实体的位置。我们会引入一个清除步骤到每个实体的渲染,并存储实体的图像的边界框。添加该步骤会修改实体对象,以包括清除步骤,如清单 5所示。
render函数的更新引入了一个常规drawImage之前发生的clearRect调用。对于该步骤,对象需要存储前一个位置。图 6显示了对象针对前一个位置所采取的步骤。
您可以为每个实体创建一个在更新步骤前被调用的clear方法,实现此渲染解决方案(但本文将不会使用clear方法)。您还可以将这个清除策略引入到PanningEntity,在地面和云实体上添加清除,如清单 6所示。
因为PanningEntity横跨了整个视区,所以您可以使用画布宽度作为清除矩形的大小。如果使用此清除策略,则会为您提供已为云、小山和地面实体定义的重绘区域。
为了进一步优化云实体,可以将云分离为单独的实体,使用它们自己的重绘区域。这样做会大幅减少在云重绘区域内要清除的屏幕空间量。图 7显示了新的重绘区域。
单一实体清除策略产生的解决方案可以解决像本例这样的分层画布游戏上的大多数问题,但仍然可以对它进行优化。为了寻找针对该渲染策略的极端情况,我们假设球会与三角形碰撞。如果两个实体碰撞,实体的重绘区域就有可能发生重叠,并创建一个不想要的渲染构件。另一个清除优化,更适合于可能会碰撞的实体,它也将有益于分层。
若没有单一清除策略,脏矩形清除策略可以是一个功能强大的替代品。您可以对有重绘区域的大量实体使用这种清除策略,这种实体包括密集的粒子系统,或有小行星的空间游戏。
从概念上讲,该算法会收集由算法管理的所有实体的重绘区域,并在一个清除调用中清除整个区域。为了增加优化,此清除策略还会删除每个独立实体产生的重复清除调用,如清单 7所示。
将脏矩形算法集成到渲染循环,这要求在进行渲染调用之前调用清单 7中的管理器。将实体添加到管理器,使管理器可以在清除时计算清除矩形的维度。虽然管理器会产生预期的优化,但根据游戏循环,管理器能够针对游戏循环进行优化,如图 8所示。
帧 1 – 实体在碰撞,几乎重叠。
帧 2 – 实体重绘区域是重叠的。
帧 3 – 重绘区域重叠,并被收集到一个脏矩形中。
帧 4 – 脏矩形被清除。
图 8显示了由针对在交互层的实体的算法计算出的重绘区域。因为游戏在这一层上包含交互,所以脏矩形策略足以解决交互和重叠的重绘区域问题。
作为清除的重写
对于在恒定重绘区域中动画的完全不透明实体,可以使用重写作为一项优化技术。将不透明的位图渲染为一个区域(默认的合成操作),这会将像素放在该区域中,不需要考虑该区域中的原始渲染。这个优化消除了渲染调用之前所需的清除调用,因为渲染会覆盖原来的区域。
通过在之前的渲染的上方重新渲染图像,重写可以加快地面实体。也可以通过相同的方式加快最大的层,比如背景。
通过减少每一层的重绘区域,您已经有效地为层和它们所包含的实体找到优化策略。
结束语
对画布进行分层是一个可以应用于所有交互式实时场景的优化策略。如果想利用分层实现优化,您需要通过分析场景的重绘区域来考虑场景如何重叠这些区域。一些场景是具有重叠的重绘区域的集合,可以定义层,因此它们是渲染分层画布的良好候选。如果您需要粒子系统或大量物理对象碰撞在一起,对画布进行分层可能是一个很好的优化选择。