Cocos2dx遊戲開發筆記21:動手學習《Flappy Bird》

來源:互聯網
上載者:User

懶骨頭(http://blog.csdn.net/iamlazybone QQ:124774397 )

《Flappy Bird》


關於這個遊戲骨頭不多說了

直接開始學習吧(山寨不好聽)

正好前段時間看了幾個DEMO拿這個遊戲練練手

開搞!


報環境:

vs2013+cocos2dx3.0beta2

首先下載apk,找到資源檔,裁剪幾個圖片:


用指令碼建立一個空的Cocos2dx項目

建立一個Scene類

#include "cocos2d.h"#include "Obstacle.h"class FlyBirdGame :public cocos2d::Layer{public:static cocos2d::Scene* createScene();virtual bool init();CREATE_FUNC(FlyBirdGame);void initUI();void gameStart(Object* pSender); void update(float time);Obstacle* obstacle;};

#include "cocos2d.h"#include "FlyBirdGame.h"#include "resource.h"; USING_NS_CC;Scene* FlyBirdGame::createScene(){auto scene = Scene::create();auto layer = FlyBirdGame::create();scene->addChild(layer);return scene;}bool FlyBirdGame::init(){if (!Layer::init()){return false;}initUI();return true;}

initUI裡是一些UI初始化方法:

        // win sizeauto winSize = Director::getInstance()->getVisibleSize();// game bgauto bg = Sprite::create(bird_bg);bg->setPosition(winSize.width / 2, winSize.height / 2);bg->setScale(winSize.width / bg->getContentSize().width, winSize.height / bg->getContentSize().height);this->addChild(bg);// start btnauto startBtn = MenuItemImage::create(bird_start_btn, bird_start_btn_pressed, CC_CALLBACK_1(FlyBirdGame::gameStart, this));auto menu = Menu::create(startBtn, NULL);menu->setTag(100);this->addChild(menu);// heroauto hero = Sprite::create(bird_hero);hero->setPosition(winSize.width / 5, winSize.height*0.8);hero->setVisible(false);hero->setTag(200);this->addChild(hero);

開始遊戲按鈕綁定的gameStart方法:

void FlyBirdGame::gameStart(Object* pSender){auto btn = this->getChildByTag(100);btn->setVisible(false);auto hero = this->getChildByTag(200); Size win = Director::getInstance()->getWinSize();obstacle->gameStart = true;}

隱藏開始按鈕,顯示小鳥,水管開始移動

還有更新方法:

scheduleUpdate();void FlyBirdGame::update(float time){obstacle->update();}

=======================================

水管類:Obstacle.cpp

update方法裡判斷遊戲是遊戲是否開始


void Obstacle::update(){if (gameStart == false)return;addCount++;if (addCount == 60){addOne(0);addCount = 0;}for (int i = obstacleList->count() - 1; i >= 0; i--){auto s = (Sprite*)obstacleList->getObjectAtIndex(i);s->setPositionX(s->getPositionX() - 3);if (s->getPositionX() < -s->getContentSize().width / 2){obstacleList->removeObjectAtIndex(i);this->removeChild(s);}}}
水管類的更新方法裡,每60幀(1秒)添加一對水管

並且遍曆水管列表

出邊界的化銷毀

接下來是addOne方法:添加水管方法:

void Obstacle::addOne(int offsetX){Size size = Director::getInstance()->getWinSize();auto sprite = Sprite::create(bird_obstacle_up);Size spriteSize = sprite->getContentSize();obstacleList->addObject(sprite);this->addChild(sprite);auto sprite2 = Sprite::create(bird_obstacle_down);Size spriteSize2 = sprite->getContentSize();obstacleList->addObject(sprite2);this->addChild(sprite2);// set positonint maxUpY = size.height + spriteSize.height / 4;int minUpY = size.height - spriteSize.height / 4;int y1 = CCRANDOM_0_1()*(maxUpY - minUpY) + minUpY;int maxDownY = spriteSize.height / 4;int minDownY = -spriteSize.height / 4;int y2 = CCRANDOM_0_1()*(maxDownY - minDownY) + minDownY;if (y1 - y2 - spriteSize.height < 160){y2 = y1 - spriteSize.height - 160;}sprite->setPosition(ccp(size.width + spriteSize.width / 2 + offsetX, y1));sprite2->setPosition(ccp(size.width + spriteSize2.width / 2 + offsetX, y2));}
這段代碼比較淩亂,就是找到水管上下位置的範圍

然後隨機一下,並且保證上下連個水管有個最小的距離

效果如下:



=============================

此時的遊戲還沒觸摸和碰撞邏輯

馬上添加:(剛才抽空玩了把魔方:五階的我只能搞定一個面,雖然有官方規律但是那樣好像比的是記憶力)

聽說cocos2dx3.0的事件監聽方式改變了

先在FlyBirdGame.h裡聲明倆方法:

void onTouchesEnded(const vector<Touch*>& touches, Event* event);void onTouchesBegan(const vector<Touch*>& touches, Event* event);

在cpp檔案的初始化裡綁定事件:

// touchauto dispatcher = Director::getInstance()->getEventDispatcher();auto listener = EventListenerTouchAllAtOnce::create();listener->onTouchesEnded = CC_CALLBACK_2(FlyBirdGame::onTouchesEnded, this);listener->onTouchesBegan = CC_CALLBACK_2(FlyBirdGame::onTouchesBegan, this);dispatcher->addEventListenerWithSceneGraphPriority(listener, this);

在兩個事件方法裡改變標記位,在小鳥的update方法雷根據這個標記位來改變高度

(哲哲喊我休息了,先到這吧,待續。。。)

=============================

碰撞檢測:

記得cocos2dx3.0以前都是自己寫一個根據CCSprite擷取CCRect的方法

現在直接用 Sprite的getBoundingBox()方法

不過如果有特殊需求還得自己寫,比如想擴大或縮小碰撞地區

在FlyBirdGame.cpp檔案裡

update算主邏輯方法:

void FlyBirdGame::update(float time){auto winSize = Director::getInstance()->getVisibleSize();auto hero = this->getChildByTag(TAG_HERO);Rect rHero = ((Sprite*)hero)->getBoundingBox();switch (GAME_STATUS){case GAME_STATUS_PLAYING:obstacle->update();// update bird positionYif (isFlying&&hero->getPositionY() < winSize.height){hero->setPositionY(hero->getPositionY() + v);}else if (hero->getPositionY()>0){hero->setPositionY(hero->getPositionY() - v);}//check collisionfor (int i = 0; i < obstacle->obstacleList->count(); i++){Sprite* obstacleRect = (Sprite*)obstacle->obstacleList->getObjectAtIndex(i);bool pia = rHero.intersectsRect(obstacleRect->getBoundingBox());if (pia == true){GAME_STATUS = GAME_STATUS_GAME_OVER;break;}}break;case GAME_STATUS_GAME_OVER:CCLog("over");this->getChildByTag(TAG_OVER)->setVisible(true);break;case GAME_STATUS_RESTART://reset gameobstacle->removeAllChildren();obstacle->obstacleList->removeAllObjects();// reset herohero->setPosition(winSize.width / 5, winSize.height*0.8);// show btnauto btn = this->getChildByTag(TAG_START_BTN);btn->setVisible(true);// show logoauto logo = this->getChildByTag(TAG_LOGO);logo->setVisible(true);break;}}

根據遊戲狀態處理。

碰撞檢測方法:intersectsRect

bool pia = rHero.intersectsRect(obstacleRect->getBoundingBox());
if (pia == true)
{
GAME_STATUS = GAME_STATUS_GAME_OVER;
break;
}


遊戲狀態定義在 resource.h 檔案裡

static const int GAME_STATUS_START = 10;static const int GAME_STATUS_PLAYING = 20;static const int GAME_STATUS_GAME_OVER = 30;static const int GAME_STATUS_RESTART = 40;


整個遊戲流程已經通了:開始,遊戲,結束,重新開始

接下來可以最佳化很多很多東西



 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.