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;
}
上一篇: Android应用-猜数字小游戏