cocos2dx 畫素碰撞
阿新 • • 發佈:2018-12-12
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); protected: unsigned char m_threshold; Image* m_image; EventListenerTouchOneByOne* m_touchListener; 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_touchListener(NULL) , m_threshold(100) , m_clickCallback(nullptr) {} FDPixelSprite::~FDPixelSprite() { CC_SAFE_DELETE(m_image); if (m_touchListener) { _eventDispatcher->removeEventListener(m_touchListener); } } 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); if (m_touchListener) { _eventDispatcher->removeEventListener(m_touchListener); } m_touchListener = EventListenerTouchOneByOne::create(); m_touchListener->setSwallowTouches(true); m_touchListener->onTouchBegan = CC_CALLBACK_2(FDPixelSprite::onTouchBegan, this); m_touchListener->onTouchEnded = CC_CALLBACK_2(FDPixelSprite::onTouchEnded, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(m_touchListener, this); } bool FDPixelSprite::onTouchBegan(Touch *touch, Event *unusedEvent) { if (!isVisible()) return false; Rect rect; rect.size = getContentSize(); bool ret = isScreenPointInRect(touch->getLocation(), Camera::getVisitingCamera(), getWorldToNodeTransform(), rect, NULL); return ret; } void FDPixelSprite::onTouchEnded(Touch *touch, Event *unusedEvent) { if (m_clickCallback == nullptr) { return; } Rect rect; rect.size = getContentSize(); Vec3 p; bool ret = isScreenPointInRect(touch->getLocation(), 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) { m_clickCallback(this, p.x, p.y); } } } }