利用C++11新特性重构自定义Button
2016-07-27 21:33
525 查看
使用C++11一些新特性将上篇的自定义Button重构
// // CustomButton.h // CustomButton // // Created by Forest on 16/5/6. // // #ifndef __CustomButton__CustomButton__ #define __CustomButton__CustomButton__ #include <stdio.h> #include "cocos2d.h" #include <functional> #include <algorithm> USING_NS_CC; enum class ButtonType{ STANDARD, CHANGE_IMAGE, SHAKE }; enum class TouchState{ Began, Moved, Ended }; class CustomButton; typedef std::function<void(CustomButton*)> buttonCallBack; class CustomButton:public Node{ private: Sprite* m_normalImage; Sprite* m_selectedImage; ButtonType m_type; buttonCallBack m_callBack; Touch* m_touch; bool m_isInside; Vec2 m_beganPoint; EventListenerTouchAllAtOnce* m_listener; CustomButton(); ~CustomButton(); bool init(const std::string& normalImage,const buttonCallBack& callBack); bool initChangeImageButton(const std::string& normalImage,const std::string& selectedImage,const buttonCallBack& callBack); bool isTouchInside(Touch* touch); void executeEvent(); void standardEvent(); void changeImageEvent(TouchState state); void shakeEvent(TouchState state); void touchBegan(const std::vector<Touch*>& touches,Event* event); void touchMoved(const std::vector<Touch*>& touches,Event* event); void touchEnded(const std::vector<Touch*>& touches,Event* event); public: static CustomButton* createButton(const std::string& normalImage,const buttonCallBack& callBack); static CustomButton* createChangeImageButton(const std::string& normalImage,const std::string& selectedImage,const buttonCallBack& callBack); static CustomButton* createShakeButton(const std::string& normalImage,const buttonCallBack& callBack); void startButton(); void stopButton(); void setButtonType(ButtonType type); }; #endif /* defined(__CustomButton__CustomButton__) */
// // CustomButton.cpp // CustomButton // // Created by Forest on 16/5/6. // // #include "CustomButton.h" CustomButton::CustomButton():m_callBack(nullptr),m_isInside(false){ } CustomButton::~CustomButton(){ }; CustomButton* CustomButton::createButton(const std::string& normalImage,const buttonCallBack& callBack){ CustomButton* button = new CustomButton(); if (button && button->init(normalImage, callBack)) { button->setButtonType(ButtonType::STANDARD); button->autorelease(); return button; } CC_SAFE_DELETE(button); return nullptr; } bool CustomButton::init(const std::string& normalImage,const buttonCallBack& callBack){ if (!Node::init()) { return false; } m_normalImage = Sprite::create(normalImage); this->addChild(m_normalImage); m_normalImage->setVisible(false); m_callBack = callBack; this->startButton(); return true; } CustomButton* CustomButton::createChangeImageButton(const std::string& normalImage, const std::string& selectedImage, const buttonCallBack& callBack){ CustomButton* button = new CustomButton(); if (button && button->initChangeImageButton(normalImage, selectedImage, callBack)) { button->setButtonType(ButtonType::CHANGE_IMAGE); button->autorelease(); return button; } CC_SAFE_DELETE(button); return nullptr; } bool CustomButton::initChangeImageButton(const std::string& normalImage, const std::string& selectedImage, const buttonCallBack& callBack){ if (!this->init(normalImage,callBack)) { return false; } m_selectedImage = Sprite::create(selectedImage); this->addChild(m_selectedImage); m_selectedImage->setVisible(false); return true; } CustomButton* CustomButton::createShakeButton(const std::string& normalImage, const buttonCallBack& callBack){ CustomButton* button = new CustomButton(); if (button && button->init(normalImage, callBack)) { button->setButtonType(ButtonType::SHAKE); button->autorelease(); return button; } CC_SAFE_DELETE(button); return nullptr; } void CustomButton::setButtonType(ButtonType type){ m_type = type; } void CustomButton::startButton(){ m_normalImage->setVisible(true); m_listener = EventListenerTouchAllAtOnce::create(); m_listener->onTouchesBegan = std::bind(&CustomButton::touchBegan,this,std::placeholders::_1,std::placeholders::_2); m_listener->onTouchesMoved = std::bind(&CustomButton::touchMoved,this,std::placeholders::_1,std::placeholders::_2); m_listener->onTouchesEnded = std::bind(&CustomButto e442 n::touchEnded,this,std::placeholders::_1,std::placeholders::_2); this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(m_listener, this); } void CustomButton::stopButton(){ m_normalImage->setVisible(true); this->getEventDispatcher()->removeEventListener(m_listener); } void CustomButton::touchBegan(const std::vector<Touch *> &touches, cocos2d::Event *event){ std::vector<Touch*>::const_iterator it = find_if(touches.cbegin(),touches.cend(),[this](Touch* touch){ return this->isTouchInside(touch); }); if (it != touches.cend()) { m_touch = *it; m_beganPoint = m_touch->getLocation(); m_isInside = true; switch (m_type) { case ButtonType::STANDARD: break; case ButtonType::CHANGE_IMAGE: this->changeImageEvent(TouchState::Began); break; case ButtonType::SHAKE: this->shakeEvent(TouchState::Began); break; } } } void CustomButton::touchMoved(const std::vector<Touch *> &touches, cocos2d::Event *event){ std::vector<Touch*>::const_iterator it = find_if(touches.cbegin(),touches.cend(),[this](Touch* touch){ return m_touch == touch ; }); if (it != touches.cend()){ if (this->isTouchInside(*it)) { switch (m_type) { case ButtonType::STANDARD: break; case ButtonType::CHANGE_IMAGE: this->changeImageEvent(TouchState::Moved); break; case ButtonType::SHAKE: this->shakeEvent(TouchState::Moved); break; } }else{ m_isInside = false; } } } void CustomButton::touchEnded(const std::vector<Touch *> &touches, cocos2d::Event *event){ std::vector<Touch*>::const_iterator it = find_if(touches.cbegin(),touches.cend(),[this](Touch* touch){ return m_touch == touch ; }); if (it != touches.cend()){ Touch* touch = *it ; if (this->isTouchInside(touch) && m_isInside) { Vec2 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 ButtonType::STANDARD: this->standardEvent(); break; case ButtonType::CHANGE_IMAGE: this->changeImageEvent(TouchState::Ended); break; case ButtonType::SHAKE: this->shakeEvent(TouchState::Ended); break; } } }else{ switch (m_type) { case ButtonType::STANDARD: break; case ButtonType::CHANGE_IMAGE: m_normalImage->setVisible(true); m_selectedImage->setVisible(false); break; case ButtonType::SHAKE: // m_normalImage->setScale(1.0f); // m_normalImage->stopAllActions(); break; } } } } bool CustomButton::isTouchInside(Touch* touch){ Vec2 p = touch->getLocation(); Vec2 point = m_normalImage->convertToNodeSpace(p); Rect rect(0.0f,0.0f,m_normalImage->getContentSize().width,m_normalImage->getContentSize().height); return rect.containsPoint(point); } void CustomButton::executeEvent(){ if (m_callBack) { m_callBack(this); } } void CustomButton::standardEvent(){ this->executeEvent(); } void CustomButton::changeImageEvent(TouchState state){ switch (state) { case TouchState::Began: m_normalImage->setVisible(false); m_selectedImage->setVisible(true); break; case TouchState::Moved: m_normalImage->setVisible(false); m_selectedImage->setVisible(true); break; case TouchState::Ended: m_normalImage->setVisible(true); m_selectedImage->setVisible(false); this->executeEvent(); break; } } void CustomButton::shakeEvent(TouchState state){ switch (state) { case TouchState::Began: m_normalImage->stopAllActions(); m_normalImage->setScaleX(1.2); m_normalImage->setScaleY(0.8); break; case TouchState::Moved: { ScaleTo* scaleTo = ScaleTo::create(1.5, 1); EaseBounceOut* bounce = EaseBounceOut::create(scaleTo); m_normalImage->runAction(bounce); } break; case TouchState::Ended: { ScaleTo* scaleTo = ScaleTo::create(0.8, 1); EaseBounceOut* bounce = EaseBounceOut::create(scaleTo); m_normalImage->runAction(bounce); this->executeEvent(); } break; } }
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "CustomButton.h" class HelloWorld : public cocos2d::Layer { public: // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::Scene* createScene(); // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // implement the "static create()" method manually CREATE_FUNC(HelloWorld); private: void customButtonCallBack(CustomButton* button); }; #endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h" #include "cocostudio/CocoStudio.h" #include "ui/CocosGUI.h" USING_NS_CC; using namespace cocostudio::timeline; Scene* HelloWorld::createScene() { // 'scene' is an autorelease object auto scene = Scene::create(); // 'layer' is an autorelease object auto 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 ( !Layer::init() ) { return false; } auto rootNode = CSLoader::createNode("MainScene.csb"); addChild(rootNode); Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); auto button = CustomButton::createButton("Icon-144.png", std::bind(&HelloWorld::customButtonCallBack, this,std::placeholders::_1)); button->setName("STANDARD"); button->setPosition(Vec2(origin.x+150,origin.y+visibleSize.height/2)); this->addChild(button); auto button2 = CustomButton::createChangeImageButton("Icon-144.png", "baowu_007.png", std::bind(&HelloWorld::customButtonCallBack,this,std::placeholders::_1)); button2->setName("CHANGEIMAGE"); button2->setPosition(button->getPositionX(), button->getPositionY()-200); this->addChild(button2); auto button3 = CustomButton::createShakeButton("Icon-144.png", std::bind(&HelloWorld::customButtonCallBack,this,std::placeholders::_1)); button3->setName("SHAKE"); button3->setPosition(button->getPositionX(),button->getPositionY()+200); this->addChild(button3); return true; } void HelloWorld::customButtonCallBack(CustomButton *button){ log("---%s",button->getName().c_str()); }
相关文章推荐
- 深度探索c++对象模型-阅读笔记
- c语言指针操作
- Leetcode 73. Set Matrix Zeroes (Medium) (cpp)
- c++重载、覆盖、隐藏
- 由static_cast和dynamic_cast到C++对象占用内存的分析
- stack应用--矩阵乘法次数计算
- 用Mac终端编写,编译C程序的实例
- [kuangbin带你飞]专题十四 数论基础-C - Aladdin and the Flying Carpet
- 简单点,switch-case的结构简单点~ C语言学习(4)
- c++内联函数(inline)使用详解
- Leetcode 229. Majority Element II (Medium) (cpp)
- Flatten Binary Tree to Linked List
- C ++ 虚函数 (转)
- C语言中printf(),sprintf(),scanf(),sscanf()的用法和区别
- c++实现图像旋转任意角度
- 趣味100道C语言程序题num six
- c++设计模式之模板模式
- 设计模式之观察者设计模式(C++实现)
- C语言学习
- errno、stderr、perror函数和strerror函数