为了满足同时显示大量图像的需求,Ren’Py支持精灵(sprite)系统。这个系统允许用户创建精灵,每个精灵包含一个可视组件。精灵可以拥有自身的界面坐标和垂直顺序改变。
如果不在乎系统性能的话,精灵系统的概念类似于 Fixed()
与 Transform()
的结合。 精灵的运行速度比变换(transform)快,但是扩展性比较低。精灵系统最大的性能提升方法是,每一帧中每个可视组件只渲染一次。精灵的限制是只能修改自身的xoffset和yoffset值,而不像变换(transform)有许多特性(property)可以修改。
使用那个精灵系统之前,需要先创建一个SpriteManager对象,然后调用它的create方法创建新的粒子(particle)。根据需要,更新每个精灵的xoffset、yoffset和zorder域,就能让精灵在界面内移动。通过把 update 和 event 入参应用于SpriteManager,创作者能根据时间调整精灵,并对用户输入做出响应。
Sprite
link这表示一个被SpriteManager类管理下的精灵(sprite)。其包含的字段(field)控制精灵在界面的位置。精灵不能直接创建,而是调用 SpriteManager.create()
。
Sprite对象的字段(field)如下:
Sprite对象含有如下的方法:
destroy
(self) link销毁该精灵,防止其再次显示,并从SpriteManager中移除。
set_child
(d) link将可视组件与精灵 d 关联。
SpriteManager
(update=None, event=None, predict=None, ignore_time=False, **properties) link这是个管理一组精灵的可视组件,并尽可能快地把所有精灵显示出来。
若非None,当某个事件发生时会调用的函数。其使用以下事件消息作为入参:
如果该函数返回了一个非空值,互动结束时将这个值返回。
在首次渲染后(在 update 函数调用前),SpriteManager如有下列字段(field):
SpriteManager包含下列方法:
create
(d) link为可视组件 d 创建一个新的精灵(Sprite),并添加到该SpriteManager中。
redraw
(delay=0) link在 delay 秒后重绘该SpriteManager。
SnowBlossom
(d, count=10, border=50, xspeed=(20, 50), yspeed=(100, 200), start=0, fast=False, horizontal=False) link雪花(snowblossom)效果可以让某个精灵(sprite)的多个实例在界面中上下左右移动。当某个精灵离开界面时,其会返回起始点。
SnowBlosson类是在界面内放置掉落物体的易用办法。
image snow = SnowBlossom("snow.png", count=100)
这个样例展示了如何使用一个SpriteManager创建复杂行为。在这个例子中,总共显示了400个粒子,并让粒子避开鼠标。
init python:
import math
def repulsor_update(st):
# 如果我们不知道鼠标在哪里,先放弃获取鼠标信息
if repulsor_pos is None:
return .01
px, py = repulsor_pos
# 使用for循环检测每一个精灵……
for i in repulsor_sprites:
# 计算从精灵到鼠标的向量
vx = i.x - px
vy = i.y - py
# 计算向量长度,将向量归一化。
vl = math.hypot(vx, vy)
if vl >= 150:
continue
# 计算需要移动的距离
distance = 3.0 * (150 - vl) / 150
# 移动
i.x += distance * vx / vl
i.y += distance * vy / vl
# 确保停留在界面上。
if i.x < 2:
i.x = 2
if i.x > repulsor.width - 2:
i.x = repulsor.width - 2
if i.y < 2:
i.y = 2
if i.y > repulsor.height - 2:
i.y = repulsor.height - 2
return .01
# 收到事件消息时,记录鼠标的坐标。
def repulsor_event(ev, x, y, st):
store.repulsor_pos = (x, y)
label repulsor_demo:
python:
# 创建一个SpriteManager。
repulsor = SpriteManager(update=repulsor_update, event=repulsor_event)
repulsor_sprites = [ ]
repulsor_pos = None
# 确保只有一个可视组件smile。
smile = Image("smile.png")
# 添加400个精灵。
for i in range(400):
repulsor_sprites.append(repulsor.create(smile))
# 放置这400个精灵。
for i in repulsor_sprites:
i.x = renpy.random.randint(2, 798)
i.y = renpy.random.randint(2, 598)
del smile
del i
# 把repulsor添加到界面。
show expression repulsor as repulsor
"..."
hide repulsor
# 清理。
python:
del repulsor
del repulsor_sprites
del repulsor_pos