【Cocos2dx】使用CCControlButton创建按钮、按钮点击事件,点击事件中的组件获取,setPosition的坐标问题

本文详细介绍了如何在Cocos2dx游戏引擎中使用按钮,包括创建按钮、设置按钮状态图片、添加点击事件及响应处理。同时展示了如何在场景中获取并操作组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

按钮不仅在游戏,在任何地方都是不可或缺却又是最基本的东西。在游戏引擎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();所声明。

<think>好的,我现在需要帮助用户解决在Cocos2d-x中使用C++实现按钮功能的问题。首先,我得回忆一下Cocos2d-x的UI系统,特别是ccui模块的相关知识。根据用户提供的引用,特别是引用[1]中的示例,里面提到了Lua的代码,但用户需要的是C++版本。所以我要将Lua示例转换成C++的写法。 首先,按钮创建。在C++中,应该使用ccui::Button的create方法,并传入正常状态和按下状态的图片路径。记得检查资源是否正确加载,路径是否正确,避免运行时错误。 然后是设置按钮的位置。Cocos2d-x使用setPosition方法,参数是Vec2类型的坐标。用户可能需要了解坐标系的原点位置,通常是左下角,但可能根据设计分辨率有所不同,这点需要注意。 接下来是点击事件的绑定。在Lua中是addClickEventListener,C++中同样有这个函数,但需要传递一个回调函数。这里要使用lambda表达式或者成员函数作为回调。需要提醒用户注意内存管理,避免循环引用,特别是如果回调中使用this指针时,要使用弱引用或者适当的处理。 添加按钮到场景中,使用addChild方法。这部分相对直接,但用户可能需要知道添加到哪个节点,比如当前层或场景。 另外,引用[4]提到了导演类和视口的设置,虽然这部分可能与按钮实现不直接相关,但如果在不同平台遇到显示问题,可能需要检查视口设置是否正确。比如,Windows平台下创建GLView的Rect参数是否合适,确保按钮位置在可视范围内。 还需要考虑资源管理,比如图片资源是否添加到项目资源目录中,以及在代码中引用的路径是否正确。如果用户遇到按钮不显示的问题,可能和资源路径错误有关,需要提示他们检查路径。 用户可能还想知道如何设置按钮的文字,或者自定义按钮样式。这时候可以提到setTitleText和setTitleFontSize等方法,以及如何为不同状态(正常、按下、禁用)设置不同的图片。 性能方面,按钮创建和事件处理通常不会有大问题,但如果有大量按钮,可能需要考虑使用缓存或者对象池优化。不过对于基本功能,可能不需要涉及这些高级内容。 最后,根据用户的需求生成相关问题,比如按钮事件处理的其他方法、如何调整按钮样式、多平台适配问题等。这些问题可以帮助用户深入理解按钮的实现和扩展应用。 总结步骤:创建按钮、设置位置、绑定点击事件、添加到场景,同时注意资源路径和平台适配。确保代码示例正确,并涵盖常见问题的解决方法。</think>### 如何在Cocos2d-x中使用C++实现按钮功能 #### 1. **创建按钮对象** 使用`ccui::Button::create`方法创建按钮,需指定按钮的默认状态图片和按下状态图片路径: ```cpp #include "ui/CocosGUI.h" // 创建按钮(需确保图片路径正确) auto button = ui::Button::create("button_normal.png", "button_pressed.png"); if (button == nullptr) { // 处理图片加载失败 return false; } ``` #### 2. **设置按钮位置** 使用`setPosition`定义按钮在屏幕中的坐标(以左下角为原点): ```cpp button->setPosition(Vec2(200, 300)); // 设置坐标(200,300) ``` #### 3. **绑定点击事件** 通过`addClickEventListener`添加点击回调函数: ```cpp button->addClickEventListener([&](Ref* sender) { // 点击事件逻辑 CCLOG("Button clicked!"); // 可在此触发游戏逻辑(如切换场景、播放音效等) }); ``` #### 4. **将按钮添加到场景** 将按钮添加为当前层的子节点: ```cpp this->addChild(button); // 假设在Layer或Scene的子类中 ``` #### 5. **进阶功能** - **设置按钮文字** 使用`setTitleText`和`setTitleFontSize`添加文字: ```cpp button->setTitleText("开始游戏"); button->setTitleFontSize(20); ``` - **禁用按钮状态** 为禁用状态设置额外图片并控制交互: ```cpp button->loadTextureDisabled("button_disabled.png"); button->setEnabled(false); // 禁用按钮 ``` #### 6. **注意事项 - **资源路径问题** 图片需放在项目`Resources`目录下,若在子目录中则需添加路径前缀(如`"ui/button_normal.png"`)[^1]。 - **多平台适配** 不同平台的视口设置可能影响按钮位置,需检查设计分辨率配置(参考`GLViewImpl::createWithRect`的参数)[^4]。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值