【问题标题】:Box2D weird behavior with std::vector带有 std::vector 的 Box2D 奇怪行为
【发布时间】:2022-01-08 03:34:30
【问题描述】:

最近我开始玩 box2d 并尝试将其抽象到类中

RigidBody::RigidBody() {

}

RigidBody::RigidBody(const RigidBody& other) {
    m_fixture = other.m_fixture;

    b2BodyDef bodyDef;
    bodyDef.position = other.m_body->GetPosition();
    bodyDef.type = other.m_body->GetType();

    m_body = Runtime::PhysicsWorld.CreateBody(&bodyDef);

    b2FixtureDef fixtureDef;
    fixtureDef.shape                = m_fixture->GetShape();
    fixtureDef.density              = m_fixture->GetDensity();
    fixtureDef.friction             = m_fixture->GetFriction();
    fixtureDef.restitution          = m_fixture->GetRestitution();
    fixtureDef.restitutionThreshold = m_fixture->GetRestitutionThreshold();

    m_fixture = m_body->CreateFixture(&fixtureDef);
}

RigidBody::RigidBody(sf::Vector2f pos, BodyType type) {
    pos /= Constants::PPM;

    b2BodyDef bodyDef;
    bodyDef.position = pos;
    bodyDef.type = (b2BodyType)type;

    m_body = Runtime::PhysicsWorld.CreateBody(&bodyDef);

    sf::Vector2f size(50.0f, 50.0f);

    size /= 2.0f;
    size /= Constants::PPM;

    b2PolygonShape shape;
    shape.SetAsBox(size.x, size.y);

    b2FixtureDef fixtureDef;

    fixtureDef.shape                = &shape;
    fixtureDef.density              = 1.0f;
    fixtureDef.friction             = 0.5f;
    fixtureDef.restitution          = 0.0f;
    fixtureDef.restitutionThreshold = 0.5f;

    m_body->CreateFixture(&fixtureDef);
}

RigidBody::~RigidBody() {
    Runtime::PhysicsWorld.DestroyBody(m_body);
}

但是向量的行为真的很奇怪,我知道这可能是因为复制构造函数或析构函数,但我无法弄清楚

std::vector<hv::RigidBody> m_Bodies;

当我调用 m_Bodies.erase(m_Bodies.begin()) 时,问题在于矢量擦除,因为某种原因它会删除最后一个对象

m_Bodies.erase(m_Bodies.begin());

在我第二次调用 m_Bodies.erase(m_Bodies.begin()) 之后,我得到了这个

另外,如果我调用 m_Bodies.erase(m_Bodies.begin() + 3) 向量中有多少对象也没关系,它总是会删除最后一个

*编辑更正的问题

【问题讨论】:

  • 您的意思是删除 m_bodies.front() 吗?否则删除最后一个元素,而不是第一个。
  • delete最后一个元素,然后你删除第一个元素,在向量中最后留下一个指向最近销毁对象的指针。如果你曾经取消引用该指针,那么所有的赌注都会被取消。
  • 顺便说一句:v.erase(v.begin()); 将是 v.pop_front(),如果它存在的话。你很可能想要delete m_Bodies.back(); m_Bodies.pop_back();
  • 哦,没错,但是当不使用指针std::vector&lt;hv::RigidBody&gt; m_Bodies然后调用m_Bodies.erase(m_Bodies.begin());时它不会解决问题,它会抛出上图所示的异常
  • 你能用文本中CreateBody的定义来编辑你的问题吗?我怀疑您交给该方法的堆栈本地地址是罪魁祸首。

标签: c++ vector box2d sfml rigid-bodies


【解决方案1】:

问题是我没有定义 operator = 解决了

RigidBody* RigidBody::operator=(const RigidBody& other) {
    if(m_body)
        Runtime::PhysicsWorld.DestroyBody(m_body);

    m_fixture = other.m_fixture;

    b2BodyDef bodyDef;
    bodyDef.position = other.m_body->GetPosition();
    bodyDef.type = other.m_body->GetType();

    m_body = Runtime::PhysicsWorld.CreateBody(&bodyDef);

    b2FixtureDef fixtureDef;
    fixtureDef.shape = m_fixture->GetShape();
    fixtureDef.density = m_fixture->GetDensity();
    fixtureDef.friction = m_fixture->GetFriction();
    fixtureDef.restitution = m_fixture->GetRestitution();
    fixtureDef.restitutionThreshold = m_fixture->GetRestitutionThreshold();

    m_fixture = m_body->CreateFixture(&fixtureDef);

    return this;
}

【讨论】:

    猜你喜欢
    • 2011-03-06
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多