0

所以我想要的是以下内容:我有 1 个球在我的屏幕上弹跳,这一切顺利 + 我可以向左或向右随机方向踢它。我是 box2d 的新手,我想在我的应用程序中有多个球。我在网上遵循了一个很好的教程,我非常了解我所做的,但我现在尝试了一段时间来复制球 1 中的所有内容,包括身体后面的“2”,所以我有 2 个相同的球反弹屏幕。虽然没有成功。

有没有一种简单的方法可以简单地“克隆”一个精灵+它的对象?

这是代码:)

#import "HelloWorldLayer.h"

@implementation HelloWorldLayer

+ (id)scene {

    CCScene *scene = [CCScene node];
    HelloWorldLayer *layer = [HelloWorldLayer node];
    [scene addChild:layer];
    return scene;

}

- (id)init {



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

        CGSize winSize = [CCDirector sharedDirector].winSize;

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

        // Create a world
        b2Vec2 gravity = b2Vec2(0.0f, -8.0f);
        _world = new b2World(gravity);

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

        b2CircleShape circle;
        circle.m_radius = 26.0/PTM_RATIO;

        b2FixtureDef ballShapeDef;
        ballShapeDef.shape = &circle;
        ballShapeDef.density = 1.0f;
        ballShapeDef.friction = 0.2f;
        ballShapeDef.restitution = 0.4f;
        _body->CreateFixture(&ballShapeDef);

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

        // Create edges around the entire screen
        b2BodyDef groundBodyDef;
        groundBodyDef.position.Set(0,0);

        b2Body *groundBody = _world->CreateBody(&groundBodyDef);
        b2EdgeShape groundEdge;
        b2FixtureDef boxShapeDef;
        boxShapeDef.shape = &groundEdge;

        //WALL DEFINITIONS
        //floor wall
        groundEdge.Set(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0));
        groundBody->CreateFixture(&boxShapeDef);
        //roof wall
        groundEdge.Set(b2Vec2(0,0), b2Vec2(0,winSize.height/PTM_RATIO));
        groundBody->CreateFixture(&boxShapeDef);
        //left wall
        groundEdge.Set(b2Vec2(0, winSize.height/PTM_RATIO),
                       b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO));
        groundBody->CreateFixture(&boxShapeDef);
        //right wall
        groundEdge.Set(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO),
                       b2Vec2(winSize.width/PTM_RATIO, 0));
        groundBody->CreateFixture(&boxShapeDef);


         //Do the kick every 5 seconds
         //[self schedule:@selector(kick) interval:5.0];

        [self setTouchEnabled:YES];

    }
    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());
        }
    }

}

//do the kick every 5 seconds
/*- (void)kick {
    b2Vec2 force = b2Vec2(30, 30);
    _body->ApplyLinearImpulse(force,_body->GetPosition());
}*/

- (void)ccTouchesBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    randomGetal = ((arc4random() % 20) - 10);
    b2Vec2 force = b2Vec2(randomGetal, 10);
    _body->ApplyLinearImpulse(force, _body->GetPosition());
}

- (void)dealloc {
    delete _world;
    _body = NULL;
    _world = NULL;
    [super dealloc];
}

@end
4

1 回答 1

1

在代码中,您创建了一个球。我认为您想要做的是创建多个球,所有这些球在物理模拟中都有一个单独的 b2Body。

有几种方法可以做到这一点,但我现在将坚持使用“蛮力方法”。

像这样创建一个静态函数:

static b2Body* CreateBall(b2World* world, CCNode* node, CCPoint position)
{
  // Create sprite and add it to the layer
    CCSprite* ballSprite = [CCSprite spriteWithFile:@"ball.png" rect:CGRectMake(0, 0, 52, 52)];
    ballSprite.position = ccp(position.x, position.y);
    [node addChild:ballSprite];

    // Create ball body and shape
    b2BodyDef ballBodyDef;
    ballBodyDef.type = b2_dynamicBody;
    ballBodyDef.position.Set(position.x/PTM_RATIO, position.y/PTM_RATIO);
    ballBodyDef.userData = ballSprite;
    b2Body* body = world->CreateBody(&ballBodyDef);

    b2CircleShape circle;
    circle.m_radius = 26.0/PTM_RATIO;

    b2FixtureDef ballShapeDef;
    ballShapeDef.shape = &circle;
    ballShapeDef.density = 1.0f;
    ballShapeDef.friction = 0.2f;
    ballShapeDef.restitution = 0.4f;
    body->CreateFixture(&ballShapeDef);

    return body;

}

注意:我输入了这个。我没有编译它。它可能需要一些调整。

每次您想创建一个新球并在世界和您希望球所在的位置传球时调用它。

这是你需要的吗?

我在我的网站http://www.NonlinearIdeas.com上有使用 Box2D 和处理图形等的更大示例(和代码)。

于 2013-11-09T14:02:17.067 回答