Cocos2dx 3.2 横版过关游戏Brave学习笔记(七)

索引篇:
http://www.cocoachina.com/bbs/read.php?tid=227226

http://www.cocoachina.com/bbs/read.php?tid=227229

http://www.cocoachina.com/bbs/read.php?tid=227305

http://www.cocoachina.com/bbs/read.php?tid=227328

http://www.cocoachina.com/bbs/read.php?tid=227522

http://www.cocoachina.com/bbs/read.php?tid=227643

这次还是按照原版教程来,补上游戏开始界面,画面滚动等等。

感觉MainScene::init里的代码有点乱,所以先整理一下。

bool MainScene::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
     //load frames into cache
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("image/role.plist","image/role.pvr.ccz");
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("image/ui.plist","image/ui.pvr.ccz");

    addRoles();
    addUI();
    addListener();
    addObserver();
    return true;
}

```


看上去好多了,运行了一下发现角色被背景挡住了,设置一下zOrder,使背景-角色-UI的zOrder依次递增。
另外发现可以用Director的方法实现暂停。


游戏开始界面


新建一个scene,名叫StartScene,并将AppDelegate.cpp中的MainScene改为StartScene。
#ifndef __StartScene__
#define __StartScene__
#include "cocos2d.h"

USING_NS_CC;

class StartScene : public Layer
{
public:
    bool init();
    static Scene* createScene();
    void onStart(Ref* obj);
    CREATE_FUNC(StartScene);
};

#endif

```


可以在这里载入缓存,添加按钮并响应。
#include "StartScene.h"
#include "MainScene.h"
#include "VisibleRect.h"
#include "CustomTool.h"

bool StartScene::init()
{
    if(!Layer::init())
        return false;
    log("StartLayer::init");

    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("image/role.plist","image/role.pvr.ccz");
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("image/ui.plist","image/ui.pvr.ccz");
    auto background = Sprite::create("image/start-bg.jpg");
    background->setPosition(VisibleRect::center());
    this->addChild(background);

    auto item = CustomTool::createMenuItemImage("start1.png", "start2.png", CC_CALLBACK_1(StartScene::onStart,this));
    auto menu = Menu::createWithItem(item);
    this->addChild(menu);
    return true;
}


Scene* StartScene::createScene()
{
    auto scene = Scene::create();   
    auto layer = StartScene::create();
    scene->addChild(layer);
    return scene;
}


void StartScene::onStart(Ref* obj)
{
    log("StartLayer::onStart");
    auto scene = MainScene::createScene();
    Director::getInstance()->replaceScene(scene);
}

```

另外使原来PauseLayer中的Home按钮实现切换到StartScene的作用:
void PauseLayer::home(Ref* obj)
{
    _eventDispatcher->removeEventListener(_listener);
    auto main = (MainScene*)this->getParent();
    main->onTouchResume();
    this->removeFromParentAndCleanup(true);
    auto start = StartScene::createScene();
    Director::getInstance()->replaceScene(start);
}

```

运行了一下,出错了,貌似忘了把listener什么的在onExit里注销掉。还忘了在点击home之后也继续一下,否则进入关卡后还是暂停状态。当然这些错误没有白犯,多犯几次就能熟练应对了。


画面滚动

下面加入过场,即敌人死光后,会出现一个GO>>>的提示,点击就会进入下个小关,有新的敌人,消灭后还可以继续切换……
建立一个容器容纳敌人,每死一个就将其移除,死光则显示Go图标。
在Player中,敌人死亡,发送一个消息通知MainScene.,在状态机回调函数onDead的回调函数func中:
            if(_type != PLAYER)
                NotificationCenter::getInstance()->postNotification("enemyDead",this);

```


MainScene接收消息
    NotificationCenter::getInstance()->addObserver(this, callfuncO_selector(MainScene::enemyDead),"enemyDead",nullptr);

```

收到后会做出反应:
void MainScene::enemyDead(Ref* obj)
{
    auto player= (Player*)obj;
    _enemys.eraseObject(player,true);
    log("onEnemyDead:%d", _enemys.size());
    if(_enemys.size() == 0)
        showNextLevelItem();
}

```

在addUI里加入这个GO图标:
    auto goItem = CustomTool::createMenuItemImage("go.png", "go.png", CC_CALLBACK_1(MainScene::gotoNextLevel,this));
    goItem->setVisible(false);
    goItem->setTag(2);
    goItem->setPosition(VisibleRect::right().x - goItem->getContentSize().width/2, VisibleRect::center().y);
    _menu = Menu::create(pauseItem, debugItem, goItem, NULL);
    _menu->setPosition(0,0);
    this->addChild(_menu, 20);

```


并加入回调函数:
void MainScene::gotoNextLevel(Ref* obj)
{
    auto goItem = this->_menu->getChildByTag(2);
    goItem->setVisible(false);
    goItem->stopAllActions();

    _background->move("left",_player);
}

```


要进行背景滚动,实现一个Background类
#ifndef __Background__
#define __Background__
#include "cocos2d.h"

USING_NS_CC;

class Background : public Layer
{
public:
    bool init();
    CREATE_FUNC(Background);
    void move(const char* direction, Sprite* withSprite);
    void onMoveEnd();
private:
    bool _isMoving;
    Sprite* _spriteA;
    Sprite* _spriteB;
};


#endif

```


滚动完毕,发消息通知MainScene再次放置怪物。
发送消息:Background::onMoveEnd()
    NotificationCenter::getInstance()->postNotification("backgroundMoveEnd");

```

接受消息:MainScene
    NotificationCenter::getInstance()->addObserver(this, callfuncO_selector(MainScene::backgroundMoveEnd),"backgroundMoveEnd",nullptr);

```

响应:
void MainScene::backgroundMoveEnd(Ref* obj)
{
    addEnemy();
    log("adding enemy...");
}

```


现在原教程里的功能就基本上实现了。

  

然后提交了一下, 名称为"Note 7 Finish Basic Tutorial"

下一步要做的事情比较明显。
即让敌人主动进攻玩家,玩家死亡显示失败界面。
以及设置过关目标,例如打败某个小boss,然后显示胜利界面。

下一篇:
http://www.cocoachina.com/bbs/read.php?tid=232616

占个沙发!期待中……

亲,一共几章~ 帮你把所有的笔记都 在索引里补全了~~

好 !!!!!!!!!!!!!!!!

抱歉,好久没上论坛,谢谢了…… 一共八章,已经更新完了。

去打球哇大大大的