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 将会一直存在。
- callback: 回调函数,带有 2 个参数:
- time: 当前对象的时间戳。
- delta: 上个更新周期距今的时间。
- 返回值: 如果该函数有返回值且为真,那么该任务将被保留至下一个更新周期。否则该任务会被删除。
setInterval(interval, times, period, start, callback)
为更新对象设定一个计时回调。设定开始后的每个period中,从start起将每隔interval触发一次callback,共计触发不超过times次。
至少带有 2 个参数interval和callback。从第三个参数起依次是times,period,start。
状态: 稳定。此 API 将会一直存在。
- interval: 每次执行回调的时间间隔。
- times: 每个周期中执行回调的次数,默认为
Infinity。 - period: 回调唤醒的一个周期,默认为
Infinity。 - start: 每个周期中回调触发的开始时间,默认为
0。 - callback: 回调函数,带有 4 个参数:
- time: 当前对象的时间戳。
- delta: 上个更新周期距今的时间。
- iCount: 当前 period 中的 interval 数,从
0开始计数。 - pCount: 当前的 period 数,从
0开始计数。
- 返回值: 一个实数,表示这个更新对象的编号。
removeInterval(id)
删除编号为 id 计时回调。
状态: 稳定。此 API 将会一直存在。
- id: 要删除的计时回调的编号。
- 返回值:
true|false,表示要删除的计时回调是否存在。
setTimeout(timeout, callback)
为更新对象设定一个定时回调。
状态: 稳定。此 API 将会一直存在。
- timeout: 下一次执行距离目前的时间。
- callback: 回调函数,带有 2 个参数:
- time: 当前对象的时间戳。
- delta: 上个更新周期距今的时间。
triggerEvent(event, ...args)
触发一个名为event的事件的回调函数。
状态: 实验。此 API 可能会更改语法或被取代。
- event: 事件的名称。
- args: 事件附带的参数表(一般情况下只有 0 或者 1 个)。
- 返回值: 这个事件的回调函数的返回值。
triggerEventOnce(event, ...args)
触发一个名为event的事件的回调函数。该函数仅会触发 1 次,触发结束后该回调函数将被删除。
状态: 实验。此 API 可能会更改语法或被取代。
- event: 事件的名称。
- args: 事件附带的参数表(一般情况下只有 0 或者 1 个)。
- 返回值: 这个事件的回调函数的返回值。
生命周期 Life Cycle
同更新周期类似,这里的任何对象都有一个生命周期。尽管生命周期的意义不如更新周期那么大,但是它也是一个非常基础的概念。为生命周期提供的支持目前仅有mounted()函数一个,在生命周期的其他阶段可以尝试使用 events 来解决。
1. create
这个阶段负责对象的构造和初始化工作。
2. mount
这个阶段负责对象的编组分配,图层的排列,与渲染器的绑定,时间戳和时间轴的初始化工作。这个阶段完成后会调用回调函数mounted()。这个函数的唯一一个参数是该对象的父对象。对于子弹和参考点来说这个父对象就是创建它们的弹幕对象,对于弹幕对象则没有这个参数。
3. update
这个阶段便是对象的更新周期,包括运动,渲染,触发各种事件等等都在这里进行。
4. destroy
这个阶段中对象将被解绑,从而最后离开页面。
弹幕 Barrage
弹幕对象是一个 brg 文件的基础。它管理了一段时间内一批子弹的总和。
new Barrage({reference, methods, mounted, mutate, events, listener})
构造一个新的弹幕对象。
状态: 稳定。此 API 将会一直存在。
- reference: 弹幕对象中涉及的参考点对象。
- methods: 要构造的弹幕对象的一些方法。
- mounted: 弹幕被挂载时触发的回调函数。
- mutate: 弹幕每个更新周期的回调函数。带有 2 个参数:
- time: 当前弹幕对象的时间戳。
- delta: 上个更新周期距今的时间。
- events: 弹幕遭遇事件的回调函数列表。
- listener: 为弹幕提供的监听器列表。
emitBullets(start, end, step, callback)
在当前弹幕中发射一批子弹。
至少带有 1 个参数callback。从第二个参数起依次是end,start,stop。
状态: 稳定。此 API 将会一直存在。
- start: 起始 index,默认值为
0。 - end: 终止 index,默认值为
1。 - step: 步长,默认值为
1。 - callback: 回调函数,参数是 index:
- index: 当前的循环变量。
- 返回值: 要创建的子弹对象。
- callback 也可以直接是子弹对象本身。
setReference(key, reference)
新建或覆盖一个名为key的参考点。
状态: 实验。此 API 可能会更改语法或被取代。
- key: 参考点的名字。
- reference: 参考点对象。也可以使用
null以删除原来的参考点。
类点 Pseudo-point
大部分时候我们为了处理方便,我们并不需要直接调用点对象的构造函数,而是采用类点来声明一个参考点或子弹,而由弹幕对象来负责对应参考点和子弹的 create 和 mount 流程。因此我们需要介绍一下类点的声明语法。
你可能在下列地方用到类点:
- Barrage 对象的 reference 声明中。
- Barrage 对象的 emitBullets 和 setReference 函数中。
类点是对象字面量,可以具有下列属性:
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 将会一直存在。
- point: 另一个点或坐标系对象,无论它们是否处于同一坐标系中。
getTheta(point)
获得当前点到另一个点的向量的幅角。
状态: 实验。此 API 可能会更改语法或被取代。
- point: 另一个点或坐标系对象,无论它们是否处于同一坐标系中。
movePolar(rho, theta)
将直角坐标中的点移动长度为rho,角度为theta的向量。
状态: 稳定。此 API 将会一直存在。
- rho: 要移动的向量的长度。默认为当前点的 rho 属性。
- theta: 要移动的向量的角度。默认为当前点的 theta 属性。
smooth(source, destination, progress)
将当前点控制在source和destination之间平滑地过渡。
状态: 实验。此 API 可能会更改语法或被取代。
- source: 起始点对象。
- destination: 终止点对象。
- progress: 一个 0 到 1 之间的参数,表明当前进度。
getGradient(color1, radius1, color2, radius2)
获得一种中心渐变色。
状态: 实验。此 API 可能会更改语法或被取代。
- color1: 第一种颜色。
- color2: 第二种颜色。
- radius1: 第一种颜色对应的半径。
- radius2: 第二种颜色对应的半径。
- 返回值: 一个渐变色对象,可用于颜色填充。
fillCircle(fill, radius)
状态: 实验。此 API 可能会更改语法或被取代。
- fill: 要填充的颜色,可以是颜色或者渐变,默认值为当前点的 color 属性。
- radius: 要填充区域的半径,默认值为当前点的 radius 属性。
emitBullets(start, end, step, callback)
在当前弹幕中发射一批子弹。语法同 Barrage 完全相同,这里就不再赘述了。
状态: 实验。此 API 可能会更改语法或被取代。
注意:用这个方法生成的子弹会和在弹幕对象中生成的子弹有一些不同,它会额外多一个名为 src 的参考点,即子弹诞生时当前点对象的位置。
copy()
生成当前点的一个坐标系实例。参考下面的“坐标系”章节。
状态: 实验。此 API 可能会更改语法或被取代。
坐标系 Coordinate
坐标系和点具有很多的共性。因此在程序的很多地方他们是可以互相转换的。那我们为什么还需要一个坐标系类呢?因为程序中我们的点都是动态的,但一个子弹被发射出去以后,我们更多地是希望它与它的发射源进行解耦,仅仅保留它诞生的坐标即可(不然发射源就会带着它的子弹跑了)。这时候,坐标系对象就能很好地帮助我们解决这个问题。因为坐标系对象是静态的,它没有更新周期。因此广泛地使用在子弹的参考点中,以实现自机狙等功能。事实上,每个子弹的 ref 都是静态点的列表。
坐标系对象有以下的方法:
resolve(x, y|point)
将当前坐标系中的点解释成绝对坐标。
状态: 实验。此 API 可能会更改语法或被取代。
- point: 如果只有 1 个参数,则读入一个当前坐标系中的点对象。
- x, y: 如果有 2 个参数,则读入当前坐标系中某个点的 x, y 坐标。
- 返回值: 一个 location 对象,即输入点的绝对坐标。
locate(x, y|point)
将任何坐标系中的点在该坐标系中进行定位。
状态: 实验。此 API 可能会更改语法或被取代。
- point: 如果只有 1 个参数,则读入一个任何坐标系中的点对象。
- x, y: 如果有 2 个参数,则读入某个点的 x, y 绝对坐标。
- 返回值: 一个 location 对象,即输入点在当前坐标系中的坐标。
位置 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 将会一直存在。
- rho: 要定位的点的极径。默认为当前点的 rho 属性。
- theta: 要定位的点的极角。默认为当前点的 theta 属性。
注意:如果此时的 rel 本身就含有 theta 属性,则极轴会默认指向 theta 方向。
drawTemplate(style)
调用内置的绘图函数。
状态: 实验。此 API 可能会更改语法或被取代。
- style: 绘图函数的样式。目前仅支持
'border'一种样式。
原生事件
- leave: 当子弹离开渲染区域过远时触发。
- border: 当子弹碰撞到屏幕边缘是触发。
- hitSelf: 当子弹命中自机时触发。
其他 Utility
Utility 库提供了其他的一些简单的 API,你可以使用下面的方法引入它:
const { Utility } = API
这个库提供了以下函数:
rgb(red, green, blue)
用三种颜色生成一个 rgb 字符串。
rgba(red, green, blue, alpha)
用三种颜色以及透明度生成一个 rgba 字符串。
状态: 不建议。此 API 可能处于即将弃用的状态或存在较大的问题。
- red: 红色系数。
- green: 绿色系数。
- blue: 蓝色系数。
- alpha: 透明度。
- 返回值: 一个 css 字符串。
注意:所有参数都应该是 0 到 1 之间的实数。
interval(period, previous, current)
判断previous和current两个时刻之间是否跨越了period周期。
状态: 实验。此 API 可能会更改语法或被取代。
- period: 周期长度。
- previous: 上一时刻。
- current: 下一时刻。
- 返回值:
true|false判断的结果。
smooth(x1, x2, t)
提供x1和x2两点间的一种较为平滑的过渡。
状态: 实验。此 API 可能会更改语法或被取代。
- x1: 起始值。
- x2: 终止值。
- t: 一个 0 到 1 之间的参数,表明当前进度。
- 返回值: t 参数下的 x 值。
rpm()
提供一个随机的正负 1。
状态: 实验。此 API 可能会更改语法或被取代。
- 返回值:
1|-1。
色彩 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, ...)
将color1,color2等颜色按照对应的prop进行混合,返回新的颜色。
最后一种颜色的prop可以缺省,默认为 1 减去之前的所有prop之和。
状态: 实验。此 API 可能会更改语法或被取代。
已经创建的 Color 实例拥有下面的方法:
blend(color, prop)
将当前颜色与color进行混合。
状态: 实验。此 API 可能会更改语法或被取代。
- color: 要混合的颜色。
- prop: 要混合颜色的占比,默认为 0.5。
- 返回值: 混合后的新颜色。
注意这个函数与
Color.blend()静态方法的区别。
lighter(scale)
将当前颜色变淡。
darker(scale)
将当前颜色变暗。
状态: 稳定。此 API 将会一直存在。
- scale: 变化的程度系数,为 0 到 1 之间的实数。设为 0 时没有变化,设为 1 时变为白色或黑色。默认为 0.5。
- 返回值: 变化后的新颜色。
inverse()
将当前颜色反色。此操作不会改变透明度。
状态: 实验。此 API 可能会更改语法或被取代。
- 返回值: 变化后的新颜色。
alpha(alpha)
设置颜色的不透明度。
opacify(scale)
将当前颜色变得更不透明。
transparentize(scale)
将当前颜色变得更透明。
状态: 实验。此 API 可能会更改语法或被取代。
- alpha: 要设置的不透明度,为 0 到 1 之间的实数,默认为 0.5。
- scale: 变化的程度系数,为 0 到 1 之间的实数。设为 0 时没有变化,设为 1 时完全透明或不透明。默认为 0.5。
- 返回值: 变化后的新颜色。