cocos2d-x游戏摇杆的实现方法

出处Himi    http://www.himigame.com   对于想学移动游戏开发的同仁强烈推荐!!!

虚拟摇杆类起名为:HRocker 

下面是 HRocker.h 文件:

#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文件

#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;
}

示例项目代码:

HRocker* rocker = HRocker::createHRocker("rocker.png", "rockerBG.png", ccp(240, 160));
    addChild(rocker);
    rocker->startRocker(true);



你可能感兴趣的:(cocos2d-x游戏摇杆的实现方法)