主场景要包含其他类的头文件
~~~
#include "cocos2d.h"
#include "MyPlane.h"
#include "Bullet.h"
#include "EnemyManager.h"
#include "Controller.h"
#include "BackgroundMove.h"
#include "FlowWord.h"
~~~
在这个游戏中,我将各种碰撞检测也放到主场景中进行
~~~
void gameUpdate(float dt); // 碰撞检测
bool bulletCollisionEnemy(Sprite* pBullet); // 子弹和敌机碰撞
void enemyCollisionPlane(); // 我机和敌机、敌机子弹碰撞
virtual void onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event);
~~~
当然,主场景要有各个类的实例做变量
~~~
MyPlane *planeLayer;
Bullet *bulletLayer;
EnemyManager *enemyLayer;
Controller *controlLayer;
~~~
主场景的实现
~~~
TollgateOne::TollgateOne() : planeLayer(NULL), bulletLayer(NULL), enemyLayer(NULL), controlLayer(NULL)
{
}
TollgateOne::~TollgateOne()
{
_eventDispatcher->removeEventListenersForTarget(this);
}
cocos2d::Scene* TollgateOne::createScene()
{
auto scene = Scene::create();
auto layer = TollgateOne::create();
scene->addChild(layer);
return scene;
}
bool TollgateOne::init()
{
if (!Layer::init())
{
return false;
}
// 启动触摸机制
this->setTouchEnabled(true);
// 背景无限滚动
auto m_back = BackgroundMove::create();
this->addChild(m_back,0);
//游戏开始 飘字效果
auto dictionary = Dictionary::createWithContentsOfFile("fonts/AboutMe.xml");
auto m_flow = FlowWord::create();
m_flow->showFlowWord(
((__String *)(dictionary->objectForKey("play")))->getCString(),
Point(Director::getInstance()->getVisibleSize().width / 2+60, Director::getInstance()->getVisibleSize().height/2),
m_flow->otherFlowWord()
);
this->addChild(m_flow);
//游戏更新
this->schedule(schedule_selector(TollgateOne::gameUpdate));
// 加入控制层
controlLayer = Controller::create();
this->addChild(controlLayer);
// 加入飞机
planeLayer = MyPlane::create();
this->addChild(planeLayer,1);
// 加入敌机和分数显示
enemyLayer = EnemyManager::create();
enemyLayer->bindController(controlLayer);
this->addChild(enemyLayer,1);
// 开启子弹
bulletLayer = Bullet::create();
bulletLayer->bindEnemyManager(enemyLayer);
this->addChild(bulletLayer,1);
//对返回键的响应
auto m_listener = EventListenerKeyboard::create();
m_listener->onKeyReleased = CC_CALLBACK_2(TollgateOne::onKeyReleased, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(m_listener, this);
return true;
}
void TollgateOne::gameUpdate(float dt)
{
bool bMoveButt = false;
//子弹和敌机对碰
for (auto& eButtle : bulletLayer->vecBullet)
{
Sprite* pBullet = (Sprite*)eButtle; // 获取子弹精灵
bMoveButt = bulletCollisionEnemy(pBullet);
if (bMoveButt)
{
// 子弹删除了,无需再遍历
return;
}
}
// 敌机、敌机子弹与我方飞机碰撞
enemyCollisionPlane();
}
bool TollgateOne::bulletCollisionEnemy(Sprite* pBullet)
{
for (auto& eEnemy : enemyLayer->vecEnemy)
{
Enemy* pEnemySprite = (Enemy*)eEnemy;
// 是否发生碰撞
if (pBullet->boundingBox().intersectsRect(pEnemySprite->getBoundingBox()))
{
// 飞机只剩下一格生命值
if (1 == pEnemySprite->getLife())
{
pEnemySprite->loseLife(); // 知道为什么这里也要loselife吗?你可以试着注释掉看看
enemyLayer->blowupEnemy(pEnemySprite);
}
else
{
pEnemySprite->loseLife();
}
//删除子弹
bulletLayer->removeBullet(pBullet);
return true;
}
}
return false;
}
void TollgateOne::enemyCollisionPlane()
{
Sprite* pPlane = (Sprite*)planeLayer->getChildByTag(AIRPLANE);
for (auto& eEnemy : enemyLayer->vecEnemy)
{
Enemy* pEnemySprite = (Enemy*)eEnemy;
// 是否发生碰撞
if (pPlane->boundingBox().intersectsRect(pEnemySprite->getBoundingBox()) && pEnemySprite->getLife() > 0)
{
if (1 == planeLayer->getAlive())
{
planeLayer->loseAlive();
controlLayer->getSaveData()->save();
this->unscheduleAllSelectors();
this->bulletLayer->StopBulletShoot();
this->planeLayer->blowUp();
Director::getInstance()->replaceScene(
TransitionMoveInT::create(0.8f, GameOver::createScene())); // 替换场景
}
else
planeLayer->loseAlive();
}
}
for (auto& eEnemyBullet : bulletLayer->vecEnemyBullet)
{
Sprite* pEnemyBullet = (Sprite*)eEnemyBullet; // 获取子弹精灵
// 是否发生碰撞
if (pPlane->boundingBox().intersectsRect(pEnemyBullet->getBoundingBox()))
{
if (1 == planeLayer->getAlive())
{
planeLayer->loseAlive();
controlLayer->getSaveData()->save();
this->unscheduleAllSelectors();
this->bulletLayer->StopBulletShoot();
this->planeLayer->blowUp();
Director::getInstance()->replaceScene(
TransitionMoveInT::create(0.8f, GameOver::createScene())); // 替换场景
}
else
planeLayer->loseAlive();
bulletLayer->removeEnemyBullet(pEnemyBullet);
return;
}
}
}
void TollgateOne::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)
{
if (keyCode == EventKeyboard::KeyCode::KEY_ESCAPE)
{
Director::getInstance()->replaceScene(HelloWorld::createScene());
}
}
~~~
主场景就是将其它类融合在一起,碰撞检测也是在这里进行。
注意一下这里的事件监听,和开始界面的不太一样,但都要在析构函数中移除。