Box2D - b2body GetUserData 始终返回 null

2024-04-13

我正在尝试根据 box2d 中的 b2body 调整精灵的位置和旋转。

创建主体后,我将 userData 属性设置为保存精灵和位置等的主体对象的属性。问题是在勾选方法 b->GetUserData 中永远不会检索我放入其中的对象。你能看出以下有什么问题吗?

这是我的添加播放器方法:

-(void) addPlayerShip
{
    CCSpriteSheet *sheet = [CCSpriteSheet spriteSheetWithFile:@"PlayerShip.png" capacity:1];

    //Get sprite sheet
    CCSprite *sprite = [CCSprite spriteWithSpriteSheet:sheet rect:CGRectMake(0,0,64,64)];
    [sheet addChild:sprite];

    CGSize screenSize = [CCDirector sharedDirector].winSize;

    sprite.position = ccp( screenSize.width/2, screenSize.height/2);

    [self addChild:sheet];

    // Define the dynamic body.
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(sprite.position.x/PTM_RATIO, sprite.position.y /PTM_RATIO);
    bodyDef.angularVelocity=0;

    b2Body *body = world->CreateBody(&bodyDef);

    b2PolygonShape dynamicTriangle;

    dynamicTriangle.m_vertexCount=3;
    dynamicTriangle.m_vertices[0].Set(0,-1);
    dynamicTriangle.m_vertices[1].Set(1,1);
    dynamicTriangle.m_vertices[2].Set(-1,1);

    // Define the dynamic body fixture.
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicTriangle;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.0f;
    fixtureDef.restitution=0.0f;

    b2Fixture *fixture = body->CreateFixture(&fixtureDef);

    b2Vec2 *vector = new b2Vec2;

    BodyObject *bodyObject = [[BodyObject alloc] initWithBody:body 
                                                   andFixture:fixture 
                                                  andVelocity:vector 
                                                    andSprite:sprite];


    bodyDef.userData = bodyObject;
}

以及在 b->GetUserData 上始终返回 null 的 tick 方法

-(void) tick: (ccTime) dt
{
    int32 velocityIterations = 8;
    int32 positionIterations = 1;

    world->Step(dt, velocityIterations, positionIterations);

    //Iterate over the bodies in the physics world
    for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
    {
        if (b->GetUserData() != NULL) {
            //Synchronize the Sprites position and rotation with the corresponding body
            GameObject *myObject = (GameObject*)b->GetUserData();
            myObject.Sprite.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
            myObject.Sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
        }   
    }
}

最后是 bodyObject

#import "BodyObject.h"


@implementation BodyObject

@synthesize Body;
@synthesize Fixture;

-(id) initWithBody:(b2Body*) body 
        andFixture:(b2Fixture*) fixture 
       andVelocity:(b2Vec2*) velocity 
         andSprite:(CCSprite*) sprite
{
    self = [super initWithSprite:(CCSprite*)sprite 
                     andVelocity:(b2Vec2*)velocity];

    self.Body=body;
    self.Fixture=fixture;

    return self;
}

@end

我是 Objective C 的新手,所以如果我做错了什么,请告诉我!

编辑: 我在这里尝试了另一段代码,我似乎能够更进一步。

if I set bodyDef.UserData = sprite; 

就在该行之后

bodyDef.position.Set(sprite.position.x/PTM_RATIO, sprite.position.y /PTM_RATIO); 

然后 GetUserData 返回精灵。但是,如果我在 addPlayerShip 方法末尾将用户数据设置为精灵,那么它会再次返回 null。精灵/身体对象是否被丢弃在某处?


您正在将用户数据分配给 bodyDef AFTER 你调用CreateBody(),所以它永远不会被添加到实际的主体中。

b2BodyDef 是一个结构体,它保存创建主体的设置。一旦调用了 CreateBody(),对该结构的更改就不起作用。

您通过移动 bodyDef.UserData = sprite; 自己找到了解决方案在调用 CreateBody() 之前的某个地方。这是放置它的正确位置。如果您认为出于某种原因(其他变量?)在函数末尾需要它,那么您需要重构您的代码,以便情况并非如此。

我会更改这一行(以及 BodyObject 类):

BodyObject *bodyObject = [[BodyObject alloc] initWithBody:body 
                                               andFixture:fixture 
                                              andVelocity:vector 
                                                andSprite:sprite];

这样您就可以实例化它,而不需要 box2d 元素(即在定义它们之前),然后在创建它们后使用属性来分配这些值。这样,您可以将此对象作为主体的用户数据传递,创建主体,然后使用分配 b2Body*[bodyObject setBody:body];

不要忘记确保您的 Body 和 Fixture 属性not只读。

最终代码可能如下所示:

-(void) addPlayerShip
{
    CCSpriteSheet *sheet = [CCSpriteSheet spriteSheetWithFile:@"PlayerShip.png" capacity:1];

    //Get sprite sheet
    CCSprite *sprite = [CCSprite spriteWithSpriteSheet:sheet rect:CGRectMake(0,0,64,64)];
    [sheet addChild:sprite];

    CGSize screenSize = [CCDirector sharedDirector].winSize;

    sprite.position = ccp( screenSize.width/2, screenSize.height/2);

    [self addChild:sheet];

    b2Vec2 *vector = new b2Vec2;

    BodyObject *bodyObject = [[BodyObject alloc] initWithSprite:sprite 
                                                   andVelocity:vector];

    //MOVES THE BODY DEFINITION AFTER THE BODYOBJECT DEFINITION
    // Define the dynamic body.
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(sprite.position.x/PTM_RATIO, sprite.position.y /PTM_RATIO);
    bodyDef.angularVelocity=0;
    bodyDef.userData = bodyObject;

    b2Body *body = world->CreateBody(&bodyDef);

    b2PolygonShape dynamicTriangle;

    dynamicTriangle.m_vertexCount=3;
    dynamicTriangle.m_vertices[0].Set(0,-1);
    dynamicTriangle.m_vertices[1].Set(1,1);
    dynamicTriangle.m_vertices[2].Set(-1,1);

    // Define the dynamic body fixture.
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicTriangle;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.0f;
    fixtureDef.restitution=0.0f;

    b2Fixture *fixture = body->CreateFixture(&fixtureDef);

    [bodyObject setBody:body];
    [bodyObject setFixture:fixture];
}

bodyObject 类将如下所示:

#import "BodyObject.h"


@implementation BodyObject

@synthesize Body;
@synthesize Fixture;

-(id) initWithSprite:(CCSprite*) sprite 
       andVelocity:(b2Vec2*) velocity 
{
    self = [super initWithSprite:(CCSprite*)sprite 
                     andVelocity:(b2Vec2*)velocity];

    return self;
}

@end
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Box2D - b2body GetUserData 始终返回 null 的相关文章

随机推荐

  • 你能在 Swift 中创建匿名内部类吗?

    我厌倦了宣布整个班级都有能力处理UIAlertView通过使它们延伸来点击UIAlertViewDelegate 当我有多种可能时 它开始感觉混乱和错误UIAlertViews 并且必须区分在处理程序中单击了哪个 我真正想要的是创建一个实现
  • 如何使用 Angular-CLI 重写反向代理中的路径?

    我已经使用 angular2 CLI 设置了反向代理 如下所示 api customer target http localhost 9010 secure false 我的问题是远程 API 在路径 customer 上公开服务 但反向代
  • 单节点图对forceCenter没有反应?

    我正在启动一个带有单个节点的图形项目 当我将它拖到某个地方时 我希望它能顺利回到 svg 的中心 但事实并非如此 它glitches回到中心 var simulation d3 forceSimulation force center d3
  • SBT停止运行而不退出

    如何在不退出的情况下终止 SBT 中的运行 我正在尝试 CTRL C 但它退出 SBT 有没有办法在保持 SBT 打开的情况下仅退出正在运行的应用程序 从 sbt 版本 0 13 5 开始 您可以添加到您的 build sbt cancel
  • 使用 Sikuli 进行拖放

    我在使用 Sikuli 拖放时遇到问题 我想在任何其他方向 上 下 左 右 拖动某些东西固定数量的像素 这看起来应该有效 t find 1325249963143 png dragDrop t t x 100 t y 100 Sikuli
  • 在 Eclipse 中导入动态 Web 项目?

    我使用 eclipse 3 6 2 Helios 和 tomcat 7 和 myfaces 1 2 10 当我想导入动态 Web 项目时遇到问题 我在工作区中导入项目并执行配置并设置 jar 文件 但是当我在 tomcat 中运行该项目时
  • 我希望我的字段只接​​受整数,并且我已将该字段保留在所需的验证中? [复制]

    这个问题在这里已经有答案了 我已经完成了我的完整项目 但它缺少这一要求 我自己无法在我的项目中解决这个问题 你会使用CodeIgniter吗表单验证 http ellislab com codeigniter user guide libr
  • 为什么 Service Worker 只能通过 HTTPS 工作?

    根据最初的提案 关于 更喜欢安全来源以获得强大的新功能 http www chromium org Home chromium security prefer secure origins for powerful new features
  • Android Studio 与 ndk 和 googletest

    我正在尝试设置我的 CI 服务器以与 Android Studio 一起使用 我希望通过新的 UI 运行 NDK 的单元测试 我正在使用 GoogleTest 当我从命令行构建时 gcov 可以完美地实现代码覆盖率 我遇到的问题是 UI 中
  • 当名称的开头保持相同而结尾不同时,将 CSS 样式应用于 ID 元素

    在 WordPress 中 博客文章的标题通常使用 ID 元素进行格式化 该 ID 元素由永远不会变化的前缀 例如 post 组成 后跟 WordPress 生成的可变数字后缀 对应于唯一的连续帖子编号 每个帖子 在 WordPress 主
  • 根据其中一个字段对元组进行排序

    我的问题与下面的问题相同 但答案很模糊 我不明白如何进行 将 List 从最高到最低排序 https stackoverflow com questions 4017728 sort a listtuple from highest to
  • 将 JSON 数据的 NSString 转换为 NSArray [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我有一个N
  • 多线程和CPU缓存

    我正在使用多个线程在 C 中实现图像过滤操作 并使其尽可能优化 但我有一个问题 如果线程 0 访问内存 并且同时线程 1 访问同一内存 它会从缓存中获取它吗 这个问题源于这两个线程可能运行在 CPU 的两个不同内核中的可能性 因此 另一种说
  • 假设没有非时间指令,“xchg”是否包含“mfence”?

    我已经看过了这个答案 https stackoverflow com a 50279772 391161 and 这个答案 https stackoverflow com a 19099164 391161 但似乎都没有清楚明确地说明等价或
  • Intellij IDEA:未命中断点,并显示为灰色

    在 Mac OS X 上运行 JDK 1 7 时 我的项目上的断点突然不起作用 并且显示为灰色 他们今天早些时候在工作 所以不确定我做了什么导致了这种情况 我正在使用 Intellij 13 1 3 为什么断点会像这样停止工作 天哪 我刚刚
  • php数组计数与动态结果

    我正在尝试计算从脚本返回的数组的结果 有两种情况我可以找回选项a是 Array Id gt 1779 SupplierId gt 1809 SupplierName gt cccccc 和第二个选项 ib Array 0 gt Array
  • 在delphi中禁用窗体大小调整

    有什么方法可以阻止用户调整表单大小吗 目前我正在使用 当表单大小改变时 MainForm Height 761 MainForm Width 777 但这看起来很可怕 因为当用户尝试更改表单大小时它会闪烁 固定尺寸很简单 你有两个选择 De
  • Cassandra Nodetool URISyntaxException:“索引 7 处的 IPv6 地址格式错误”

    Cassandra nodetool 更新 OpenJDK 后抛出错误 nodetool status nodetool Failed to connect to 127 0 0 1 7199 URISyntaxException Malf
  • 什么是托管代码和非托管代码? [复制]

    这个问题在这里已经有答案了 我发现有人说托管代码和非托管代码 有什么不同 它仅适用于 Net吗 你可以阅读这篇维基百科文章 托管代码 http en wikipedia org wiki Managed code 基本上托管代码是一个微软术
  • Box2D - b2body GetUserData 始终返回 null

    我正在尝试根据 box2d 中的 b2body 调整精灵的位置和旋转 创建主体后 我将 userData 属性设置为保存精灵和位置等的主体对象的属性 问题是在勾选方法 b gt GetUserData 中永远不会检索我放入其中的对象 你能看