【cocos2dx】监听安卓机的返回键
来源:互联网 发布:网络市场调研报告范文 编辑:程序博客网 时间:2024/06/05 23:59
2016-02-19新增-------------------------------------------------------------------------------------------------------------
--quick-cocos2d-x_2.2.6
--返回按键监听self.layer = display.newLayer()self.layer:addNodeEventListener(cc.KEYPAD_EVENT, function(event) if event.key == "back" then --self.mainPopup:show("要退出吗", true)--再按一次返回键退出end end)self.layer:setKeypadEnabled(true)self:addChild(self.layer)
原文-----------------------------------------------------------------------------------------------------------------------------
(Cocos-2.2.6 & Framework-3.5)
在玩cocos2d-x的时候,每次真机实测,都要按home键来‘退出’游戏,因为没有监听返回键,这让我想起了某个版本的手机QQ,也是没有监听返回键来着。
来简单写一下cocos2d-x监听安卓的返回键。
简单的用helloworld项目来实验
首先在.h文件覆盖onKeyReleased函数。
virtual void onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event);
在.cpp中init函数里面注册键盘监听
bool HelloWorld::init(){//省略一些代码auto backKeyListener = EventListenerKeyboard::create();backKeyListener->onKeyReleased = CC_CALLBACK_2(HelloWorld::onKeyReleased, this);_eventDispatcher->addEventListenerWithSceneGraphPriority(backKeyListener, this);}
之后捕捉返回键(不排除手机机型问题和引擎版本问题引起keyCode的不同,keyCode请自行真机测试,我这里三星S4的返回键对应KEY_BACK)
void HelloWorld::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event){if (keyCode == EventKeyboard::KeyCode::KEY_BACK){Director::getInstance()->end();}}
好了,很简单。返回键按下立马退出。但是也太简单了,我们比较常见的app或者游戏的返回键监听一般设计成这两种形式:
1、“再按一次返回键退出”。2、弹出对话框确认退出。
先来第一种。
我们要实现“再按一次返回键退出”,那就得让程序知道,用户到底按了几次返回键。
另外,这两次按下返回键的间隔也应该有个限制,总不能,第一按下的时候,提示“再按一次返回键退出”,过了10分钟再按返回键就直接退出了。
相应的步骤大概是这样。
在上一段的代码基础上,.h文件里面声明一个bool变量来标记是否按了第一次。
bool m_keyBackFlag;
之后在init函数里面初始化为false
m_keyBackFlag = false;
然后HelloWorld::onKeyReleased要改挺多,因为我们要区别对待是否按了第一次返回键,所以先套一个if(!m_keyBackFlag)else,之后再分别编写。
void HelloWorld::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event){if (keyCode == EventKeyboard::KeyCode::KEY_BACK){if (!m_keyBackFlag)// 在过去的1秒钟之内没按过返回键,提示信息再按一次{TTFConfig ttfConfig("fonts/jt.ttf", 24);auto pMessage = Label::createWithTTF(ttfConfig,"再按一次返回键", TextHAlignment::LEFT, Director::getInstance()->getWinSize().width * 0.7);pMessage->setPosition(Point(100, 80));this->addChild(pMessage);auto pMessageFadeOut = FadeOut::create(1.0f);auto pMessageMoveBy = MoveBy::create(1.0f, Vec2(0, 75));auto pSpawn = Spawn::create(pMessageMoveBy, pMessageFadeOut, nullptr);pMessage->runAction(pSpawn);m_keyBackFlag = true;this->scheduleOnce([=](float dt){this->m_keyBackFlag = false;},1,//1秒之内如果不按返回键,那么m_keyBackFlag变量重置"keyBackFlag");}else//在过去的1秒钟之内曾按下返回键,现在按的是第二下{Director::getInstance()->end();}}}
效果图
细心的同学可能发现了,我们的左下角的信息里节点数在涨个不停。原因是,虽然这个提示信息(Label)消失了,但是我们没有移除它。
所以,每次显示的提示信息(Label)都会一直存在于我们的项目中。所以我们要移除它。也就是,在它消失的那一刻,他的生命是周期也结束了。
我们既然写有了一个lambda,那就好好利用它。
首先在pMessage->runAction(pSpawn);下加一句pMessage->retain();。为什么,后面再提。
之后在lambda里面的this->m_keyBackFlag = false;后面加一句this->removeChild(pMessage);。
刚刚前面要调用pMessage的retain函数,原因是,我们需要在一段时间后才移除这个pMessage指针,但是呢,那个时候程序已经离开了这个代码快。
pMessage指针失效了,pMessage指向的Label还在(透明的)。所以我们需要调用retain(),让它摆脱cocos的内存管理机制,来让lambda能捕捉到它。
再上图这回节点数就正常了。(因为只加了两行代码,请自行添加吧,我不贴代码了)
==========================================================================================再看第二种,弹出确认框。
这里我先说一下,对话框的类我没有实现,只是用成员指针来模拟实现的。
弹出对话框的实现,bool变量的flag我还是留着的,防止按多次返回键来弹出创建多次对话框(因为我没有写对话框的类,只是当场创建精灵和按钮来模拟对话框的)
当然用别的方法来预防也是可以的。
相应的步骤大概是这样。
这里要解决的一个小问题是,在弹出退出确认框的时候,游戏本身的所有监听事件就要屏蔽了,防止被玩家误触。也可以说,弹出来的对话框优先级最高。
我这里大概的思路就是,先做一个遮盖层,这个层吸收所有的触摸事件,然后在这个层之上,创建对话框。
如果用户选择退出,则退出游戏。如果取消,则返回游戏,移除这个遮盖层和对话框。
思路是这样,实现起来可以用层(Layer),我这里不用层(Layer)来实现这个遮盖用的层。
我们用一个足够大ui::ImageView对象,设置交互性setTouchEnabled(true);,这样,就能做到我们想要的效果了。
当然,也可以用其他的有setTouchEnable成员的类,只不过,ui::ImageView的创建已经非常简便了。就用这个好了。
之后,再创建对话框,并且设置好回调函数就好了。
因为要用成员变量来模拟对话框,所以成员变量比较多,如果自己已经实现了对话框类,那么只要少量成员变量就好了。
.h文件中声明的变量和函数。我们依然需要覆盖onKeyReleased函数。另外声明两个回调函数,分别作为确定退出和取消退出的回调。
先上效果图。
对话框是用精灵和按钮模拟的,所以成员变量有点多,如果自己实现了对话框类的话,变量会少很多。
virtual void onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event);void testCallback(Ref* pSender);void testCallback2(Ref* pSender);bool m_keyBackFlag;ui::ImageView* m_cover;Sprite* m_outBox;Label* m_pMessage2;Label* m_pLabelYes;Label* m_pLabelNo;MenuItemLabel* m_pItemYes;MenuItemLabel* m_pItemNo;Menu* m_pm;
那么初始化的时候可以全部赋空指针。
bool HelloWorld::init(){ //省略了一些代码m_cover = nullptr;m_pMessage2 = nullptr;m_pLabelYes = nullptr;m_pLabelNo = nullptr;m_pItemYes = nullptr;m_pItemNo = nullptr;m_pm = nullptr;m_outBox = nullptr;m_keyBackFlag = false;//同样还要注册监听auto backKeyListener = EventListenerKeyboard::create();backKeyListener->onKeyReleased = CC_CALLBACK_2(HelloWorld::onKeyReleased, this);_eventDispatcher->addEventListenerWithSceneGraphPriority(backKeyListener, this);}void HelloWorld::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event){if (keyCode == EventKeyboard::KeyCode::KEY_BACK){if (!m_keyBackFlag){//遮挡层用ui::ImageView来吸收触屏事件<span style="white-space:pre"></span>m_cover = ui::ImageView::create("colorBG.png");m_cover->setPosition(Vec2(Director::getInstance()->getWinSize().width * 0.5, Director::getInstance()->getWinSize().height * 0.5));m_cover->setTouchEnabled(true);m_cover->setOpacity(128);this->addChild(m_cover);//下面都是对话框的模拟实现m_outBox = Sprite::create("outBox.png");m_outBox->setPosition(270, 450);this->addChild(m_outBox);TTFConfig ttfConfig("fonts/jt.ttf", 24);m_pMessage2 = Label::createWithTTF(ttfConfig,"确定要退出么?",TextHAlignment::LEFT, Director::getInstance()->getWinSize().width * 0.7);m_pMessage2->setPosition(Vec2(270, 500));this->addChild(m_pMessage2);m_pLabelYes = Label::createWithTTF(ttfConfig,"是的",TextHAlignment::LEFT, Director::getInstance()->getWinSize().width * 0.7);m_pLabelNo = Label::createWithTTF(ttfConfig,"不要",TextHAlignment::LEFT, Director::getInstance()->getWinSize().width * 0.7);m_pItemYes = MenuItemLabel::create(m_pLabelYes, CC_CALLBACK_1(HelloWorld::testCallback, this));m_pItemNo = MenuItemLabel::create(m_pLabelNo, CC_CALLBACK_1(HelloWorld::testCallback2, this));m_pItemYes->setPosition(Vec2(270, 450));m_pItemNo->setPosition(Vec2(270, 400));m_pm = Menu::create(m_pItemYes, m_pItemNo, nullptr);m_pm->setPosition(Vec2(0, 0));this->addChild(m_pm);m_keyBackFlag = true;}}}void HelloWorld::testCallback(Ref* pSender)//确定退出的回调{Director::getInstance()->end();}void HelloWorld::testCallback2(Ref* pSender)//取消退出的回调{//移除对话框CCLOG("testCallback2");this->m_keyBackFlag = false;this->removeChild(m_pMessage2);this->removeChild(m_pLabelYes);this->removeChild(m_pLabelNo);this->removeChild(m_pm);this->removeChild(m_pItemYes);this->removeChild(m_pItemNo);this->removeChild(m_outBox);this->removeChild(m_cover);}
- 【cocos2dx】监听安卓机的返回键
- cocos2dx 安卓返回键的监听
- cocos2dx设置监听Android的返回键、Home键
- 返回按键监听-Quick-Cocos2dx
- 返回键的监听
- 返回键的监听
- 返回键的监听
- cocos2dx用lua监听android的返回事件
- cocos2dx 监听Android返回键、菜单键等
- cocos2dx中调用Andriod中的返回键和菜单监听
- Android返回键的监听
- 监听系统的返回键
- android 返回键的监听
- ProgressDialog返回键的监听
- android返回键的监听
- Cocos2dx 3.2键盘监听的打开方式以及点击两次返回退出的实现方法
- ionic2 监听back键;监听navbar的返回键
- ActivityGroup对返回键的监听
- 你不知道的JavaScript--Item31 值得你挑战的JavaScript面试题(45题)
- Android Studio 汉字转拼音
- nginx优化
- Word 导出带目录书签的PDF文档 Office
- Android中对Log日志文件的分析
- 【cocos2dx】监听安卓机的返回键
- [kuangbin带你飞]专题一 简单搜索G - Shuffle'm Up(POJ 3087)
- 欢迎使用CSDN-markdown编辑器
- iOS开发消息篇—NSRunLoop
- Spring源码学习(一源码下载)
- 2015.11.9
- 文件的读取
- 引入矩阵乘法的主要原因来源于线性方程组的应用
- muduo库阅读(20)——时间戳类