【麦可网】Cocos2d-X跨平台游戏开发学习笔记---第十五课:Cocos2D-X事件处理1-7

前端之家收集整理的这篇文章主要介绍了【麦可网】Cocos2d-X跨平台游戏开发学习笔记---第十五课:Cocos2D-X事件处理1-7前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

【麦可网】Cocos2d-X跨平台游戏开发---学习笔记

第十五课:Cocos2D-X事件处理1-7

=======================================================================================================================================================================

课程目标:

-Cocos2D-X事件处理机制

-Cocos2D-X输入框使用

课程重点:

-Cocos2D-X事件处理机制

-Cocos2D-X输入框使用

-为节点添加触摸事件

考核目标:

-掌握Cocos2D-X但多点触摸

-掌握Cocos2D-X重力感应事件

-掌握Cocos2D-X输入框使用

-理解为节点添加触摸事件

=======================================================================================================================================================================

一、单点/多点触摸事件接口

  1. 事件队列
  2. CCTouchDispather //存需要处理事件节点的类
  3. CCTouchDelegate
  4. CCTargetedTouchDelegate //单点触摸的事件
  5. CCStandardTouchDelegate //多点触摸的事件
  6.  
  7. 参考代码tests->touch_dispatcher
  8. -------------触摸事件接口-------------
  9. class CC_DLL CCTouchDelegate
  10. {
  11. public:
  12.  
  13. CCTouchDelegate() {}
  14.  
  15. virtual ~CCTouchDelegate()
  16. {
  17. }
  18.  
  19. //返回值bool来判读是否继续往下执行,true不执行后面的事件,反之则执行
  20. virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent) {CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent); return false;};
  21. // optional
  22.  
  23. virtual void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent) {CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent);}
  24. virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent) {CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent);}
  25. virtual void ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent) {CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent);}
  26.  
  27. // optional
  28. virtual void ccTouchesBegan(CCSet *pTouches,CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
  29. virtual void ccTouchesMoved(CCSet *pTouches,CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
  30. virtual void ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
  31. virtual void ccTouchesCancelled(CCSet *pTouches,CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
  32.  
  33. };


二、单点/多点触摸事件处理

  1. CCTargetedTouchDelegate
  2. virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);
  3. virtual bool ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent);
  4. virtual bool ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent);
  5. virtual bool ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent);
  6. CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this,true);
  7.  
  8. setTouchEnabled(true); <span style="white-space:pre"> </span> //开启触摸使能
  9. ----------------触摸使能-----------------
  10. void CCLayer::setTouchEnabled(bool enabled)
  11. {
  12. if (m_bTouchEnabled != enabled)
  13. {
  14. m_bTouchEnabled = enabled;
  15. if (m_bRunning)
  16. {
  17. if (enabled)
  18. {
  19. this->registerWithTouchDispatcher(); //添加节点到管理器
  20.  
  21. }
  22. else
  23. {
  24. // have problems?
  25. //节点移除管理器
  26. CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
  27. }
  28. }
  29. }
  30. }
  31.  
  32. ----------------触摸开始-----------------
  33. void LayerTest1::ccTouchesBegan(CCSet *pTouches,CCEvent *pEvent)
  34. {
  35. ccTouchesMoved(pTouches,pEvent);
  36. }
  37.  
  38. ----------------触摸移动-----------------
  39. void LayerTest1::ccTouchesMoved(CCSet *pTouches,CCEvent *pEvent)
  40. {
  41. CCTouch *touch = (CCTouch*)pTouches->anyObject();
  42. CCPoint touchLocation = touch->getLocation(); //获得单点
  43.  
  44. updateSize(touchLocation); //更新尺寸
  45. }
  46.  
  47. ----------------更新尺寸-----------------
  48. void LayerTest1::updateSize(CCPoint &touchLocation)
  49. {
  50. CCSize s = CCDirector::sharedDirector()->getWinSize();
  51. CCSize newSize = CCSizeMake( fabs(touchLocation.x - s.width/2)*2,fabs(touchLocation.y - s.height/2)*2); //重新计算大小
  52. CCLayerColor* l = (CCLayerColor*) getChildByTag(kTagLayer);
  53.  
  54. l->setContentSize( newSize ); //重新绘制大写
  55. }
  56.  
  57. 默认情况下,节点是实现多点触控,要想节点实现单点触控,则复写以下虚函数,并把多点触摸函数改成单点触摸函数
  58. void LayerTest1::registerWithTouchDispatcher()
  59. CCTouchDispather::sharedDispatcher()->addTargetedDelegate(this,true);


三、重力感应事件处理

  1. CCAccelerometerDelegate
  2. virtual void didAccelerate(CCAcceleration *pAccelerationValue);
  3. setAccelerometerEnabled(ture);
  4.  
  5. 参考代码tests->Accelerometer Test
  6. setAccelerometerEnabled(true); //启用重力感应


四、按键事件处理

  1. class CC_DLL CCKeypadDelegate
  2. {
  3. public:
  4. // 返回键
  5. virtual void keyBackClicked() {}
  6.  
  7. // 菜单键,安卓手机可用
  8. virtual void keyMenuClicked() {};
  9. };
  10.  
  11. 参考代码tests->KeypadTest


五、为精灵添加事件

步骤1:继承触摸

步骤2:实现接口

步骤3注册添加到事件管理器

步骤4:从事件管理器中删除

四个步骤代码对应如下:

参考代码tests->TouchesTest


  1. 步骤1:继承触摸
  2. class Paddle : public CCSprite,public CCTargetedTouchDelegate
  3. {
  4. ……
  5. };
  6.  
  7. 步骤2:实现接口
  8. bool Paddle::ccTouchBegan(CCTouch* touch,CCEvent* event)
  9. {
  10. if (m_state != kPaddleStateUngrabbed) return false;
  11. //判断触摸点是否在矩形区域内
  12. if ( !containsTouchLocation(touch) ) return false;
  13. m_state = kPaddleStateGrabbed;
  14. return true;
  15. }
  16.  
  17. 其中:
  18. bool Paddle::containsTouchLocation(CCTouch* touch)
  19. {
  20. //坐标转换,坐标原点设置在精灵的锚点
  21. return rect().containsPoint(convertTouchToNodeSpaceAR(touch));
  22. }
  23.  
  24. CCRect Paddle::rect()
  25. {
  26. CCSize s = getTexture()->getContentSize();
  27. return CCRectMake(-s.width / 2,-s.height / 2,s.width,s.height);
  28. }
  29.  
  30. #define CCRectMake(x,y,width,height) CCRect((float)(x),(float)(y),(float)(width),(float)(height))
  31.  
  32. ---------------------------------------------------------
  33. void Paddle::ccTouchMoved(CCTouch* touch,CCEvent* event)
  34. {
  35. // If it weren't for the TouchDispatcher,you would need to keep a reference
  36. // to the touch from touchBegan and check that the current touch is the same
  37. // as that one.
  38. // Actually,it would be even more complicated since in the Cocos dispatcher
  39. // you get CCSets instead of 1 UITouch,so you'd need to loop through the set
  40. // in each touchXXX method.
  41. CCAssert(m_state == kPaddleStateGrabbed,"Paddle - Unexpected state!");
  42. CCPoint touchPoint = touch->getLocation();
  43. setPosition( ccp(touchPoint.x,getPosition().y) );
  44. }
  45.  
  46. void Paddle::ccTouchEnded(CCTouch* touch,CCEvent* event)
  47. {
  48. CCAssert(m_state == kPaddleStateGrabbed,"Paddle - Unexpected state!");
  49. m_state = kPaddleStateUngrabbed;
  50. }
  51.  
  52. 步骤3注册添加到事件管理器
  53. void Paddle::onEnter()
  54. {
  55. CCDirector* pDirector = CCDirector::sharedDirector();
  56. pDirector->getTouchDispatcher()->addTargetedDelegate(this,true);
  57. CCSprite::onEnter();
  58. }
  59.  
  60. 步骤4:从事件管理器中删除
  61. void Paddle::onExit()
  62. {
  63. CCDirector* pDirector = CCDirector::sharedDirector();
  64. pDirector->getTouchDispatcher()->removeDelegate(this);
  65. CCSprite::onExit();
  66. }


六、通知中心

  1. //添加监听消息
  2. CCNotificationCenter::sharedNotificationCenter()->addObserver(this,callfuncO_selector(GameManager::onClickTest),CLICK_TEST_MSG,NULL);
  3. //发送消息
  4. CCNotificationCenter::sharedNotificationCenter()->postNotification(CLICK_TEST_MSG,(CCObject*)data);
  5. //取消监听消息
  6. CCNotificationCenter::sharedNotificationCenter()->removerObserver(this,CLICK_TEST_MSG);
  7. //收到消息后的执行动作
  8. void GameManager::onClickTest(CCObject *obj)
  9. {
  10. }


七、输入框使用

步骤1:创建文本框

步骤2:启用事件处理

步骤3注册事件

步骤4:实现键盘的弹出

步骤5:判读键盘是否挡住其它节点

参考代码tests->TextInputTest


  1. CCTextFieldTTF //创建输入框
  2. CCIMEDelegate //输入法,弹出键盘
  3. CCTextFieldDelegate <span style="white-space:pre"> </span>//添加输入效果的接口
  4.  
  5. -----------------------------------------------------
  6. class CC_DLL CCIMEDelegate
  7. {
  8. public:
  9. virtual ~CCIMEDelegate();
  10.  
  11. virtual bool attachWithIME(); //打开键盘
  12. virtual bool detachWithIME(); //关闭键盘
  13. ……
  14. };
  15. --------------------------触摸按下--------------------------
  16. bool KeyboardNotificationLayer::ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent)
  17. {
  18. CCLOG("++++++++++++++++++++++++++++++++++++++++++++");
  19. m_beginPos = pTouch->getLocation();
  20. return true;
  21. }
  22. --------------------------触摸结束--------------------------
  23. void KeyboardNotificationLayer::ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent)
  24. {
  25. if (! m_pTrackNode)
  26. {
  27. return;
  28. }
  29. CCPoint endPos = pTouch->getLocation();
  30.  
  31. float delta = 5.0f;
  32. if (::abs(endPos.x - m_beginPos.x) > delta //排除滑动操作
  33. || ::abs(endPos.y - m_beginPos.y) > delta)
  34. {
  35. // not click
  36. m_beginPos.x = m_beginPos.y = -1;
  37. return;
  38. }
  39.  
  40. // decide the trackNode is clicked.
  41. CCRect rect;
  42. CCPoint point = convertTouchToNodeSpaceAR(pTouch);
  43. CCLOG("KeyboardNotificationLayer:clickedAt(%f,%f)",point.x,point.y);
  44.  
  45. rect = getRect(m_pTrackNode);
  46. CCLOG("KeyboardNotificationLayer:TrackNode at(origin:%f,%f,size:%f,rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);
  47.  
  48. this->onClickTrackNode(rect.containsPoint(point)); //判断在输入框内点击
  49. CCLOG("----------------------------------");
  50. }
  51.  
  52.  
  53.  
  54. --------------------------判断是否打开键盘--------------------------
  55. void TextFieldTTFDefaultTest::onClickTrackNode(bool bClicked)
  56. {
  57. CCTextFieldTTF * pTextField = (CCTextFieldTTF*)m_pTrackNode;
  58. if (bClicked)
  59. {
  60. // TextFieldTTFTest be clicked
  61. CCLOG("TextFieldTTFDefaultTest:CCTextFieldTTF attachWithIME");
  62. pTextField->attachWithIME();
  63. }
  64. else
  65. {
  66. // TextFieldTTFTest not be clicked
  67. CCLOG("TextFieldTTFDefaultTest:CCTextFieldTTF detachWithIME");
  68. pTextField->detachWithIME();
  69. }
  70. }
  71.  
  72. --------------------------键盘打开前的动作--------------------------
  73. 比如键盘把输入框遮住了,输入框要整体往上移动,代码则放在这里面
  74. void KeyboardNotificationLayer::keyboardWillShow(CCIMEKeyboardNotificationInfo& info) //包含键盘信息,如尺寸
  75. {
  76. CCLOG("TextInputTest:keyboardWillShowAt(origin:%f,info.end.origin.x,info.end.origin.y,info.end.size.width,info.end.size.height);
  77.  
  78. if (! m_pTrackNode)
  79. {
  80. return;
  81. }
  82.  
  83. CCRect rectTracked = getRect(m_pTrackNode);
  84. CCLOG("TextInputTest:trackingNodeAt(origin:%f,rectTracked.origin.x,rectTracked.origin.y,rectTracked.size.width,rectTracked.size.height);
  85.  
  86. // 如果键盘没有覆盖输入框,则直接返回
  87. if (! rectTracked.intersectsRect(info.end))
  88. {
  89. return;
  90. }
  91.  
  92. // assume keyboard at the bottom of screen,calculate the vertical adjustment.
  93. float adjustVert = info.end.getMaxY() - rectTracked.getMinY();
  94. CCLOG("TextInputTest:needAdjustVerticalPosition(%f)",adjustVert);
  95.  
  96. // 所有的子节点都向上移动
  97. CCArray * children = getChildren();
  98. CCNode * node = 0;
  99. int count = children->count();
  100. CCPoint pos;
  101. for (int i = 0; i < count; ++i)
  102. {
  103. node = (CCNode*)children->objectAtIndex(i);
  104. pos = node->getPosition();
  105. pos.y += adjustVert;
  106. node->setPosition(pos);
  107. }
  108. }
  109.  
  110. --------------------------为输入和删除文字添加动画--------------------------
  111. 继承于CCTextFieldDelegate
  112.  
  113. virtual bool onTextFieldAttachWithIME(CCTextFieldTTF * pSender);
  114. virtual bool onTextFieldDetachWithIME(CCTextFieldTTF * pSender);
  115. virtual bool onTextFieldInsertText(CCTextFieldTTF * pSender,const char * text,int nLen);
  116. virtual bool onTextFieldDeleteBackward(CCTextFieldTTF * pSender,const char * delText,int nLen);
  117. virtual bool onDraw(CCTextFieldTTF * pSender);

===================================================================

总结:

理解了这几个步骤就差不多了

步骤1:创建文本框 CCTextFieldTTF

步骤2:启用触摸事件处理 KeyboardNotificationLayer

步骤3注册事件 registerWithTouchDispatcher

步骤4:实现键盘的弹出 attachWithIME

步骤5:判读键盘是否挡住其它节点 keyboardWillShow

步骤6:设置输入动画 CCTextFieldDelegate

开心一刻:

小明上课迟到了。

  老师怒:小明,今天来这么晚?

  小明:睡过了!

  老师:怎么会睡过呢?

  小明:做梦梦见老师讲课,就想多听一会…

老师:滚!

【麦可网】Cocos2d-X跨平台游戏开发---教程下载:http://pan.baidu.com/s/1kTio1Av

【麦可网】Cocos2d-X跨平台游戏开发---笔记系列:http://blog.csdn.net/qiulanzhu

猜你在找的Cocos2d-x相关文章