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);
}
}
}
}