前一篇我们已经实现了游戏的开始界面,这一篇我们来实现关卡选择画面。先上图:
那么我们要如何实现关卡选择画面呢?
1. 创建一个场景类:ScrollViewScene.h和ScrollViewScene.cpp
头文件ScrollViewScene.h的代码如下:
#ifndef ScrollView_ScrollViewScene_h
#define ScrollView_ScrollViewScene_h
#include "cocos2d.h"
USING_NS_CC;
class ScrollViewScene: public Scene
{
public:
virtual bool init();
CREATE_FUNC(ScrollViewScene);
void menuCloseCallback(Object* pSender);
static ScrollViewScene *sharedSC();
};
#endif
ScrollViewScene.cpp的代码如下:
#include "ScrollViewScene.h"
#include "ScrollView.h"
#include "ScorllMainLayer01.h"
#include "ScorllMainLayer02.h"
#include "ScorllMainLayer03.h"
#include "ScorllMainLayer04.h"
#include "ScorllMainLayer05.h"
#include "ScorllMainLayer06.h"
#include "ScorllMainLayer07.h"
#include "HelloWorldScene.h"
//声明静态变量
static ScrollView *scrollView;
static ScrollViewScene *sc;
ScrollViewScene *ScrollViewScene::sharedSC(){
if(sc != NULL){
return sc;
}
return NULL;
}
bool ScrollViewScene::init()
{
sc = this;
bool bRet = false;
do {
CC_BREAK_IF(!CCScene::init());
scrollView = ScrollView::create();
//制作7个可以滑动的屏幕(每一个屏幕都有4个关卡)
for (int i=0; i<7; ++i) {
if (0==i) {
ScorllMainLayer01 *layer = ScorllMainLayer01::create();
layer->setTag(i);
scrollView->addPage(layer);
}else if(1==i){
ScorllMainLayer02 *layer = ScorllMainLayer02::create();
layer->setTag(i);
scrollView->addPage(layer);
}else if(2==i){
ScorllMainLayer03 *layer = ScorllMainLayer03::create();
layer->setTag(i);
scrollView->addPage(layer);
}else if(3==i){
ScorllMainLayer04 *layer = ScorllMainLayer04::create();
layer->setTag(i);
scrollView->addPage(layer);
}else if(4==i){
ScorllMainLayer05 *layer = ScorllMainLayer05::create();
layer->setTag(i);
scrollView->addPage(layer);
}else if(5==i){
ScorllMainLayer06 *layer = ScorllMainLayer06::create();
layer->setTag(i);
scrollView->addPage(layer);
}else if(6==i){
ScorllMainLayer07 *layer = ScorllMainLayer07::create();
layer->setTag(i);
scrollView->addPage(layer);
}
}
Size size = CCDirector::getInstance()->getWinSize();
//将图片加载在缓存中
SpriteFrameCache *cache = SpriteFrameCache::getInstance();
cache->addSpriteFramesWithFile("level_scene.plist");
//设置背景精灵
Sprite* spritebg =Sprite::createWithSpriteFrameName("list-bg.png");
spritebg->setPosition(Point(size.width*0.5+100,size.height*0.5));
addChild(spritebg);
//下面的7个星星,第一个为点中状态
Sprite* sprite1 =Sprite::createWithSpriteFrameName("dots-1.png");
sprite1->setPosition(Point(size.width*0.5-150,size.height*0.5-200));
addChild(sprite1);
Sprite* sprite2 =Sprite::createWithSpriteFrameName("dots-1.png");
sprite2->setPosition(Point(size.width*0.5-100,size.height*0.5-200));
addChild(sprite2);
Sprite* sprite3 =Sprite::createWithSpriteFrameName("dots-1.png");
sprite3->setPosition(Point(size.width*0.5-50,size.height*0.5-200));
addChild(sprite3);
Sprite* sprite4 =Sprite::createWithSpriteFrameName("dots-1.png");
sprite4->setPosition(Point(size.width*0.5,size.height*0.5-200));
addChild(sprite4);
Sprite* sprite5 =Sprite::createWithSpriteFrameName("dots-1.png");
sprite5->setPosition(Point(size.width*0.5+50,size.height*0.5-200));
addChild(sprite5);
Sprite* sprite6 =Sprite::createWithSpriteFrameName("dots-1.png");
sprite6->setPosition(Point(size.width*0.5+100,size.height*0.5-200));
addChild(sprite6);
Sprite* sprite7 =Sprite::createWithSpriteFrameName("dots-1.png");
sprite7->setPosition(Point(size.width*0.5+150,size.height*0.5-200));
addChild(sprite7);
Sprite* sprite =Sprite::createWithSpriteFrameName("dots-2.png");
sprite->setPosition(Point(size.width*0.5-150,size.height*0.5-200));
sprite->setTag(888);
addChild(sprite);
//制作一个菜单,点击之后返回游戏开始界面
MenuItemImage *closeItem = MenuItemImage::create();
closeItem->setNormalSpriteFrame(cache->spriteFrameByName("back-1.png"));
closeItem->setSelectedSpriteFrame(cache->spriteFrameByName("back-2.png"));
closeItem->initWithTarget(this, menu_selector(ScrollViewScene::menuCloseCallback));
closeItem->setPosition(Point(80,80));
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu, 1);
this->addChild(scrollView);
bRet = true;
} while (0);
return bRet;
}
void ScrollViewScene::menuCloseCallback(Object* pSender){
CCDirector::getInstance()->replaceScene(CCTransitionFade::create(0.5, HelloWorld::createScene()));
}
我们在init函数中,制作7个可以滑动的屏幕,然后加载图片到缓存中,紧接着制作了背景精灵,还有下面的7个星星以及一个返回菜单。代码已经注释得很详细了。
2. 场景工具类:实现左右滑动的效果
ScrollView.h的代码如下:
#ifndef ScrollView_ScrollView_h
#define ScrollView_ScrollView_h
#include "cocos2d.h"
USING_NS_CC;
// 屏幕尺寸
const float WINDOW_WIDTH = 1136.0f;
const float WINDOW_HEIGHT = 640.0f;
// 触摸误差
const int TOUCH_DELTA = 20;
class ScrollView: public Layer
{
private:
// 按下点
Point m_TouchDownPoint;
// 抬起点 配合使用判断是否为点击事件
Point m_TouchUpPoint;
// 当前触摸点
Point m_TouchCurPoint;
private:
// 总页数
int m_Page;
// 当前显示页
int m_CurPage;
private:
// 存储所有页层
Array *m_PageLayer;
private:
// 跳转页
void goToPage();
public:
ScrollView();
~ScrollView();
virtual bool init();
CREATE_FUNC(ScrollView);
public:
// 初始化相关
//virtual void onEnter();
//virtual void onExit();
// 触摸事件相关
bool onTouchBegan(Touch *pTouch, Event *pEvent);
void onTouchMoved(Touch *pTouch, Event *pEvent);
void onTouchEnded(Touch *pTouch, Event *pEvent);
void onTouchCancelled(Touch *pTouch, Event *pEvent);
public:
// 添加页
void addPage(Layer *pPageLayer);
//公开方法跳转页面
void gotoUserChoosePage(int _isToOrBack);
};
#endif
ScrollView.cpp的代码如下:
#include "ScrollView.h"
#include "ScrollViewScene.h"
ScrollView::ScrollView()
{
m_Page = 0;
m_CurPage = 0;
m_PageLayer = CCArray::createWithCapacity(5);
m_PageLayer->retain();
init();
}
ScrollView::~ScrollView()
{
m_PageLayer->removeAllObjects();
m_PageLayer->release();
}
bool ScrollView::init()
{
bool bRet = false;
do {
CC_BREAK_IF(!CCLayer::init());
bRet = true;
} while (0);
setTouchEnabled(true);
//设置为单点响应
setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
//3.0新的触摸机制
auto myListener = EventListenerTouchOneByOne::create();
myListener->onTouchBegan = CC_CALLBACK_2(ScrollView::onTouchBegan, this);
myListener->onTouchMoved = CC_CALLBACK_2(ScrollView::onTouchMoved, this);
myListener->onTouchEnded = CC_CALLBACK_2(ScrollView::onTouchEnded, this);
myListener->onTouchCancelled = CC_CALLBACK_2(ScrollView::onTouchCancelled, this);
return bRet;
}
void ScrollView::goToPage()
{
MoveTo *moveTo = MoveTo::create(0.2f, Point::Point(-m_CurPage * WINDOW_WIDTH, 0));
this->runAction(moveTo);
}
void ScrollView::addPage(cocos2d::Layer *pPageLayer)
{
if (pPageLayer) {
// 设置成一页大小
pPageLayer->setContentSize(Size::Size(WINDOW_WIDTH, WINDOW_HEIGHT));
pPageLayer->setPosition(Point(WINDOW_WIDTH * m_Page, 0));
this->addChild(pPageLayer);
// 添加到页
m_PageLayer->addObject(pPageLayer);
m_Page = m_PageLayer->count();
}
}
//公开方法进行页面跳转
void ScrollView::gotoUserChoosePage(int _isToOrBack){
if (0 == _isToOrBack) {
//上一页
if (m_CurPage > 0) {
--m_CurPage;
}
}else if(1 == _isToOrBack){
//下一页
if (m_CurPage < (m_Page - 1)) {
++m_CurPage;
}
}
// 执行跳转动画
goToPage();
}
bool ScrollView::onTouchBegan(Touch *pTouch, Event *pEvent){
m_TouchDownPoint = CCDirector::getInstance()->convertToGL(pTouch->getLocationInView());
m_TouchCurPoint = m_TouchDownPoint;
return true;
}
void ScrollView::onTouchMoved(Touch *pTouch, Event *pEvent){
// 移动
Point touchPoint = CCDirector::getInstance()->convertToGL(pTouch->getLocationInView());
Point posPoint = Point::Point(getPositionX() + touchPoint.x - m_TouchCurPoint.x, getPositionY());
setPosition(posPoint);
m_TouchCurPoint = touchPoint;
}
void ScrollView::onTouchEnded(Touch *pTouch, Event *pEvent){
m_TouchUpPoint = CCDirector::getInstance()->convertToGL(pTouch->getLocationInView());
// 计算按下和抬起的偏移量
float offset = (m_TouchUpPoint.x - m_TouchDownPoint.x) * (m_TouchUpPoint.x - m_TouchDownPoint.x) + (m_TouchUpPoint.y - m_TouchDownPoint.y) * (m_TouchUpPoint.y - m_TouchDownPoint.y);
if (offset < (TOUCH_DELTA * TOUCH_DELTA)) {
}
else {
// 滑动结束
int offset = getPositionX() - m_CurPage * (-WINDOW_WIDTH);
//if (offset > WINDOW_WIDTH / 2) {
if (offset > 50) {
// 上一页
if (m_CurPage > 0) {
--m_CurPage;
Sprite *sprite = (Sprite *)ScrollViewScene::sharedSC()->getChildByTag(888);
sprite->setPosition(Point(sprite->getPositionX()-50,sprite->getPositionY()));
}
}
//else if (offset < -WINDOW_WIDTH / 2) {
else if (offset < -50) {
// 下一页
if (m_CurPage < (m_Page - 1)) {
++m_CurPage;
Sprite *sprite = (Sprite *)ScrollViewScene::sharedSC()->getChildByTag(888);
sprite->setPosition(Point(sprite->getPositionX()+50,sprite->getPositionY()));
}
}
// 执行跳转动画
goToPage();
}
}
void ScrollView::onTouchCancelled(Touch *pTouch, Event *pEvent){
}
3. 建立不同的场景
接下来我们建立不同的场景,这样就能实现场景的切换和关卡的选择了。之前我们说过场景有7个,下面我们详细介绍一个,其他六个是类似的。
ScrollMainLayer01.h的代码如下:
#ifndef __ScorllMainLayer01__
#define __ScorllMainLayer01__
#include <iostream>
#include "cocos2d.h"
USING_NS_CC;
class ScorllMainLayer01: public Layer
{
public:
ScorllMainLayer01();
~ScorllMainLayer01();
virtual bool init();
CREATE_FUNC(ScorllMainLayer01);
void menuCloseCallback01(Object* pSender);
void menuCloseCallback02(Object* pSender);
void menuCloseCallback03(Object* pSender);
void menuCloseCallback04(Object* pSender);
};
#endif
#include "ScorllMainLayer01.h"
ScorllMainLayer01::ScorllMainLayer01()
{
}
ScorllMainLayer01::~ScorllMainLayer01()
{
}
bool ScorllMainLayer01::init()
{
bool bRet = false;
do {
Size size = CCDirector::getInstance()->getWinSize();
//初始化信息
SpriteFrameCache *cache = SpriteFrameCache::getInstance();
cache->addSpriteFramesWithFile("level_image.plist");
//建立四个具体的游戏菜单
MenuItemImage *closeItem01 = MenuItemImage::create();
closeItem01->setNormalSpriteFrame(cache->spriteFrameByName("shutdown-pc-cover.png"));
closeItem01->setSelectedSpriteFrame(cache->spriteFrameByName("shutdown-pc-cover.png"));
closeItem01->initWithTarget(this, menu_selector(ScorllMainLayer01::menuCloseCallback01));
closeItem01->setPosition(Point(size.width*0.5-150,size.height*0.5+200));
MenuItemImage *closeItem02 = MenuItemImage::create();
closeItem02->setNormalSpriteFrame(cache->spriteFrameByName("clickon-the-100times-cover.png"));
closeItem02->setSelectedSpriteFrame(cache->spriteFrameByName("clickon-the-100times-cover.png"));
closeItem02->initWithTarget(this, menu_selector(ScorllMainLayer01::menuCloseCallback02));
closeItem02->setPosition(Point(size.width*0.5+150,size.height*0.5+200));
MenuItemImage *closeItem03 = MenuItemImage::create();
closeItem03->setNormalSpriteFrame(cache->spriteFrameByName("through-the-bridge-cover.png"));
closeItem03->setSelectedSpriteFrame(cache->spriteFrameByName("through-the-bridge-cover.png"));
closeItem03->initWithTarget(this, menu_selector(ScorllMainLayer01::menuCloseCallback03));
closeItem03->setPosition(Point(size.width*0.5-150,size.height*0.5));
MenuItemImage *closeItem04 = MenuItemImage::create();
closeItem04->setNormalSpriteFrame(cache->spriteFrameByName("click-me-cover.png"));
closeItem04->setSelectedSpriteFrame(cache->spriteFrameByName("click-me-cover.png"));
closeItem04->initWithTarget(this, menu_selector(ScorllMainLayer01::menuCloseCallback04));
closeItem04->setPosition(Point(size.width*0.5+150,size.height*0.5));
auto menu = Menu::create(closeItem01,closeItem02,closeItem03,closeItem04, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu, 1);
bRet = true;
} while (0);
return bRet;
}
//分别进入游戏
void ScorllMainLayer01::menuCloseCallback01(Object* pSender){
log("SS");
}
void ScorllMainLayer01::menuCloseCallback02(Object* pSender){
}
void ScorllMainLayer01::menuCloseCallback03(Object* pSender){
}
void ScorllMainLayer01::menuCloseCallback04(Object* pSender){
}
再建立六个这样的场景,我们的关卡选择画面就实现了。