cocos2dx3.x实现FlappyBird(二)

1.引言

        之前基本实现了界面部分的代码,本文为此游戏实现的第二个部分,主要内容是游戏的开始界面,也主要分为两个阶段,一点击屏幕;二开始游戏。游戏考虑到小鸟与柱子的碰撞以及自动下落的特性,引入了物理引擎,暂时只添加了小鸟的刚体。

2.代码部分

#ifndef GAME_SCENE_H_
#define GAME_SCENE_H_
#include"cocos2d.h"
#include"GameManager.h"
USING_NS_CC;
class GameScene:public Layer
{
	enum class Logic
	{
		PreStart,
		Start,
	};
public:
	bool init()override;
	static Scene* createScene();
	CREATE_FUNC(GameScene);
private:
	Logic logic = Logic::PreStart;
	Sprite* bgDownSprite;
	int offset = 0;
	Size _size;
	Sprite* _player;
	Vector<Sprite*> vectors;
	Vector<Sprite*> rubVectors;
	void update(float)override;
	bool onTouchBegan(Touch*, Event*)override;
	void onTouchMoved(Touch*,Event*)override;
	void onTouchEnded(Touch*,Event*)override;
	void updatePhysicsWorld(float);
	void rubRaise(float);
	void rubMove(float);
	int  _rate = GameManager::getInstance()->getRate();

};
#endif // !GAME_SCENE_H_
#include "GameScene.h"

bool GameScene::init()
{
	if (!Layer::init())
	{
		return false;
	}
	//
	_size = Director::getInstance()->getWinSize();
	//set background
	auto bgSprite = Sprite::create("media/1.png");
	bgSprite->setPosition(Vec2(_size.width / 2, 368));
	this->addChild(bgSprite);
	bgDownSprite = Sprite::create("media/2.png", Rect(0, 0, 288, 112));
	bgDownSprite->setPosition(Vec2(_size.width / 2, 56));
	this->addChild(bgDownSprite);
	//title sprite
	auto title1Sprite = Sprite::create("media/10.png");
	title1Sprite->setPosition(Vec2(_size.width / 2 - 50, _size.height / 2 + 150));
	vectors.pushBack(title1Sprite);
	this->addChild(title1Sprite);
	auto title2Sprite = Sprite::create("media/11.png");
	title2Sprite->setPosition(Vec2(_size.width / 2 + 50, _size.height / 2 + 148));
	vectors.pushBack(title2Sprite);
	this->addChild(title2Sprite);
	//tap sprite
	auto tap1Sprite = Sprite::create("media/20.png");
	tap1Sprite->setPosition(Vec2(_size.width / 2 - 40, _size.height / 2));
	vectors.pushBack(tap1Sprite);
	this->addChild(tap1Sprite);
	auto tap2Sprite = Sprite::create("media/21.png");
	tap2Sprite->setPosition(Vec2(_size.width / 2 + 40, _size.height / 2));
	vectors.pushBack(tap2Sprite);
	this->addChild(tap2Sprite);
	//finger
	auto fingerSprite = Sprite::create("media/22.png");
	fingerSprite->setPosition(_size / 2);
	vectors.pushBack(fingerSprite);
	this->addChild(fingerSprite);
	auto blink = Blink::create(4.0f, 5);
	fingerSprite->runAction(RepeatForever::create(blink));
	//up point
	auto upPointSprite = Sprite::create("media/17.png");
	upPointSprite->setPosition(Vec2(_size.width / 2, _size.height / 2 + 40));
	vectors.pushBack(upPointSprite);
	this->addChild(upPointSprite);
	//undisable bird
	auto unBirdSprite = Sprite::create("media/15.png");
	unBirdSprite->setPosition(Vec2(_size.width / 2, _size.height / 2 + 80));
	vectors.pushBack(unBirdSprite);
	this->addChild(unBirdSprite);
	//listener
	auto listener = EventListenerTouchOneByOne::create();
	listener->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegan, this);
	listener->onTouchMoved = CC_CALLBACK_2(GameScene::onTouchMoved, this);
	listener->onTouchEnded = CC_CALLBACK_2(GameScene::onTouchEnded, this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
	//
	auto keyPressListener = EventListenerKeyboard::create();
	keyPressListener->onKeyPressed = [&](EventKeyboard::KeyCode kecycode,Event* event)
	{
		if (kecycode==EventKeyboard::KeyCode::KEY_W)
		{
			_player->getPhysicsBody()->applyImpulse(Vec2(0,100));
		}
	};
	_eventDispatcher->addEventListenerWithSceneGraphPriority(keyPressListener,this);
	//contact listener
	auto contactListener = EventListenerPhysicsContact::create();
	contactListener->onContactBegin = [&](PhysicsContact& contact)
	{
		return true;
	};
	contactListener->onContactSeparate = [&](PhysicsContact& contact)
	{

	};
	_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener,this);
	//
	//schedule(CC_SCHEDULE_SELECTOR(GameScene::updatePhysicsWorld));
	schedule(CC_SCHEDULE_SELECTOR(GameScene::rubRaise), _rate);
	schedule(CC_SCHEDULE_SELECTOR(GameScene::rubMove));
	scheduleUpdate();
	return true;
}

Scene* GameScene::createScene()
{
	auto scene = Scene::createWithPhysics();
	scene->getPhysicsWorld()->setGravity(Vec2(0,-200));
	scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
	scene->getPhysicsWorld()->setAutoStep(true);
	auto layer = GameScene::create();
	scene->addChild(layer);
	return scene;
}
void GameScene::update(float)
{
	offset += _rate;
	if (offset > 49)
	{
		offset = 0;
	}
	else
	{
		bgDownSprite->setTextureRect(Rect(offset, 0, 288, 112));
	}
}

bool GameScene::onTouchBegan(Touch*, Event*)
{
	if (logic == Logic::PreStart)
	{
		for (auto child : vectors)
		{		
			this->removeChild(child);
		}
		logic = Logic::Start;
		//init the palyer
		const auto physicsMaterial = PhysicsMaterial(0, 0, 0);
		const auto physicsBody = PhysicsBody::createBox(Size(34, 24), physicsMaterial);
		_player = Sprite::create("media/55.png");
		_player->setPhysicsBody(physicsBody);
		_player->getPhysicsBody()->setDynamic(true);
		_player->setPosition(Vec2(_size.width / 2, _size.height / 2 + 80));
		this->addChild(_player);
		_player->runAction(Animate::create(AnimationCache::getInstance()->getAnimation("birdfly")));
	}
	else
	{
		_player->getPhysicsBody()->applyImpulse(Vec2(0,100));
	}
	return true;
}

void GameScene::onTouchMoved(Touch*, Event*)
{
}

void GameScene::onTouchEnded(Touch*, Event*)
{
}

void GameScene::updatePhysicsWorld(float dt)
{
	for (int i = 0; i < 3; i++)
	{
		static_cast<Scene*>(this->getParent())->getPhysicsWorld()->step(1 / 180.0f);
	}
}

void GameScene::rubRaise(float)
{
	if (logic==Logic::Start)
	{
		//change the anchor to (0.5,1)
		int y1 = random() % 271 + 50;
		auto downRub = Sprite::create("media/45.png", Rect(0, 0, 52, y1));
		downRub->setAnchorPoint(Vec2(0.5, 1));
		downRub->setPosition(Vec2(414, y1 + 112));
		this->addChild(downRub);
		//change the anchor to (0.5,0)
		int y2 = 522 - 180 - y1;
		auto topRub = Sprite::create("media/44.png", Rect(0, 320 - y2, 52, y2));
		topRub->setAnchorPoint(Vec2(0.5, 0));
		topRub->setPosition(Vec2(414, y1 + 292));
		this->addChild(topRub);
		//add
		rubVectors.pushBack(downRub);
		rubVectors.pushBack(topRub);
	}
}

void GameScene::rubMove(float)
{
	if (!rubVectors.empty())
	{
		Vector<Sprite*> removeVector;
		for (auto& v : rubVectors)
		{
			if (v->getPositionX() <= -26)
			{
				removeVector.pushBack(v);
			}
			else
			{
				v->setPositionX(v->getPositionX() - _rate*2.5);
			}
		}
		if (!removeVector.empty())
		{
			for (auto& v:removeVector)
			{
				rubVectors.eraseObject(v);
			}
		}
	}
}

3.效果图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值