1. 程式人生 > >【Cocos2dx】使用CCControlButton建立按鈕、按鈕點選事件,點選事件中的元件獲取,setPosition的座標問題

【Cocos2dx】使用CCControlButton建立按鈕、按鈕點選事件,點選事件中的元件獲取,setPosition的座標問題

按鈕不僅在遊戲,在任何地方都是不可或缺卻又是最基本的東西。在遊戲引擎Cocos2dx中也不例外。

下面用一個例子說明Cocos2dx中如何使用按鈕,同時,如果在Cocos2dx中獲取層,也就是場景、舞臺中的元件。

如下圖,有一個按鈕Clickme,被點選時候與不被點選的時間,其背景圖片是不同的。其實就是資原始檔夾Resource中早就被玩壞的兩個圖片,一張CloseNormal.png一張CloseSelected.png被拉伸後的慘狀。

Cocos2dx的資原始檔夾在《【Cocos2dx】資原始檔夾,播放背景音樂,匯入外部庫》(點選開啟連結)中已經介紹過了。

如何拉伸圖片,請參考《【Cocos2dx】使用CCScale9Sprite拉伸圖片》(

點選開啟連結

在點選的時候,其上方的文字,點選數在改變。點選一次,增加一次。


1、首先還是老樣子,利用命令列建立一個工程,這個我就不多說了,可以參考《【Cocos2dx】Windows平臺下Cocos2dx 2.x的下載、安裝、配置,打造自己的Helloworld》(點選開啟連結

2、之後,開啟./projects/工程名/proj.win32/HelloCpp.sln,和《【Cocos2dx】新建場景、場景的切換、設定啟動場景與選單的新建》(點選開啟連結)一樣,先在AppDelegate.cpp的第22行設定pDirector->setDisplayStats(false);關閉除錯相信,直接對Helloworld這個場景進行修改。首先開啟HelloWorldScene.h這個檔案,原來的Helloworld場景的標頭檔案太過臃腫了,可以刪除一些無用的跨平臺巨集彙編的資訊,關鍵是就是裡面的4個函式宣告,主要是第3個的函式宣告進行引數的擴充,以匹配按鈕的點選事件cccontrol_selector,如果不加第2個引數CCControlEvent event是無法通過編譯的。

HelloWorldScene.h此檔案修改之後的全程式碼如下:

#include "cocos2d.h"
#include "cocos-ext.h"//使用按鈕事件,必須要需要的標頭檔案
USING_NS_CC_EXT;//使用按鈕事件,必須要需要的名稱空間

class HelloWorld : public cocos2d::CCLayer
{
public:
    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  

    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::CCScene* scene();
    
    // a selector callback
    void menuCloseCallback(CCObject* pSender,CCControlEvent event);//對原來的關閉事件進行改造,增加引數,讓其支援cccontrol_selector
    
    // implement the "static node()" method manually
    CREATE_FUNC(HelloWorld);
};
3、之後對HelloWorldScene.cpp這個檔案中的bool HelloWorld::init(){}場景初始化佈局函式,原本Helloworld場景中,右下角按鈕的點選回撥函式menuCloseCallback進行修改。修改之後的程式碼如下,詳見註釋:
#include "HelloWorldScene.h"
#include "cocos-ext.h" //使用按鈕事件,必須要需要的標頭檔案

USING_NS_CC;
USING_NS_CC_EXT;//使用按鈕事件,必須要需要的名稱空間

int hits=0;//全域性變數,用來統計點選被點選次數

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();
    
    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
	//獲取螢幕的尺寸、位置資訊等  
    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
     
	//宣告按鈕部分
    cocos2d::extension::CCScale9Sprite *btn_noraml = cocos2d::extension::CCScale9Sprite::create("CloseSelected.png");//宣告CloseNormal圖片,用於按鈕沒被按下時的背景圖片
	cocos2d::extension::CCScale9Sprite *btn_down = cocos2d::extension::CCScale9Sprite::create("CloseNormal.png");//宣告CloseSelected圖片,用於按鈕被按下時的背景圖片
	CCLabelTTF *labelTTF = CCLabelTTF::create("Click me!","arial",72);//宣告一個文字Click me!第2個引數是字型,僅能使用Resource資料夾中fonts資料夾中的字型,第3個引數是字型大小
	CCControlButton *controlButton = CCControlButton::create(labelTTF,btn_noraml);//宣告一個按鈕,第一個引數是宣告的文字、第二個引數是宣告的圖片
	controlButton->setBackgroundSpriteForState(btn_down,CCControlStateHighlighted);//設定按鈕被按下時候的背景圖片,第一個引數是宣告的圖片,第二個引數是一個定值常量
	controlButton->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));//按鈕的中心點位於螢幕的中央  
	controlButton->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::menuCloseCallback), CCControlEventTouchDown);//宣告按鈕的事件,第三個引數為定值常量意為,點選此按鈕之後,觸發第二個函式所宣告的,下面給出的HelloWorld::menuCloseCallback(){}中所有程式碼。
	this->addChild(controlButton);//將此按鈕新增到場景,預設不自動新增

	//宣告檔案部分
	CCLabelTTF *label1 = CCLabelTTF::create("0 hits","arial",36);//宣告一個文字0 hits!
	label1->setPosition(ccp(visibleSize.width/2,visibleSize.height-visibleSize.height/6));//按鈕的中心點位於螢幕的中央  
	this->addChild(label1,0,1);//新增此文字到場景中,與普通的this->addChild(label1)不同,第3個引數可以理解為此檔案的Tag,也就是類似其他程式語言中id的東西,一會兒,按鈕點選觸發menuCloseCallback函式的時候,此函式可以通過this->getChildByTag(1);獲取這個文字

    return true;
}

//controlButton被點選時候,所觸發的事件menuCloseCallback
void HelloWorld::menuCloseCallback(CCObject* pSender,CCControlEvent event)
{
	hits++;//點選此數+1
	CCLabelTTF *label=(CCLabelTTF*)this->getChildByTag(1);//獲取Tag1為1的元件,用label指標指向
	label->setString(CCString::createWithFormat("%d hits",hits)->getCString());//將其修改為XXhits,其中createWithFormat的使用同C語言的printf,不贅述
}

幾個關鍵點:

(1)menuCloseCallback()與init()通過init()新增元件addChild時候,設定labelTTF的Tag,而menuCloseCallback()通過getChildByTag獲取Tag為1的元件,並於安卓的findviewbyid強制型別轉換所聯絡起來,產生互動。

(2)關於眾元件在被addChild新增之前,皆要通過setPosition方法設定其位置。其中setPosition中的座標,必須存活的ccp這個方法中,ccp中不能直接寫數字,建議通過Cocos2dx的螢幕百分比來擺放元件。本程式的佈局如下圖:


Cocos2dx的螢幕座標是,以螢幕左下角為原點,以螢幕右邊為X軸正方向,螢幕上方為Y正方向的座標軸。其中X軸的取值範圍為0到visibleSize.width,Y則為0到visibleSize.height,其中visibleSize需要通過CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();所宣告。