閱讀309 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Cocos2d-x 酷跑遊戲例子

1. 效果圖

 

 

可以拉到底部看下動態圖,鼠標點擊屏幕,主角會跳下,遇到間隙或碰上較高建築就掛了。在空中如果點擊鼠標,主角會撐起一把雨傘,會有緩慢降落效果。主角掛的時候,會有主角的帽子升上的動畫,不知為什麼這個簡單的動畫看起來是那麼的有趣,點睛之筆。

 


2. cocos2d-x 中菜單的使用

 

?
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
//add menu
    CCSprite * menuItemOn;
    CCSprite * menuItemOff;
    //菜單有兩個狀態,平時展示的樣子和點擊的樣子
    menuItemOn = CCSprite::createWithSpriteFrameName("btn_new_on.png");
    menuItemOff = CCSprite::createWithSpriteFrameName("btn_new_off.png");
    //New Game 菜單
    CCMenuItemSprite * starGametItem = CCMenuItemSprite::create(
                                                                menuItemOff,
                                                                menuItemOn,
                                                                this,
                                                                //這個最重要,點擊菜單調用係統哪個方法
                                                                menu_selector(GameLayer::startGame));
 
    menuItemOn = CCSprite::createWithSpriteFrameName("btn_howto_on.png");
    menuItemOff = CCSprite::createWithSpriteFrameName("btn_howto_off.png");
    //How to Play 菜單
    CCMenuItemSprite * howToItem = CCMenuItemSprite::create(
                                                            menuItemOff,
                                                            menuItemOn,
                                                            this,
                                                            menu_selector(GameLayer::showTutorial));
 
    _mainMenu = CCMenu::create(howToItem, starGametItem, NULL);//創建菜單
    _mainMenu->alignItemsHorizontallyWithPadding(120);//設置兩個菜單的水平間距
    _mainMenu->setPosition(ccp(_screenSize.width * 0.5f, _screenSize.height * 0.54));
 
    this->addChild(_mainMenu, kForeground);

 

3.創建水平移動效果(Parallax)

 

 所謂酷跑遊戲,很多時候你會發現主角的位置其實沒動,動的都是背景,背景往左移,看起來主角就往右前進了,背景往後退,看起來主角就往前進了,所謂的相對運動。 

 

那麼這遊戲是如何實現的呢?非常簡單。拿背景舉例子。下麵這代碼會放在update函數裏執行。

 

 

?
1
2
3
4
5
6
7
8
//背景一直往左移
        _background->setPositionX(_background->getPosition().x - _player->getVector().x * 0.25f);
        float diffx;
        //移完一個寬度時,重新把位置設置為接近0的位置
        if (_background->getPositionX() < -_background->getContentSize().width) {
            diffx = fabs(_background->getPositionX()) - _background->getContentSize().width;
            _background->setPositionX(-diffx);
        }

 

 

這種方式效率可能比較低,但這種是所有平台通用的方式。查看了Cocos2d-x的示例,發現了一個叫ParallaxTest的例子,是可以混合幾種東西一起使用動畫。下麵是官方的例子。

 

 

?
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
// create a void node, a parent node
   CCParallaxNode* voidNode = CCParallaxNode::create();
 
   // NOW add the 3 layers to the 'void' node
 
   // background image is moved at a ratio of 0.4x, 0.5y
   voidNode->addChild(background, -1, ccp(0.4f,0.5f), CCPointZero);
 
   // tiles are moved at a ratio of 2.2x, 1.0y
   voidNode->addChild(tilemap, 1, ccp(2.2f,1.0f), ccp(0,-200) );
 
   // top image is moved at a ratio of 3.0x, 2.5y
   voidNode->addChild(cocosImage, 2, ccp(3.0f,2.5f), ccp(200,800) );
 
   // now create some actions that will move the 'void' node
   // and the children of the 'void' node will move at different
   // speed, thus, simulation the 3D environment
   CCActionInterval* goUp = CCMoveBy::create(4, ccp(0,-500) );
   CCActionInterval* goDown = goUp->reverse();
   CCActionInterval* go = CCMoveBy::create(8, ccp(-1000,0) );
   CCActionInterval* goBack = go->reverse();
   CCSequence* seq = CCSequence::create(goUp, go, goDown, goBack, NULL);
   voidNode->runAction( (CCRepeatForever::create(seq) ));
 
   addChild( voidNode );

 


4. 如何隨機?

 

 遊戲有時候就是需要很多隨機情況,看下主角腳下的房子,有不同的顏色,有不同的高度,寬度,房子之間的間隙也不一定地出現。可能隨機數是一個解決方案,這裏用了一個更加有趣的方案,給定幾組數組,然後對這數組進行洗牌。用一個index對數組取數,到尾了再回到0,進行洗牌。這種方式我想了下可以更好的控製難度。下麵是建築物高度的例子。

?
1
2
3
4
5
6
7
8
9
10
int heights[] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,3,3,3,3,3,3,4};//可控製的難度,建築物的高度
vector<int> _blockHeights (heights, heights + sizeof(heights) / sizeof(int));
random_shuffle(_blockHeights.begin(), _blockHeights.end());//洗牌
int blockHeight = _blockHeights[_currentHeightIndex];
_currentHeightIndex++;//以後每次移動index來訪問數組中每個元素。
 
   if (_currentHeightIndex == _blockHeights.size()) { //是數組最後一個元素是,回到第一個元素,重新洗牌
                _currentHeightIndex = 0;
                random_shuffle(_blockHeights.begin(), _blockHeights.end());//重新洗牌              
  }

 


5.碰撞檢測

 

 這沒有用到box2d物理引擎,碰撞就需要自己來寫了,非常簡單,在遊戲中主角隻有跟下麵的房子又碰撞,碰撞又隻有分兩種:

  1. 主角在上麵隨著重力加速度的存在,自由落體時,跟下麵的房子相碰。
  2. 主角迎麵碰上一個高的房子。

碰撞結果分兩種:

  1. 主角掉下跟房子相碰時,不再往下降,房子看起來像一個實體。
  2. 主角迎麵碰上一個高的房子時,主角產生一個向後退的效果。

主角是一個矩形,房子也是一個矩形,兩種相碰就容易了。

 

 

?
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
for (i = 0; i < count; i++) {
 
        block = (Block *) _blocks->objectAtIndex(i);
        if (block->getType() == kBlockGap) continue;
 
        //if within x, check y (bottom collision),檢測上下碰撞
        if (player->right() >= this->getPositionX() + block->left()
            && player->left() <= this->getPositionX() + block->right()) {
 
            if (player->bottom() >= block->top() && player->next_bottom() <= block->top()
                && player->top() > block->top()) {
                player->setNextPosition(ccp(player->getNextPosition().x, block->top() + player->getHeight()));//碰撞完更改位置在block上麵
                player->setVector ( ccp(player->getVector().x, 0) );//碰撞完沒有Y軸上的加速度
                player->setRotation(0.0);
                inAir = false;
                break;
            }
 
        }
    }
 
    for (i = 0; i < count; i++) {
        block = (Block *) _blocks->objectAtIndex(i);
        if (block->getType() == kBlockGap) continue;
 
        //now if within y, check x (side collision)左右碰撞
        if ((player->bottom() < block->top() && player->top() > block->bottom())
            || (player->next_bottom() < block->top() && player->next_top() > block->bottom())) {
 
                if (player->right() >= this->getPositionX() + block->getPositionX()
                    && player->left() < this->getPositionX() + block->getPositionX()) {
 
                        player->setPositionX( this->getPositionX() + block->getPositionX() - player->getWidth() * 0.5f );
                        player->setNextPosition(ccp(this->getPositionX() + block->getPositionX() - player->getWidth() * 0.5f, player->getNextPosition().y));
                        player->setVector ( ccp(player->getVector().x * -0.5f, player->getVector().y) );
                        if (player->bottom() + player->getHeight() * 0.2f < block->top()) {
                            player->setState(kPlayerDying);
                            return;
 
                        }
 
                        break;
                }
        }
    }

 


6.動態圖

 

7.代碼下載(請用7z解壓)

 

 https://www.waitingfy.com/?attachment_id=787

 


8.參考書目

《Cocos2d-X by Example Beginner’s Guide》

猜你還喜歡:

最後更新:2017-04-03 12:56:08

  上一篇:go Extjs中對ajax中request方法的重寫,對請求的過濾
  下一篇:go 獲取手機短信內容