cocos2d-x-3.3-019-碰撞檢測1-矩形區域是否相交
阿新 • • 發佈:2019-02-15
原文同步釋出於我的wiki,檢視原文或更新請移步:
點選開啟連結
原理
- Cocos裡面的每個Node都有一個和它對應的矩形區域,通過api getBoundingBox()得到。碰撞監測就是判斷兩個物體的矩形區域是否有交疊,相應的API是intersectsRect。有交疊則認為是碰撞了。
Demo及原始碼
Demo解讀
- 每隔5s生成: 兩架飛機,並從右往左飛行; 兩顆子彈,從左向右飛。
- 每一幀裡面作碰撞檢測,若有碰撞,則播放相應的動畫。
- 為了追蹤所有的子彈和飛機,得有對應的輔助資料結構,這裡採用Vector。
主要程式碼
- 開啟相關timer
scheduleUpdate(); schedule(schedule_selector(HelloWorld::updateCustom), 5.0f, kRepeatForever, 0);
- 生成子彈或者飛機並放到對應的輔助資料結構來跟蹤
void HelloWorld::buildBullet(int startX, int endX, int actualY) { log("buildBullet"); std::string name = "bullet1.png"; auto sp = Sprite::createWithSpriteFrameName(name); Point startPos = Point(startX, actualY); Point endPos = Point(endX, actualY); sp->setPosition(startPos); sp->runAction( Sequence::create(MoveTo::create(3.0, endPos), CallFuncN::create(this, callfuncN_selector(HelloWorld::spriteDone)), NULL)); sp->setRotation(-90); sp->setTag(TAG_BULLET); mBullets.pushBack(sp);//放入陣列 this->addChild(sp); }
- 每一幀裡作碰撞監測,這裡簡單demo了下。 更復雜的邏輯處理見擴充套件閱讀
void HelloWorld::update(float dt) { // log("update, %d", mPlanes.size()); // log("update, %d", mBullets.size()); //碰撞檢測 Vector<Sprite*> bulletsToBeRemoved; Vector<Sprite*> planeToBeRemoved; for (auto bullet : mBullets) { for (auto plane : mPlanes) { if (bullet->boundingBox().intersectsRect(plane->getBoundingBox())) { log("碰撞了。。。。。。。。"); bulletsToBeRemoved.pushBack(bullet); planeToBeRemoved.pushBack(plane); } } } // do remove for (auto bullet : bulletsToBeRemoved) { mBullets.eraseObject(bullet); log("removeChild(bullet)"); this->removeChild(bullet); } bulletsToBeRemoved.clear(); for (auto plane : planeToBeRemoved) { mPlanes.eraseObject(plane); planeBlowup(plane); } planeToBeRemoved.clear(); }
優缺點
- 優點: 對於簡單需求,使用起來簡單
- 缺點: 要費力的維護幾個陣列,當需求複雜時不易擴充和複用
效果圖
https://github.com/cheyiliu/All-in-One/raw/master/res/cocos2d/CollisionDetection-way1-use-intersectsRect.gif