Cocos2dx游戏开发笔记21:动手学习《Flappy Bird》(待续)

懒骨头(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 size
	auto winSize = Director::getInstance()->getVisibleSize();

	// game bg
	auto 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 btn
	auto 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);

	// hero
	auto 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 positon
	int 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文件的初始化里绑定事件:

	// touch
	auto 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方法里根据这个标记位来改变高度

(哲哲喊我休息了,先到这吧,待续。。。)










郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。