Closed1

Box2D基礎4_コンタクトを使ったオブジェクトの削除パターン

かじるかじる

コンタクトを使ったオブジェクトの削除パターン

Step実行の直後、"b2World_GetContactEvents()"で、
接触しているオブジェクトを調べる事が可能です。

SceneGame.cpp
#include "SceneBox2d.h"

#include "box2d/box2d.h"
#include "box2d/collision.h"
#include "box2d/math_functions.h"

SceneBox2d *SceneBox2d::create(int dWidth, int dHeight) {
    // New
    auto obj = new SceneBox2d(dWidth, dHeight);
    if (obj && obj->init()) return obj;
    DX_SAFE_DELETE(obj);
    return nullptr;
}

SceneBox2d::SceneBox2d(int dWidth, int dHeight) : SceneMain(dWidth, dHeight),
                                                  camMan(nullptr), readyTime(1.0f),
                                                  car(nullptr) {
    LOGD("Main", "SceneBox2d()");
}

SceneBox2d::~SceneBox2d() {
    LOGD("Main", "~SceneBox2d()");
    // Delete
    DX_SAFE_DELETE(camMan);
    DX_SAFE_DELETE_VECTOR(bodies);
    // Destroy
    b2DestroyWorld(worldId);
}

bool SceneBox2d::init() {
    LOGD("Main", "SceneBox2d::init()");
    SceneMain::init();
    this->ready();// Ready

    // 省略

    // Box2D
    worldDef = b2DefaultWorldDef();
    worldDef.gravity = (b2Vec2) {0.0f, -10.0f};

    worldId = b2CreateWorld(&worldDef);
    const string result = b2World_IsValid(worldId) ? "Success!!" : "Failed...";
    LOGD("Main", "Box2D: %s", result.c_str());

    const int deg = UtilMath::getInstance()->getRandom(-10, 10);
    const auto ground = DrawerBox::create(
            worldId, cX, cY - gSize * 6, DrawerBase::TYPE_STATIC,
            gSize * 6, gSize * 2, deg);
    ground->setCameraFlg(true);
    bodies.push_back(ground);

    const auto remover = DrawerBox::create(
            worldId, cX, cY, DrawerBase::TYPE_REMOVER,
            gSize * 32, gSize * 2, 0);
    remover->setCameraFlg(true);
    bodies.push_back(remover);
    
    for (int i = 0; i < 10; i++) {
        const int x = cX + UtilMath::getInstance()->getRandom(gSize * -4, gSize * 4);
        const int y = cY - UtilMath::getInstance()->getRandom(gSize * 18, gSize * 50);
        const auto box = DrawerBox::create(
                worldId, x, y, DrawerBase::TYPE_DYNAMIC,
                gSize * 1, gSize * 2, 0);
        box->setCameraFlg(true);
        bodies.push_back(box);
    }

    for (int i = 0; i < 10; i++) {
        const int x = cX + UtilMath::getInstance()->getRandom(gSize * -4, gSize * 4);
        const int y = cY - UtilMath::getInstance()->getRandom(gSize * 18, gSize * 50);
        const auto circle = DrawerCircle::create(
                worldId, x, y, DrawerBase::TYPE_DYNAMIC,
                gSize);
        circle->setCameraFlg(true);
        bodies.push_back(circle);
    }
    
    // 省略
    return true;
}

void SceneBox2d::update(const float delay) {

    // 省略

    // Update Box2D
    for (auto body: bodies) body->update(delay);// Update
    b2World_Step(worldId, delay, 8);// Step

    // Contact
    const auto events = b2World_GetContactEvents(worldId);
    for (int i = 0; i < events.beginCount; ++i) {
        const auto *event = events.beginEvents + i;
        const auto objA = static_cast<DrawerBase *>(b2Shape_GetUserData(event->shapeIdA));
        const auto objB = static_cast<DrawerBase *>(b2Shape_GetUserData(event->shapeIdB));
        if (objA->isRemover() && !objB->isRemover()) objB->setDead(true);
        if (!objA->isRemover() && objB->isRemover()) objA->setDead(true);
    }

    // Remove
    UtilDebug::getInstance()->cleanVector(bodies);

    // 省略
}
このスクラップは15時間前にクローズされました