cocos2dx 基础触碰效果封装(通用于具有触碰效果的节点或精灵,类似按钮,方便扩展),很久以前的代码

本文介绍了一种使用cocos2dx进行基础触碰效果封装的方法,适用于创建具有触碰反馈的节点和精灵,如按钮。通过封装,可以方便地扩展功能并简化代码维护。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
* @note		:基础触碰效果封装(通用于具有触碰效果的节点或精灵,类似按钮,方便扩展)
* @author	:Andy.Ro
* @email	:Qwuloo@qq.com
*/
#ifndef _XBASETOUCH_SPRITE_H_INCLUDE_
#define _XBASETOUCH_SPRITE_H_INCLUDE_

#include "cocos2d.h"
#include <map>

USING_NS_CC;

class xBaseTouchSprite;			/* 基础触碰精灵 */
class xBaseTouchDelegate;		/* 基础触碰代理 */

// 基础触碰节点
typedef xBaseTouchSprite xBaseTouchNode;

//------------------------------------------------------------------------
// xBaseTouchDelegate
//------------------------------------------------------------------------
class xBaseTouchDelegate
{
public:
	virtual void onTouch(cocos2d::CCObject* sender)		= 0;
	virtual void onMoved(cocos2d::CCObject* sender)		= 0;
	virtual void onEnded(cocos2d::CCObject* sender)		= 0;
};

//------------------------------------------------------------------------
// BaseTouchSprite:基础触碰节点(2.1.4之后版本继承CCSprite和CCTargetedTouchDelegate)
//------------------------------------------------------------------------
class xBaseTouchSprite : /*public cocos2d::CCSprite, public cocos2d::CCTargetedTouchDelegate*/ public cocos2d::CCLayerColor
{
public:
	xBaseTouchSprite(void);
	static xBaseTouchSprite* create(float width, float height);
	//
	// @note:触屏使能
	virtual void setTouchEnabled(bool bValue);
protected:
	//
	// @note:初始化
	bool initWith(float width, float height);
	
	//
	// @note:检索子节点精灵颜色值
	void traverseChildrenColor(void);

	//
	// @note:检索子节点精灵颜色值(递归遍历)
	void recurseChildrenColor(CCNode* parent);

	//
	// @note:绘制选中或未选中状态
	// @param bValue 是否选中
	void recurseSmoothDraw(CCNode* parent, bool bValue);
	
	//
	// @note:绘制效果
	virtual void draw(void);
protected:
	//
	// @note:单点触屏
	virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
	virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
	virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
	
	//
	// @note:触屏点判断
	bool containsTouchLocation(CCTouch *pTouch);
	
	//
	// @note:消息回调
	virtual void onTouch(cocos2d::CCObject* sender);
	virtual void onMoved(cocos2d::CCObject* sender);
	virtual void onEnded(cocos2d::CCObject* sender);

	//
	// @note:注册优先级
	virtual void registerWithTouchDispatcher(void);
	
protected:
	std::map<CCNode*,ccColor3B> _mapcolor;
	CC_SYNTHESIZE(bool,					_bSelected,	Selected);
	CC_SYNTHESIZE(BaseTouchDelegate*, _target, Delegate);
public:
	virtual ~xBaseTouchSprite(void);
};

// @note:绘制矩形边框
extern void drawRect(CCRect const& rect);

#endif // _XBASETOUCH_SPRITE_H_INCLUDE_


/*
* @note		:基础触碰效果封装(通用于具有触碰效果的节点或精灵,类似按钮,方便扩展)
* @author	:Andy.Ro
* @email	:Qwuloo@qq.com
*/
#include "xBaseTouchSprite.h"

// @note:绘制矩形边框
inline void drawRect(CCRect const& rect)
{
	CCPoint pos1, pos2, pos3, pos4;
	pos1 = ccp(rect.origin.x, rect.origin.y);
	pos2 = ccp(rect.origin.x, rect.origin.y + rect.size.height);
	pos3 = ccp(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
	pos4 = ccp(rect.origin.x + rect.size.width, rect.origin.y);

	ccDrawLine(pos1, pos2);
	ccDrawLine(pos2, pos3);
	ccDrawLine(pos3, pos4);
	ccDrawLine(pos4, pos1);
}

//------------------------------------------------------------------------
// xBaseTouchSprite
//------------------------------------------------------------------------
xBaseTouchSprite::xBaseTouchSprite(void)
	:_bSelected(0)
	,_target(0)
{

}

xBaseTouchSprite* xBaseTouchSprite::create(float width, float height)
{
	xBaseTouchSprite* s = new xBaseTouchSprite();
	if ( s && s->initWith(width, height) )
	{
		s->autorelease();
	}
	else CC_SAFE_DELETE( s );
	return s;
}

bool xBaseTouchSprite::initWith(float width, float height)
{
	// 触碰节点
	this->initWithColor( ccc4(255,0,0,0), width, height );
	// 启用锚点(这里注意了)
	this->ignoreAnchorPointForPosition(false);
	// 节点锚点
	this->setAnchorPoint( ccp(0.5f, 0.5f) );
	return true;
}

void xBaseTouchSprite::setTouchEnabled(bool bValue)
{
	__super::setTouchEnabled(bValue);
	switch( bValue )
	{
	case true:
		{
			break;
		}
	case false:
		{
			this->setSelected(false);
			break;
		}
	}
}

// @note:触屏点判断
inline bool xBaseTouchSprite::containsTouchLocation(CCTouch *pTouch)
{
	//
	// @note:自身节点坐标
	CCRect const& rect = \
					this->getAnchorPoint().equals(CCPointZero) ?
					// @note:锚点(0,0)
					CCRect(
							 0
							,0
							, this->getContentSize().width
							, this->getContentSize().height) :
					// @note:锚点(0.5,0.5)
					CCRect(
							 -this->getContentSize().width  * 0.5f
							,-this->getContentSize().height * 0.5f
							, this->getContentSize().width
							, this->getContentSize().height);
	//
	// 变换触屏坐标为自身节点坐标,判断
	return rect.containsPoint( convertTouchToNodeSpaceAR(pTouch) );
}

inline void xBaseTouchSprite::onTouch(CCObject* sender)
{
//	std::cout<<"xBaseTouchSprite::onTouch()"<<std::endl;
	
	CC_ASSERT( this->_target );
	this->_target->onTouch( sender );
}

inline void xBaseTouchSprite::onMoved(CCObject* sender)
{
//	std::cout<<"xBaseTouchSprite::onMoved()"<<std::endl;
	
	CC_ASSERT( this->_target );
	this->_target->onMoved( sender );
}

inline void xBaseTouchSprite::onEnded(CCObject* sender)
{
//	std::cout<<"xBaseTouchSprite::onEnded()"<<std::endl;
	
	CC_ASSERT( this->_target );
	this->_target->onEnded( sender );
}

// @note:单点触屏
bool xBaseTouchSprite::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
	// 触碰点位于节点区域内,则进行拦截
	if ( this->containsTouchLocation(pTouch) )
	{
		this->onTouch( this );
		return true;
	}
	// 触碰点不在节点区域内,则往下传递
	return false;
}

void xBaseTouchSprite::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
	// 触碰点位于节点区域内,则进行响应
	if ( this->containsTouchLocation(pTouch) )
	{
		this->setSelected(true);
		this->onMoved( this );
	}
	// 触碰点不在节点区域内,则另做处理
	else
	{
		this->setSelected(false);
	}
}

void xBaseTouchSprite::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
	// 触碰点位于节点区域内,则进行响应
	if ( this->containsTouchLocation(pTouch) )
	{
		this->setSelected(false);
		this->onEnded( this );
	}
}

void xBaseTouchSprite::registerWithTouchDispatcher(void)
{
	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, kCCMenuHandlerPriority - 1, true);
}

inline void xBaseTouchSprite::draw(void)
{
	if ( this->getSelected() )
	{
		ccDrawColor4F(0,255,0,100);
		glLineWidth(2.0);
//		this->recurseSmoothDraw(this, true);
		// @note:绘制节点边框
		drawRect(
			CCRect(
				 0
				,0
				,this->getContentSize().width
				,this->getContentSize().height) );
	}
	else
	{
//		this->recurseSmoothDraw(this, false);
	}
}

// @note:检索子节点精灵颜色值
void xBaseTouchSprite::traverseChildrenColor(void)
{
	this->recurseChildrenColor(this);
}

// @note:检索子节点精灵颜色值(递归遍历)
void xBaseTouchSprite::recurseChildrenColor(CCNode* parent)
{
	CC_ASSERT( parent );

	CCObject* obj = 0;
	CCARRAY_FOREACH(parent->getChildren(), obj)
	{
		CCSprite* s = dynamic_cast<CCSprite*>(obj); CC_ASSERT( s );
		this->recurseChildrenColor(s);
	}
	CCSprite* s = dynamic_cast<CCSprite*>(parent);/* CC_ASSERT( s );*/
	if ( s )
	{
		this->_mapcolor[s] = s->getColor();
	}
}

// @note:绘制选中或未选中状态
// @param bValue 是否选中
void  xBaseTouchSprite::recurseSmoothDraw(CCNode* parent, bool bValue)
{
	CC_ASSERT( parent );

	CCObject* obj = 0;
	CCARRAY_FOREACH(parent->getChildren(), obj)
	{
		CCSprite* s = dynamic_cast<CCSprite*>(obj); CC_ASSERT( s );
		this->recurseSmoothDraw(s, bValue);
	}
	CCSprite* s = dynamic_cast<CCSprite*>(parent);/* CC_ASSERT( s );*/
	if ( s )
	{
		s->setColor(bValue ? ccYELLOW : this->_mapcolor[s]);
	}
}

xBaseTouchSprite::~xBaseTouchSprite(void)
{

} // class xBaseTouchSprite


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值