Cocos2d-x 3.10 版本的模拟摇杆控制精灵移动

VS2017下测试没有问题,网上代码大多有瑕疵什么的,这个经过我一定的修改。
Joystick.cpp

#include "Joystick.h" using namespace cocos2d; //定义一个计时器,随时检测鼠标点击的位置 void HRocker::updatePos(float 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); touchListener = EventListenerTouchOneByOne::create(); touchListener->setSwallowTouches(true); touchListener->onTouchBegan = CC_CALLBACK_2(HRocker::onTouchBegan, this); touchListener->onTouchMoved = CC_CALLBACK_2(HRocker::onTouchMoved, this); touchListener->onTouchEnded = CC_CALLBACK_2(HRocker::onTouchEnded, this); // 注册事件监听机制 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); } else { } } //解除摇杆 void HRocker::Inactive() { if (active) { active = false; this->unschedule(schedule_selector(HRocker::updatePos)); //删除刷新 _eventDispatcher->removeEventListener(touchListener); //删除委托 } else { } }//摇杆方位 Vec2 HRocker::getDirection() { return ccpNormalize(ccpSub(currentPoint, centerPoint)); }//摇杆力度 float HRocker::getVelocity() { return ccpDistance(centerPoint, currentPoint); }HRocker* HRocker::HRockerWithCenter(Vec2 point, float aRadius, Sprite* aJsSprite, Sprite* aJsBg, bool _isFollowRole) { HRocker *jstick = HRocker::create(); jstick->initWithCenter(point, aRadius, aJsSprite, aJsBg, _isFollowRole); return jstick; }bool HRocker::onTouchBegan(Touch* touch, Event* event) { if (!active) return false; this->setVisible(true); Vec2 touchPoint = touch->getLocationInView(); touchPoint = Director::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::onTouchMoved(Touch* touch, Event* event) { Vec2 touchPoint = touch->getLocationInView(); touchPoint = Director::sharedDirector()->convertToGL(touchPoint); if (ccpDistance(touchPoint, centerPoint) > radius) { currentPoint = ccpAdd(centerPoint, ccpMult(ccpNormalize(ccpSub(touchPoint, centerPoint)), radius)); } else { currentPoint = touchPoint; } }void HRocker::onTouchEnded(Touch* touch, Event* event) { currentPoint = centerPoint; if (isFollowRole) { this->setVisible(false); } } HRocker* HRocker::initWithCenter(Vec2 aPoint, float aRadius, Sprite* aJsSprite, Sprite* 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); aJsBg->setOpacity(100.0f); this->addChild(aJsBg); this->addChild(jsSprite); if (isFollowRole) { this->setVisible(false); } this->Active(); //激活摇杆 return this; }

【Cocos2d-x 3.10 版本的模拟摇杆控制精灵移动】Joystick.h
#ifndef HRocker_H #define HRocker_H #include "cocos2d.h"using namespace cocos2d; class HRocker :public Layer { public: //初始化 aPoint是摇杆中心 aRadius是摇杆半径 aJsSprite是摇杆控制点 aJsBg是摇杆背景 static HRocker* HRockerWithCenter(Vec2 point, float Radius, Sprite* aJsSprite, Sprite* aJsBg, bool _isFollowRole); //启动摇杆 void Active(); //解除摇杆 void Inactive(); // 获取摇杆方向向量 Vec2 getDirection(); // 获取摇杆力度 float getVelocity(); private: EventListenerTouchOneByOne* touchListener; HRocker * initWithCenter(Vec2 point, float aRadius, Sprite* aJsSprite, Sprite* aJsBg, bool _isFollowRole); Vec2 centerPoint; //摇杆中心 Vec2 currentPoint; //摇杆当前位置 bool active; //是否激活摇杆 float radius; //摇杆半径 Sprite *jsSprite; bool isFollowRole; //是否跟随用户点击 void updatePos(float dt); virtual bool onTouchBegan(Touch *pTouch, Event *pEvent); virtual void onTouchMoved(Touch *pTouch, Event *pEvent); virtual void onTouchEnded(Touch *pTouch, Event *pEvent); CREATE_FUNC(HRocker); }; #endif

在游戏场景init方法添加:
Sprite *spRocker2 = Sprite::create("joystick_ball.png"); //摇杆 Sprite *spRockerBG2 = Sprite::create("joystick.png"); //摇杆背景 HRocker* rocker2 = HRocker::HRockerWithCenter(Vec2(210.0f, 130.0f), 50.0f, spRocker2, spRockerBG2, false); //创建摇杆 this->addChild(rocker2, 0, "joystick"); //摇杆添加到layer中 this->scheduleUpdate(); Rect rect = Rect(0.0f, 0.0f, 130.0f, 130.0f); auto role = Sprite::create("FinalTestnew.png", rect); // 被控制的精灵 role->setPosition(Vec2(300.0f, 200.0f)); this->addChild(role, 0, "role");

在update里面添加, 记得在头文件加上update的声明:
void HelloWorld::update(float dt) { HRocker* rocker2 = (HRocker*)getChildByName("joystick"); Vec2 direct = rocker2->getDirection(); // 获取摇杆方向向量 auto role = getChildByName("role"); float speed = 3.0f; // 每一帧角色移动的速度 Size WindowSize = Director::getInstance()->getWinSize(); // 获取窗口大小,防止精灵移动出去 Vect newPosition = role->getPosition() + direct * speed; if (newPosition.x > 0 && newPosition.x < WindowSize.width && newPosition.y > 0 && newPosition.y < WindowSize.height) role->setPosition(newPosition); }

Cocos2d-x 3.10 版本的模拟摇杆控制精灵移动
文章图片

    推荐阅读