版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_22990635/article/details/75212240
在游戏中,有时候会遇到不规则的按钮,比如:三国类的地图上的按钮,根据国家的的大小,划分成不同大小的不规则按钮,我们知道,素材都是规则的矩形,只不过有些圆形,不规则等图形中,在Image中处理时的数据为0而已。具体的像素问题不是很了解,好了,直接上代码。
IrregularButton.h
#ifndef __IRREGULAR_BUTTON_H__
#define __IRREGULAR_BUTTON_H__
#include "cocos2d.h"
#include "ui/CocosGUI.h"
USING_NS_CC;
using namespace ui;
class IrregularButton : public Button
{
public:
IrregularButton();
virtual ~IrregularButton();
static IrregularButton* create(const std::string& normalImage,const std::string& selectedImage = "",const std::string& disableImage = "",Widget::TextureResType texType = Widget::TextureResType::LOCAL);
virtual bool init(const std::string& normalImage, const std::string& selectedImage = "", const std::string& disableImage = "", Widget::TextureResType texType = Widget::TextureResType::LOCAL) override;
virtual bool hitTest(const cocos2d::Vec2 &pt) override;
void loadNormalTransparentInfo(std::string normalImage); //初始化按钮
bool getIsTransparentAtPoint(cocos2d::Vec2 point); //获取点击到的像素数据
private:
int normalImageWidth_;
int normalImageHeight_;
bool* normalTransparent_;
};
#endif
IrregularButton.cpp
#include "IrregularButton.h"
IrregularButton::IrregularButton() :
Button(),
normalTransparent_(nullptr)
{}
IrregularButton::~IrregularButton()
{
delete[] normalTransparent_;
}
IrregularButton* IrregularButton::create(const std::string& normalImage, const std::string& selectedImage, const std::string& disableImage, TextureResType texType)
{
IrregularButton* btn = new IrregularButton();
if (btn && btn->init(normalImage, selectedImage, disableImage, texType)) {
btn->autorelease();
return btn;
}
CC_SAFE_DELETE(btn);
return nullptr;
}
bool IrregularButton::init(const std::string &normalImage, const std::string& selectedImage, const std::string& disableImage, TextureResType texType)
{
bool ret = true;
do {
if (!Button::init(normalImage, selectedImage, disableImage, texType)) {
ret = false;
break;
}
} while (0);
loadNormalTransparentInfo(normalImage);
return ret;
}
void IrregularButton::loadNormalTransparentInfo(std::string sName)
{
Image* normalImage = new Image();
normalImage->initWithImageFile(sName);
normalImageWidth_ = normalImage->getWidth();
normalImageHeight_ = normalImage->getHeight();
this->setContentSize(Size(normalImageWidth_, normalImageHeight_));
auto dataLen = normalImage->getDataLen();
if (normalTransparent_ != nullptr) {
delete[] normalTransparent_;
}
auto normalPixels = normalImage->getData();
normalTransparent_ = new bool[dataLen / (sizeof(unsigned char)* 4)];
for (auto i = 0; i < normalImageHeight_; i++) {
for (auto j = 0; j < normalImageWidth_; j++) {
normalTransparent_[i * normalImageWidth_ + j] = (normalPixels[(i * normalImageWidth_ + j) * 4] == 0);
}
}
delete normalImage;
}
bool IrregularButton::getIsTransparentAtPoint(cocos2d::Vec2 point)
{
point.y = _buttonNormalRenderer->getContentSize().height - point.y;
int x = (int)point.x - 1;
if (x < 0) {
x = 0;
}
else if (x >= normalImageWidth_) {
x = normalImageWidth_ - 1;
}
int y = (int)point.y - 1;
if (y < 0) {
y = 0;
}
else if (y >= normalImageHeight_) {
y = normalImageHeight_ - 1;
}
return normalTransparent_[normalImageWidth_ * y + x];
}
bool IrregularButton::hitTest(const Vec2 &pt)
{
Vec2 localLocation = _buttonNormalRenderer->convertToNodeSpace(pt);
Rect validTouchedRect;
validTouchedRect.size = _buttonNormalRenderer->getContentSize();
if (validTouchedRect.containsPoint(localLocation) && getIsTransparentAtPoint(localLocation) == false)
{
log("IN");
//NotificationCenter::getInstance()->postNotification("NotifyIrregularBtn", (Ref*)m_iBtnID);
return true;
}
return false;
}
然后在HelloWorld中直接创建就可以了
const std::string sNameN = "smile.png";
const std::string sNameP = "angry.png";
IrregularButton* alphaBtn = IrregularButton::create(sNameN, sNameP, sNameP);
alphaBtn->setPosition(ccp(400, 400));
this->addChild(alphaBtn);
alphaBtn->addTouchEventListener(CC_CALLBACK_2(HelloWorld::IrregularButtonCallBack, this));
void HelloWorld::IrregularButtonCallBack(Ref* pSender, Widget::TouchEventType touchtype)
{
switch (touchtype)
{
case Widget::TouchEventType::BEGAN:
log("IrregularButtonCallBack--------TouchBegan");
break;
case Widget::TouchEventType::MOVED:
log("IrregularButtonCallBack--------TouchMoved");
break;
case Widget::TouchEventType::ENDED:
log("IrregularButtonCallBack--------TouchEnded");
break;
}
}
这样我们就能够跟普通的按钮一样使用了,源码下载地址:
https://pan.baidu.com/s/1dEYi6tF