溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

【cocos2d-x】橫向滾屏射擊游戲②----虛擬控制手柄

發(fā)布時(shí)間:2020-06-20 14:49:48 來源:網(wǎng)絡(luò) 閱讀:1960 作者:包灬子 欄目:游戲開發(fā)

  因?yàn)閕OS,Android設(shè)備使用觸摸屏來輸入,沒有傳統(tǒng)移動(dòng)游戲設(shè)備配備的按鈕,十字按鈕或者模擬手柄,我們需要一個(gè)虛擬手柄來控制游戲。你可以使用虛擬手柄對(duì)游戲物體進(jìn)行操控,就像使用實(shí)際的手柄一樣。


SneakyInput控制手柄源碼: 點(diǎn)我下載

把×××下來,加入到你的項(xiàng)目中,別忘了在android.mk添加相關(guān)內(nèi)容哦!

我們首要目標(biāo)是添加一個(gè)可以讓玩家進(jìn)行飛船射擊的按鈕,他們點(diǎn)擊按鈕的時(shí)候 會(huì)發(fā)射×××,

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

接下來  我會(huì)在項(xiàng)目中添加一個(gè)新的類InputLayer ,這個(gè)類繼承自CCLayer,他會(huì)被添加到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" 

另外,我在頭文件中加了一個(gè)SneakyButton成員變量,因?yàn)槲覀凂R上就會(huì)用到。

  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方法中 我們生成了一個(gè)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; 

 

  因?yàn)镾neakyButton沒有用到initWithRect方法中的CGRect參數(shù),所以我傳了一個(gè)CGRectZero給這個(gè)方法。實(shí)際的處理觸摸事件的代碼是使用radius(半徑)這個(gè)屬性來決定按鈕是否要響應(yīng)觸摸。

InputLayer類通過以下代碼預(yù)約更新

  1. this->scheduleUpdate(); 

 

更新方法是用來測(cè)試按鈕是否已被點(diǎn)擊

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

運(yùn)行程序,你會(huì)發(fā)現(xiàn)屏幕上沒有任何按鈕  不過你可以點(diǎn)擊屏幕右下角 然后可以在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. //      這個(gè)屬性可以讓玩家按住按鈕不放的時(shí)候,×××?xí)掷m(xù)地射擊出去 
  13.         snkBtn->setIsHoldable(true); 
  14.  
  15.         SneakyButtonSkinnedBase *sbsb = SneakyButtonSkinnedBase::create(); 
  16.         //默認(rèn)狀態(tài) 
  17.         sbsb->setDefaultSprite(CCSprite::create("nor.png")); 
  18.         //點(diǎn)擊狀態(tài) 
  19.         sbsb->setPressSprite(CCSprite::create("tou.png")); 
  20.         //激活狀態(tài) 
  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; 
  我們不需要設(shè)置按鈕的半徑屬性了,因?yàn)镾neakyButtonSkinnedBase類會(huì)使用提供的按鈕圖片來確定按鈕半徑的大小

控制動(dòng)作

接下來我們?cè)谟螒蛑刑砑訐u桿

  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.         //自動(dòng)回到中心 
  14.         snkJs->setAutoCenter(true); 
  15.  
  16.         //是否支持死亡區(qū)域,該區(qū)域不會(huì)觸發(fā) 
  17.         snkJs->setHasDeadzone(true); 
  18.         //死亡區(qū)域的半徑 
  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; 

 完成搖桿的添加  接下來要實(shí)現(xiàn)搖桿事件的監(jiān)聽 

  1. void InputLayer::update(ccTime time) { 
  2.  
  3. //  getVelocity()到的數(shù)值很小 需要放大  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.     } 


 

接下來一章將開發(fā)一個(gè)小游戲,如有問題,請(qǐng)?zhí)岢?/span>

本教程根據(jù)Cocos2d教程翻譯過來

使用的cocos2d-x版本為2.02

 

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI