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

Cocos3.4 横版游戏制作-《KillBear》-暂停层+屏蔽下层监听

2015-02-17 15:15 591 查看
转载时请务必以超链接形式标明文章,原始出处 。

资源为网上寻找的,仅研究学习用,若是侵犯版权请通知本人整改。

上一篇: Cocos3.4 横版游戏制作-《KillBear》-技能及CD实现

上篇实现了添加一个有冷却效果的技能按钮,如果还有其他技能状况的话依次添加就可以了,就不再多说

本篇在游戏层中右上角添加一个按钮,用于暂停游戏功能的实现

开发环境

win64 : vs2010

Cocos2d-x v3.4Final

TexturePackerGUI

MapEdit

开始之前先说明下实现方法:

当游戏暂停的时候,下方按键应该是无法触摸的.不然会出现不可控的各种BUG,比如动画不动了,角色还可以转向之类的奇葩.

所以先添加一个屏蔽层,然后在上方添加我们的按钮

代码

other

BarrierLayer

.h

#ifndef _BARRIER_LAYER_H_
#define _BARRIER_LAYER_H_
#include "cocos2d.h"
USING_NS_CC;

class BarrierLayer : public Layer
{
public:
BarrierLayer();
~BarrierLayer();
bool init();
CREATE_FUNC(BarrierLayer);
};

#endif


这个.h没啥好说的.

.cpp

#include "BarrierLayer.h"

BarrierLayer::BarrierLayer()
{
}

BarrierLayer::~BarrierLayer()
{
}

bool BarrierLayer::init()
{

if(!Layer::init())
return false;

//添加一个半灰色的层
LayerColor* backLayerColor = LayerColor::create(Color4B(25, 25, 25, 125));
this->addChild(backLayerColor);

//添加向下触摸屏蔽
auto callback = [](Touch * ,Event *)
{
return true;
};
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = callback;
listener->setSwallowTouches(true);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);


首先创建了一个半透明的层,然后添加一个监听,只要在添加时候设置好ZOerder,就可以实实现我们需要的屏蔽监听功能.

这是我认为最好理解和最好实现的方法,其实也可以通过改变原先层的按钮监听顺序来.但是太麻烦了.

最笨的暴力破解也是万能破解方法.

然后创建我们所需要的真正的暂停层

GamePause

.h

和上面的基本相同,单纯的创建一个层.所以不需要在分析一遍了吧?

.cpp

#include "GamePause.h"
#include "GameScene.h"
#include "BarrierLayer.h"
#include "GameStartScene.h"
GamePause::GamePause()
{
}

GamePause::~GamePause()
{
}

bool GamePause::init()
{

if(!Layer::init())
return false;
//下面是我们的按钮
Size WinSize = Director::getInstance()->getWinSize();
Vec2 CenterPoint = Vec2(WinSize.width/2,WinSize.height/2);
auto continuebutton = Button::create("buttonclick.png");
continuebutton->setTitleText("Continue");
continuebutton->addTouchEventListener([=](Ref * pSender , Widget::TouchEventType type){
switch (type)
{
case cocos2d::ui::Widget::TouchEventType::ENDED:
{
getParent()->removeFromParent();
Director::getInstance()->resume();
}
break;
}
});

auto restartbutton = Button::create("buttonclick.png");
restartbutton->setTitleText("Restart");
restartbutton->addTouchEventListener([=](Ref * pSender , Widget::TouchEventType type){
switch (type)
{
case cocos2d::ui::Widget::TouchEventType::ENDED:
{
//之前就停止了所有的scene,不回复下就算创建新场景也是pause的
Director::getInstance()->resume();
Director::getInstance()->replaceScene(TransitionCrossFade::create(0.5f,GameScene::createScene()));

}
break;
}
});

auto titlebutton =  Button::create("buttonclick.png");
titlebutton->setTitleText("ToTitle");
titlebutton->addTouchEventListener([=](Ref * pSender , Widget::TouchEventType type){
switch (type)
{
case cocos2d::ui::Widget::TouchEventType::ENDED:
{
Director::getInstance()->resume();
//Director::getInstance()->replaceScene(GameStartScene::createScene());
}
break;
}
});

continuebutton->setPosition(Vec2(0,50)+CenterPoint);
restartbutton->setPosition(CenterPoint);
titlebutton->setPosition(Vec2(0,-50)+CenterPoint);
addChild(continuebutton);
addChild(restartbutton);
addChild(titlebutton);
return true;
}


CPP里面需要注意的是.我使用了cocosstudio的UI控件,比原来的创建一个menu要快,而且Button用的是9Sprite,自带拉伸变化动画,而且保证图像不失真

(其实用到是为了偷懒,少写很多代码)

(代码include需要注意下,我把下一篇要将的也给弄进去了.自行删改下)

下面这种也是按键监听方法,只是把回调函数直接写在后面了

continuebutton->addTouchEventListener([=](Ref * pSender , Widget::TouchEventType type){
switch (type)
{
case cocos2d::ui::Widget::TouchEventType::ENDED:
{
getParent()->removeFromParent();
Director::getInstance()->resume();
}
break;
}
});


需要注意的是这里我通过调用parent的removeFromParent.那是需要结合下面的来用的

单独使用直接removeFromParent就好了,千万注意不然整个游戏就没了..

在此需要用到的几个方法是

Director::getInstance()->pause()//暂停场景
Director::getInstance()->replaceScene()//创建新场景代替原来的
Director::getInstance()->resume();//恢复场景


如果没有resume…..感兴趣的可以试试是什么状况

PopupLayer

这是个弹出层.

在这里可以写一些动画效果,展现某一个层弹出

由于上面用的是Layer而不是Scene实现的暂停回调.(为啥其他教程喜欢压栈一个Scene?重新载入不慢?)

所以我们可以根据自己的需求写弹出动画.

在此吐槽狂斩三国2,弹出时还能看到半灰色屏蔽层动画..

.h

#ifndef _POPUP_LAYER_H_
#define _POPUP_LAYER_H_
#include "cocos2d.h"
#include "BarrierLayer.h"
USING_NS_CC;

class PopupLayer : public Layer
{
public:
PopupLayer();
~PopupLayer();
bool init(Layer * targetLayer,int type);
static PopupLayer* create(Layer * targetLayer,const int type);
static PopupLayer* create(Layer *  targetLayer)
{return PopupLayer::create(targetLayer,0);};
Action * getActionWithNum(int num);

};

#endif


需要往里输入弹出的对象层,所以不能用CREATE_FUNC这个宏了.

.cpp

#include "PopupLayer.h"

PopupLayer::PopupLayer()
{
}

PopupLayer::~PopupLayer()
{
}
PopupLayer* PopupLayer::create(Layer * targetLayer,const int type)
{
PopupLayer* popupLayer = new PopupLayer();
if (popupLayer && popupLayer->init(targetLayer,type))
{
popupLayer->autorelease();
return popupLayer;
}
else
{
CC_SAFE_DELETE(popupLayer);
return nullptr;
}
}

bool PopupLayer::init(Layer * targetLayer,const int type)
{

if(!Layer::init())
return false;
addChild(BarrierLayer::create(),0);
targetLayer->setTag(1);
addChild(targetLayer,1);

auto popup = getChildByTag(1);
//popup->setScale(0.9f);
popup->runAction(getActionWithNum(type));
return true;
}
//下面是回调的动画,自己通过序号创建,反正只写了几个从窗口外移入和一个抖动动画
//默认是抖动动画,也就是0
Action *  PopupLayer::getActionWithNum(int num)
{
Size WinSize = Director::getInstance()->getWinSize();
switch (num)
{
case 1:
{
auto  act1 = MoveTo::create(0.0f,Vec2(0,WinSize.height));
auto  act2 = MoveTo::create(0.5f,Vec2::ZERO);
return Sequence::createWithTwoActions(act1,act2);
}
case 2:
{
auto  act1 = MoveTo::create(0.0f,Vec2(WinSize.width,0));
auto  act2 = MoveTo::create(0.5f,Vec2::ZERO);
return Sequence::createWithTwoActions(act1,act2);
}
case 3:
{
auto  act1 = MoveTo::create(0.0f,Vec2(0,-WinSize.height));
auto  act2 = MoveTo::create(0.5f,Vec2::ZERO);
return Sequence::createWithTwoActions(act1,act2);
}
case 4:
{
auto  act1 = MoveTo::create(0.0f,Vec2(WinSize.width,0));
auto  act2 = MoveTo::create(0.5f,Vec2::ZERO);
return Sequence::createWithTwoActions(act1,act2);
}
default:
{
auto scaleTo = ScaleTo::create(0.15f, 1.25f);
auto scaleTo2 = ScaleTo::create(0.1f, 0.8f);
return Sequence::createWithTwoActions(scaleTo,scaleTo2);
}

}
}


在init中,

加入先一个屏蔽层

加入需要弹出的对象层

让对象层运行动画,默认是0,也就是抖动

当然,也可以随你的愿意创建删除时动画.这里就不再说了

Operter

operterLayer

.cpp

在我们的控制层init放上一个按钮,实现弹出层回调

不要忘了在上面

#include "ui/CocosGUI.h"
#include "GamePause.h"
using namespace ui;


auto pause = Button::create("pause.png");
pause->setPosition(Vec2(WinSize.width- pause->getContentSize().width/2,WinSize.height-pause->getContentSize().height/2));
pause->addTouchEventListener([=](Ref* pSender , Widget::TouchEventType type)
{
switch (type)
{
case cocos2d::ui::Widget::TouchEventType::ENDED:
{
addChild(PopupLayer::create(GamePause::create()));
Director::getInstance()->pause();
}
break;
}
});

addChild(pause);


效果





截图问题,动画给吞了…….

结语

本篇效果就是添加了一按钮,实现游戏的暂停和重新开始,额外内容是添加了一个防止触摸穿透的屏蔽层和弹出动画.

下一篇,创建游戏开始画面,毕竟不可能刚打开这游戏就直接在运行了吧?

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