这篇文章中,我们讲下虚拟摇杆,一般游戏中都会有虚拟摇杆,看了下别人写的Joystick,发现版本都是比较老的了,一些api已经改变了,稍微修改了下。OK,上代码:
摇杆类头文件:
- #include "cocos2d.h"
- using namespace cocos2d;
- class HRocker :public CCLayer {
- public :
- //初始化 aPoint是摇杆中心 aRadius是摇杆半径 aJsSprite是摇杆控制点 aJsBg是摇杆背景
- static HRocker* HRockerWithCenter(CCPoint aPoint ,float aRadius ,CCSprite* aJsSprite,CCSprite* aJsBg,bool _isFollowRole);
- //启动摇杆
- void Active();
- //解除摇杆
- void Inactive();
- CCPoint getDirection();
- private:
- HRocker * initWithCenter(CCPoint aPoint ,float aRadius ,CCSprite* aJsSprite,CCSprite* aJsBg,bool _isFollowRole);
- CCPoint centerPoint;//摇杆中心
- CCPoint currentPoint;//摇杆当前位置
- bool active;//是否激活摇杆
- float radius;//摇杆半径
- CCSprite *jsSprite;
- bool isFollowRole;//是否跟随用户点击
- float getVelocity();
- void updatePos(CCTime dt);
- virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
- virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
- virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
- CREATE_FUNC(HRocker);
- };
.cpp:
- #include "Joystick.h"
- using namespace cocos2d;
- void HRocker::updatePos(CCTime dt){
- jsSprite->setPosition(ccpAdd(jsSprite->getPosition(),ccpMult(ccpSub(currentPoint, jsSprite->getPosition()),0.5)));
- }
- //启动摇杆
- void HRocker::Active()
- {
- if (!active) {
- active=true;
- schedule(schedule_selector(HRocker::updatePos));//添加刷新函数
- CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0,false);
- }else {
- }
- }
- //解除摇杆
- void HRocker::Inactive()
- {
- if (active) {
- active=false;
- this->unschedule(schedule_selector(HRocker::updatePos));//删除刷新
- CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);//删除委托
- }else {
- }
- }
- //摇杆方位
- CCPoint HRocker::getDirection()
- {
- return ccpNormalize(ccpSub(centerPoint, currentPoint));
- }
- //摇杆力度
- float HRocker::getVelocity()
- {
- return ccpDistance(centerPoint, currentPoint);
- }
- HRocker* HRocker:: HRockerWithCenter(CCPoint aPoint ,float aRadius ,CCSprite* aJsSprite,CCSprite* aJsBg,bool _isFollowRole){
- HRocker *jstick=HRocker::create();
- jstick->initWithCenter(aPoint,aRadius,aJsSprite,aJsBg,_isFollowRole);
- return jstick;
- }
- bool HRocker::ccTouchBegan(CCTouch* touch, CCEvent* event)
- {
- if (!active)
- return false;
- this->setVisible(true);
- CCPoint touchPoint = touch->getLocationInView();
- touchPoint = CCDirector:: sharedDirector()->convertToGL(touchPoint);
- if(!isFollowRole){
- if (ccpDistance(touchPoint, centerPoint) > radius){
- return false;
- }
- }
- currentPoint = touchPoint;
- if(isFollowRole){
- centerPoint=currentPoint;
- jsSprite->setPosition(currentPoint);
- this->getChildByTag(88)->setPosition(currentPoint);
- }
- return true;
- }
- void HRocker::ccTouchMoved(CCTouch* touch, CCEvent* event)
- {
- CCPoint touchPoint = touch->getLocationInView();
- touchPoint = CCDirector:: sharedDirector()->convertToGL(touchPoint);
- if (ccpDistance(touchPoint, centerPoint) > radius)
- {
- currentPoint =ccpAdd(centerPoint,ccpMult(ccpNormalize(ccpSub(touchPoint, centerPoint)), radius));
- }else {
- currentPoint = touchPoint;
- }
- }
- void HRocker::ccTouchEnded(CCTouch* touch, CCEvent* event)
- {
- currentPoint = centerPoint;
- if(isFollowRole){
- this->setVisible(false);
- }
- }
- HRocker* HRocker::initWithCenter(CCPoint aPoint ,float aRadius ,CCSprite* aJsSprite,CCSprite* aJsBg,bool _isFollowRole){
- isFollowRole =_isFollowRole;
- active = false;
- radius = aRadius;
- if(!_isFollowRole){
- centerPoint =aPoint;
- }else{
- centerPoint =ccp(0,0);
- }
- currentPoint = centerPoint;
- jsSprite = aJsSprite;
- jsSprite->setPosition(centerPoint);
- aJsBg->setPosition(centerPoint);
- aJsBg->setTag(88);
- this->addChild(aJsBg);
- this->addChild(jsSprite);
- if(isFollowRole){
- this->setVisible(false);
- }
- this->Active();//激活摇杆
- return this;
- }
OK,我们看下实现加载这个类:
- //摇杆
- CCSprite *controlSprite=CCSprite::create("cen.png");
- //摇杆背景
- CCSprite *bgSprite=CCSprite::create("control_bg.png");
- joystick=HRocker::HRockerWithCenter(ccp(200.0f,200.0f),60.0f ,controlSprite ,bgSprite,false);
- this->addChild(joystick,1);
- this->scheduleUpdate();
发现里面有个getDirection ()方法,可以作为判断方向,大家可以试试,我们看下效果图: