您的位置:首页 > 编程语言 > C语言/C++

利用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());
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: