#ifndef HROCKER_H #define HROCKER_H #include "cocos2d.h" using namespace cocos2d; //用於標識搖桿與搖桿的背景 typedef enum{ tag_rocker, tag_rockerBG, }tagForHRocker; class HRocker:public CCLayer { public: HRocker(void); ~HRocker(void); //建立搖桿(搖桿的操作題圖片資源名,搖桿背景圖片資源名,起始座標) static HRocker* createHRocker(const char *rockerImageName,const char *rockerBGImageName,CCPoint position); //啟動搖桿(顯示搖桿、監聽搖桿觸屏事件) void startRocker(bool _isStopOther); //停止搖桿(隱藏搖桿,取消搖桿的觸屏監聽) void stopRocker(); CREATE_FUNC(HRocker); private: //自定義初始化函式 void rockerInit(const char* rockerImageName,const char* rockerBGImageName,CCPoint position); //是否可操作搖桿 bool isCanMove; //獲取當前搖桿與使用者觸屏點的角度 float getRad(CCPoint pos1,CCPoint pos2); //搖桿背景的座標 CCPoint rockerBGPosition; //搖桿背景的半徑 float rockerBGR; //觸屏事件 virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); }; #endif
#include "HRocker.h" HRocker::HRocker(void) { } HRocker::~HRocker(void) { } //建立搖桿(搖桿的操作題圖片資源名,搖桿背景圖片資源名,起始座標) HRocker* HRocker::createHRocker(const char *rockerImageName,const char *rockerBGImageName,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,CCPoint position) { CCSprite *spRockerBG = CCSprite::create(rockerBGImageName); spRockerBG->setPosition(position); spRockerBG->setVisible(false); addChild(spRockerBG,0,tag_rockerBG); CCSprite *spRocker = CCSprite::create(rockerImageName); spRocker->setPosition(position); spRocker->setVisible(false); addChild(spRocker,1,tag_rocker); rockerBGPosition = position; rockerBGR = spRockerBG->getContentSize().width*0.5; } //啟動搖桿(顯示搖桿、監聽搖桿觸屏事件) void HRocker::startRocker(bool _isStopOther) { CCSprite *rocker = (CCSprite*)this->getChildByTag(tag_rocker); rocker->setVisible(true); CCSprite *rockerBG = (CCSprite *)this->getChildByTag(tag_rockerBG); rockerBG->setVisible(true); CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-1,_isStopOther); } //停止搖桿(隱藏搖桿,取消搖桿的觸屏監聽) void HRocker::stopRocker() { CCSprite *rocker = (CCSprite *)this->getChildByTag(tag_rocker); rocker->setVisible(false); CCSprite * rockerBG = (CCSprite *)this->getChildByTag(tag_rockerBG); rockerBG->setVisible(false); CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); } //獲取當前搖桿與使用者觸屏點的角度 float HRocker::getRad(CCPoint pos1,CCPoint pos2) { float px1 = pos1.x; float py1 = pos1.y; float px2 = pos2.x; float py2 = pos2.y; //得到兩點x的距離 float x = px2 - px1; //得到兩點y的距離 float y = py1 - py2; //算出斜邊長度 float xie = sqrt(pow(x,2) + pow(y,2)); //得到這個角度的餘弦值(通過三角函式中的店裡:角度餘弦值=斜邊/斜邊) float cosAngle = x / xie; //通過反餘弦定理獲取到期角度的弧度 float rad = acos(cosAngle); //注意:當觸屏的位置Y座標<搖桿的Y座標,我們要去反值-0~-180 if (py2 < py1) { rad = -rad; } return rad; } CCPoint getAngelePosition(float r,float angle){ return ccp(r*cos(angle),r*sin(angle)); } //抬起事件 bool HRocker::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { CCPoint point = pTouch->getLocation(); CCSprite *rocker = (CCSprite *)this->getChildByTag(tag_rocker); if (rocker->boundingBox().containsPoint(point)) { isCanMove = true; } return true; } //移動事件 void HRocker::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) { if (!isCanMove) { return; } CCPoint point = pTouch->getLocation(); CCSprite *rocker = (CCSprite *)this->getChildByTag(tag_rocker); //判斷兩個圓的圓心距是否大於搖桿背景的半徑 if (sqrt(pow((rockerBGPosition.x - point.x),2) + pow((rockerBGPosition.y - point.y),2)) >= rockerBGR) { //得到搖桿與觸屏點所形成的角度 float angle = getRad(rockerBGPosition,point); //保證內部小圓運動的長度限制 rocker->setPosition(ccpAdd(getAngelePosition(rockerBGR,angle),ccp(rockerBGPosition.x,rockerBGPosition.y))); } else { //當沒有超過,讓搖桿跟隨使用者觸屏點移動即可 rocker->setPosition(point); } } //離開事件 void HRocker::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) { if (!isCanMove) { return; } CCSprite *rockerBG = (CCSprite*)this->getChildByTag(tag_rockerBG); CCSprite *rocker = (CCSprite*)this->getChildByTag(tag_rocker); rocker->stopAllActions(); rocker->runAction(CCMoveTo::create(0.08,rockerBG->getPosition())); isCanMove = false; }
// on "init" you need to initialize your instance bool HelloWorld::init() { bool bRet = false; do { HRocker* rocker = HRocker::createHRocker("rocker.png","rockerBG.png",ccp(240,160)); addChild(rocker); rocker->startRocker(true); bRet = true; } while (0); return bRet; }