【发布时间】:2014-09-16 01:27:58
【问题描述】:
一些背景:
我正在制作的游戏中使用 Box2D。它有一种将“用户数据”存储到 Box2D 对象的方法。此“用户数据”采用 void*,因此可用于存储用户定义的数据。现在,当 Box2D 发生碰撞时,您可以使用此“用户数据”来识别哪些对象发生了碰撞。然后您可以将数据转换为一个类,并访问该类的函数或变量(以及该类的特定实例,如果您已将“用户数据”设置为对该实例的引用)。我有两组“用户数据”,一组是对类实例的引用,另一组是对结构的引用,因此我可以检查对象的类型。
这适用于不在向量中的对象。我已经对此进行了测试,我可以访问类实例的函数和变量(并修改它们)而无需重置它们。 但是当我通过从 void* 强制转换访问我的 std::vector
相关代码:
我这样设置“用户数据”:
tile->SetUserData(static_cast<Entity*>(this));
ball->SetUserData(static_cast<Entity*>(this));
bUserData* bud = new bUserData;
bud->entityType = BALL;
ballFixture.userData = bud;
bUserData* bud = new bUserData;
bud->entityType = TILE;
tileFixture.userData = bud;
MyContactListener 类跟踪碰撞开始和结束的时间,这也是从 void* 到 foo* 的转换发生的地方:
MyContactListener.cpp
std::vector<Tile> solidTiles;
Ball ball;
// Called when two objects begin to touch.
void MyContactListener::BeginContact(b2Contact* contact) {
// Cast from void* to a struct, from which I can check the object type.
bUserData* budA = (bUserData*)contact->GetFixtureA()->GetUserData();
bUserData* budB = (bUserData*)contact->GetFixtureB()->GetUserData();
// Cast from void* UserData to Entity* (super-class of all the entities).
Entity* entityA = (Entity*)contact->GetFixtureA()->GetBody()->GetUserData();
Entity* entityB = (Entity*)contact->GetFixtureB()->GetBody()->GetUserData();
if((budA->entityType == TILE && budB->entityType == BALL)) {
Tile* tile = (Tile*)entityA; // Tiles are in std::vector<Tile>
Ball* ball = (Ball*)entityB; // Only one ball instance exists
// Modifying a tile instance variable, gets reset to the original value immediately!
tile->flaggedToErase = true;
// This works fine!
ball->setColorToBlue = true;
}
}
问题:如何使向量中的 tile 实例的变量不被重置为原始值?
【问题讨论】:
-
正在重置或根本没有改变?
-
当您将用户数据指针设置为
Tile*时,您是否正在对Entity*进行显式转换?否则,您的Entity*演员表是未定义的行为。您应该从Tile*转换为Entity*,然后依赖隐式void*转换,然后从void*转换为Entity*即可。 -
Tugrul:它们确实发生了变化,我在设置后尝试打印磁贴的变量,它表明磁贴->flaggedToErase 为真。
-
简单:不,我只用 SetUserData(this) 设置用户数据指针。
-
它应该是
Tile或Tile*的向量吗?猜测一下,我怀疑这个问题是由于使用了存储对象副本的vector<Tile>,而不是vector<Tile*>,如果您以后想更改存储的对象,则需要这样做。
标签: c++ vector box2d reset void-pointers