【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此檔案修改之後的全程式碼如下:
3、之後對HelloWorldScene.cpp這個檔案中的bool HelloWorld::init(){}場景初始化佈局函式,原本Helloworld場景中,右下角按鈕的點選回撥函式menuCloseCallback進行修改。修改之後的程式碼如下,詳見註釋:#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); };
#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();所宣告。