RenPy中文空间

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 322|回复: 0

[旧版] 粒子系统

 关闭 [复制链接]
发表于 2017-12-3 15:09:47 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 BuErShen 于 2017-12-9 16:35 编辑

粒子系统(Sprites)

为支持多图像的同时显示,RenPy支持粒子系统。该系统可生成粒子,每个粒子均可显示对象,之后粒子可再视屏中寻找位置并进行垂直规律性位移。

如果忽略性能的话,粒子系统在原理上类似与Fixed()与Transform()。粒子比Transform更快,但灵活度会有所降低。粒子的效果显著提升是由于每个可显示对象在一个画框中只进行一次描绘,即使该可显示对象被许多粒子使用,也是如此。限制就是粒子使得用户仅可以改变其x位移和y位移,不像变换那样有许多属性可以 更改。

在使用粒子系统时,首先创建一个SpriteManager对象,然后调用其创建方法来创建新的粒子。根据需要,更新每个精灵的xoffset,yoffset和zorder字段以在视屏上移动。你可以通过对SpriteManager进行参数更新来使粒子随着时间进行变化,并对玩家输入做出反应。

粒子类型(Sprite Classes)

class Sprite
指的是被粒子系统控制的粒子。包括控制粒子在视屏上位置的区域。粒子不能被直接生成,而要通过调用 SpriteManager.create() 来创建。

一个粒子作用区域:

x, y
粒子左上角的x和y坐标,相对于SpriteManager。

zorder
一个用来控制粒子在SpriteManager中顺序的整数,数字越大,粒子距离玩家的距离越近。
译注:靠近,层级上面

events
如果结果是True,项目被传送至child,如果为False,则child忽略事件(因此不需要花时间对其进行处理)。

创建粒子对象的方法是:

destroy(self)

破坏该粒子,阻止其进行显示,将其从SpriteManager移除。

set_child(d)
将与该粒子有关的可显示对象改变为d。

class SpriteManager(update=None, event=None, predict=None, ignore_time=False, **properties)

该可显示对象管理一定量的粒子,并尽可能快地显示这些粒子。

update
如果不是None,该粒子管理器每渲染一个粒子都调用一个函数。通过判据进行调用,即粒子管理器初次显示后的时间,以秒计算。当函数再次调用时,会反馈秒数,粒子管理器将再次渲染。

event
如果不是None,事件发生时将调用函数,它需要作为参数:*一个pygame事件对象。 *事件的x坐标。 *事件的y坐标。 *粒子管理器第一次显示的时间。 如果它返回非None值,则交互结束,并返回该值。

predict
如果不是None,则返回可显示列表的函数。这些可显示对象可以被预测。

ignore_time
如果是True,那么在描绘可显示对象时忽略时间。当粒子管理在于一些类类似的小型图像,同时使用且图像不会随时间改变时应如此使用。仅用于少量的可显示对象,因为它会终生保存所有可显示对象的粒子管理。

在首次被描绘后(在调用更新函数之前)

SpriteManagers作用区域:

width, height
该SpriteManager的宽度和高度是以像素为单位。

SpriteManagers 有以下方法:

create(d)
为可显示对象d创建一个新的粒子,并将该粒子加入到SpriteManager中。

redraw(delay=0)
使该SpriteManager在延迟秒数内重新绘制。

SnowBlossom(d, count=10, border=50, xspeed=(20, 50), yspeed=(100, 200), start=0, fast=False, horizontal=False)
雪花效应可以在视屏上将一个粒子向上、向下、向左或向右移动。当粒子离开视屏时,它会回到起点。

d
用于粒子的可显示对象。

border
视屏边界的尺寸。认为粒子在视屏内部,不能超过边界,保证粒子不会突然消失。

xspeed, yspeed
粒子分别在水平和垂直方向移动的速度。可以是一个单一的数字或两个数字的元组。如果是后者的话,每个粒子会被给定一个介于这两个数字之间的速度。速度可正可负,只要元组中第二个数字比第一个数字大即可。

start
在添加每个粒子前的数秒的延迟。可以使得粒子从视屏的最上方开始,而不像是一个波效应。

fast
如果为True,粒子从视屏的中央而不是边缘开始。

horizontal
如果为True,粒子从视屏的左边或右边而不是从上边或下边出现。

粒子示例

SnowBlossom是一种方便实用在视屏中放置降落物体的方法。
[RenPy] 纯文本查看 复制代码
image snow = SnowBlossom("snow.png", count=100)

该实例展示粒子管理如何应用于创建复杂动画。在这种情况下, 它展示了400个粒子,并且在不使用鼠标的情况下完成。

[RenPy] 纯文本查看 复制代码
init python:
    import math

    def repulsor_update(st):

        # 如果我们不知道鼠标在哪里就放弃。
        if repulsor_pos is None:
            return .01

        px, py = repulsor_pos

        # 对于每个粒子...
        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

            # Move
            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

    # 在event上,记录鼠标位置。
    def repulsor_event(ev, x, y, st):
        store.repulsor_pos = (x, y)


label repulsor_demo:

    python:
        # 创建一个粒子系统。
        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-8-17 15:15 , Processed in 0.027492 second(s), 21 queries , File On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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