制作飞镖忍者(3) Cocos2d-x 3.0alpha0

来源:互联网 发布:网络办公软件排名 编辑:程序博客网 时间:2024/04/29 09:39

在第一篇《制作飞镖忍者(1)》和第二篇《制作飞镖忍者(2)》基础上,增加游戏难度和关卡。原文《How To Make A Simple iPhone Game with Cocos2D 2.X Part 3》,在这里继续以Cocos2d-x进行实现。有关源码、资源等在文章下面给出了地址。


步骤如下:
1.使用上一篇的工程;
2.下载本游戏所需的资源,将资源放置"Resources"目录下:

3.创建不同类型的怪物。一种软弱的,但是移动快速的怪物,另一种强壮的,但是移动缓慢的怪物。现在创建一个Monster类,基类为CCSprite。同时也创建以Monster为基类的两种类型怪物类。

Monster.h文件代码为:

#include "cocos2d.h"USING_NS_CC;class Monster:public Sprite {    public:    virtual bool initWithFile(const char* pszFilename,int hp,int minMoveDuration,int maxMoveDuration);    protected:    CC_SYNTHESIZE(int, _hp, Hp);    CC_SYNTHESIZE(int, _minMoveDuration, MinMoveDuration);    CC_SYNTHESIZE(int, _maxMoveDuration, MaxMoveDuration);    };class WeakAndFastMonster:public Monster {    public:    virtual bool init();    CREATE_FUNC(WeakAndFastMonster);};class StrongAndSlowMonster:public Monster {    public:    virtual bool init();    CREATE_FUNC(StrongAndSlowMonster);};
Monster.cpp文件代码为:

#include "Monster.h"bool Monster::initWithFile(const char *pszFilename, int hp, int minMoveDuration, int maxMoveDuration){    bool bRet = false;    do {        CC_BREAK_IF(!Sprite::initWithFile(pszFilename));                this->_hp = hp;        this->_minMoveDuration = minMoveDuration;        this->_maxMoveDuration = maxMoveDuration;                                bRet = true;    } while (0);    return bRet;}bool WeakAndFastMonster::init(){    return Monster::initWithFile("monster.png", 1, 3, 5);}bool StrongAndSlowMonster::init(){    return Monster::initWithFile("monster2.png", 3, 6, 12);}
4.在HelloWorldScene.cpp文件中,添加头文件引用:

#include "Monster.h"
修改addMonster函数,改变创建怪物精灵的语句,如下代码:

//    _monster = Sprite::create("monster.png");//    _monster->setTag(1);//    _monsters->addObject(_monster);//    _monster->setScale(2);        Monster* monster = NULL;        if (rand() % 2 == 0) {        monster = WeakAndFastMonster::create();    }    else    {        monster = StrongAndSlowMonster::create();            }    monster->setTag(1);    _monsters->addObject(monster);    monster->setScale(2);
这样就有一半的机会创建不同类型的怪物。另外,我们定义了不同类型怪物的移动速度,故需更改移动时间,如下代码:

    int minDuration = monster->getMinMoveDuration();    int maxDuration = monster->getMaxMoveDuration();
最后,修改update函数,更改_monsters循环的代码:

        bool monsterHit = false;        CCARRAY_FOREACH(_monsters, pObject2)        {            Monster* monster = (Monster*)pObject2;            if (projectile->getBoundingBox().intersectsRect(monster->getBoundingBox())) {                            monsterHit = true;                monster->setHp(monster->getHp() - 1);                if (monster->getHp() <= 0) {                     monstersToDelete->addObject(monster);                }                break;            }        }
每次击中怪物,减少它的一个HP血量,只有当小于等于0时,才被消灭。并且,记得跳出循环,因为每个子弹只能打中一只怪物。最后,更改projectilesToDelete语句为:

       // if (monstersToDelete->count() > 0)        if (monsterHit)        {            projectilesToDelete->addObject(projectile);        }
5.编译运行,可以看到不同类型的怪物出现在屏幕上,如下图所示:

6.多个关卡。需要创建一个类,记录所有的信息来区分不同的关卡。在这个简单的游戏中,只需记录三种信息:关卡序号、出现敌人的间隔时间(更高关卡将更快的出现怪物)、背景颜色(可以任意地分辨不同的关卡)。创建Level类,派生自CCObject。Level.h文件代码为:

#include "cocos2d.h"USING_NS_CC;class Level:public Object {    public:    virtual bool initWithLevelNum(int levelNum,float secsPerSpawn,Color4B background);    protected:    CC_SYNTHESIZE(int, _levelNum, LevelNum);    CC_SYNTHESIZE(float, _secsPerSpawn, SecsPerSpawn);    CC_SYNTHESIZE(Color4B, _backgroundColor, BackgroundColor);};
Level.cpp文件代码为:

#include "LevelInfo.h"bool Level::initWithLevelNum(int levelNum, float secsPerSpawn, cocos2d::Color4B backgroundColor){    this->_levelNum = levelNum;    this->_secsPerSpawn = secsPerSpawn;    this->_backgroundColor = backgroundColor;    return true;}
接下去创建一个类,记录所有的关卡信息,以及当前处在哪个关卡。创建LevelManager类,派生自CCObject。LevelManager.h文件代码为:

#include "cocos2d.h"#include "LevelInfo.h"USING_NS_CC;class LevelManager:public Object {    public:        static LevelManager* getInstance();    Level* curLevel();    void nextLevel();    void reset();    bool init();    void end();private:    LevelManager();    ~LevelManager();        Array* _levels;    int _curLevelIdx;};
LevelManager.cpp文件代码为:

////  LevelInfoManager.cpp//  HelloCpp////  Created by 杜甲 on 13-12-1.////#include "LevelInfoManager.h"LevelManager::LevelManager(){    _levels = NULL;}LevelManager* LevelManager::getInstance(){    static LevelManager* s_LevelManager = NULL;    if (!s_LevelManager) {        s_LevelManager = new LevelManager();        s_LevelManager->init();    }    return s_LevelManager;}Level* LevelManager::curLevel(){    if (_curLevelIdx >= (int)_levels->count()) {        return NULL;    }    return (Level*)_levels->getObjectAtIndex(_curLevelIdx);}void LevelManager::nextLevel(){    _curLevelIdx++;}void LevelManager::reset(){    _curLevelIdx = 0;}bool LevelManager::init(){    _curLevelIdx = 0;    Level* level1 = new Level();    level1->initWithLevelNum(1, 2, Color4B(255, 255, 255, 255));    level1->autorelease();        Level* level2 = new Level();    level2->initWithLevelNum(2, 1, Color4B(100, 150, 20, 255));    level2->autorelease();        _levels = Array::create(level1,level2, NULL);    _levels->retain();    return true;    }void LevelManager::end(){    this->release();}
用一个数组来记录关卡,一个索引指示当前关卡,以及一些方法,包括:获得当前关卡、进入下一个关卡、重置到第一个关卡。这个类是单例的,要通过sharedInstance方法来操作。
7.在HelloWorldScene.cpp文件中,添加头文件引用:

#include "LevelInfoManager.h"
修改init函数,修改背景色的设置,如下代码:

        CC_BREAK_IF(!LayerColor::initWithColor(LevelManager::getInstance()->curLevel()->getBackgroundColor()));
修改游戏逻辑定时器的安装,如下代码:

        this->schedule(schedule_selector(HelloWorld::gameLogic), LevelManager::getInstance()->curLevel()->getSecsPerSpawn());
这样就能根据不同的关卡,来设定不同的出现敌人间隔时间。
8.接着,在GameOverLayer.cpp文件中,添加头文件引用:

#include "LevelInfoManager.h"
initWithWon函数,修改成如下代码:

bool GameOverLayer::initWithWon(bool won){    bool bRet = false;    do {        CC_BREAK_IF(!LayerColor::initWithColor(Color4B(255, 255, 255, 255)));                String* message;        if (won) {            LevelManager::getInstance()->nextLevel();            Level* curLevel = LevelManager::getInstance()->curLevel();            if (curLevel) {                message = String::createWithFormat("Get ready gor level %d!",curLevel->getLevelNum());                            }            else            {                message  = String::create("You Won!");                LevelManager::getInstance()->reset();            }        }        else        {            message = String::create("You Lose !");            LevelManager::getInstance()->reset();        }        Size winSize = Director::getInstance()->getWinSize();        LabelTTF* label = LabelTTF::create(message->getCString(), "Arial", 32);        label->setColor(Color3B(0, 0, 0));        label->setPosition(Point(winSize.width / 2, winSize.height / 2));        this->addChild(label);                this->runAction(Sequence::create(DelayTime::create(3),                                         CallFunc::create(std::bind(&GameOverLayer::gameOverDone, this)), NULL));        bRet = true;    } while (0);    return bRet;}
10.编译运行,就可以看到不同类型的怪物、多个关卡的游戏了,如下图所示:

参考资料:
1.How To Make A Simple iPhone Game with Cocos2D 2.X Part 3http://www.raywenderlich.com/25806/harder-monsters-and-more-levels-how-to-make-a-simple-iphone-game-with-cocos2d-2-x-part-3
2.如何使用cocos2d来制作简单的iphone游戏:更猛的怪物和更多的关卡http://www.cnblogs.com/zilongshanren/archive/2011/03/28/1997966.html

非常感谢以上资料的学习,本例子源代码附加资源下载地址:http://pan.baidu.com/s/1d5fFt
如文章存在错误之处,欢迎指出,以便改正。