zoukankan      html  css  js  c++  java
  • 制作一个塔防游戏 Cocos2d-x 2.1.4 (一)

         在这篇文章,将会学习到怎样制作一个塔防游戏。在这其中,学习怎样在设定的时间内出现一波波的敌人,使这些敌人沿着指定的路点前进。怎样在地图上指定的位置创建炮塔。怎样使炮塔射击敌人,怎样可视化调试路点和炮塔的攻击范围。

         对于刚開始学习的人来说。这个样例是非常适合的。对于熟悉cocos2d有非常好的帮助,希望初学cocos的博友们细致搞搞, 本人刚開始做这个 咨询了原文作者好几次。祝大家成功!


    1.新建Cocos2d-win32project,project名为"TowerDefense",去除"Box2D"选项,勾选"Simple Audio Engine in Cocos Denshion"选项;
    2.下载本游戏所需的资源,将资源放置"Resources"文件夹下;

    资源中包含源码:http://download.csdn.net/detail/yangshuo528/7426007

    3.为场景加入背景图片。打开HelloWorldScene.cpp文件,改动init函数。例如以下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    bool HelloWorld::init()
    {
        bool bRet = false;
        do 
        {
            CC_BREAK_IF(! CCLayer::init());
            
            this->setTouchEnabled(true);
            CCSize wins = CCDirector::sharedDirector()->getWinSize();
            CCSprite *background = CCSprite::create("Bg.png");
            this->addChild(background);
            background->setPosition(ccp(wins.width / 2, wins.height / 2));

            bRet = true;
        } while (0);
        return bRet;
    }

    通过放置的背景图片。能够直观的看出哪些地方同意玩家放置炮塔。编译执行,例如以下图所看到的:

    4.接着。须要沿路设置一些点,在这些点上能够让玩家触摸和建立炮塔。为了方便管理,使用.plist文件来存储炮塔的放置点。这样就能够非常easy的改变它们。TowersPosition.plist已经在资源目录中。当中已经有了一些炮塔的位置。查看这个文件,能够看到一个字典数组,字典仅仅包括两个键"x"和"y"。每一个字典条目代表一个炮塔位置的x和y坐标。

    如今须要读取这个文件,而且放置塔基到地图上。打开HelloWorldScene.h文件,加入下面变量:

    1
    cocos2d::CCArray* towerBases;
    打开HelloWorldScene.cpp文件,加入例如以下方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    void HelloWorld::loadTowerPositions()
    {
        CCArray* towerPositions = CCArray::createWithContentsOfFile("TowersPosition.plist");
        towerBases = CCArray::createWithCapacity(10);
        towerBases->retain();

        CCObject *pObject = NULL;
        CCARRAY_FOREACH(towerPositions, pObject)
        {
            CCDictionary* towerPos = (CCDictionary*)pObject;
            CCSprite* towerBase = CCSprite::create("open_spot.png");
            this->addChild(towerBase);
            towerBase->setPosition(ccp(((CCString*)towerPos->objectForKey("x"))->intValue(),
                ((CCString*)towerPos->objectForKey("y"))->intValue()));
            towerBases->addObject(towerBase);
        }
    }

    init函数里面。加入背景图片代码之后,加入例如以下代码:

    1
    this->loadTowerPositions();
    在析构函数里面。加入例如以下代码:
    1
    towerBases->release();
    编译执行。就能够看到道路两側的方块,这些是做为玩家炮塔的基座。例如以下图所看到的:

    5.開始建立炮塔。打开HelloWorldScene.h文件。加入例如以下代码:
    1
    CC_SYNTHESIZE_RETAIN(cocos2d::CCArray*, _towers, Towers);
    加入Tower类,派生自CCNode类。Tower.h文件代码例如以下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #ifndef __TOWER_H__
    #define __TOWER_H__

    #include "cocos2d.h"
    #include "HelloWorldScene.h"

    #define kTOWER_COST 300

    class Tower : public cocos2d::CCNode
    {
    public:
        Tower(void);
        ~Tower(void);

        static Tower* nodeWithTheGame(HelloWorld* game, cocos2d::CCPoint location);
        bool initWithTheGame(HelloWorld* game, cocos2d::CCPoint location);

        void update(float dt);
        void draw(void);

        CC_SYNTHESIZE(HelloWorld*, _theGame, TheGame);
        CC_SYNTHESIZE(cocos2d::CCSprite*, _mySprite, MySprite);

    private:
        int attackRange;
        int damage;
        float fireRate;
    };

    #endif  // __TOWER_H__

    打开Tower.cpp文件,代码例如以下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #include "Tower.h"
    using namespace cocos2d;

    Tower::Tower(void)
    {
    }

    Tower::~Tower(void)
    {
    }

    Tower* Tower::nodeWithTheGame(HelloWorld* game, CCPoint location)
    {
        Tower *pRet = new Tower();
        if (pRet && pRet->initWithTheGame(game, location))
        {
            return pRet;
        }
        else
        {
            delete pRet;
            pRet = NULL;
            return NULL;
        }
    }

    bool Tower::initWithTheGame(HelloWorld* game, CCPoint location)
    {
        bool bRet = false;
        do 
        {
            attackRange = 70;
            damage = 10;
            fireRate = 1;
            
            _mySprite = CCSprite::create("tower.png");
            this->addChild(_mySprite);
            _mySprite->setPosition(location);
            _theGame = game;
            _theGame->addChild(this);

            this->scheduleUpdate();

            bRet = true;
        } while (0);

        return bRet;
    }

    void Tower::update(float dt)
    {

    }

    void Tower::draw(void)
    {
    #ifdef COCOS2D_DEBUG
        ccDrawColor4F(255255255255);
        ccDrawCircle(_mySprite->getPosition(), attackRange, 36030false);
    #endif
        CCNode::draw();
    }

    这个Tower类包括几个属性:一个精灵对象,这是炮塔的可视化表现;一个父层的引用,方便訪问父层。还有三个变量:

    • attackRange: 炮塔能够攻击敌人的距离。
    • damage: 炮塔对敌人造成的伤害值。

    • fireRate: 炮塔再次攻击敌人的时间间隔。

    有了这三个变量。就能够创建各种不同攻击属性的炮塔,比方须要非常长时间来又一次载入的远程重击,或者范围有限的高速攻击。最后。代码中的draw方法,用于在炮塔周围绘制一个圆。以显示出它的攻击范围,这将方便调试。



    6.让玩家加入炮塔。打开HelloWorldScene.cpp文件,加入下面头文件声明:

    1
    #include "Tower.h"
    在析构函数中加入例如以下代码:
    1
    _towers->release();
    init函数,加入例如以下代码:
    1
    2
    _towers = CCArray::create();
    _towers->retain();
    加入例如以下两个方法。代码例如以下(在 HelloWorldScene.h别忘了加入函数声明 ):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    bool HelloWorld::canBuyTower()
    {
        return true;
    }

    void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
    {
        CCSetIterator iter = pTouches->begin();
        for (; iter != pTouches->end(); iter++)
        {
            CCTouch* pTouch = (CCTouch*)(*iter);
            CCPoint location = pTouch->getLocation();

            CCObject *pObject = NULL;
            CCARRAY_FOREACH(towerBases, pObject)
            {
                CCSprite *tb = (CCSprite*)pObject;
                if (this->canBuyTower() && tb->boundingBox().containsPoint(location) && !tb->getUserData())
                {
                    //We will spend our gold later.

                    Tower* tower = Tower::nodeWithTheGame(this, tb->getPosition());
                    _towers->addObject(tower);
                    tb->setUserData(tower);
                }           
            }
        }
    }

    方法ccTouchesBegan检測当用户触摸屏幕上不论什么点时,遍历towerBases数组,检查触摸点是否包括在不论什么一个塔基上。

    只是在创建炮塔前。还有两件事须要检查:
    ①玩家是否买得起炮塔?canBuyTower方法用来检查玩家是否有足够的金币来购买炮塔。

    在这里先如果玩家有非常多金币。方法返回true。


    ②玩家是否违法了建筑规则?假设tb的UserData已经设置了。那么这个塔基已经有了炮塔,不能再加入一个新的了。
    假设一切检查都通过,那么就创建一个新的炮塔。放置在塔基上,并将它加入到炮塔数组中。编译执行,触摸塔基,就能够看到炮塔放置上去了,而且它的周围还有白色的圆圈显示攻击范围,例如以下图所看到的:


    參考资料:1.How To Make a Tower Defense Game  http://www.raywenderlich.com/15730/how-to-make-a-tower-defense-game

    怎样制作一个塔防游戏:http://blog.csdn.net/akof1314/article/details/8674186

  • 相关阅读:
    python 01
    Node.js 基础库
    Node 编程规范
    Linux_异常_08_本机无法访问虚拟机web等工程
    inux_异常_07_ftp查看不到文件列表
    Linux_异常_04_ftp: command not found...
    Linux_异常_03_Failed to restart iptables.service: Unit not found.
    Linux_异常_02_WinSCP上传文件时显示Permission denied
    Linux_异常_01_CentOS7无法ping 百度
    Linux_配置_02_配置dns
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6791210.html
Copyright © 2011-2022 走看看