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

在第一篇《制作飞镖忍者(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
如文章存在错误之处,欢迎指出,以便改正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杜甲同学

感谢打赏,我会继续努力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值