目录
Timer
Package | laya.utils |
类 | public class Timer |
Inheritance | Timer Object |
Timer 是时钟管理类,它是一个单例,不要手动实例化此类,应该通过 Laya.timer 访问。
Property(属性) |
---|
currFrame : int = 0 ,当前的帧数。 |
currTimer : Number ,当前帧开始的时间。 |
delta : int ,[read-only] 两帧之间的时间间隔,单位毫秒。 |
scale : Number = 1 ,时针缩放。 |
Method(方法) |
---|
callLater(caller:*, method:Function, args:Array = null):void ,延迟执行。 |
clear(caller:*, method:Function):void ,清理定时器。 |
clearAll(caller:*):void ,清理对象身上的所有定时器。 |
frameLoop(delay:int, caller:*, method:Function, args:Array = null, coverBefore:Boolean = true):void ,定时重复执行(基于帧率)。 |
frameOnce(delay:int, caller:*, method:Function, args:Array = null, coverBefore:Boolean = true):void ,定时执行一次(基于帧率)。 |
loop(delay:int, caller:*, method:Function, args:Array = null, coverBefore:Boolean = true, jumpFrame:Boolean = false):void 定时重复执行。 |
once(delay:int, caller:*, method:Function, args:Array = null, coverBefore:Boolean = true):void ,定时执行一次。 |
pause():void ,暂停时钟 |
resume():void ,恢复时钟 |
runCallLater(caller:*, method:Function):void ,立即执行 callLater 。 |
runTimer(caller:*, method:Function):void ,立即提前执行定时器,执行之后从队列中删除 |
编码示例
callLater 延迟调用
/**延迟执行一次
* @param caller 执行域(this)。
* @param method 定时器回调函数——只会执行一次
* @param args 回调参数。
*/
callLater(caller: any, method: Function, args?: Array<any>): void;
实现上述效果有很多的方式,这里以使用 callLater 函数为例进行说明。为 label 绑定单击事件,每点击一次label,则调用一次 callLater 方法,callLater 函数会执行一次自己的回调函数,在回调函数中修改 label 的透明度 alpha。
纯粹是为了演示用法,这个需求并不适合使用 callLater 函数,实现代码如下:
(function () {
Laya.init(1080, 1920, Laya.WebGL);//初始化引擎,不支持WebGL时自动切换至Canvas
Laya.stage.bgColor = "#252525";
/**创建一个 label*/
var label_info = createLabel("alpha=1");
label_info.pos(250, 20);//组建显示的位置
/**为label绑定单击事件 */
label_info.on(Laya.Event.CLICK, this, function () {
/**callLater:延迟执行,调用会马上执行其回调函数 */
Laya.timer.callLater(this, animation, []);
/**无论循环多次,callLater 也只会执行一次 animation ;只有下次点击进入时才会再次执行*/
/* for (let i = 0; i < 10; i++) {
Laya.timer.callLater(this, animation, []);
} */
});
/** alpha_flag:为 true 时,label 的alpha值减小;为 false 时,label 的alpha值增加;*/
var alpha_flag = true;
function animation() {
if (alpha_flag) {
/**alpha:透明度,值为0-1,默认值为1,表示不透明 */
label_info.alpha -= 0.2;
} else {
label_info.alpha += 0.2;
}
alpha_flag = label_info.alpha <= 0.1 ? false : alpha_flag;
alpha_flag = label_info.alpha >= 1 ? true : alpha_flag;
/**改变label的文本值
* Number 的 toFixed 用于设置小数点位数,会四舍五入*/
label_info.text = "alpha=" + label_info.alpha.toFixed(2);
}
//创建一个标签并添加到舞台
function createLabel(message) {
var label = new Laya.Label(message);
label.fontSize = 30;//文本的字体大小
label.color = "#fff";//文本颜色
Laya.stage.addChild(label);//添加到舞台显示
return label;
}
})();
官网 demo:https://layaair.ldc.layabox.com/demo2/?language=ch&category=2d&group=Timer&name=CallLater
延迟执行
/**
* 定时执行一次。
* @param delay 延迟时间(单位为毫秒)。
* @param caller 执行域(this)。
* @param method 定时器回调函数。
* @param args 回调参数。
* @param coverBefore 是否覆盖之前的延迟执行,默认为 true 。
*/
once(delay: number, caller: any, method: Function, args?: Array<any>, coverBefore?: boolean): void;
/**
* 定时执行一次(基于帧率)。
* @param delay 延迟几帧(单位为帧)。
* @param caller 执行域(this)。
* @param method 定时器回调函数。
* @param args 回调参数。
* @param coverBefore 是否覆盖之前的延迟执行,默认为 true 。
*/
frameOnce(delay: number, caller: any, method: Function, args?: Array<any>, coverBefore?: boolean): void;
实现代码如下:
(function () {
Laya.init(1080, 1920, Laya.WebGL);//初始化引擎,不支持WebGL时自动切换至Canvas
Laya.stage.bgColor = "#252525";
/**创建 label*/
var label_info = createLabel("点我0.5秒后执行");
var label_show = createLabel("点我30帧后执行");
label_info.pos(100, 20);//组建显示的位置
label_show.pos(400, 20);//组建显示的位置
/**为label绑定单击事件 */
var isLeft = false;
label_info.on(Laya.Event.CLICK, this, function () {
/**once在延迟指定时间后执行一次,单位为毫秒;如果多次调用 */
Laya.timer.once(500, this, function () {
if (isLeft) {
label_info.x = label_info.x + 50;
label_info.color = "#fff";
isLeft = false;
} else {
label_info.x = label_info.x - 50;
label_info.color = "#ff0";
isLeft = true;
}
});
});
/**为label绑定单击事件 */
var isRight = false;
label_show.on(Laya.Event.CLICK, this, function () {
/**frameOnce:基于帧率,在指定延迟后执行一次回调函数 */
Laya.timer.frameOnce(30, this, function () {
if (isRight) {
label_show.x = label_show.x - 50;
label_show.alpha = 1;
isRight = false;
} else {
label_show.x = label_show.x + 50;
label_show.alpha = 0.5;
isRight = true;
}
});
});
//创建一个标签并添加到舞台
function createLabel(message) {
var label = new Laya.Label(message);
label.fontSize = 30;//文本的字体大小
label.color = "#fff";//文本颜色
Laya.stage.addChild(label);//添加到舞台显示
return label;
}
})();
官网 demo:https://layaair.ldc.layabox.com/demo2/?language=ch&category=2d&group=Timer&name=DelayExcute
间隔循环
/**
* 定时重复执行。
* @param delay 间隔时间(单位毫秒)。
* @param caller 执行域(this)。
* @param method 定时器回调函数。
* @param args 回调参数。
* @param coverBefore 是否覆盖之前的延迟执行,默认为 true 。
* @param jumpFrame 时钟是否跳帧。基于时间的循环回调,单位时间间隔内,如能执行多次回调,出于性能考虑,引擎默认只执行一次,设置jumpFrame=true后,则回调会连续执行多次
*/
loop(delay: number, caller: any, method: Function, args?: Array<any>, coverBefore?: boolean, jumpFrame?: boolean): void;
/**
* 定时重复执行(基于帧率)。
* @param delay 间隔几帧(单位为帧)。
* @param caller 执行域(this)。
* @param method 定时器回调函数。
* @param args 回调参数。
* @param coverBefore 是否覆盖之前的延迟执行,默认为 true 。
*/
frameLoop(delay: number, caller: any, method: Function, args?: Array<any>, coverBefore?: boolean): void;
实现代码如下:
(function () {
Laya.init(1080, 1920, Laya.WebGL);//初始化引擎,不支持WebGL时自动切换至Canvas
Laya.Stat.show(0, 0);/**显示性能统计面板 */
Laya.stage.bgColor = "#252525";
/**创建 label*/
var label_info = createLabel("I am Loop");
var label_show = createLabel("I am frameLoop");
label_info.pos(Laya.Browser.clientWidth, 20);//组建显示的位置
label_show.pos(Laya.Browser.clientWidth, 80);//组建显示的位置
/**loop:定时重复执行(基于时间,单位为毫秒)
* frameLoop:定时重复执行(基于帧率)*/
Laya.timer.loop(40, this, animation_loop);
Laya.timer.frameLoop(2, this, animation_frameLoop);
function animation_loop() {
label_info.x -= 2;
if (label_info.x + label_info.width < 0) {
label_info.x = Laya.Browser.clientWidth;
}
}
function animation_frameLoop() {
label_show.x -= 2;
if (label_show.x + label_show.width < 0) {
label_show.x = Laya.Browser.clientWidth;
}
}
//创建一个标签并添加到舞台
function createLabel(message) {
var label = new Laya.Label(message);
label.fontSize = 30;//文本的字体大小
label.color = "#fff";//文本颜色
Laya.stage.addChild(label);//添加到舞台显示
return label;
}
})();
时钟暂停与恢复
/**
* 暂停时钟————暂停所有 Timer
*/
pause(): void;
/**
* 恢复时钟————恢复所有 Timer
*/
resume(): void;
实现代码如下:
(function () {
Laya.init(1080, 1920, Laya.WebGL);//初始化引擎,不支持WebGL时自动切换至Canvas
Laya.Stat.show(0, 0);/**显示性能统计面板 */
Laya.stage.bgColor = "#252525";
/**创建 label*/
var label_info = createLabel("I am Loop");
var label_show = createLabel("I am frameLoop");
var label_btn = createLabel("定时器暂停");
label_info.pos(Laya.Browser.clientWidth, 20);//组件显示的位置
label_show.pos(Laya.Browser.clientWidth, 80);//组件显示的位置
label_btn.pos(Laya.Browser.clientWidth / 2, 150);//组件显示的位置
/**loop:定时重复执行(基于时间,单位为毫秒)
* frameLoop:定时重复执行(基于帧率)*/
Laya.timer.loop(40, this, animation_loop);
Laya.timer.frameLoop(2, this, animation_frameLoop);
function animation_loop() {
label_info.x -= 2;
if (label_info.x + label_info.width < 0) {
label_info.x = Laya.Browser.clientWidth;
}
}
function animation_frameLoop() {
label_show.x -= 2;
if (label_show.x + label_show.width < 0) {
label_show.x = Laya.Browser.clientWidth;
}
}
var isStop = false;
label_btn.on(Laya.Event.CLICK, this, function () {
if (isStop) {
Laya.timer.resume();/**恢复时钟 */
label_btn.text = "定时器运行";
label_btn.color = "#fff";
isStop = false;
} else {
Laya.timer.pause();/**暂停时钟 */
label_btn.text = "定时器暂停";
label_btn.color = "#f00";
isStop = true;
}
});
//创建一个标签并添加到舞台
function createLabel(message) {
var label = new Laya.Label(message);
label.fontSize = 30;//文本的字体大小
label.color = "#fff";//文本颜色
Laya.stage.addChild(label);//添加到舞台显示
return label;
}
})();
结束定时器
/**
* 清理定时器。
* @param caller 执行域(this)。——定时器与 clear 必须是同一个对象
* @param method 定时器回调函数。——定时器回调函数的名称
*/
clear(caller: any, method: Function): void;
/**
* 清理对象身上的所有定时器。
* @param caller 执行域(this)。——定时器与 clear 必须是同一个对象
*/
clearAll(caller: any): void;
对于在某个时刻需要清理/结束的定时器,在指定定时器与清理定时时,执行域都指定为 Laya.stage,而不再是 this。
实现代码如下:
(function () {
Laya.init(1080, 1920, Laya.WebGL);//初始化引擎,不支持WebGL时自动切换至Canvas
Laya.Stat.show(0, 0);/**显示性能统计面板 */
Laya.stage.bgColor = "#252525";
/**创建 label*/
var label_info = createLabel("I am Loop");
var label_show = createLabel("I am frameLoop");
var label_btn = createLabel("结束第1个定时器");
var label_btn_2 = createLabel("结束第所有定时器");
label_info.pos(Laya.Browser.clientWidth, 20);//组件显示的位置
label_show.pos(Laya.Browser.clientWidth, 80);//组件显示的位置
label_btn.pos(Laya.Browser.clientWidth / 4, 150);//组件显示的位置
label_btn_2.pos(Laya.Browser.clientWidth * (2 / 3), 150);//组件显示的位置
/**loop:定时重复执行(基于时间,单位为毫秒)
* frameLoop:定时重复执行(基于帧率)
* 对于将来某个时刻需要清理的定时器,执行域设置为 Laya.stage,清理时的执行域也是 Laya.stage,如果使用 this,则定时器会结束不了*/
Laya.timer.loop(40, Laya.stage, animation_loop);
Laya.timer.frameLoop(2, Laya.stage, animation_frameLoop);
function animation_loop() {
label_info.x -= 2;
if (label_info.x + label_info.width < 0) {
label_info.x = Laya.Browser.clientWidth;
}
}
function animation_frameLoop() {
label_show.x -= 2;
if (label_show.x + label_show.width < 0) {
label_show.x = Laya.Browser.clientWidth;
}
}
label_btn.on(Laya.Event.CLICK, this, function () {
/**清理指定的定时器,通过函数名确定
* 清理定时器同样执行域为 Laya.stage */
Laya.timer.clear(Laya.stage, animation_loop);
});
label_btn_2.on(Laya.Event.CLICK, this, function () {
/**清理对象身上的所有定时器
* 清理定时器同样执行域为 Laya.stage */
Laya.timer.clearAll(Laya.stage);
});
//创建一个标签并添加到舞台
function createLabel(message) {
var label = new Laya.Label(message);
label.fontSize = 30;//文本的字体大小
label.color = "#fff";//文本颜色
Laya.stage.addChild(label);//添加到舞台显示
return label;
}
})();
当一个对象的生命周期结束时,记得清除其内部的Timer。
优化策略
1、不要在 Timer 的循环里创建对象及复杂计算。
2、由于Timer的loop()与frameLoop()方法里会不断的循环执行,当创建对象及复杂计算时,会导致大量的性能消耗出现在循环里,因此尽可能不要在循环里创建对象及复杂计算。