用C++函数指针封装自定义的Button
2016-07-26 22:08
861 查看
自定义Button类:
在HelloWorld场景中使用:
运行效果:
// // CustomButton.h // fun_point_button // // Created by Forest on 16/4/28. // // #ifndef __fun_point_button__CustomButton__ #define __fun_point_button__CustomButton__ #include <stdio.h> #include "cocos2d.h" USING_NS_CC; typedef enum { STANDARD, CHANGE_IMG, SHAKE }ButtonType; typedef enum { Began, Moved, Ended }TouchState; class CustomButton; typedef void (CCObject::*FUNCTION)(CustomButton*); #define function_selector(_SEC) (FUNCTION)(&_SEC) class CustomButton:public CCNode , public CCStandardTouchDelegate { public: // 创建标准button static CustomButton* createButton(const char* normalImage,CCObject* target,FUNCTION callBack); // 创建换图button static CustomButton* createChangeImageButton(const char* normalImage,const char* selectedImage,CCObject* target,FUNCTION callBack); // 创建抖动button static CustomButton* createShakeButton(const char* normalImage,CCObject* target,FUNCTION callBack); CC_SYNTHESIZE(int, m_tag, Tag); CC_SYNTHESIZE(std::string, m_name, Name); void setButtonType(ButtonType type); // 开启按钮 void startButton(); // 结束按钮 void stopButton(); private: CustomButton(); ~CustomButton(); void onEnter(); void onExit(); // 触摸方法 virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) ; virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent) ; virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent) ; bool initButton(const char* normalImage,CCObject* target,FUNCTION callBack); bool initChangeImageButton(const char* normalImage,const char* selectedImage,CCObject* target,FUNCTION callBack); CCSprite* m_normalImage; CCSprite* m_selectedImage; ButtonType m_type; bool m_isInside; CCPoint m_beganPoint; CCObject* m_target; FUNCTION m_callBack; CCTouch* m_touch; bool isTouchInside(CCTouch* touch); // 执行回调 void executeEvent(); // 标准按钮处理 void standardEvent(); // 换图按钮处理 void changeImageEvent(TouchState state); // 抖动按钮处理 void shakeEvent(TouchState state); }; #endif /* defined(__fun_point_button__CustomButton__) */
// // CustomButton.cpp // fun_point_button // // Created by Forest on 16/4/28. // // #include "CustomButton.h" CustomButton::CustomButton(){ } CustomButton::~CustomButton(){ } void CustomButton::onEnter(){ CCNode::onEnter(); } void CustomButton::onExit(){ CCNode::onExit(); this->stopButton(); } CustomButton* CustomButton::createButton(const char *normalImage, cocos2d::CCObject *target, FUNCTION callBack){ CustomButton* button = new CustomButton(); if (button && button->initButton(normalImage, target, callBack)) { button->setButtonType(STANDARD); button->autorelease(); return button; } CC_SAFE_DELETE(button); return NULL; } bool CustomButton::initButton(const char *normalImage, cocos2d::CCObject *target, FUNCTION callBack){ if (!CCNode::init()) { return false; } m_normalImage = CCSprite::create(normalImage); this->addChild(m_normalImage); m_normalImage->setVisible(false); m_target = target; m_callBack = callBack; this->startButton(); return true; } CustomButton* CustomButton::createChangeImageButton(const char *normalImage, const char *selectedImage, cocos2d::CCObject *target, FUNCTION callBack){ CustomButton* button = new CustomButton(); if (button && button->initChangeImageButton(normalImage, selectedImage, target, callBack)) { button->setButtonType(CHANGE_IMG); button->autorelease(); return button; } CC_SAFE_DELETE(button); return NULL; } bool CustomButton::initChangeImageButton(const char *normalImage, const char *selectedImage, cocos2d::CCObject *target, FUNCTION callBack){ if (!this->initButton(normalImage, target, callBack)) { return false; } m_selectedImage = CCSprite::create(selectedImage); this->addChild(m_selectedImage); m_selectedImage->setVisible(false); return true; } CustomButton* CustomButton::createShakeButton(const char *normalImage, cocos2d::CCObject *target, FUNCTION callBack){ CustomButton* button = new CustomButton(); if (button && button->initButton(normalImage, target, callBack)) { button->setButtonType(SHAKE); button->autorelease(); return button; } CC_SAFE_DELETE(button); return NULL; } void CustomButton::setButtonType(ButtonType type){ m_type = type; } // 显示 注册 开始按钮 void CustomButton::startButton(){ m_normalImage->setVisible(true); // 会使引用计数 +1 CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0); } // 隐藏 注销 结束按钮 void CustomButton::stopButton(){ m_normalImage->setVisible(false); CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); } // 触摸方法 void CustomButton::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){ CCSetIterator iter = pTouches->begin(); while (iter != pTouches->end()) { CCTouch* touch = (CCTouch*)(*iter); if (this->isTouchInside(touch)) { m_touch = touch; m_beganPoint = touch->getLocation(); m_isInside = true; switch (m_type) { case STANDARD: break; case CHANGE_IMG: this->changeImageEvent(Began); break; case SHAKE: this->shakeEvent(Began); break; default: break; } break; } ++iter; } } void CustomButton::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){ CCSetIterator iter = pTouches->begin(); while (iter != pTouches->end()) { CCTouch* touch = (CCTouch*)(*iter); ++iter; if (touch != m_touch) { continue; } if (this->isTouchInside(touch)) { if (!m_isInside) { m_isInside = false; } switch (m_type) { case STANDARD: break; case CHANGE_IMG: this->changeImageEvent(Moved); break; case SHAKE: this->shakeEvent(Moved); break; default: break; } break; }else{ m_isInside = false; } } } void CustomButton::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent){ CCSetIterator iter = pTouches->begin(); while (iter != pTouches->end()) { CCTouch* touch = (CCTouch*)(*iter); ++iter; if (touch != m_touch) { continue; } if (this->isTouchInside(touch) && m_isInside) { CCPoint endPoint = touch->getLocation(); if (abs((int)m_beganPoint.x -(int)endPoint.x) < 10 && abs((int)m_beganPoint.y - (int)endPoint.y) < 10){ switch (m_type) { case STANDARD: this->standardEvent(); break; case CHANGE_IMG: this->changeImageEvent(Ended); break; case SHAKE: this->shakeEvent(Ended); break; default: break; } } break; }else{ switch (m_type) { case STANDARD: break; case CHANGE_IMG: m_normalImage->setVisible(true); m_selectedImage->setVisible(false); break; case SHAKE: m_normalImage->setScale(1.0f); m_normalImage->stopAllActions(); break; } } } } // 触摸是否在按钮上 bool CustomButton::isTouchInside(CCTouch* touch){ CCPoint p = touch->getLocation(); CCPoint point = m_normalImage->convertToNodeSpace(p); CCRect rect(0.0f, 0.0f, m_normalImage->getContentSize().width, m_normalImage->getContentSize().height); return rect.containsPoint(point); } void CustomButton::executeEvent(){ if (m_target && m_callBack) { (m_target->*m_callBack)(this); } } void CustomButton::standardEvent(){ this->executeEvent(); } void CustomButton::changeImageEvent(TouchState state){ switch (state) { case Began: m_normalImage->setVisible(false); m_selectedImage->setVisible(true); break; case Moved: m_normalImage->setVisible(false); m_selectedImage->setVisible(true); break; case Ended: m_normalImage->setVisible(true); m_selectedImage->setVisible(false); this->executeEvent(); break; default: break; } } void CustomButton::shakeEvent(TouchState state){ switch (state) { case Began: m_normalImage->stopAllActions(); m_normalImage->setScaleX(1.2); m_normalImage->setScaleY(0.8); break; case Moved: { CCScaleTo* scaleTo = CCScaleTo::create(1.5, 1); CCEaseBounceOut* bounce = CCEaseBounceOut::create(scaleTo); m_normalImage->runAction(bounce); } break; case Ended: { CCScaleTo* scaleTo = CCScaleTo::create(0.8, 1); CCEaseBounceOut* bounce = CCEaseBounceOut::create(scaleTo); m_normalImage->runAction(bounce); this->executeEvent(); } break; default: break; } }
在HelloWorld场景中使用:
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "CustomButton.h" 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); // implement the "static node()" method manually CREATE_FUNC(HelloWorld); // button callBack void buttonCallBack(CustomButton* button); CCLabelTTF* pLabel; CustomButton* button3; }; #endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h" USING_NS_CC; 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() { ////////////////////////////// // 1. super init first if ( !CCLayer::init() ) { return false; } CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); ///////////////////////////// // 2. add a menu item with "X" image, which is clicked to quit the program // you may modify it. // add a "close" icon to exit the progress. it's an autorelease object CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback)); pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 , origin.y + pCloseItem->getContentSize().height/2)); // create menu, it's an autorelease object CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); pMenu->setPosition(CCPointZero); this->addChild(pMenu, 1); ///////////////////////////// // 3. add your codes below... // add a label shows "Hello World" // create and initialize a label pLabel = CCLabelTTF::create("Hello World", "Arial", 24); // position the label on the center of the screen pLabel->setPosition(ccp(origin.x + visibleSize.width/2, origin.y + visibleSize.height - pLabel->getContentSize().height)); // add the label as a child to this layer this->addChild(pLabel, 1); // add "HelloWorld" splash screen" CCSprite* pSprite = CCSprite::create("HelloWorld.png"); // position the sprite on the center of the screen pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); // add the sprite as a child to this layer this->addChild(pSprite, 0); CustomButton* button = CustomButton::createButton("Icon-144.png", this, function_selector(HelloWorld::buttonCallBack)); button->setPosition(ccp(150, visibleSize.height/2 + origin.y)); button->setTag(10); button->setName("Standard"); this->addChild(button); CustomButton* button2 = CustomButton::createChangeImageButton("Icon-144.png", "baowu_007.png", this, function_selector(HelloWorld::buttonCallBack)); this->addChild(button2); button2->setPosition(button->getPositionX(),button->getPositionY()-200); button2->setTag(11); button2->setName("ChangeImage"); button3 = CustomButton::createShakeButton("Icon-144.png", this, function_selector(HelloWorld::buttonCallBack)); this->addChild(button3); button3->setPosition(button->getPositionX(),button->getPositionY()+200); button3->setTag(12); button3->setName("Shake"); return true; } void HelloWorld::buttonCallBack(CustomButton *button){ pLabel->setString(button->getName().c_str()); pLabel->setFontSize(30.0f); pLabel->setColor(ccYELLOW); } void HelloWorld::menuCloseCallback(CCObject* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); #else CCDirector::sharedDirector()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif #endif }
运行效果:
相关文章推荐
- C语言控制台注册登录 选择功能案例
- C++多重继承
- 大话设计模式27----解释器模式
- C++函数重载案例
- 为什么C++类定义中,数据成员不能被指定为自身类型,但可以是指向自身类型的指针或引用?
- Validate Binary Search Tree
- 【c++】初步探索c++对象模型
- C++ Primer 第三章 标准库类型string运算
- 【hdu5741】helter skelter
- C语言实验——整数位(用顺序表)
- 5-29 修理牧场
- UVALive 3266 Tian Ji -- The Horse Racing
- CodeForces 560A-Currency System in Geraldion
- UVA 748-Exponentiation
- 1112. Stucked Keyboard (20)
- C/C++定义全局变量
- 读书笔记(一)_VC++深入详解
- POJ 3041-Asteroids(二分图匹配)
- UVa - 1615 Highway 高速公路 贪心+区间选点 重庆一中高2018级竞赛班第五次测试 2016.7.26 Problem 1
- C++ - PAT - 1053. 住房空置率 (20)