欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

cocos2dx 像素碰撞

程序员文章站 2024-03-16 20:46:10
...

FDPixelSprite.h

#pragma once

#include "cocos2d.h"

using namespace cocos2d;


class FDPixelSprite : public Sprite
{
public:
	FDPixelSprite();
	~FDPixelSprite();

	static FDPixelSprite* create(const std::string& filename);

	void setAlphaThreshold(float threshold);

	inline void setClickCallback(const std::function<void(FDPixelSprite*, float, float)>& call);
	
protected:
	
	void initImageData(const std::string& filename);

	virtual bool onTouchBegan(Touch *touch, Event *unusedEvent);

	virtual void onTouchEnded(Touch *touch, Event *unusedEvent);

	bool isClick(const Vec2& location, Vec2* outPoint = NULL);

protected:

	unsigned char m_threshold;

	Image* m_image;

	std::function<void(FDPixelSprite*, float, float)> m_clickCallback;
};

void FDPixelSprite::setClickCallback(const std::function<void(FDPixelSprite*, float, float)>& call)
{
	m_clickCallback = call;
}

FDPixelSprite.cpp

#include "FDPixelSprite.h"


FDPixelSprite* FDPixelSprite::create(const std::string& filename)
{
	FDPixelSprite *sprite = new (std::nothrow) FDPixelSprite();
	if (sprite && sprite->initWithFile(filename))
	{
		sprite->initImageData(filename);
		sprite->autorelease();
		return sprite;
	}
	CC_SAFE_DELETE(sprite);
	return nullptr;
}

FDPixelSprite::FDPixelSprite()
	: m_image(NULL)
	, m_threshold(100)
	, m_clickCallback(nullptr)
{}

FDPixelSprite::~FDPixelSprite()
{
	CC_SAFE_DELETE(m_image);
}

void FDPixelSprite::setAlphaThreshold(float threshold)
{
	threshold = MAX(threshold, 0.0f);
	threshold = MIN(threshold, 1.0f);
	m_threshold = 255 * threshold;
}

void FDPixelSprite::initImageData(const std::string& filename)
{
	CC_SAFE_DELETE(m_image);

	m_image = new Image();
	m_image->initWithImageFile(filename);

	EventListenerTouchOneByOne* touchListener = EventListenerTouchOneByOne::create();
	touchListener->setSwallowTouches(true);
	touchListener->onTouchBegan = CC_CALLBACK_2(FDPixelSprite::onTouchBegan, this);
	touchListener->onTouchEnded = CC_CALLBACK_2(FDPixelSprite::onTouchEnded, this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
}

bool FDPixelSprite::onTouchBegan(Touch *touch, Event *unusedEvent)
{
	if (!isVisible())
		return false;
	return isClick(touch->getLocation());
}

void FDPixelSprite::onTouchEnded(Touch *touch, Event *unusedEvent)
{
	if (m_clickCallback == nullptr)
	{
		return;
	}

	Vec2 v;
	if (isClick(touch->getLocation(), &v))
	{
		m_clickCallback(this, v.x, v.y);
	}
}

bool FDPixelSprite::isClick(const Vec2& location, Vec2* outPoint)
{
	Rect rect;
	rect.size = getContentSize();
	Vec3 p;
	bool ret = isScreenPointInRect(location, Camera::getVisitingCamera(), getWorldToNodeTransform(), rect, &p);

	if (ret)
	{
		int width = m_image->getWidth();
		int height = m_image->getHeight();
		int _x = p.x;
		int _y = p.y;
		if (_x > 0 && _x <= width && _y > 0 && _y <= height)
		{
			_y = height - _y;
			int index = _y * width + _x;
			index = index * 4;
			unsigned char* colorData = m_image->getData() + index;

			//CCLOG("r:%d g:%d b:%d a:%d", colorData[0], colorData[1], colorData[2], colorData[3]);
			//alpha
			if (colorData[3] > m_threshold)
			{
				if (outPoint)
				{
					outPoint->x = p.x;
					outPoint->y = p.y;
				}
				return true;
			}
		}
	}
	return false;
}

 

相关标签: cocos 像素碰撞