Cocos2dx 3.x Lua 中使用定时器有两种方式:
(1)self:scheduleUpdateWithPriorityLua(update, priority)
> 参数一:刷新函数
> 参数二:刷新优先级
其中 self 为 Node类 的子类。
该方法默认为每帧都刷新一次,无法自定义刷新时间间隔。
(2)scheduler:scheduleScriptFunc(update, inteval, false)
> 参数一:刷新函数
> 参数二:每次刷新的时间间隔
> 参数三:是否只执行一次。false为无限次。
其中 scheduler 为定时器管理:cc.Director:getInstance():getScheduler()
推荐使用第二种方式,因为比较通用。
在 引擎根目录/cocos/scripting/lua-bindings/script 的extern.lua文件中定义了 schedule 和 performWithDelay 两个函数:
function schedule(node, callback, delay)
local delay = cc.DelayTime:create(delay)
local sequence = cc.Sequence:create(delay, cc.CallFunc:create(callback))
local action = cc.RepeatForever:create(sequence)
node:runAction(action)
return action
end
function performWithDelay(node, callback, delay)
local delay = cc.DelayTime:create(delay)
local sequence = cc.Sequence:create(delay, cc.CallFunc:create(callback))
node:runAction(sequence)
return sequence
end
不难看出,这2个函数其实是用Action来实现了循环定时器和一次性回调定时器,按照这个思路也可以自己实现有限次调用的定时器
小结:以上方法提供的定时器是和Node相关的,因此当Node被移除出场景或者其他情况下,这类回调定时器将会被取消
如果要用到独立于Node的定时器,那么就要是用Scheduler的定时器函数了,
在引擎根目录/cocos/scripting/lua-bindings/manual的lua_cocos2dx_manual.cpp文件中定义了scheduleScriptFunc和unscheduleScriptEntry两个函数,分别用来加入和删除定时器:
例子代码如下:
local callbackEntry =nil
local function callback(dt)
cclog("callback")
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(callbackEntry)
end
callbackEntry = cc.Director:getInstance():getScheduler():scheduleScriptFunc(callback, 3, false)
其中scheduleScriptFunc的 scheduleScriptFunc)是返回值是一个定时器凭据,该凭据用于在需要删除对应的定时器时传入作为参数,正如上面的例子代码所示。
注意:定义的定时器,必须要删除,实例代码实现背景的滚动
滚动背景:
function SyMapScene:createBg()
local bg = cc.Sprite:create("map.png")
bg:setAnchorPoint(0,0)
bg:setPosition(0,0)
local bg2 = cc.Sprite:create("map.png")
bg2:setAnchorPoint(0,0)
bg2:setPosition(0, bg:getContentSize().height - 2)
local function bgMove()
bg:setPositionY(bg:getPositionY() - 1)
bg2:setPositionY(bg2:getPositionY() - 1)
if (bg:getPositionY() < - bg:getContentSize().height) then
bg:setPositionY(bg2:getPositionY() + bg2:getContentSize().height)
elseif (bg2:getPositionY() <- bg2:getContentSize().height) then
bg2:setPositionY(bg:getPositionY() + bg:getContentSize().height)
end
end
schedulerID = cc.Director:getInstance():getScheduler():scheduleScriptFunc(bgMove, 0, false)
return bg,bg2
end
必须在场景退出的时候删除,否则在场景切换到下一个场景的时候会报一下错误:
LUA ERROR: [string "SyMap.lua"]:37: invalid 'cobj' in function 'lua_cocos2dx_Node_getPositionY'
这是一个类似于空指针的错误,Node已经手动死亡之后依然会调用Node,定时调用依旧在生效即在调用。
场景退出的时候取消调用;
function SyMapScene:onExit()
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(schedulerID)
end
或者直接使用第一种调用方式:
self:scheduleUpdateWithPriorityLua(bgMove,0)
不必手动删除schedule的调用,在场景切换到下一个场景的时候不会报错。
二:关于 invalid 'cobj' in function 错误:
这是因为对一个Node调用其函数时其已经被GC了。
首先尝试手动控制Node的生命周期:
发现无效,原来有一个定时器在定时调用一个函数对Node进行处理:
littleMonsterBullet.schedulerID =cc.Director:getInstance():getScheduler():scheduleScriptFunc(tick_attack_hero,0, false)
Node已经手动死亡之后依然会调用Node
于是调用:littleMonsterBullet:unscheduleUpdate()
tyLua(update,priority)添加的schedule,这样unschedule是无效的。
最后只能:
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(littleMonsterBullet.schedulerID)
Cocos2dx 3.x Lua 中使用定时器有两种方式:
(1)self:scheduleUpdateWithPriorityLua(update, priority)
> 参数一:刷新函数
> 参数二:刷新优先级
其中 self 为 Node类 的子类。
该方法默认为每帧都刷新一次,无法自定义刷新时间间隔。
(2)scheduler:scheduleScriptFunc(update, inteval, false)
> 参数一:刷新函数
> 参数二:每次刷新的时间间隔
> 参数三:是否只执行一次。false为无限次。
其中 scheduler 为定时器管理:cc.Director:getInstance():getScheduler()
推荐使用第二种方式,因为比较通用。
在 引擎根目录/cocos/scripting/lua-bindings/script 的extern.lua文件中定义了 schedule 和 performWithDelay 两个函数:
function schedule(node, callback, delay)
local delay = cc.DelayTime:create(delay)
local sequence = cc.Sequence:create(delay, cc.CallFunc:create(callback))
local action = cc.RepeatForever:create(sequence)
node:runAction(action)
return action
end
function performWithDelay(node, callback, delay)
local delay = cc.DelayTime:create(delay)
local sequence = cc.Sequence:create(delay, cc.CallFunc:create(callback))
node:runAction(sequence)
return sequence
end
不难看出,这2个函数其实是用Action来实现了循环定时器和一次性回调定时器,按照这个思路也可以自己实现有限次调用的定时器
小结:以上方法提供的定时器是和Node相关的,因此当Node被移除出场景或者其他情况下,这类回调定时器将会被取消
如果要用到独立于Node的定时器,那么就要是用Scheduler的定时器函数了,
在引擎根目录/cocos/scripting/lua-bindings/manual的lua_cocos2dx_manual.cpp文件中定义了scheduleScriptFunc和unscheduleScriptEntry两个函数,分别用来加入和删除定时器:
例子代码如下:
local callbackEntry =nil
local function callback(dt)
cclog("callback")
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(callbackEntry)
end
callbackEntry = cc.Director:getInstance():getScheduler():scheduleScriptFunc(callback, 3, false)
其中scheduleScriptFunc的 scheduleScriptFunc)是返回值是一个定时器凭据,该凭据用于在需要删除对应的定时器时传入作为参数,正如上面的例子代码所示。
注意:定义的定时器,必须要删除,实例代码实现背景的滚动
滚动背景:
function SyMapScene:createBg()
local bg = cc.Sprite:create("map.png")
bg:setAnchorPoint(0,0)
bg:setPosition(0,0)
local bg2 = cc.Sprite:create("map.png")
bg2:setAnchorPoint(0,0)
bg2:setPosition(0, bg:getContentSize().height - 2)
local function bgMove()
bg:setPositionY(bg:getPositionY() - 1)
bg2:setPositionY(bg2:getPositionY() - 1)
if (bg:getPositionY() < - bg:getContentSize().height) then
bg:setPositionY(bg2:getPositionY() + bg2:getContentSize().height)
elseif (bg2:getPositionY() <- bg2:getContentSize().height) then
bg2:setPositionY(bg:getPositionY() + bg:getContentSize().height)
end
end
schedulerID = cc.Director:getInstance():getScheduler():scheduleScriptFunc(bgMove, 0, false)
return bg,bg2
end
必须在场景退出的时候删除,否则在场景切换到下一个场景的时候会报一下错误:
LUA ERROR: [string "SyMap.lua"]:37: invalid 'cobj' in function 'lua_cocos2dx_Node_getPositionY'
这是一个类似于空指针的错误,Node已经手动死亡之后依然会调用Node,定时调用依旧在生效即在调用。
场景退出的时候取消调用;
function SyMapScene:onExit()
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(schedulerID)
end
或者直接使用第一种调用方式:
self:scheduleUpdateWithPriorityLua(bgMove,0)
不必手动删除schedule的调用,在场景切换到下一个场景的时候不会报错。
二:关于 invalid 'cobj' in function 错误:
这是因为对一个Node调用其函数时其已经被GC了。
首先尝试手动控制Node的生命周期:
发现无效,原来有一个定时器在定时调用一个函数对Node进行处理:
littleMonsterBullet.schedulerID =cc.Director:getInstance():getScheduler():scheduleScriptFunc(tick_attack_hero,0, false)
Node已经手动死亡之后依然会调用Node
于是调用:littleMonsterBullet:unscheduleUpdate()
tyLua(update,priority)添加的schedule,这样unschedule是无效的。
最后只能:
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(littleMonsterBullet.schedulerID)