RenPy中文空间

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 184|回复: 0

精灵(sprite)(新)

 关闭 [复制链接]
发表于 2018-5-21 09:37:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
精灵(sprite)(翻译:被诅咒的章鱼)

为了满足同时显示大量图像的需求,Ren’Py支持精灵(sprite)系统。这个系统允许用户创建精灵,每个精灵包含一个可视组件。精灵可以拥有自身的界面坐标和垂直顺序改变。

如果不在乎系统性能的话,精灵系统的概念类似于 Fixed()Transform() 的结合。精灵的运行速度比变换(transform)快,但是扩展性比较低。精灵系统最大的性能提升方法是,每一帧中每个可视组件只渲染一次。精灵的限制是只能修改自身的xoffset和yoffset值,而不像变换(transform)有许多特性(property)可以修改。

使用那个精灵系统之前,需要先创建一个 SpriteManager 对象,然后调用它的 create 方法创建新的粒子(particle)。根据需要,更新每个精灵的 xoffset、yoffset 和 zorder 域,就能让精灵在界面内移动。通过把 update 和 event 入参应用于 SpriteManager,创作者能根据时间调整精灵,并对用户输入做出响应。

Sprite类

class Sprite
    这表示一个被 SpriteManager 类管理下的精灵(sprite)。其包含的字段(field)控制精灵在界面的位置。精灵不能直接创建,而是调用 SpriteManager.create()

    Sprite对象的字段(field)如下:

    x, y
        精灵左上角为原点的x和y轴坐标值,与SpriteManager相关。

    zorder
        一个整数值,控制SpriteManager中所有精灵叠放顺序。这个数值越大,对应精灵距离观看者(viewer)越近。

    events
        若为 True,事件消息会传给子组件。若为 False,也是默认值,子组件忽略所有事件消息(并屏蔽事件消息以免浪费时间处理)。

    Sprite 对象含有如下的方法:

    destroy(self)
        销毁该精灵,防止其再次显示,并从 SpriteManager 中移除。

    set_child(d)
        将可视组件与精灵 d 关联。

class SpriteManager(update=None, event=None, predict=None, ignore_time=False, **properties)
    这是个管理一组精灵的可视组件,并尽可能快地把所有精灵显示出来。

    update
        若非 None,每次 SpriteManager 渲染某个精灵都会调用的函数。调用时带一个入参,值是从 SpriteManager 第一次显示后的时间长度,单位为秒。返回值一般是该函数再次被调用以及 SpriteManager 再次被渲染的时间间隔,单位为 秒。

    event
        若非None,当某个事件发生时会调用的函数。其使用以下事件消息作为入参:

  •   某个 pygame 事件对象。
  •   事件的 x坐标 调整。
  •   事件的 y坐标 调整。
  •   从 SpriteManager 第一次显示开始计算的时间。

        如果该函数返回了一个非空值,互动结束时将这个值返回。

    predict
        若非 None,该函数返回一个可视组件列表。These displayables are predicted when the sprite manager is.

    ignore_time
        若为True,渲染可视组件时忽略的时间。当 SpriteManager 使用了一些数量不大的图像,并且这些图像不会变化时,才应该使用这项值。使用这项值的可视组件数量不能多,因为使用后的可视组件在 SpriteManager 对象的整个生命周期内,会一直保留在内存中。

    在首次渲染后(在 update 函数调用前),SpriteManager 如有下列字段(field):

    width, height
  • SpriteManager 的宽度和高度,单位为像素。

    SpriteManager包含下列方法:

    create(d)
        为可视组件 d 创建一个新的精灵(Sprite),并添加到该 SpriteManager 中。

    redraw(delay=0)
        在 delay 秒后重绘该 SpriteManager。

SnowBlossom(d, count=10, border=50, xspeed=(20, 50), yspeed=(100, 200), start=0, fast=False, horizontal=False)
    雪花(snowblossom)效果可以让某个精灵(sprite)的多个实例在界面中上下左右移动。当某个精灵离开界面时,其会返回起始点。

    d
        用作精灵的可视组件。

    border
        界面边界(border)的尺寸。精灵会被看作处于界面内,除非它越出了边界。需要确保精灵不会突然消失。

    xspeed, yspeed
        精灵移动速度,分别对应水平和垂直方向。这可以是一个数值或者两个数值的元组。在后面那种情况,每个粒子(particle)的速度可以声明为两个值之间的随机数。速度可以是整数或负数,只要保证后面的数值比前面的大。

    start
        每添加一个粒子(particle),延迟的时间,单位为秒。这项值允许粒子从界面顶部出发,跟 “wave” 效果不同。

    fast
        若为 True,粒子从界面中心出发,而不是界面四边。

    horizontal
        若为 True,粒子在界面的左右两边出现,而不是上下两边。

Sprite样例
SnowBlosson类是在界面内放置掉落物体的易用办法。
[RenPy] 纯文本查看 复制代码
image snow = SnowBlossom("snow.png", count=100)

这个样例展示了如何使用一个SpriteManager创建复杂行为。在这个例子中,总共显示了400个粒子,并让粒子避开鼠标。
[RenPy] 纯文本查看 复制代码
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

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|RenPy中文空间 ( 苏ICP备17067825号 | 苏公网安备 32092302000068号 )

GMT+8, 2018-12-19 07:56 , Processed in 0.027581 second(s), 21 queries , File On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表