【cocos2d-x】横向滚屏射击游戏②----虚拟控制手柄
更新:HHH   时间:2023-1-7


  因为iOS,Android设备使用触摸屏来输入,没有传统移动游戏设备配备的按钮,十字按钮或者模拟手柄,我们需要一个虚拟手柄来控制游戏。你可以使用虚拟手柄对游戏物体进行操控,就像使用实际的手柄一样。


SneakyInput控制手柄源码: 点我下载

把×××下来,加入到你的项目中,别忘了在android.mk添加相关内容哦!

我们首要目标是添加一个可以让玩家进行飞船射击的按钮,他们点击按钮的时候 会发射×××,

----------------------

接下来  我会在项目中添加一个新的类InputLayer ,这个类继承自CCLayer,他会被添加到MainScene

  1. CCScene *MainScene::scene() { 
  2.     CCScene *pScene = NULL; 
  3.     do { 
  4.         pScene = CCScene::create(); 
  5.         MainScene *main = MainScene::create(); 
  6.         pScene->addChild(main, -1); 
  7.         InputLayer *input = InputLayer::create(); 
  8.         pScene->addChild(input, 0); 
  9.     } while (0); 
  10.     return pScene; 

将SneakyInput添加到InputLayer的头文件中

  1. #include "SneakyInput/SneakyButton.h" 
  2. #include "SneakyInput/SneakyJoystick.h" 
  3. #include "SneakyInput/SneakyButtonSkinnedBase.h" 
  4. #include "SneakyInput/SneakyJoystickSkinnedBase.h" 

另外,我在头文件中加了一个SneakyButton成员变量,因为我们马上就会用到。

  1. class InputLayer: public CCLayer { 
  2. public
  3.     InputLayer(); 
  4.     virtual ~InputLayer(); 
  5.  
  6.     SneakyButton *snkBtn; 
  7.  
  8.     void update(ccTime time); 
  9.  
  10.     bool init();CREATE_FUNC(InputLayer) 
  11.     ; 
  12. }; 

在init方法中 我们生成了一个SneakyButton

  1. bool InputLayer::init() { 
  2.     bool bRet = false
  3.     do { 
  4.  
  5.         CCSize size = CCDirector::sharedDirector()->getWinSize(); 
  6.  
  7.         float buttonRadius = 42; 
  8.  
  9.         snkBtn = new SneakyButton(); 
  10.         snkBtn->autorelease(); 
  11.         snkBtn->initWithRect(CCRectZero); 
  12.         snkBtn->setPosition(CCPointMake(size.width-buttonRadius,buttonRadius)); 
  13.         snkBtn->setRadius(buttonRadius); 
  14.         this->addChild(snkBtn); 
  15.  
  16.         this->scheduleUpdate(); 
  17.         bRet = true
  18.     } while (0); 
  19.     return bRet; 

 

  因为SneakyButton没有用到initWithRect方法中的CGRect参数,所以我传了一个CGRectZero给这个方法。实际的处理触摸事件的代码是使用radius(半径)这个属性来决定按钮是否要响应触摸。

InputLayer类通过以下代码预约更新

  1. this->scheduleUpdate(); 

 

更新方法是用来测试按钮是否已被点击

  1. void InputLayer::update(ccTime time) { 
  2.     if (snkBtn->getIsActive()) { 
  3.         CCLog("按下按钮"); 
  4.     } 

运行程序,你会发现屏幕上没有任何按钮  不过你可以点击屏幕右下角 然后可以在log日志中正在打印“按下按钮”


接下来  我们将让按钮可见,也就是添加皮肤

 这里 我们使用到了SneakyButtonSkinnedBase

  1. bool InputLayer::init() { 
  2.     bool bRet = false
  3.     do { 
  4.  
  5.         CCSize size = CCDirector::sharedDirector()->getWinSize(); 
  6.  
  7.         float buttonRadius = 42; 
  8.  
  9.         snkBtn = new SneakyButton(); 
  10.         snkBtn->autorelease(); 
  11.         snkBtn->initWithRect(CCRectZero); 
  12. //      这个属性可以让玩家按住按钮不放的时候,×××会持续地射击出去 
  13.         snkBtn->setIsHoldable(true); 
  14.  
  15.         SneakyButtonSkinnedBase *sbsb = SneakyButtonSkinnedBase::create(); 
  16.         //默认状态 
  17.         sbsb->setDefaultSprite(CCSprite::create("nor.png")); 
  18.         //点击状态 
  19.         sbsb->setPressSprite(CCSprite::create("tou.png")); 
  20.         //激活状态 
  21.         sbsb->setActivatedSprite(CCSprite::create("tou.png")); 
  22.         sbsb->setPosition(CCPointMake(size.width-buttonRadius,buttonRadius)); 
  23.         sbsb->setButton(snkBtn); 
  24.         this->addChild(sbsb); 
  25.  
  26.         this->scheduleUpdate(); 
  27.         bRet = true
  28.     } while (0); 
  29.     return bRet; 
  我们不需要设置按钮的半径属性了,因为SneakyButtonSkinnedBase类会使用提供的按钮图片来确定按钮半径的大小

控制动作

接下来我们在游戏中添加摇杆

  1. bool InputLayer::init() { 
  2.     bool bRet = false
  3.     do { 
  4.  
  5.         CCSize size = CCDirector::sharedDirector()->getWinSize(); 
  6.  
  7.         float buttonRiadus = 75; 
  8.  
  9.         snkJs = new SneakyJoystick(); 
  10.         snkJs->autorelease(); 
  11. //      决定虚拟手柄的半径大小 
  12.         snkJs->initWithRect(CCRectMake(0,0,buttonRiadus,buttonRiadus)); 
  13.         //自动回到中心 
  14.         snkJs->setAutoCenter(true); 
  15.  
  16.         //是否支持死亡区域,该区域不会触发 
  17.         snkJs->setHasDeadzone(true); 
  18.         //死亡区域的半径 
  19.         snkJs->setDeadRadius(15); 
  20.  
  21.         SneakyJoystickSkinnedBase *sjssb =SneakyJoystickSkinnedBase::create(); 
  22.         sjssb->setPosition(CCPointMake(buttonRiadus*1.5,1.5*buttonRiadus)); 
  23.         //摇杆的背景图 
  24.         sjssb->setBackgroundSprite(CCSprite::create("handle1.png")); 
  25.         //摇杆的图片 
  26.         sjssb->setThumbSprite(CCSprite::create("handle2.png")); 
  27.         sjssb->setJoystick(snkJs); 
  28.         this->addChild(sjssb); 
  29.         this->scheduleUpdate(); 
  30.         bRet = true
  31.     } while (0); 
  32.     return bRet; 

 完成摇杆的添加  接下来要实现摇杆事件的监听 

  1. void InputLayer::update(ccTime time) { 
  2.  
  3. //  getVelocity()到的数值很小 需要放大  800是估算的 
  4.     CCPoint velocity = ccpMult(snkJs->getVelocity(), 800); 
  5.     if (velocity.x != 0 && velocity.y != 0) { 
  6.         CCLog("x=%f,y=%f", velocity.x, velocity.y); 
  7.     } 


 

接下来一章将开发一个小游戏,如有问题,请提出

本教程根据Cocos2d教程翻译过来

使用的cocos2d-x版本为2.02

 

返回游戏开发教程...