code-prettify

2014年10月16日 星期四

Cocos2d-x 3.2 - Chapter 5 - How to Detect the Collisions

Cocos2d-x 3.2 - Chapter 5 - How to Detect the Collisions

Cocos2d-x 3.2 - Step by Step Cocos2dxSimpleGame Series

接著上一篇 Cocos2d-x 3.2 - Chapter 4 - How to Fire some Bullets
我們的英雄現在會發射子彈了,但是子彈只有視覺效果,要怎麼殺死敵人呢?

在這個章節,我們會介紹並實現碰撞。

我們將 Sprites 分成兩類,tag = 1 的是敵人,tag = 2 的是子彈。因為 Sprite 類別是繼承 Node 類別,已經有一個成員變數 _tag 及兩個用來操作的函式 getTag()、setTag()。我們可以直接使用他們來區分兩種 Sprites。

在 HelloWorldScene.h 加兩個成員變數


protected:
 cocos2d::Vector<cocos2d::Sprite *> _targets;
 cocos2d::Vector<cocos2d::Sprite *> _projectiles;


然後針對兩個變數在建構式及解構式作處理


HelloWorld::HelloWorld()
{

}

HelloWorld::~HelloWorld()
{
 for (auto target : this->_targets)
 {
  this->removeChild(target, true);
 }

 this->_targets.clear();

 for (auto projectile : this->_projectiles)
 {
  this->removeChild(projectile, true);
 }

 this->_projectiles.clear();
}


在 addTarget() 將新產生的 target 加到 vector


 target->setTag(1);
 _targets.pushBack(target);


同樣在 addProjectile() 將新產生的 projectile 加到 vector


 projectile->setTag(2);
 _projectiles.pushBack(projectile);


然後,將 spriteMoveFinished() 修改為下列的樣子,將 sprites 從 vecotr 移除


 Sprite *sprite = (Sprite *)sender;
 this->removeChild(sprite, true);

 if (sprite->getTag() == 1)  // target
 {
  _targets.eraseObject(sprite);
 }
 else if (sprite->getTag() == 2) // projectile
 {
  _projectiles.eraseObject(sprite);
 }


新增一個 update() 函式,用來偵測是否發生碰撞,移除碰撞的敵人及子彈。
函式的內容如下


void HelloWorld::update(float dt)
{
 cocos2d::Vector<cocos2d::Sprite *> targetsToDelete;
 cocos2d::Vector<cocos2d::Sprite *> projectilesToDelete;

 for (auto projectile : this->_projectiles)
 {
  Rect projectileRect = Rect(
   projectile->getPosition().x - (projectile->getContentSize().width / 2),
   projectile->getPosition().y - (projectile->getContentSize().height / 2),
   projectile->getContentSize().width,
   projectile->getContentSize().height);

  for (auto target : this->_targets)
  {
   Rect targetRect = Rect(
    target->getPosition().x - (target->getContentSize().width / 2),
    target->getPosition().y - (target->getContentSize().height / 2),
    target->getContentSize().width,
    target->getContentSize().height);

   if (projectileRect.intersectsRect(targetRect))
   {
    targetsToDelete.pushBack(target);
    projectilesToDelete.pushBack(projectile);
   }
  }
 }

 for (auto target : targetsToDelete)
 {
  _targets.eraseObject(target);
  this->removeChild(target, true);
 }

 for (auto projectile : projectilesToDelete)
 {
  _projectiles.eraseObject(projectile);
  this->removeChild(projectile, true);
 }
}


最後,在 init() 將 update() 加入排程 (schedule),每個 frame 都會呼叫一次。


this->schedule(schedule_selector(HelloWorld::update));


這章的成果圖跟上一章一樣,但是現在的子彈充滿了力量,哈哈,敵人來一個殺一個啦!

下一章,Cocos2d-x 3.2 - Chapter 6 - How to Play Music and Sound Effect

參考資料:
Cocos2d-x
http://www.cocos2d-x.org/

Step by Step Cocos2dxSimpleGame Series (Old Version for cocos2d-x v2.x)
http://www.cocos2d-x.org/wiki/Step_by_Step_Cocos2dxSimpleGame_Series

沒有留言:

張貼留言