您的位置:首页 > 移动开发 > Cocos引擎

用封装ClippingNode实现新手引导(cocos2dx 3.2版本)

2015-06-02 11:21 399 查看
<1>JNClipLayer.h

//
// JNClipLayer.h
// JNTest
//
// Created by jianan on 15/6/1.
//
//

#ifndef __JNTest__JNClipLayer__
#define __JNTest__JNClipLayer__

#include "cocos2d.h"
USING_NS_CC;
#include<vector>
using namespace std;

class JNClipLayer : public Ref
{
public:
JNClipLayer();
~JNClipLayer();
void showJNClip(const vector<Vec2>& ptVec); //参数:要打孔的位置数组
void hideJNClip();
public:
bool onTouchBegan(Touch* touch, Event* event);
EventListenerTouchOneByOne* _touchListener;
private:
Node* _node; //模板节点
ClippingNode* _clippingNode; //被裁减节点
Layer* _layer; //事件触摸层
vector<Sprite*>* _spVec; //在模版上打的孔,用户只能在上面点击
};

#endif /* defined(__JNTest__JNClipLayer__) */<2>JNClipLayer.cpp
//
// JNClipLayer.cpp
// JNTest
//
// Created by jianan on 15/6/1.
//
//

#include "JNClipLayer.h"

#define SCENE_TAG 999 //游戏场景tag
#define clippingSp_path "CloseNormal.png" //模板大小
#define winScaleMin 2 //屏幕适配缩放比例

JNClipLayer::JNClipLayer():_node(NULL), _clippingNode(NULL), _spVec(new vector<Sprite*>()), _layer(NULL){
}

JNClipLayer::~JNClipLayer(){
CC_SAFE_DELETE(_spVec);
}

void JNClipLayer::showJNClip(const vector<Vec2>& ptVec){
//--------------------
///模板 (大小与药遮挡的精灵大小一样,它的颜色根本看不到)
///底板 (被裁减的内容,灰色)
///Layer(触摸层)
//--------------------

if(_layer){
return;
}

_layer = Layer::create();

_spVec->clear();

Size winSize = Director::getInstance()->getWinSize();

Scene* scene = Director::getInstance()->getRunningScene();
Layer* rootLayer = (Layer*)(scene->getChildByTag(SCENE_TAG));
rootLayer->addChild(_layer, 9999); //保持模板在最上层

//1,模板
_node = Node::create();

//裁减节点
_clippingNode = ClippingNode::create();
_clippingNode->setStencil(_node);
_clippingNode->setInverted(true);
_clippingNode->setAlphaThreshold(0);

_layer->addChild(_clippingNode); //非常重要,把裁减节点房上面了

//2,被裁减内容
auto content = LayerColor::create(Color4B(0, 0, 0, 150)); //设置被裁剪的内容是一个灰色的层
_clippingNode->addChild(content);

//3,Layer
_touchListener = EventListenerTouchOneByOne::create();
_touchListener->onTouchBegan = CC_CALLBACK_2(JNClipLayer::onTouchBegan, this);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(_touchListener, _layer);

//触摸层中可以触摸的位置
for(vector<Vec2>::const_iterator iter = ptVec.begin(); iter != ptVec.end(); iter++){
Sprite* sp = Sprite::create(clippingSp_path);
sp->setScale(winScaleMin);
sp->setPosition(*iter);
_clippingNode->addChild(sp);

Sprite* sp1 = Sprite::create(clippingSp_path);
sp1->setScale(winScaleMin);
sp1->setPosition(*iter);
_node->addChild(sp1);

_spVec->push_back(sp);
}

}

void JNClipLayer::hideJNClip(){
if(!_layer){
return;
}
_node->removeAllChildren();
_spVec->clear();
_layer->removeFromParent();
_layer = NULL;
}

bool JNClipLayer::onTouchBegan(Touch* touch, Event* event){
auto point = touch->getLocation();

bool bTouchFlag = false; //是否有点击在屏幕内

for(vector<Sprite*>::iterator iter = _spVec->begin(); iter != _spVec->end(); iter++){
if((*iter)->getBoundingBox().containsPoint(point)){
bTouchFlag = true;
break;
}
}

if(!bTouchFlag){ //如果没有点击在孔里面,则吞噬触摸,否则就传递触摸
_touchListener->setSwallowTouches(true);
}else{
_touchListener->setSwallowTouches(false);
}

log("<<<x:%f, y:%f", point.x, point.y);

return true;
}<3>HelloWorld.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
USING_NS_CC;
#include "JNClipLayer.h"

class HelloWorld : public cocos2d::Layer
{
public:
// there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::Scene* createScene();

// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init();

// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
HelloWorld();
~HelloWorld();
bool onTouchBegan(Touch* touch, Event* event);
private:
void Main(float dt);
JNClipLayer* _jnClipLayer;
};

#endif // __HELLOWORLD_SCENE_H__

<4>HelloWorld.cpp
#include "HelloWorldScene.h"
USING_NS_CC;
using namespace std;

HelloWorld::HelloWorld():_jnClipLayer(new JNClipLayer()){

}

HelloWorld::~HelloWorld(){
CC_SAFE_DELETE(_jnClipLayer);
}

bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
this->setTag(999);

scheduleOnce(schedule_selector(HelloWorld::Main), 0.1f);
return true;
}

void HelloWorld::Main(float dt){

Size winSize = Director::getInstance()->getWinSize();

auto content1 = Sprite::create("bg.jpg");
content1->setPosition(Vec2(winSize.width/2, winSize.height/2));
content1->setScale(winSize.width/content1->getContentSize().width, winSize.height/content1->getContentSize().height);
this->addChild(content1, -100);

vector<Vec2> v;

for(int i = 0; i < 10; i++){
int x = rand() % (int)winSize.width;
int y = rand() % (int)winSize.height;
v.push_back(Vec2(x, y));
}

_jnClipLayer->showJNClip(v);

auto _touchListener = EventListenerTouchOneByOne::create();
_touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(_touchListener, this);
}

bool HelloWorld::onTouchBegan(Touch* touch, Event* event){

_jnClipLayer->hideJNClip();

return true;
}

Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();

// 'layer' is an autorelease object
auto layer = HelloWorld::create();

// add layer as a child to scene
scene->addChild(layer);

// return the scene
return scene;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: