cocos2d-x-3.16 实例开发之FlappyBird【5】控制层与游戏层

一、控制层

在OptionLayer层中,我们实现了触摸事件的监听

bool OptionLayer::init()
{
	if(Layer::init()){
		auto dispatcher = Director::getInstance()->getEventDispatcher();
        auto listener = EventListenerTouchAllAtOnce::create();
        listener->onTouchesBegan = CC_CALLBACK_2(OptionLayer::onTouchesBegan, this);
        dispatcher->addEventListenerWithSceneGraphPriority(listener, this);

		return true;
	}else {
		return false;
	}
}

void OptionLayer::onTouchesBegan(const std::vector<Touch*>& touches, Event *event)
{
	this->delegator->onTouch();
}

在头文件OptionLayer.h中定义了delegator

CC_SYNTHESIZE(OptionDelegate*, delegator, Delegator);

还有OptionDelegate类

class OptionDelegate
{
public:
    virtual void onTouch() = 0;
};

二、控制层与游戏层的关系

游戏层GameLayer和控制层OptionLayer通过代理OptionDelegate来进行通讯

游戏层继承OptionDelegate实现onTouch()方法

class GameLayer : public Layer , public OptionDelegate{
    ...
};

在游戏主场景GameScene中将两者联系起来

		// Add operation layer to control the game
		auto optionLayer = OptionLayer::create();
		if(optionLayer) {
			optionLayer->setDelegator(gameLayer);
			this->addChild(optionLayer);
		}

三、游戏层

1、游戏状态

游戏有三种状态:准备、开始、结束

typedef enum _game_status {
GAME_STATUS_READY = 1,
GAME_STATUS_START,
GAME_STATUS_OVER
} GameStatus;

2、添加小鸟

在上一节中我们已经完成了小鸟类的封装,我们先在GameLayer.h中声明这只小鸟

BirdSprite *bird;

设置物理引擎的相关属性并添加到游戏层中

// Add the bird
this->bird = BirdSprite::getInstance();
this->bird->createBird();
PhysicsBody *body = PhysicsBody::create();
        body->addShape(PhysicsShapeCircle::create(BIRD_RADIUS));
        body->setCategoryBitmask(ColliderTypeBird);
        body->setCollisionBitmask(ColliderTypeLand & ColliderTypePip);
        body->setContactTestBitmask(ColliderTypeLand | ColliderTypePip);
        body->setDynamic(true);
body->setLinearDamping(0.0f);
body->setGravityEnable(false);
this->bird->setPhysicsBody(body);
this->bird->setPosition(origin.x + visiableSize.width*1/3 - 5,origin.y + visiableSize.height/2 + 5);
this->bird->idle();
this->addChild(this->bird);

游戏进行过程当中,每次点击屏莫的时候,给小鸟设置一个向上的初速度:

this->bird->getPhysicsBody()->setVelocity(Vect(0, 260)

3、水管的添加

水管的添加,主要是通过createPips()函数来生成水管

void GameLayer::createPips() {
    // Create the pips
    for (int i = 0; i < PIP_COUNT; i++) {
        Size visibleSize = Director::getInstance()->getVisibleSize();
        Sprite *pipUp = Sprite::createWithSpriteFrameName("pipe_up.png");
        Sprite *pipDown = Sprite::createWithSpriteFrameName("pipe_down.png");
        Node *singlePip = Node::create();
        
        // bind to pair
        pipDown->setPosition(0, PIP_HEIGHT + PIP_DISTANCE);
		singlePip->addChild(pipDown, 0, DOWN_PIP);
        singlePip->addChild(pipUp, 0, UP_PIP);
        singlePip->setPosition(visibleSize.width + i*PIP_INTERVAL + WAIT_DISTANCE, this->getRandomHeight());
		auto body = PhysicsBody::create();
		auto shapeBoxDown = PhysicsShapeBox::create(pipDown->getContentSize(),PHYSICSSHAPE_MATERIAL_DEFAULT, Point(0, PIP_HEIGHT + PIP_DISTANCE));
		body->addShape(shapeBoxDown);
		body->addShape(PhysicsShapeBox::create(pipUp->getContentSize()));
		body->setDynamic(false);
		body->setContactTestBitmask(true);
		singlePip->setPhysicsBody(body);
        singlePip->setTag(PIP_NEW);

        this->addChild(singlePip);
        this->pips.push_back(singlePip);
    }
}

一组水管由上下2半根组成,用vector容器添加两组管道,每次出现在屏幕中的管子只有两组,当一组消失在屏幕范围内则重设置其横坐标

    // move the pips
    for (auto singlePip : this->pips) {
        singlePip->setPositionX(singlePip->getPositionX() - 2);
        if(singlePip->getPositionX() < -PIP_WIDTH) {
            singlePip->setTag(PIP_NEW);
            Size visibleSize = Director::getInstance()->getVisibleSize();
            singlePip->setPositionX(visibleSize.width);
            singlePip->setPositionY(this->getRandomHeight());
        }
    }

4、碰撞检查

在GameLayer初始化的时候,我们创建了一个碰撞监听:

auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_1(GameLayer::onContactBegin, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener, this);


一旦出现碰撞,则进入游戏结束状态

bool GameLayer::onContactBegin(PhysicsContact& contact) {
this->gameOver();
return true;
}

项目源码托管在Github:https://github.com/smiger/FlappyBird


发表评论

(必填)

(必填)

(以便回访)

博客已稳定运行: 访问量:156,394 views 网站备案号:闽ICP备17026396号-1