使用C++委托实现全方向的摇杆
2016-07-28 21:24
801 查看
1.摇杆类
2.角色类
3.在场景中使用摇杆
运行效果:
![](https://img-blog.csdn.net/20160728211728271)
![](https://img-blog.csdn.net/20160728211755803)
![](https://img-blog.csdn.net/20160728211823892)
// // Rocker.hpp // Rocker // // Created by Forest on 16/7/11. // // #ifndef Rocker_hpp #define Rocker_hpp #include <stdio.h> #include "cocos2d.h" USING_NS_CC; class Rocker; class RockerDelegate{ public: virtual void rockerTouchBegan(Rocker* rocker,const Vec2& normalize) = 0; virtual void rockerTouchMoved(Rocker* rocker,const Vec2& normalize) = 0; virtual void rockerTouchEnded(Rocker* rocker,const Vec2& normalize) = 0; }; class Rocker : public Node { Rocker(); ~Rocker(); Sprite* m_rocker; Sprite* m_rockerBG; Touch* m_touch; EventListenerTouchAllAtOnce* m_listener; bool isTouchInside(Touch* touch); void touchBeganRocker(const Vec2& normalize); void touchMovedRocker(const Vec2& normalize); void touchEndedRocker(const Vec2& normalize); void touchesBegan(const std::vector<Touch*>& touches, Event* event); void touchesMoved(const std::vector<Touch*>& touches, Event* event); void touchesEnded(const std::vector<Touch*>& touches, Event* event); public: static Rocker* createRocker(const std::string& rockerImage,const std::string& rockerBGImage); bool initRocker(const std::string& rockerImage,const std::string& rockerBGImage); void startRocker(); void stopRocker(); CC_SYNTHESIZE(RockerDelegate*, m_rockerDelegate, RockerDelegate); }; #endif /* Rocker_hpp */
// // Rocker.cpp // Rocker // // Created by Forest on 16/7/11. // // #include "Rocker.hpp" #include <algorithm> Rocker::Rocker(): m_rocker(nullptr),m_rockerBG(nullptr),m_touch(nullptr),m_listener(nullptr) { } Rocker::~Rocker(){ } Rocker* Rocker::createRocker(const std::string &rockerImage, const std::string &rockerBGImage){ Rocker* rocker = new Rocker(); if (rocker && rocker->initRocker(rockerImage,rockerBGImage)) { rocker->autorelease(); return rocker; } CC_SAFE_DELETE(rocker); return nullptr; } bool Rocker::initRocker(const std::string &rockerImage, const std::string &rockerBGImage){ if (!Node::init()) { return false; } m_rocker = Sprite::create(rockerImage); this->addChild(m_rocker); m_rocker->setVisible(false); m_rockerBG = Sprite::create(rockerBGImage); this->addChild(m_rockerBG); m_rockerBG->setVisible(false); this->startRocker(); return true; } void Rocker::startRocker(){ m_rocker->setVisible(true); m_rockerBG->setVisible(true); m_listener = EventListenerTouchAllAtOnce::create(); m_listener->onTouchesBegan = CC_CALLBACK_2(Rocker::touchesBegan, this); m_listener->onTouchesMoved = CC_CALLBACK_2(Rocker::touchesMoved, this); m_listener->onTouchesEnded = CC_CALLBACK_2(Rocker::touchesEnded, this); this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(m_listener, this); } void Rocker::stopRocker(){ m_rocker->setVisible(false); m_rockerBG->setVisible(false); this->getEventDispatcher()->removeEventListener(m_listener); } void Rocker::touchesBegan(const std::vector<Touch *> &touches, cocos2d::Event *event){ const 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; Vec2 point = this->convertToNodeSpace(m_touch->getLocation()); m_rocker->setPosition(point); point.normalize(); this->touchBeganRocker(point); } } void Rocker::touchesMoved(const std::vector<Touch *> &touches, cocos2d::Event *event){ const std::vector<Touch*>::const_iterator it = find_if(touches.cbegin(),touches.cend(),[this](Touch* touch){ return m_touch == touch; }); if (it != touches.cend()) { Vec2 point = this->convertToNodeSpace(m_touch->getLocation()); if (this->isTouchInside(m_touch)) { m_rocker->setPosition(point); point.normalize(); this->touchMovedRocker(point); }else{ point.normalize(); Vec2 rPoint = point * m_rockerBG->getContentSize().width/2; m_rocker->setPosition(rPoint); this->touchMovedRocker(point); } } } void Rocker::touchesEnded(const std::vector<Touch *> &touches, cocos2d::Event *event){ m_rocker->stopAllActions(); m_rocker->runAction(MoveTo::create(0.1f, Vec2(0.0f, 0.0f))); this->touchEndedRocker(Vec2(0.0f, < e883 span class="hljs-number">0.0f)); } bool Rocker::isTouchInside(Touch* touch){ Vec2 point = m_rockerBG->convertToNodeSpace(touch->getLocation()); Rect rect(0.f,0.f,m_rockerBG->getContentSize().width,m_rockerBG->getContentSize().height); return rect.containsPoint(point); } void Rocker::touchBeganRocker(const Vec2& normalize){ if (m_rockerDelegate) { m_rockerDelegate->rockerTouchBegan(this, normalize); } } void Rocker::touchMovedRocker(const Vec2& normalize){ if (m_rockerDelegate) { m_rockerDelegate->rockerTouchMoved(this, normalize); } } void Rocker::touchEndedRocker(const Vec2& normalize){ if (m_rockerDelegate) { m_rockerDelegate->rockerTouchEnded(this, normalize); } }
2.角色类
// // Role.hpp // Rocker // // Created by Forest on 16/7/11. // // #ifndef Role_hpp #define Role_hpp #include <stdio.h> #include "cocos2d.h" USING_NS_CC; #define ROLE_SPEED 5 class Role : public Node { Role(); ~Role(); Animation* createAnimate(const char* frameName,const int frameCount,const float delay = 0.1); Sprite* m_role; Vec2 m_movePoint; public: enum class Dir {RIGHT , LEFT}; enum class Statue {IDLE , WALK}; CC_SYNTHESIZE(Dir, m_dir, Dir); CC_SYNTHESIZE(Statue, m_status, Statue); void roleWalk(const Vec2& normalize); void roleIdle(); void onEnter(); void onExit(); bool init(); CREATE_FUNC(Role); }; #endif /* Role_hpp */
// // Role.cpp // Rocker // // Created by Forest on 16/7/11. // // #include "Role.hpp" Role::Role(){ } Role::~Role(){ } void Role::onEnter(){ Node::onEnter(); } void Role::onExit(){ SpriteFrameCache::getInstance()->removeSpriteFramesFromFile("walk.plist"); SpriteFrameCache::getInstance()->removeSpriteFramesFromFile("idle.plist"); AnimationCache::getInstance()->removeAnimation("walk"); AnimationCache::getInstance()->removeAnimation("idle"); this->unschedule("ROLE_WALK"); Node::onExit(); } bool Role::init(){ if (!Node::init()) { return false; } SpriteFrameCache::getInstance()->addSpriteFramesWithFile("walk.plist"); SpriteFrameCache::getInstance()->addSpriteFramesWithFile("idle.plist"); // walk AnimationCache::getInstance()->addAnimation(this->createAnimate("swk_move_%02d.png", 18, 0.05), "walk"); // idle AnimationCache::getInstance()->addAnimation(this->createAnimate("swk_idle_%02d.png", 24), "idle"); m_role = Sprite::create(); this->addChild(m_role); this->roleIdle(); Size visibleSize = Director::getInstance()->getWinSize(); this->schedule([=](float d){ if (m_status == Statue::WALK) { this->setPosition(this->getPosition() + m_movePoint); if (this->getPosition().x + m_role->getContentSize().width/2 >= visibleSize.width) { this->setPositionX(visibleSize.width - m_role->getContentSize().width/2); } if (this->getPositionX() - m_role->getContentSize().width/2 <= 0) { this->setPositionX(m_role->getContentSize().width/2); } } }, 0.03, "ROLE_WALK"); return true; } Animation* Role::createAnimate(const char* frameName, const int frameCount,const float delay){ Animation* animation = Animation::create(); for (int i = 1; i <= frameCount ; i++) { std::string name = StringUtils::format(frameName,i); SpriteFrame* frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(name); animation->addSpriteFrame(frame); } animation->setDelayPerUnit(delay); animation->setLoops(-1); return animation; } void Role::roleWalk(const Vec2& normalize){ if (this->getStatue() != Statue::WALK){ this->setStatue(Statue::WALK); m_role->stopAllActions(); m_role->runAction(Animate::create(AnimationCache::getInstance()->getAnimation("walk"))); } if (normalize.x >= 0) { this->setDir(Dir::RIGHT); m_role->setScaleX(1); }else{ this->setDir(Dir::LEFT); m_role->setScaleX(-1); } m_movePoint = normalize * ROLE_SPEED ; } void Role::roleIdle(){ this->setStatue(Statue::IDLE); m_role->stopAllActions(); m_role->runAction(Animate::create(AnimationCache::getInstance()->getAnimation("idle"))); }
3.在场景中使用摇杆
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "Role.hpp" #include "Rocker.hpp" class HelloWorld : public cocos2d::Layer , public RockerDelegate { 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); void rockerTouchBegan(Rocker* rocker,const Vec2& normalize) ; void rockerTouchMoved(Rocker* rocker,const Vec2& normalize) ; void rockerTouchEnded(Rocker* rocker,const Vec2& normalize) ; private: Role* m_role; }; #endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h" USING_NS_CC; 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; } Size visibleSize = Director::getInstance()->getWinSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); auto sp = Sprite::create("HelloWorld.png"); this->addChild(sp); sp->setPosition(origin.x+visibleSize.width/2,origin.y+visibleSize.height/2); m_role = Role::create(); this->addChild(m_role); m_role->setPosition(300,300); Rocker* rocker = Rocker::createRocker("rocker.png", "rockerBG.png"); this->addChild(rocker); rocker->setPosition(100,200); rocker->setRockerDelegate(this); return true; } void HelloWorld::rockerTouchBegan(Rocker *rocker, const Vec2& normalize){ m_role->roleWalk(normalize); } void HelloWorld::rockerTouchMoved(Rocker *rocker, const Vec2& normalize){ m_role->roleWalk(normalize); } void HelloWorld::rockerTouchEnded(Rocker *rocker, const Vec2& normalize){ m_role->roleIdle(); }
运行效果:
相关文章推荐
- 一个好的讲解
- 生成全排列的省事方法
- C++ STL 之 lower_bound and upper_bound
- 【Effective C++读书笔记】篇十(条款25)
- noip2013提高组day201积木大赛
- c++设计模式之责任链模式
- Arithmetic_ 上楼梯的走法
- c++ fstream中seekg()和seekp()的用法
- C++的一大误区——深入解释直接初始化与复制初始化的区别
- C++ - PAT - 1049. 数列的片段和(20)
- VC使用动态库关于/MD与/MT的一个坑
- Best Time to Buy and Sell Stock III
- C++ 获取特定进程的CPU使用率
- 个人对一些C语言小技巧的总结(160728更新)
- C、C++算法集合
- Leetcode 90. Subsets II (Medium) (cpp)
- c++11之function_traits
- C语言学习1
- C++ - PAT - 1052. 卖个萌 (20)(栈)(三位数组)
- Effective C++_Item3笔记