Box2D动体掉屏

发布于 2024-11-17 21:35:17 字数 2894 浏览 3 评论 0原文

我基本上有一个矩形物体(如矛)和一个地面主体。问题是,当矛击中地面时,它不会反弹,而是从屏幕上掉下来。这是我的物理设置:(忽略球参考,它应该被称为矛(矩形))

-(id) init {

    if( (self=[super init])) {

        CGSize winSize = [CCDirector sharedDirector].winSize;

        self.isAccelerometerEnabled = YES;
        self.isTouchEnabled = YES;

        // Create sprite and add it to the layer
        _ball = [CCSprite spriteWithFile:@"SPEAR.png" rect:CGRectMake(0, 0, 100, 10)];
        _ball.position = ccp(100, 100);
        [self addChild:_ball];

        // Create a world
        b2Vec2 gravity = b2Vec2(0.0f, -20.0f);
        bool doSleep = true;
        _world = new b2World(gravity, doSleep);

        // Create edges around the entire screen
        b2BodyDef groundBodyDef;
        groundBodyDef.position.Set(0,0);
        b2Body *groundBody = _world->CreateBody(&groundBodyDef);
        b2PolygonShape groundBox;
        b2FixtureDef boxShapeDef;
        boxShapeDef.shape = &groundBox;
        groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0));
        groundBody->CreateFixture(&boxShapeDef);
        groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(0, winSize.height/PTM_RATIO));
        groundBody->CreateFixture(&boxShapeDef);
        groundBox.SetAsEdge(b2Vec2(0, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO));
        groundBody->CreateFixture(&boxShapeDef);
        groundBox.SetAsEdge(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, 0));
        groundBody->CreateFixture(&boxShapeDef);

        // Create ball body and shape
        b2BodyDef ballBodyDef;
        ballBodyDef.type = b2_dynamicBody;
        ballBodyDef.position.Set(100/PTM_RATIO, 100/PTM_RATIO);
        ballBodyDef.userData = _ball;
        b2Body *_body = _world->CreateBody(&ballBodyDef);


        b2PolygonShape spearShape;
        spearShape.SetAsBox(100/PTM_RATIO, 10/PTM_RATIO);
        b2FixtureDef ballShapeDef;
        ballShapeDef.shape = &spearShape;


        ballShapeDef.density = 1.0f;
        ballShapeDef.friction = 0.9f;
        ballShapeDef.restitution = 0.89f;

        b2Vec2 force;
        force.Set(_body->GetLinearVelocity().x+5.0f, _body->GetLinearVelocity().y+10.0f);
        _body->SetLinearVelocity(force);

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

- (void)tick:(ccTime) dt {

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

I basically have a rectangular object (like a spear) and I have a ground body. The problem is, when the spear hits the ground, it doesn't bounce back, it falls though and off the screen. Here my physics setup: (Ignore the ball reference, it suppose to be called spear (rectangular))

-(id) init {

    if( (self=[super init])) {

        CGSize winSize = [CCDirector sharedDirector].winSize;

        self.isAccelerometerEnabled = YES;
        self.isTouchEnabled = YES;

        // Create sprite and add it to the layer
        _ball = [CCSprite spriteWithFile:@"SPEAR.png" rect:CGRectMake(0, 0, 100, 10)];
        _ball.position = ccp(100, 100);
        [self addChild:_ball];

        // Create a world
        b2Vec2 gravity = b2Vec2(0.0f, -20.0f);
        bool doSleep = true;
        _world = new b2World(gravity, doSleep);

        // Create edges around the entire screen
        b2BodyDef groundBodyDef;
        groundBodyDef.position.Set(0,0);
        b2Body *groundBody = _world->CreateBody(&groundBodyDef);
        b2PolygonShape groundBox;
        b2FixtureDef boxShapeDef;
        boxShapeDef.shape = &groundBox;
        groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0));
        groundBody->CreateFixture(&boxShapeDef);
        groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(0, winSize.height/PTM_RATIO));
        groundBody->CreateFixture(&boxShapeDef);
        groundBox.SetAsEdge(b2Vec2(0, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO));
        groundBody->CreateFixture(&boxShapeDef);
        groundBox.SetAsEdge(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, 0));
        groundBody->CreateFixture(&boxShapeDef);

        // Create ball body and shape
        b2BodyDef ballBodyDef;
        ballBodyDef.type = b2_dynamicBody;
        ballBodyDef.position.Set(100/PTM_RATIO, 100/PTM_RATIO);
        ballBodyDef.userData = _ball;
        b2Body *_body = _world->CreateBody(&ballBodyDef);


        b2PolygonShape spearShape;
        spearShape.SetAsBox(100/PTM_RATIO, 10/PTM_RATIO);
        b2FixtureDef ballShapeDef;
        ballShapeDef.shape = &spearShape;


        ballShapeDef.density = 1.0f;
        ballShapeDef.friction = 0.9f;
        ballShapeDef.restitution = 0.89f;

        b2Vec2 force;
        force.Set(_body->GetLinearVelocity().x+5.0f, _body->GetLinearVelocity().y+10.0f);
        _body->SetLinearVelocity(force);

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

- (void)tick:(ccTime) dt {

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

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

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

发布评论

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

评论(4

爱她像谁 2024-11-24 21:35:18

Box2D 中的边缘夹具不会相互碰撞。将地面或矛设为多边形。

Edge fixtures do not collide with each other in Box2D. Make either the ground or the spear a polygon.

深白境迁sunset 2024-11-24 21:35:17

我在代码中没有看到任何将形状附加到球和矛的地方。如果物体没有形状——它就不会碰撞。

I don't see anywhere in your code attaching the shapes to ball and to spear. If the body does not have a shape - it will not collide.

北城半夏 2024-11-24 21:35:17

我认为 box2d 中只有装置发生碰撞。
但你的矛没有固定装置。
您只创建夹具定义,而不创建夹具本身。

将恢复设置为fixtureDef后,添加此行:

_body->CreateFixture(&ballShapeDef);

一切都应该没问题!

知道的有点晚了..

I think only the fixtures are colliding in box2d.
But your spear has no fixture.
You only create the fixture def but not the fixture itself.

after setting restitution to you fixtureDef, add this line:

_body->CreateFixture(&ballShapeDef);

Everything should then be fine !

A bit late I know..

逐鹿 2024-11-24 21:35:17

我已经有一段时间没有使用 cocos2d 了,但我记得你需要创建一个空间并将对象添加到其中,这样它们就可以相互了解。

I haven't used cocos2d in a while, but I remember you needed to create an space an add the objects to it, so they were aware of each other.

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