1. 程式人生 > >Cocos2d-x 3.10 版本的模擬搖桿控制精靈移動

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

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

圖示效果