API 文档

本文档提供了目前所有 API 的使用说明。

为了编写一个弹幕,你需要编辑一个 brg 文件。这个文件使用 JavaScript 作为脚本,文件将输出一个 Barrage 对象。在这个 Barrage 对象中,你不仅可以定义弹幕和子弹的配置,还可以精细地控制每一个子弹在每时每刻的行为。不过不用担心,我们也提供了丰富的 API,使得你可以非常方便地控制所有的一切。

提示:如果不加特殊说明,本文中所有的时间都以毫秒为单位,本文中的所有角度以 π 弧度为单位。

更新周期 Update Cycle

在我们的软件中,无论是子弹,自机,敌机还是整片的弹幕都是 UpdateObject,即更新对象。它通过更新周期来进行管理。了解对象的更新周期可以帮助我们充分地认识弹幕和子弹具有的特性,有利于避免失误和提高性能。

任何一个更新对象都包含下列形式的更新周期:

1. timestamp

这是一个更新周期的开始,对象的时间戳将被更新。

2. nextTick

这个阶段将完成对象的 nextTick 任务,比如子弹的destroy()方法的在弹幕对象中的回调等。它们可以通过setNextTick()函数来设置。

3. interval

这个阶段将完成对象的 interval 任务,举个例子,弹幕的周期性发射一般都在这里实现。它们可以通过setInterval()函数来设置。

4. mutate

这个阶段将执行mutate()回调函数,用户可以在这里进行子弹速度的更新,或者处理一些难以用setInterval()描述的任务。

5. listen

这个阶段将逐一判断对象的每一个监视器是否被触发。如果被触发了则会调用相应的回调函数。

6. display

这个阶段将完成对象的显示相关的任务,包括图形的渲染等。对于弹幕来说,其拥有的所有子弹的生命周期也将在这里进行一轮触发。

7. timeline

这是一个更新周期的结束,对象的时间轴将被更新。


一个更新对象本身具有下面的 API:

setNextTick(callback)
为更新对象的下个更新周期设定一个回调函数。

状态: 稳定。此 API 将会一直存在。


setInterval(interval, times, period, start, callback)
为更新对象设定一个计时回调。设定开始后的每个period中,从start起将每隔interval触发一次callback,共计触发不超过times次。
至少带有 2 个参数intervalcallback。从第三个参数起依次是timesperiodstart

状态: 稳定。此 API 将会一直存在。


removeInterval(id)
删除编号为 id 计时回调。

状态: 稳定。此 API 将会一直存在。


setTimeout(timeout, callback)
为更新对象设定一个定时回调。

状态: 稳定。此 API 将会一直存在。


triggerEvent(event, ...args)
触发一个名为event的事件的回调函数。

状态: 实验。此 API 可能会更改语法或被取代。


triggerEventOnce(event, ...args)
触发一个名为event的事件的回调函数。该函数仅会触发 1 次,触发结束后该回调函数将被删除。

状态: 实验。此 API 可能会更改语法或被取代。

生命周期 Life Cycle

同更新周期类似,这里的任何对象都有一个生命周期。尽管生命周期的意义不如更新周期那么大,但是它也是一个非常基础的概念。为生命周期提供的支持目前仅有mounted()函数一个,在生命周期的其他阶段可以尝试使用 events 来解决。

1. create

这个阶段负责对象的构造和初始化工作。

2. mount

这个阶段负责对象的编组分配,图层的排列,与渲染器的绑定,时间戳和时间轴的初始化工作。这个阶段完成后会调用回调函数mounted()。这个函数的唯一一个参数是该对象的父对象。对于子弹和参考点来说这个父对象就是创建它们的弹幕对象,对于弹幕对象则没有这个参数。

3. update

这个阶段便是对象的更新周期,包括运动,渲染,触发各种事件等等都在这里进行。

4. destroy

这个阶段中对象将被解绑,从而最后离开页面。

弹幕 Barrage

弹幕对象是一个 brg 文件的基础。它管理了一段时间内一批子弹的总和。

new Barrage({reference, methods, mounted, mutate, events, listener})
构造一个新的弹幕对象。

状态: 稳定。此 API 将会一直存在。

emitBullets(start, end, step, callback)
在当前弹幕中发射一批子弹。
至少带有 1 个参数callback。从第二个参数起依次是endstartstop

状态: 稳定。此 API 将会一直存在。

setReference(key, reference)
新建或覆盖一个名为key的参考点。

状态: 实验。此 API 可能会更改语法或被取代。

类点 Pseudo-point

大部分时候我们为了处理方便,我们并不需要直接调用点对象的构造函数,而是采用类点来声明一个参考点或子弹,而由弹幕对象来负责对应参考点和子弹的 create 和 mount 流程。因此我们需要介绍一下类点的声明语法。

你可能在下列地方用到类点:

类点是对象字面量,可以具有下列属性:

point.state
子弹或参考点的初始状态。其属性参见下面的介绍。
point.events
子弹或参考点的事件回调列表。同 Barrage 类似。
point.listener
子弹或参考点的监听器列表。同 Barrage 类似。
point.mounted
子弹或参考点的挂载回调函数。带有 1 个参数 barrage,即当前子弹或参考点所在的弹幕对象。
point.mutate
子弹或参考点的更新回调函数。带有 2 个参数 time 和 delta。同 Barrage 类似。
point.display
子弹或参考点的渲染函数。带有 2 个参数 time 和 delta。

注意:对于弹幕构造函数中参考点的mounted()函数,它的调用处于父对象的 create 阶段,因此其还没有和渲染器进行绑定,而子弹则没有这个问题。如果想要在参考点构造时访问渲染器或其他弹幕属性,可以使用setReference()函数。

下面的属性只能供子弹对象构造时使用:

point.layer
子弹的图层编号。渲染时图层号更大的子弹会出现在更上方;图层号相同的子弹,后构造的子弹出现在更上方。图层号的默认值为0

上述 state 中你可以写任何属性作为子弹或参考点对象的初始化,但是有一些属性是具有特殊含义的:

state.x
对象的 x 相对坐标,默认为0
state.y
对象的 y 相对坐标,默认为0
state.radius
对象的默认渲染半径和子弹的默认碰撞半径。被用于 display 函数和子弹碰撞事件中。如果你覆写了那些函数或者设定了 show 和 solid 属性为false,则这个参数不是必需的。
state.color
对象的默认渲染颜色。如果你覆写了 display 函数或将 show 属性设置为了false,则这个参数不是必需的。
state.show
对象是否显示。设置成false可以避免调用 display 函数。
state.face
对象的朝向。设置这个属性可以改变这个对象上建立的坐标系的旋转角度。

下面的属性仅供子弹对象构造时使用:

state.solid
子弹是否检测碰撞。设置成false可以避免调用一切系统默认的 hitSelf 事件,但它将不会阻止自定义碰撞事件的检测和触发。
state.rel
子弹所处坐标系。它是一个字符串,表示选取当前弹幕中哪一个 reference 作为坐标系。默认为'base'。如果找不到这个坐标系则默认使用 canvas 坐标系。除了在 reference 中定义的键以外,另一些键也是支持的,比如'self'自机坐标系等等。对于由点对象生成的子弹,它还有一个保留选项,即'src',表示生成它的坐标系。
state.style
子弹的样式。我们提供了一些内置的子弹样式,它们会改变子弹的默认事件,回调和渲染函数等,但它们的优先级仍然比用户定义的要低。设置 style 可以引入对应的子弹样式。

部分属性的使用依赖于其他的属性,另一些属性可以作为一些原生方法的默认属性,在此仅作简要的介绍:

state.rho
对象的极径,当使用了极坐标相关函数时是必需的。
state.theta
对象的极角,当使用了极坐标相关函数时是必需的。
state.bdColor
对象的边界颜色,当使用了'border'等样式时是必需的。
state.innerR
对象的外部半径,当使用了'border'等样式是是必需的。
state.glColor
对象的边界颜色,当使用了'glow'等样式时是必需的。
state.outerR
对象的外部半径,当使用了'glow'等样式是是必需的。

诸如此类的还有一些。我们将在样式部分继续介绍。

Point

点类是重要的基类,我们的自机,敌机,子弹,参考点都是点类下的对象。

我们为点对象提供了以下原生方法:

getDistance(point)
获得当前点到另一个点的距离。

状态: 稳定。此 API 将会一直存在。


getTheta(point)
获得当前点到另一个点的向量的幅角。

状态: 实验。此 API 可能会更改语法或被取代。


movePolar(rho, theta)
将直角坐标中的点移动长度为rho,角度为theta的向量。

状态: 稳定。此 API 将会一直存在。


smooth(source, destination, progress)
将当前点控制在sourcedestination之间平滑地过渡。

状态: 实验。此 API 可能会更改语法或被取代。


getGradient(color1, radius1, color2, radius2)
获得一种中心渐变色。

状态: 实验。此 API 可能会更改语法或被取代。


fillCircle(fill, radius)

状态: 实验。此 API 可能会更改语法或被取代。


emitBullets(start, end, step, callback)
在当前弹幕中发射一批子弹。语法同 Barrage 完全相同,这里就不再赘述了。

状态: 实验。此 API 可能会更改语法或被取代。

注意:用这个方法生成的子弹会和在弹幕对象中生成的子弹有一些不同,它会额外多一个名为 src 的参考点,即子弹诞生时当前点对象的位置。


copy()
生成当前点的一个坐标系实例。参考下面的“坐标系”章节。

状态: 实验。此 API 可能会更改语法或被取代。

坐标系 Coordinate

坐标系和点具有很多的共性。因此在程序的很多地方他们是可以互相转换的。那我们为什么还需要一个坐标系类呢?因为程序中我们的点都是动态的,但一个子弹被发射出去以后,我们更多地是希望它与它的发射源进行解耦,仅仅保留它诞生的坐标即可(不然发射源就会带着它的子弹跑了)。这时候,坐标系对象就能很好地帮助我们解决这个问题。因为坐标系对象是静态的,它没有更新周期。因此广泛地使用在子弹的参考点中,以实现自机狙等功能。事实上,每个子弹的 ref 都是静态点的列表。

坐标系对象有以下的方法:

resolve(x, y|point)
将当前坐标系中的点解释成绝对坐标。

状态: 实验。此 API 可能会更改语法或被取代。


locate(x, y|point)
将任何坐标系中的点在该坐标系中进行定位。

状态: 实验。此 API 可能会更改语法或被取代。

位置 Location

坐标系对象的一些方法会返回一个位置对象,用来描述一个点的坐标。位置对象是一个长度为 2 的数组,两个元素分别为坐标的 x 和 y 参数。除此以外,它还拥有下面的属性:

location.x = location[0]
当前点的 x 坐标。
location.y = location[1]
当前点的 y 坐标。
location.rho
当前点的距离原点的距离。
location.theta
当前点的在坐标系中的幅角。

子弹 Bullet

子弹类是点类的子类。子弹类额外增加了一些事件和方法:

destroy()
清除一枚子弹。

状态: 稳定。此 API 将会一直存在。


polarLocate(rho, theta)
将极径为rho,极角为theta的点定位到当前直角坐标。

状态: 稳定。此 API 将会一直存在。

注意:如果此时的 rel 本身就含有 theta 属性,则极轴会默认指向 theta 方向。


drawTemplate(style)
调用内置的绘图函数。

状态: 实验。此 API 可能会更改语法或被取代。

原生事件

其他 Utility

Utility 库提供了其他的一些简单的 API,你可以使用下面的方法引入它:

const { Utility } = API

这个库提供了以下函数:

rgb(red, green, blue)
用三种颜色生成一个 rgb 字符串。
rgba(red, green, blue, alpha)
用三种颜色以及透明度生成一个 rgba 字符串。

状态: 不建议。此 API 可能处于即将弃用的状态或存在较大的问题。

注意:所有参数都应该是 0 到 1 之间的实数。


interval(period, previous, current)
判断previouscurrent两个时刻之间是否跨越了period周期。

状态: 实验。此 API 可能会更改语法或被取代。


smooth(x1, x2, t)
提供x1x2两点间的一种较为平滑的过渡。

状态: 实验。此 API 可能会更改语法或被取代。


rpm()
提供一个随机的正负 1。

状态: 实验。此 API 可能会更改语法或被取代。

色彩 Color

Color 库提供了一些色彩相关的 API,你可以使用下面的方法引入它:

const { Color } = API

尽管 Color 是一个类,我们仍然建议使用 Color 的静态方法而不是构造函数来创建它的实例:

Color.rgba(red, green, blue, alpha)
创建一个 rgb 颜色,允许额外包含一个 alpha 不透明度属性。这里的参数均为 0 到 1 之间的实数。
Color.hsla(hue, saturation, lightness, alpha)
创建一个 hsl 颜色,允许额外包含一个 alpha 不透明度属性。这里的 hue 可以是任意角度,其他参数均为 0 到 1 之间的实数。
Color.hsva(hue, saturation, value, alpha)
创建一个 hsv 颜色,允许额外包含一个 alpha 不透明度属性。这里的 hue 可以是任意角度,其他参数均为 0 到 1 之间的实数。
Color.from(name)
创建一个名称为name的系统内置颜色。这里的name不区分大小写。
Color.hex(code)
创建一个十六进制代码为code的颜色。code的开头可以有一个#,也可以没有。code支持 3, 4, 6, 8 位颜色代码。不区分大小写。

状态: 实验。此 API 可能会更改语法或被取代。


除此以外,Color 库还有以下的静态方法:

Color.blend(color1, prop1, color2, prop2, ...)
color1color2等颜色按照对应的prop进行混合,返回新的颜色。
最后一种颜色的prop可以缺省,默认为 1 减去之前的所有prop之和。

状态: 实验。此 API 可能会更改语法或被取代。


已经创建的 Color 实例拥有下面的方法:

blend(color, prop)
将当前颜色与color进行混合。

状态: 实验。此 API 可能会更改语法或被取代。

注意这个函数与Color.blend()静态方法的区别。


lighter(scale)
将当前颜色变淡。
darker(scale)
将当前颜色变暗。

状态: 稳定。此 API 将会一直存在。


inverse()
将当前颜色反色。此操作不会改变透明度。

状态: 实验。此 API 可能会更改语法或被取代。


alpha(alpha)
设置颜色的不透明度。
opacify(scale)
将当前颜色变得更不透明。
transparentize(scale)
将当前颜色变得更透明。

状态: 实验。此 API 可能会更改语法或被取代。