製作一個塔防遊戲 Cocos2d-x 2.1.4 (一)

來源:互聯網
上載者:User

     在這篇文章,將會學習到如何製作一個塔防遊戲。在這當中,學習如何在設定的時間內出現一波波的敵人,使這些敵人沿著指定的路點前進,如何在地圖上指定的位置建立炮塔,如何使炮塔射擊敵人,如何可視化調試路點和炮塔的攻擊範圍。

     對於初學者來說,這個例子是非常適合的,對於熟悉cocos2d有很好的協助,希望初學cocos的博友們仔細搞搞, 本人剛開始做這個 諮詢了原文作者好幾次,祝大家成功!


1.建立Cocos2d-win32工程,工程名為"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檔案來儲存炮塔的放置點,這樣就可以很容易的改變它們。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(255, 255, 255, 255);
    ccDrawCircle(_mySprite->getPosition(), attackRange, 360, 30, false);
#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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.