Cocos2D-X摇杆

用到相似三角形,和两点间的距离公式。
具体实现如下。

头文件

#ifndef _MYROCKER_H_
#define _MYROCKER_H_
#include"cocos2d.h"
//摇杆状态枚举
enum ROCKER_STATE
{
	ROCKER_STAT,
	ROCKER_UP,
	ROCKER_DOWN,
	ROCKER_LEFT,
	ROCKER_RIGHT

};
class MyRocker:public cocos2d::Layer
{
private:
	//摇杆状态
	ROCKER_STATE state;
	//摇杆背景
	cocos2d::Sprite*m_spRockerbg;
	//摇杆
	cocos2d::Sprite*m_spRocker;
	//单点触摸事件
	cocos2d::EventListenerTouchOneByOne*_listenertouch;
	//是否触碰摇杆
	bool m_isTouchRocker;
	//动态获取坐标
	cocos2d::Vec2 getRockerPos(cocos2d::Vec2 touchPos);
public:
	//获取摇杆
	cocos2d::Vec2 getDirection();
	//获取摇杆状态
	ROCKER_STATE getState();


	virtual void setPosition(const cocos2d::Vec2& pos) override//重写,有继承关系,在子类中
	{
		m_spRockerbg->setPosition(pos);
		m_spRocker->setPosition(pos);
	}
	static MyRocker*create(const std::string& rockerbgfilename,const std::string& rockerfilename,const cocos2d::Vec2& pos);
	virtual bool init(const std::string& rockerbgfilename, const std::string& rockerfilename, const cocos2d::Vec2& pos);

};
#endif

源文件

#include"MyRocker.h"
USING_NS_CC;
Vec2 MyRocker::getRockerPos(Vec2 touchPos)
{
	//大三角
	float R = touchPos.distance(m_spRockerbg->getPosition());	
	float X = touchPos.x - m_spRockerbg->getPositionX();
	float Y = touchPos.y - m_spRockerbg->getPositionY();
	//小三角
	float r = m_spRockerbg->getContentSize().width / 2;
	float x = r / R*X;
	float y = r / R*Y;

	x += m_spRockerbg->getPositionX();
	y += m_spRockerbg->getPositionY();
	return Vec2(x, y);
}
//获取摇杆状态
ROCKER_STATE MyRocker::getState()
{
	return state;
}
Vec2 MyRocker::getDirection()
{
	float x = m_spRocker->getPositionX() - m_spRockerbg->getPositionX();
	float y = m_spRocker->getPositionY() - m_spRockerbg->getPositionY();
	Vec2 vec2(x, y);
	vec2.normalize();
	return vec2;
}
MyRocker*MyRocker::create(const std::string& rockerbgfilename, const std::string& rockerfilename, const Vec2& pos)
{
	MyRocker*myrocker = new MyRocker;
	if (myrocker&&myrocker->init(rockerbgfilename, rockerfilename, pos))
	{
		myrocker->autorelease();
	}
	else
	{
		delete myrocker;
		myrocker = nullptr;
	}
	return myrocker;
}
bool MyRocker::init(const std::string& rockerbgfilename, const std::string& rockerfilename, const Vec2& pos)
{
	if (!Layer::init())
	{
		return false;
	}
	m_isTouchRocker = false;
	state = ROCKER_STAT;
	//摇杆背景
	m_spRockerbg = Sprite::create(rockerbgfilename);
	m_spRockerbg->setLocalZOrder(5);
	this->addChild(m_spRockerbg);
	m_spRockerbg->setPosition(pos);
	//摇杆
	m_spRocker = Sprite::create(rockerfilename);
	m_spRocker->setLocalZOrder(5);
	this->addChild(m_spRocker);
	m_spRocker->setPosition(pos);
	//初始化单点触摸事件
	_listenertouch = EventListenerTouchOneByOne::create();
	_listenertouch->onTouchBegan = [&](Touch*touch, Event*event){
	
		//1获取触摸点坐标
		Vec2 touchPos = touch->getLocation();
		//2.获取摇杆的包围盒
		Rect boundingbox = m_spRocker->getBoundingBox();
		//3,判断包围盒是否包含触摸点坐标
		if (boundingbox.containsPoint(touchPos))
		{
			m_isTouchRocker = true;
			m_spRocker->setOpacity(127);
			m_spRockerbg->setOpacity(127);
		}
		return true;
	};
	_listenertouch->onTouchMoved = [&](Touch*touch, Event*event){
	//有触摸到摇杆
		if (m_isTouchRocker)
		{
			//1获取触摸点坐标
			Vec2 pos = touch->getLocation();
			// 2.判断触摸点是否在摇杆背景范围内
			// 触摸点到圆心的距离
			float dis = pos.distance(m_spRockerbg->getPosition());
			//圆的半径
			float r = m_spRockerbg->getContentSize().width / 2;
			if (dis < r)
			{//跟随手指移动
				m_spRocker->setPosition(pos);
			}
			else
			{//不在,动态获取坐标设置给摇杆
				m_spRocker->setPosition(getRockerPos(pos));
			}
			//	// 根据手指的位置来确定摇杆的状态
			pos -= m_spRockerbg->getPosition();
			if (pos.y / pos.x >= 1 || pos.y / pos.x <= -1)
			{
				if (pos.y > 0)
				{
					state = ROCKER_UP;
				}
				else
				{
					state = ROCKER_DOWN;
				}
			}
			else if (pos.y / pos.x<1 && pos.y / pos.x>-1)
			{
				if (pos.x > 0)
				{
					state = ROCKER_RIGHT;
				}
				else
				{
					state = ROCKER_LEFT;
				}
			}
		}
	};
	_listenertouch->onTouchEnded = [&](Touch*touch, Event*event){
		// 1.是否触碰到摇杆还原
		m_isTouchRocker = false;
		// 2.摇杆位置还原
		m_spRocker->setPosition(m_spRockerbg->getPosition());
		//m_spRocker->runAction(MoveTo::create(0.1, m_spRockerBG->getPosition()));
		// 3.还原摇杆状态
		state = ROCKER_STAT;
		m_spRocker->setOpacity(255);

		m_spRockerbg->setOpacity(255);
	};
	Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(_listenertouch, this);
	return true;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gxy_w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值