cocos2dx游戏摇杆的实现方法

虚拟摇杆类起名为:HRocker 
下面是 HRocker.h 文件:
[cpp] view plaincopy
#include <iostream>  
#include "cocos2d.h"  
using namespace cocos2d;  
  
//枚举型:用于标识摇杆与摇杆的背景  
typedef enum{  
      
    tag_rocker,  
    tag_rockerBG,  
      
}tagForHRocker;  
  
class HRocker : public CCLayer  
{  
public:  
    //创建摇杆,摇杆图片,摇杆背景图片,起始坐标  
    static HRocker* createHRocker(const char* rockerImageName, const char* rockerBGImageName, CCPoint position);  
      
    //启动摇杆  
    void startRocker(bool _isStopOther);  
  
    //停止摇杆  
    void stopRocker();  
  
private:  
      
    void rockerInit(const char* rockerImageName, const char* rockerBGImageName, CCPoint position);  
  
    //得到半径为r的圆周运动上一个角度应对应的x,y坐标  
    CCPoint getAnglePosition(float r, float angle);  
      
    //是否可操作摇杆  
    bool isCanMove;  
  
    //得到摇杆与用户触屏点的角度  
    float getRad(CCPoint pos1, CCPoint pos2);  
  
    //摇杆背景的坐标  
    CCPoint rockerBGPosition;  
  
    //摇杆背景的半径  
    float rockerBGR;  
  
    //触屏事件  
    virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);  
    virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);  
    virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);  
      
    CREATE_FUNC(HRocker);  
};  
  
#endif  

HRocker.cpp文件
[cpp] view plaincopy
#include "HRocker.h"  
  
HRocker* HRocker::createHRocker(const char *rockerImageName, const char *rockerBGImageName, cocos2d::CCPoint position)  
{  
    HRocker* layer = HRocker::create();  
    if(layer)  
    {  
        layer->rockerInit(rockerImageName, rockerBGImageName, position);  
        return layer;  
    }  
      
    CC_SAFE_DELETE(layer);  
    return NULL;  
      
}  
  
void HRocker::rockerInit(const char *rockerImageName, const char *rockerBGImageName, cocos2d::CCPoint position)  
{  
    //添加摇杆背景图  
    CCSprite* spRockerBG = CCSprite::create(rockerBGImageName);  
    spRockerBG->setVisible(false);  
    spRockerBG->setPosition(position);  
    addChild(spRockerBG, 0, tag_rockerBG);  
      
    //添加摇杆上方那个可移动的图  
    CCSprite* spRocker = CCSprite::create(rockerImageName);  
    spRocker->setVisible(false);  
    spRocker->setPosition(position);  
    addChild(spRocker, 1, tag_rocker);  
      
    //摇杆背景图坐标  
    rockerBGPosition = position;  
      
    //摇杆背景图半径  
    rockerBGR = spRockerBG->getContentSize().width*0.5;  
}  
  
//启动摇杆  
void HRocker::startRocker(bool _isStopOther)  
{  
    //精灵设置可见,设置监听  
    CCSprite* rocker = (CCSprite*) getChildByTag(tag_rocker);  
    rocker->setVisible(true);  
      
    CCSprite* rockerBG = (CCSprite*) getChildByTag(tag_rockerBG);  
    rockerBG->setVisible(true);  
      
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -1, _isStopOther);  
}  
  
//停止摇杆  
void HRocker::stopRocker()  
{  
    //精灵设置不可见,取消监听  
    CCSprite* rocker = (CCSprite*)getChildByTag(tag_rocker);  
    rocker->setVisible(false);  
      
    CCSprite* rockerBG = (CCSprite*)getChildByTag(tag_rockerBG);  
    rockerBG->setVisible(false);  
      
    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);  
}  
  
//得到两坐标的角度值  
float HRocker::getRad(cocos2d::CCPoint pos1, cocos2d::CCPoint pos2)  
{  
    //得到两点的坐标x,y坐标值  
    float px1 = pos1.x;  
    float py1 = pos1.y;  
    float px2 = pos2.x;  
    float py2 = pos2.y;  
      
    //求出两边长度  
    float x = px2 - px1;  
    float y = py1 - py2;  
      
    //开方   与  几次方 公式  
    float xie = sqrt(pow(x, 2) + pow(y , 2));  
    float cos = x/xie;  
      
    //反余弦定理,知道两边长求角度:cos = 邻边/斜边  
    float rad = acos(cos);  
      
    //当触屏Y坐标 <摇杆的Y坐标时,取反值  
    if(py1 > py2)  
    {  
        rad = -rad;  
    }  
      
    return rad;  
      
}  
   
//得到与角度对应的半径为r的圆上一坐标点  
CCPoint HRocker::getAnglePosition(float r, float angle)  
{  
    return ccp(r*cos(angle), r*sin(angle));  
}  
  
  
bool HRocker::ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)  
{  
    CCSprite* sp = (CCSprite*)getChildByTag(tag_rocker);  
      
    //得到触屏点坐标  
    CCPoint point = touch->getLocation();  
      
    //判断是否点击到sp这个精灵:boundingBox()精灵大小之内的所有坐标  
    if(sp->boundingBox().containsPoint(point))  
       {  
           isCanMove = true;  
       }  
  
      
    return true;  
}  
  
void HRocker::ccTouchMoved(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)  
{  
    if(!isCanMove)  
    {  
        return;  
    }  
      
    CCSprite* sp = (CCSprite*)getChildByTag(tag_rocker);  
      
    CCPoint point = touch->getLocation();  
      
    //判断两个圆心的距离是否大于摇杆背景的半径  
    if(sqrt(pow(point.x - rockerBGPosition.x, 2) + pow(point.y - rockerBGPosition.y, 2)) >= rockerBGR)  
    {  
        //得到触点与摇杆背景圆心形成的角度  
        float angle = getRad(rockerBGPosition, point);  
          
        //确保小圆运动范围在背景圆内  
        sp->setPosition(ccpAdd(getAnglePosition(rockerBGR, angle), ccp(rockerBGPosition.x, rockerBGPosition.y)));  
          
    }  
    else {  
        //触点在背景圆内则跟随触点运动  
        sp->setPosition(point);  
    }  
    
}  
  
void HRocker::ccTouchEnded(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)  
{  
    if(!isCanMove)  
    {  
        return;  
    }  
      
    CCSprite* rocker = (CCSprite*)getChildByTag(tag_rocker);  
      
    CCSprite* rockerBG = (CCSprite*)getChildByTag(tag_rockerBG);  
      
    rocker->stopAllActions();  
      
    rocker->runAction(CCMoveTo::create(0.08, rockerBG->getPosition()));  
     
    isCanMove = false;  
}  
示例项目代码:
[cpp] view plaincopy
HRocker* rocker = HRocker::createHRocker("rocker.png", "rockerBG.png", ccp(240, 160));  
    addChild(rocker);  
    rocker->startRocker(true); 
原文地址:https://www.cnblogs.com/jiackyan/p/3042568.html