--添加按钮
function?GameScene:addButton(layer)
?
--创建button
local?function?scale9_normal()
????????
return ?
cc.Scale9Sprite:create(
"buttonBackground.png"
)
end
local?function?scale9_press()
"buttonHighlighted.png"
end
???? ?
--文本信息
self.button1_label?=?cc.Label:createWithTTF(
"Ready"
"fonts/label.TTF"
self.button2_label?=?cc.Label:createWithTTF(
self.button3_label?=?cc.Label:createWithTTF(
???? ?
--button1
local?button1?=?cc.ControlButton:create(self.button1_label,scale9_normal())
button1:setBackgroundSpriteForState(scale9_press(),cc.CONTROL_EVENTTYPE_TOUCH_DOWN)
button1:setTag(1)
button1:setPosition(self.size.width*0.2,self.size.height*0.2)
???? ?
--button2
local?button2?=?cc.ControlButton:create(self.button2_label,scale9_normal())
button2:setBackgroundSpriteForState(scale9_press(),cc.CONTROL_EVENTTYPE_TOUCH_DOWN)
button2:setTag(2)
button2:setPosition(self.size.width*0.5,self.size.height*0.2)
???? ?
--button3
local?button3?=?cc.ControlButton:create(self.button3_label,scale9_normal())
button3:setBackgroundSpriteForState(scale9_press(),cc.CONTROL_EVENTTYPE_TOUCH_DOWN)
button3:setTag(3)
button3:setPosition(self.size.width*0.8,self.size.height*0.2)
?
--设置button的回调函数
local?button_callback?=?function?(ref,button)
???????? ?
--如果正确跟新分数
if ?
self.correct?==?ref:getTag()?then
????????????
self:correct_callback()
else
self:wrong_callback()
end
end
?
--设置回调函数
button1:registerControlEventHandler(button_callback,cc.CONTROL_EVENTTYPE_TOUCH_UP_INSIDE)
button2:registerControlEventHandler(button_callback,cc.CONTROL_EVENTTYPE_TOUCH_UP_INSIDE)
button3:registerControlEventHandler(button_callback,cc.CONTROL_EVENTTYPE_TOUCH_UP_INSIDE)
?
--添加到层中
layer:addChild(button1)
layer:addChild(button2)
layer:addChild(button3)
2、添加Android返回键的响应代码
Android返回键同样需要回调函数来做这件事情,在Cocos中使用的是事件监听和分发机制,所以我们需要先注册一下事件类型,然后绑定回调,代码如下:
14
--监听手机返回键
local?key_listener?=?cc.EventListenerKeyboard:create()
???? ?
--返回键回调
local?function?key_return()
???????? ?
--结束游戏
cc.Director:getInstance():endToLua()
end
???? ?
--lua中得回调,分清谁绑定,监听谁,事件类型是什么
key_listener:registerScriptHandler(key_return,cc.Handler.EVENT_KEYBOARD_RELEASED)
local?eventDispatch?=?layer:getEventDispatcher()
eventDispatch:addEventListenerWithSceneGraphPriority(key_listener,layer)
|
这次我们使用的注册回调函数是registerScriptHandler,没有Tap,显然就不是为菜单和按钮回调准备的,所以这个函数是用来注册一般的回调函数所使用的。其中注释有句话说的比较好,就是一定要明白谁绑定,监听谁,事件类型是什么,在这个例子看来,是事件监听器去绑定了一个回调函数key_return,然后事件的类型是放到了一个Handler表中的,我们的事件类型是keyBoard,可以到Handler中看看都有哪些事件类型,然后所有你熟悉的东西都会看到了,比如以下的代码所代表的事件类型。
6
local?listener?=?cc.EventListenerTouchOneByOne:create()
listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN?)
listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED?)
listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED?)
local?eventDispatcher?=?layerFarm:getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(listener,?layerFarm)
|
3、动作的回调
3.x以后在C++层的动作回调函数只剩下Callfunc和CallfuncN了,其他的都可以用c++11的std::bind解决,而在Lua中就剩下一个了,这个是由Lua的特性决定的,用法如下。
8
--ready和go的回调函数?函数可以有俩个参数,第一个代表接受动作的对象,就是谁执行了动作,第二个是传过来的参数,全部放到了表中
local??ready_action?=?function(actionSelf,tab)
end
?
local?go_action?=?function()
end
?
cc.CallFunc:create(ready_action,{x=1})
|
CallFunc中有俩个参数,一个是绑定的回调函数,另一个是table表,这个表中可以存放一些命名参数,把你想要传递的东西统统通过这个表传递过去,然后在回调函数中,我们有俩个参数来接受,第一个当然是动作的执行者了,第二个就是传递过来的这张表,里边有所有我们要得参数,是不是很高大上啊!
4、小结
看完了以上的这些东西,我们基本明白了怎么使用,所谓知其然更要知其所以然,这些回调函数是怎么分发到Lua层的代码中的,我们就需要看一个文件了。打开你引擎目录的cocos/scripting/lua-bindings/manual/CCLuaEngine.cpp文件,我们需要找到这样一处代码。
55
56
57
58
59
60
61
62
63
int ?
LuaEngine::sendEvent(ScriptEvent*?evt)
{
????
(NULL?==?evt)
0;
?
switch ?
(evt->type)
{
case ?
kNodeEvent:
{
???????????????
handleNodeEvent(evt->data);
}
????????????
break
;
kMenuClickedEvent:
{
????????????????
handleMenuClickedEvent(evt->data);
}
;
kCallFuncEvent:
{
handleCallFuncActionEvent(evt->data);
}
;
kScheduleEvent:
{
handleScheduler(evt->data);
}
;
kTouchEvent:
{
handleTouchEvent(evt->data);
}
;
kTouchesEvent:
{
handleTouchesEvent(evt->data);
}
;
kKeypadEvent:
{
handleKeypadEvent(evt->data);
}
;
kAccelerometerEvent:
{
handleAccelerometerEvent(evt->data);
}
;
kCommonEvent:
{
handleCommonEvent(evt->data);
}
;
kControlEvent:
{
handlerControlEvent(evt->data);
}
;
default
:
;
}
?
0;
}
|
sendEvent顾名思义,这段代码就是向Lua层来分发回调事件的代码,在这段代码中,我们看到了很多熟悉的身影,比如说node的分发,menu的分发,schedule的分发,touch的分发等等都在这里,但是却没有事件监听器的分发,没错,事件监听器的回调Lua并没有写在这个文件中,而是在其他的文件中处理的,大家可以自行研究。我们以node回调Lua层的代码为例,看看是怎么回调Lua层的函数的,关键的代码在这里:
28
action?=?*((
int
*)(basicScriptData->value));
(action)
{
kNodeOnEnter:
_stack->pushString(
"enter"
);
;
?
kNodeOnExit:
"exit"
);
;
?
kNodeOnEnterTransitionDidFinish:
"enterTransitionFinish"
);
;
?
kNodeOnExitTransitionDidStart:
"exitTransitionStart"
);
;
?
kNodeOnCleanup:
"cleanup"
);
;
?
:
0;
????
ret?=?_stack->executeFunctionByHandler(handler,?1);
_stack->clean();
|
根据action的类型,我们将不同的字符串压入了栈中,然后执行了executeFunctionByHandler函数,第一个参数handler就是回调的函数,第二个参数代表传递到回调函数中的参数个数。其他的回调Lua层的函数大同小异,大家自行研究吧。那么在Lua层,这个回调函数是怎么被注册的呢?我们新建工程由系统创建了一个GameScene.lua文件,这个文件中的这段代码,不知道大家是否留意过。
local?function?onNodeEvent(event)
??????
if ?
"exit" ?
==?event?then
??????????
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(self.schedulerID)
??????
end
end
layerFarm:registerScriptHandler(onNodeEvent)
所以以后Lua中实现onEnter,onExit函数知道怎么做了吧,本文就到这里了。
推荐阅读:
浅析回调函数和Schedule
来源网址:http://www.zaojiahua.com/lua-callback-functions.html
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|