Late bone (http://blog.csdn.net/iamlazybone QQ: 124774397)
Flappy Bird
I'm not talking about this game.
Start learning directly (The Shanzhai is not nice)
Some time ago I saw several demos and used this game trainer.
Start!
Reporting Environment:
Vs2013 + cocos2dx3.0beta2
First download the apk, find the resource file, and crop several images:
Create an empty Cocos2dx project using scripts
Create a Scene class
#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;}
In initUI, there are some UI initialization methods:
// 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);
The gameStart method bound to the Start game button is as follows:
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;}
Hide start button, show birds, and start to move Pipe
There are also update Methods:
scheduleUpdate();void FlyBirdGame::update(float time){obstacle->update();}
========================================================
Pipe class: Obstacle. cpp
In the update method, determine whether the game starts.
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);}}}
In the update method of water pipes, a pair of water pipes is added every 60 frames (1 second ).
And traverse the pipe list
Destruction of outbound boundaries
The addOne method is used to add a pipe:
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));}
This code is messy, that is, to find the upper and lower positions of the pipe
Then random, and make sure there is a minimum distance between the upper and lower pipes.
The effect is as follows:
==================================
At this time, the game has no touch and collision Logic
Add now: (I just took the time to get the Cube: I can only deal with one level, although there are official rules, it seems like memory)
I heard that the event listening method of cocos2dx3.0 has changed.
First declare the two methods in FlyBirdGame. h:
void onTouchesEnded(const vector<Touch*>& touches, Event* event);void onTouchesBegan(const vector<Touch*>& touches, Event* event);
Bind events to the cpp file during initialization:
// 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);
Change the flag position in two event methods, and change the height in the update method of the bird.
(Zhezhe calls me a break. Come here first, To be continued ...)
==================================
Collision Detection:
I remember cocos2dx3.0 used to write a CCRect Method Based on CCSprite.
Use the Sprite getBoundingBox () method directly.
However, if you have special requirements, you have to write them yourself, such as expanding or narrowing down the collision area.
In the FlyBirdGame. cpp File
The update calculation logic method is as follows:
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;}}
Based on the game status.
Collision Detection Method: intersectsRect
Bool pia = rHero. intersectsRect (obstacleRect-> getBoundingBox ());
If (pia = true)
{
GAME_STATUS = GAME_STATUS_GAME_OVER;
Break;
}
The game status is defined in the resource. h file.
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;
The entire game process has passed: Start, game, end, start again
Next, we can optimize many things.