Cocos2D-x引擎支持按键事件,它能检测设备的键盘输入并处理相应的事件。而基于不同操作系统的移动设备,可供用户操作的按键数量和功能都存在差异。
Cocos2D-x使用CCKeypadDelegate接口类处理相应的事件,这个类定义很简单,如下:
class CC_DLL CCKeypadDelegate
{
public:
virtual void keyBackClicked() {} //返回按键事件
virtual void keyMenuClicked() {}; //Menu菜单按键事件(仅android支持该按键)
};
只有继承并实现该接口才能处理按键事件。布景层类CCLayer和其子类是继承自CCKeypadDelegate,如下:
自定义类如何支持按键事件呢?很简单。需要继承CCLayer或其子类,在自定义类初始化时,调用方法setKeypadEnabled(true)将自定义类对象添加到按键事件分发类CCKeypadDispatcher中。在添加时使用了CCKeypadHandler类,它用于对CCKeypadDelegate进行封装。接着,就是在自定义类中重写CCKeypadDelegate的两个接口方法。
当用户按键时,系统将触发相应的按键事件,平台底层会调用CCKeypadDispatcher的相应的按键事件分发方法,将按键事件分发到指定所有按键事件响应对象中,由该对象完成按键事件的响应处理。
CCKeypadDispatcher的按键事件分发如下:
bool CCKeypadDispatcher::dispatchKeypadMSG(ccKeypadMSGType nMsgType)
{
CCKeypadHandler* pHandler = NULL;
CCKeypadDelegate* pDelegate = NULL;m_bLocked = true;if (m_pDelegates->count() > 0)
{
CCObject* pObj = NULL;
CCARRAY_FOREACH(m_pDelegates, pObj)
{
CC_BREAK_IF(!pObj);pHandler = (CCKeypadHandler*)pObj;
pDelegate = pHandler->getDelegate();switch (nMsgType)
{
case kTypeBackClicked:
pDelegate->keyBackClicked(); //调用回退按键事件响应方法
break;
case kTypeMenuClicked:
pDelegate->keyMenuClicked(); //调用菜单按键事件响应方法
break;
default:
break;
}
}
}m_bLocked = false;
if (m_bToRemove)
{
m_bToRemove = false;
for (unsigned int i = 0; i < m_pHandlersToRemove->num; ++i)
{
forceRemoveDelegate((CCKeypadDelegate*)m_pHandlersToRemove->arr[i]);
}
ccCArrayRemoveAllValues(m_pHandlersToRemove);
}if (m_bToAdd)
{
m_bToAdd = false;
for (unsigned int i = 0; i < m_pHandlersToAdd->num; ++i)
{
forceAddDelegate((CCKeypadDelegate*)m_pHandlersToAdd->arr[i]);
}
ccCArrayRemoveAllValues(m_pHandlersToAdd);
}return true;
}在TestCpp工程的KeypadTest测试项中有按键事件的代码实例。
在手游中如果需要进行文字输入,这时就需要用到虚拟键盘。在Cocos2D-x中,通过类CCIMEDelegate来实现虚拟键盘功能。还是看类继承关系图,如下:
从上图知,CCTextFieldTTF和CCEditBox两个类继承了CCIMEDelegate,这两个类都需要文字输入功能。看一下CCIMEDelegate的定义。class CC_DLL CCIMEDelegate
{
public:
virtual ~CCIMEDelegate();virtual bool attachWithIME(); //打开虚拟键盘并允许输入
virtual bool detachWithIME(); //关闭虚拟键盘并停止输入protected:
friend class CCIMEDispatcher;
virtual bool canAttachWithIME() { return false; } //是否接收输入
virtual void didAttachWithIME() {} //接收输入时调用
virtual bool canDetachWithIME() { return false; } //是否结束输入
virtual void didDetachWithIME() {} //结束输入时调用
virtual void insertText(const char * text, int len) {CC_UNUSED_PARAM(text);CC_UNUSED_PARAM(len);}//输入文字时调用
virtual void deleteBackward() {} //按回格(Backspace)键调用
virtual const char * getContentText() { return 0; } //获取输入文字//虚拟键盘准备显示时调用
virtual void keyboardWillShow(CCIMEKeyboardNotificationInfo& info) {CC_UNUSED_PARAM(info);}//虚拟键盘已显示时调用
virtual void keyboardDidShow(CCIMEKeyboardNotificationInfo& info) {CC_UNUSED_PARAM(info);}//虚拟键盘准备隐藏时调用
virtual void keyboardWillHide(CCIMEKeyboardNotificationInfo& info) {CC_UNUSED_PARAM(info);}//虚拟键盘已隐藏时调用
virtual void keyboardDidHide(CCIMEKeyboardNotificationInfo& info) {CC_UNUSED_PARAM(info);}protected:
CCIMEDelegate();
};以上定义了虚拟键盘的接口方法,再看一看如何使用虚拟键盘。要显示虚拟键盘首先要在场景中加入一个继承自CCIMEDelegate的可显示的CCNode。在TestCpp工程的TextInputTest测试项有虚拟键盘的代码实例。代码定义了类KeyboardNotificationLayer,它从CCLayer和CCIMEDelegate继承而来,专门负责虚拟键盘操作。它的流程是将KeyboardNotificationLayer实例作为节点添加到上一层CCLayer中,因为KeyboardNotificationLayer继承于CCLayer,所以支持触屏事件。当用户触屏时,KeyboardNotificationLayer的触屏事件响应方法ccTouchEnded被调用,ccTouchEnded将调用onClickTrackNode方法,这个方法如下:void TextFieldTTFDefaultTest::onClickTrackNode(bool bClicked)
{
CCTextFieldTTF * pTextField = (CCTextFieldTTF*)m_pTrackNode;
if (bClicked)
{
// TextFieldTTFTest be clicked
CCLOG("TextFieldTTFDefaultTest:CCTextFieldTTF attachWithIME");
pTextField->attachWithIME();
}
else
{
// TextFieldTTFTest not be clicked
CCLOG("TextFieldTTFDefaultTest:CCTextFieldTTF detachWithIME");
pTextField->detachWithIME();
}
}现在应该显示出虚拟键盘了。-------------------------------------------------------------------------------------------------------------------注:本人在本博客的原创文章采用创作共用版权协议(http://creativecommons.org/licenses/by-nc-sa/2.5/cn/), 要求署名、非商业用途和保持一致。要求署名包含注明我的网名及文章来源(我的博客地址:http://www.cnblogs.com/binbingg)。