【史上最坑爹的游戏】002 关卡选择画面的实现

前一篇我们已经实现了游戏的开始界面,这一篇我们来实现关卡选择画面。先上图:






那么我们要如何实现关卡选择画面呢?


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){

}

再建立六个这样的场景,我们的关卡选择画面就实现了。






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值