主場景要包含其他類的頭文件
~~~
#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());
}
}
~~~
主場景就是將其它類融合在一起,碰撞檢測也是在這里進行。
注意一下這里的事件監聽,和開始界面的不太一樣,但都要在析構函數中移除。