【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】使用CCControlButton创建按钮、按钮点击事件,点击事件中的组件获取,setPosition的坐标问题_第1张图片

Cocos2dx的屏幕坐标是,以屏幕左下角为原点,以屏幕右边为X轴正方向,屏幕上方为Y正方向的坐标轴。其中X轴的取值范围为0到visibleSize.width,Y则为0到visibleSize.height,其中visibleSize需要通过CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();所声明。

你可能感兴趣的:(按钮,cocos2dx,布局,回调函数,游戏引擎)