设计模式 微信小程序实战教程 ASP.NET Java Spring 分布式服务 windows express d3 video directory scrapy 后台系统模板 jq获取最后一个子元素 matlab中如何定义函数 本地安装mysql hbuilder插件 mysql临时表 python语言编程 java编程环境 java的for循环 java获取当前日期 ntscan ad19 服务器系统安装 烧饼修改器打不开 spss22安装教程 我的世界透视 音乐狂app wegame更新失败 游戏linux正则表达式 java大数据语言 ae怎么复制图层 php递归算法 editplus中文版 frontpage教程 mmc无法创建管理单元 平衡德天赋 血岩碎片有什么用 方正兰亭粗黑简体 ae关键帧
当前位置: 首页 > 学习教程  > 编程语言

cocos2dx 新手引导 ClippingNode + DrawNode + Sprite

2020/8/31 14:30:23 文章标签:

.h头文件

/*!

  • @brief GuideLayer

  • @author elvis cui

  • @date 2020-08-28

  • @ingroup Scenes/GuideLayer

  • 新手引导层

2.3、分析总结

通过ClippingNode进行裁剪遮罩,其实是这样的:

将模板(Stencil)上所有元素的形状集合作为“形状模板”,其元素本身不渲染。

使用“形状模板”对底板进行裁剪。

显示从底板上裁剪下来的图片区域。

总的来说:

模板(Stencil)相当于是一个样板,上面有很多不同形状的"洞洞"。

然后根据样板,对底板进行裁剪,“挖洞”。

然后将剪下来的那些碎片,按照原来的位置进行摆放。

其中:模板(Stencil)只是一个“形状模板”,本身的图片是不进行绘制的。

模板节点是Node的子类,一般常常使用DrawNode,因为它可以绘制不同形状的图形。当然也可以直接使用Node节点作为作为模板。

*/

#pragma once

#include “cocos2d.h”
#include “cocostudio.h”
#include “cocos-ext.h”
#include “MobileKit.h”

USING_NS_CC;
USING_NS_CC_EXT;

typedef enum GuideType
{
Type_None = -1,
Type_Circle = 1, //圆形遮罩
Type_Rect = 2, //矩形遮罩
Type_ImageOrBtn = 3, //图片或按钮遮罩
}GuideType;

class GuideLayer : public Layer, public MKNodeBinder, public MKObserver
{
public:
GuideLayer();
virtual ~GuideLayer();

public:
static GuideLayer* create();
static std::string LayerName;

//开始圆形引导  世界坐标下的圆中心和半径
void startCircleGuide(cocos2d::Vec2 circle_center_worldPos, float radius);

//开始矩形引导   世界坐标下的矩形
void startRectGuide(Rect worldSpaceRect);

//开始图片或者按钮形状的新手引导    图片路径和时间坐标的位置
void startImageOrBtnGuide(std::string filePath, cocos2d::Vec2 worldSpacePos);

private:
/*!
* @brief 初始化GuideLayer
* @param
*/
virtual bool init();

virtual bool onTouchBegan(Touch *touch, Event *unused_event) override;
virtual void onTouchMoved(Touch *touch, Event *unused_event) override;
virtual void onTouchEnded(Touch *touch, Event *unused_event) override;

protected:
/*!
* @brief 绑定变量
* @param node 节点
/
virtual void onBindVariable(Node
node) override;

/**
* @brief	绑定触摸事件的回调方法
* @param   node 节点
*/
virtual void onBindCallback(Node* node) override;

/**
* @brief	绑定变量完成
*/
virtual void onFinishBinding() override;

/**
* @brief	设备按键
*/
void onKeyReleased(EventKeyboard::KeyCode keyCode, cocos2d::Event *event);

/*!
* @brief	响应通知
* @param    通知数据
*/
virtual void onNotify(MKNotice* notify) override;

private:
/*!
* @brief 关闭界面
*/
void close();

private:
//创建灰色的bg
EventListenerTouchOneByOne* m_touchListener = nullptr; //触摸监听器
LayerColor* createGrayBg();

bool touchInRectArea(Touch* touch); //是否点中了扣洞的矩形区域
bool touchInCircleArea(Touch *touch); //是否点中了扣洞的圆形区域
bool touchInImageOrBtnArea(Touch* touch); //是否点中了扣洞的图片或按钮区域

GuideType m_guideType = GuideType::Type_None;

cocos2d::Vec2 m_circle_center_pos = cocos2d::Vec2::ZERO; //原点位置
float m_circle_radius = 1.0f; //圆的半径

// 触摸事件如果在这个矩形区域内,则可以穿透   继续传递下去
cocos2d::Rect m_rectArea = Rect::ZERO;

//图片或按钮的新手引导
cocos2d::Sprite* m_sprite_imageOrBtn_guide = nullptr;

};

.cpp文件
#include “GuideLayer.h”
#include “GameUtils.h”
#include “SoundManager.h”
#include “GameNotify.h”

std::string GuideLayer::LayerName = “GuideLayer”;

GuideLayer::GuideLayer()
{
auto listener = EventListenerKeyboard::create();
listener->onKeyReleased = CC_CALLBACK_2(GuideLayer::onKeyReleased, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

registerAllNotice();

}

GuideLayer::~GuideLayer()
{
}

GuideLayer* GuideLayer::create()
{
GuideLayer* layer = new GuideLayer();
if (layer && layer->init())
{
layer->autorelease();
return layer;
}
else
{
delete layer;
layer = nullptr;
}
return nullptr;
}

bool GuideLayer::init()
{
if (!Layer::init())
{
return false;
}

Node* node = MKUIHelper::readNode("Guide/GuideLayer.csb", this);
addChild(node);
MKUIHelper::bindNodes(node, this, true);

//auto action = CSLoader::createTimeline("Guide/GuideLayer.csb");
//node->runAction(action);
//action->gotoFrameAndPlay(0, false);

return true;

}

bool GuideLayer::onTouchBegan(Touch* touch, Event *event)
{
bool result = false; //isTouch

if (this->m_guideType == GuideType::Type_Rect)
{
	result = this->touchInRectArea(touch);
}
else if (this->m_guideType == GuideType::Type_Circle)
{
	result = this->touchInCircleArea(touch);
}
else if (this->m_guideType == GuideType::Type_ImageOrBtn)
{
	result = this->touchInImageOrBtnArea(touch);
}

//根据是否点中设置是否吞噬触摸
if (result)
{ //点击到了遮罩位置
	LogD("1111111111111111");
	this->m_touchListener->setSwallowTouches(false);
}
else
{ //点击的背景
	LogD("2222222222222222");
	this->m_touchListener->setSwallowTouches(true);
}

return true;

}

void GuideLayer::onTouchMoved(Touch* touch, Event *event)
{

}

void GuideLayer::onTouchEnded(Touch* touch, Event *event)
{
Point point = touch->getLocation();
Point startPoint = touch->getStartLocation();
//Point pannelPoint = m_imgBg->getParent()->convertToNodeSpace(point);//->getParent()
//if (!m_imgBg->getBoundingBox().containsPoint(pannelPoint))
//{
// close();
//}
}

void GuideLayer::onKeyReleased(EventKeyboard::KeyCode keyCode, cocos2d::Event *event)
{
if (keyCode == EventKeyboard::KeyCode::KEY_BACK)
{
//MKEventSystem::sendNotice(kOnClickKeyBackNtf);
}
else if (keyCode == EventKeyboard::KeyCode::KEY_ESCAPE)
{ //esc键
//MKEventSystem::sendNotice(kOnClickKeyBackNtf);
}
event->stopPropagation();
}

void GuideLayer::onBindVariable(Node * node)
{

}

void GuideLayer::onBindCallback(Node* node)
{

}

void GuideLayer::onFinishBinding()
{
//test code elviscui todo

//this->startCircleGuide(cocos2d::Vec2(200, 200), 100);

//this->startRectGuide(Rect(300, 300, 300, 300)); //x, y, width, height

this->startImageOrBtnGuide("textures/game/StartLayer/btn_signIn.png", Vec2(Director::getInstance()->getWinSize().width / 2, Director::getInstance()->getWinSize().height / 2));

}

void GuideLayer::onNotify(MKNotice* notify)
{
const std::string& type = notify->getType();

}

void GuideLayer::close()
{
this->removeFromParentAndCleanup(true);
}

bool GuideLayer::touchInCircleArea(Touch *touch)
{
bool result = false;

auto touchPos = touch->getLocation();
//Vec2 nodeSpace = this->convertToNodeSpace(touchPos);
if (touchPos.getDistance(this->m_circle_center_pos) <= this->m_circle_radius)
{
	return true;
}

return false;

}

bool GuideLayer::touchInRectArea(Touch* touch)
{
bool result = false;

auto touchPos = touch->getLocation();
//Vec2 nodeSpace = this->convertToNodeSpace(touchPos);
if (this->m_rectArea.containsPoint(touchPos))
{
	result = true;
}

return result;

}

bool GuideLayer::touchInImageOrBtnArea(Touch* touch)
{
bool result = false;

auto touchPos = touch->getLocation();
if (this->m_sprite_imageOrBtn_guide != nullptr)
{
	Vec2 nodeSpace = this->m_sprite_imageOrBtn_guide->getParent()->convertToNodeSpace(touchPos);
	Rect boundBox = this->m_sprite_imageOrBtn_guide->getBoundingBox();
	if (boundBox.containsPoint(nodeSpace))
	{
		result = true;
	}
}

return result;

}

LayerColor* GuideLayer::createGrayBg()
{
cocos2d::Size winSize = Director::getInstance()->getWinSize();
LayerColor* layerColor = LayerColor::create(Color4B(0, 0, 0, 255 * 0.7f), winSize.width, winSize.height); //黑色底板

if (m_touchListener == nullptr)
{
	m_touchListener = EventListenerTouchOneByOne::create();
	m_touchListener->onTouchBegan = CC_CALLBACK_2(GuideLayer::onTouchBegan, this);
	m_touchListener->onTouchMoved = CC_CALLBACK_2(GuideLayer::onTouchMoved, this);
	m_touchListener->onTouchEnded = CC_CALLBACK_2(GuideLayer::onTouchEnded, this);
	m_touchListener->setSwallowTouches(true);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(m_touchListener, layerColor);
}

return layerColor;

}

//------------------------------public method begin-------------------------------

void GuideLayer::startCircleGuide(cocos2d::Vec2 circle_center_worldPos, float radius)
{

this->m_guideType = GuideType::Type_Circle; //设置引导类型
this->m_circle_center_pos = circle_center_worldPos;
this->m_circle_radius = radius;

ClippingNode* clippingNode = ClippingNode::create(); //创建裁剪节点

//设置模板
DrawNode* drawNode = DrawNode::create();
drawNode->drawSolidCircle(circle_center_worldPos, radius, 360, 9999, Color4F(1, 0, 0, 1));
clippingNode->setStencil(drawNode);

//设置底板
LayerColor* diban = this->createGrayBg();
clippingNode->addChild(diban);

clippingNode->setInverted(true); //反向显示
clippingNode->setAlphaThreshold(0.05f);
this->addChild(clippingNode);

}

void GuideLayer::startRectGuide(cocos2d::Rect worldSpaceRect)
{
this->m_guideType = GuideType::Type_Rect; //设置引导类型
this->m_rectArea = worldSpaceRect;

ClippingNode* clippingNode = ClippingNode::create(); //创建裁剪节点

//设置模板
DrawNode* drawNode = DrawNode::create();
drawNode->drawSolidRect(cocos2d::Vec2(worldSpaceRect.getMinX(), worldSpaceRect.getMinY()), 
	cocos2d::Vec2(worldSpaceRect.getMaxX(), worldSpaceRect.getMaxY()), Color4F(1, 0, 0, 1)); //矩形的起点, 矩形的终点  左下角为 0,0 点
clippingNode->setStencil(drawNode);

//设置底板
LayerColor* diban = this->createGrayBg();
clippingNode->addChild(diban);

clippingNode->setInverted(true); //反向显示
clippingNode->setAlphaThreshold(0.05f);
this->addChild(clippingNode);

}

void GuideLayer::startImageOrBtnGuide(std::string filePath, cocos2d::Vec2 worldSpacePos)
{

this->m_guideType = GuideType::Type_ImageOrBtn; //设置引导类型

ClippingNode* clippingNode = ClippingNode::create(); //创建裁剪节点

//设置模板
Node* stencil_node = Node::create();

this->m_sprite_imageOrBtn_guide = cocos2d::Sprite::create(filePath);
m_sprite_imageOrBtn_guide->setPosition(worldSpacePos);
m_sprite_imageOrBtn_guide->getTexture()->setAntiAliasTexParameters(); //抗锯齿
//m_sprite_imageOrBtn_guide->getTexture()->setAliasTexParameters();  //不抗锯齿
stencil_node->addChild(m_sprite_imageOrBtn_guide);

clippingNode->setStencil(stencil_node);

//设置底板
LayerColor* diban = this->createGrayBg();
clippingNode->addChild(diban);

clippingNode->setInverted(true); //反向显示
clippingNode->setAlphaThreshold(0.05f);
this->addChild(clippingNode);

}

//------------------------------public method end-------------------------------


本文链接: http://www.dtmao.cc/news_show_150229.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?