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

图示效果

猜你喜欢

转载自blog.csdn.net/a543658883/article/details/84709380