为什么我的精灵没有与 b2Body 对齐?

发布于 2025-01-02 01:49:39 字数 2042 浏览 1 评论 0原文

我最近开始使用 Cocos2d 和 Box2d 在 iPhone 上进行游戏编程。所以这是我的问题:

我有一个继承自 CCSprite 的 Player 类,在该类中,有这个方法:

-(void) createBox2dObject:(Player *)sender 
             forWorld:(b2World*)world {

b2BodyDef playerBodyDef;
playerBodyDef.type = b2_dynamicBody;
playerBodyDef.position.Set(sender.position.x/PTM_RATIO, sender.position.y/PTM_RATIO);
playerBodyDef.userData = sender;
body = world->CreateBody(&playerBodyDef);

b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(sender.contentSize.width/PTM_RATIO,
                    sender.contentSize.height/PTM_RATIO);
b2FixtureDef polygonShapeDef;
polygonShapeDef.shape = &dynamicBox;
polygonShapeDef.density = 1.0f;
polygonShapeDef.friction = 1.0f;
polygonShapeDef.restitution = 0;
body->CreateFixture(&polygonShapeDef);
}

这就是我的调用方式:

    self.player = [Player spriteWithSpriteFrameName:@"runningrupol-1.png"];        
    _player.position = ccp(_player.boundingBox.size.width/2 + 32, _player.boundingBox.size.height/2 + 32);
    self.walkAction = [CCRepeatForever actionWithAction:
                       [CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
    [_player runAction:_walkAction];
    [spriteSheet addChild:_player];
    [_player createBox2dObject:_player forWorld:_world];

显然,我正在使用一个动画的 spritesheet。

这是我更新世界的方法:

- (void)tick:(ccTime) dt {

    _world->Step(dt, 8, 10);

    for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {    
        if (b->GetUserData() != NULL) {
            CCSprite *playerData = (CCSprite *)b->GetUserData();
            playerData.position = ccp(b->GetPosition().x * PTM_RATIO,
                                    b->GetPosition().y * PTM_RATIO);
            playerData.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
        }        
    }

}

这是我在 init 方法中调用它的方法:

[self schedule:@selector(tick:)];

这就是我所看到的:

请帮忙。如果您需要更多信息,请告诉我。

I recently started game programming on the iPhone using Cocos2d and Box2d. So here's my problem:

I've got a Player class which inherits from CCSprite, and within that class, there's this method:

-(void) createBox2dObject:(Player *)sender 
             forWorld:(b2World*)world {

b2BodyDef playerBodyDef;
playerBodyDef.type = b2_dynamicBody;
playerBodyDef.position.Set(sender.position.x/PTM_RATIO, sender.position.y/PTM_RATIO);
playerBodyDef.userData = sender;
body = world->CreateBody(&playerBodyDef);

b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(sender.contentSize.width/PTM_RATIO,
                    sender.contentSize.height/PTM_RATIO);
b2FixtureDef polygonShapeDef;
polygonShapeDef.shape = &dynamicBox;
polygonShapeDef.density = 1.0f;
polygonShapeDef.friction = 1.0f;
polygonShapeDef.restitution = 0;
body->CreateFixture(&polygonShapeDef);
}

and here's how I call this:

    self.player = [Player spriteWithSpriteFrameName:@"runningrupol-1.png"];        
    _player.position = ccp(_player.boundingBox.size.width/2 + 32, _player.boundingBox.size.height/2 + 32);
    self.walkAction = [CCRepeatForever actionWithAction:
                       [CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
    [_player runAction:_walkAction];
    [spriteSheet addChild:_player];
    [_player createBox2dObject:_player forWorld:_world];

Obviously, I'm using a spritesheet which is animated.

Here's how I update the world:

- (void)tick:(ccTime) dt {

    _world->Step(dt, 8, 10);

    for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {    
        if (b->GetUserData() != NULL) {
            CCSprite *playerData = (CCSprite *)b->GetUserData();
            playerData.position = ccp(b->GetPosition().x * PTM_RATIO,
                                    b->GetPosition().y * PTM_RATIO);
            playerData.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
        }        
    }

}

And here's how I call it in the init method:

[self schedule:@selector(tick:)];

This is what I see:

enter image description here

Please help. And if you need additional info, just tell me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愁以何悠 2025-01-09 01:49:39

SetAsBox() 使用半高和半宽(我知道这很奇怪),因此将参数除以 2:

dynamicBox.SetAsBox(sender.contentSize.width/PTM_RATIO/2,
                sender.contentSize.height/PTM_RATIO/2);

当您尝试此操作时,请保持锚点不变(如果您没有明确设置,则默认值应该是 ccp (0.5,0.5),你的精灵的中心,你想要那个)。

SetAsBox() uses half-height and half-width (quirky I know), so divide the parameters by 2:

dynamicBox.SetAsBox(sender.contentSize.width/PTM_RATIO/2,
                sender.contentSize.height/PTM_RATIO/2);

When you try this, leave the anchor point as is (the default value if you don't explicitly set it should be ccp(0.5,0.5), the center of your sprite, and you want that).

生来就爱笑 2025-01-09 01:49:39

您可以更改精灵的锚点。这是一个很好的教程:

http://www.qcmat.com/understand-anchorpoint-在-cocos2d/

You can change the anchorpoint for the sprite. Here is a good tutorial:

http://www.qcmat.com/understanding-anchorpoint-in-cocos2d/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文