计时器用法
星火编辑器支 持使用计时器来实现等待逻辑和每隔一段时间重复执行的操作。
计时器的类型
等待
等待计时器有两种形式:『等待一段时间』和『等待一段时间后执行动作』,它们的效果和作用不完全一致。
『等待一段时间』 语句会阻塞后续的语句,也就是说,过了等待时间后才会执行后续逻辑。
输出结果为:
1
(过1秒后)
2
3
『等待一段时间后执行动作』 则不会阻塞后续语句,因为该语句是异步的。
输出结果为:
1
3
(过1秒后)
2
特别说明:等待0秒并非完全不等待,而是等待一帧,下一帧执行后续或回调函数内的逻辑。
每隔一段时间执行
顾名思义,执行该语句后, 每隔一段时间将会执行回调函数内的逻辑。该语句也不会阻塞,是异步逻辑。
这类定时器有两种语句:『每隔一段时间后执行动作』和『每隔一段时间后执行动作(限定次数)』。前者是无限循环的定时器,只要游戏还在运行,每隔一段时间一定会执行内部的函数;而后者会限定次数。
下面是一个计数器的案例:
输出结果为:(以下均为每隔1秒的输出)
1
2
3
4
5
操作计时器
计时器创建后,可以使用赋值语句赋值给一个变量,用面向对象的方法控制这个计时器的生命周期。
计时器面向对象的方法
此外,计时器之间也可以互相搭配使用,为游戏实现一些更有趣的逻辑,比如下方的例子:
计时器与协程的关系
在星火编辑器中,每一个触发器都是一个协程。『等待一段时间』 语句的本质是挂起当前触发器协程,过了规定的时间后再继续执行;而其他所有定时器语句都是在主线程执行的,和当前触发器协程无关。
由于目前星火编辑器的限制,在主线程中包裹协程会引发“cannot wrap coroutine by main thread”报错。这种报错常见于开发者在定时器的回调中进行了云变量操作,比如下方的案例:
运行上述触发语句将会在服务器底层抛出“cannot wrap coroutine by main thread”报错。
不难看出,该问题的解决方法是创建一个协程,在协程中执行云变量或其他包裹主线程的操作。这里给出如下两种方法,开发者可以任选其一:
- 采用函数创建触发器的语句,将云变量操作放到该函数中,并添加自定义事件处理,执行完毕后关闭该触发器。
- 新建一个单独的触发器,等待一段时间后发送自定义事件,执行完毕后关闭该触发器。
注:目前星火编辑器服务端主线程的日志在『信息面板-服务器底层』中,各协程的日志才会打印在『服务端日志』中。