1. 程式人生 > >cocos2d-x-3.3-019-碰撞檢測1-矩形區域是否相交

cocos2d-x-3.3-019-碰撞檢測1-矩形區域是否相交

原文同步釋出於我的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

擴充套件閱讀