Box2D Forums

It is currently Sat May 25, 2013 3:02 am

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sat Apr 14, 2012 7:25 pm 
Offline

Joined: Fri Mar 09, 2012 1:43 pm
Posts: 69
Im building a level with box2d but it will essentially have 2 ground levels; a bottom ground created by stringing various ground pieces together and a second level that should sit like a highway on top of the ground about halfway on the screen.

I'm guessing I would need to build the bottom ground and then add the top piece with a base structure made of columns to hold it up, right?


Top
 Profile  
 
PostPosted: Mon Apr 16, 2012 12:31 pm 
Offline

Joined: Wed Nov 16, 2011 6:18 pm
Posts: 28
You could make the 2nd level a static body just like the ground body. Then it doesn't respond to forces such as gravity. It just sits there no matter what happens. Dynamic bodies react to it (ie they bounce off of it, etc.) but forces have no effect on the second .

Unless you want the second level to collapse or something when you hit it. Then yeah you would just make it a dynamic body and support it with columns or something similar.


Top
 Profile  
 
PostPosted: Mon Apr 16, 2012 12:52 pm 
Offline

Joined: Fri Mar 09, 2012 1:43 pm
Posts: 69
Ok the static body idea sounds better.

Just out of curiosity if I Wanted to make the ground collapse and thus make it dynamic. We can only make convex bodies right?

So I would have to make the columns first and then place the flat ground on top as separate pieces right?


Top
 Profile  
 
PostPosted: Mon Apr 16, 2012 1:39 pm 
Offline

Joined: Wed Nov 16, 2011 6:18 pm
Posts: 28
That is true box2d only supports convex shapes (ie no angles pointing in). It depends on what you are looking to do though.

If you were making it collapse or something that is what I would do. Essentially you would have 3 bodies each with there own box fixture. Create the 2 column bodies and put the ground body on top of them. (like an angry birds box tower)

alternatively you could have one body with 3 fixtures. (not the way I would go for this application but it illustrates how to build concave bodies out of convex ones) This would make them basically welded together. ie they act in concert rather than independently when hit with forces.

Hope that helps


Top
 Profile  
 
PostPosted: Mon Apr 16, 2012 2:51 pm 
Offline

Joined: Fri Mar 09, 2012 1:43 pm
Posts: 69
Thx so much.


Top
 Profile  
 
PostPosted: Tue Apr 17, 2012 7:52 am 
Offline

Joined: Fri Mar 09, 2012 1:43 pm
Posts: 69
Ok, my original level was one with ground pieces strung together by a helper method:

Code:
- (void)createLevel {
    [self createGround1];
}

-(void)createGround1{
    //row 1, col 1
    int num = 2;
    b2Vec2 verts[] = {
        b2Vec2(-468.0f / PTM_RATIO, 34.5f / PTM_RATIO),
        b2Vec2(468.0f / PTM_RATIO, 36.5f / PTM_RATIO)
    };
    [self createGroundEdgesWithVerts:verts numVerts:num spriteFrameName:@"ground1.png"];   
}

- (void)createGroundEdgesWithVerts:(b2Vec2 *)verts numVerts:(int)num spriteFrameName:(NSString *)spriteFrameName {
    CCSprite *ground =
    [CCSprite spriteWithSpriteFrameName:spriteFrameName];
    ground.position = ccp(groundMaxX+ground.contentSize.width/2,
                          ground.contentSize.height/2);
    [groundSpriteBatchNode addChild:ground];
    b2PolygonShape groundShape;
    b2FixtureDef groundFixtureDef;
    groundFixtureDef.shape = &groundShape;
    groundFixtureDef.density = 0.0;
    for(int i = 0; i < num - 1; ++i) {
        b2Vec2 offset = b2Vec2(groundMaxX/PTM_RATIO +
                               ground.contentSize.width/2/PTM_RATIO,
                               ground.contentSize.height/2/PTM_RATIO);
        b2Vec2 left = verts[i] + offset;
        b2Vec2 right = verts[i+1] + offset;
        groundShape.SetAsEdge(left, right);
        groundBody->CreateFixture(&groundFixtureDef);
    }
    groundMaxX += ground.contentSize.width;
}


So as I mentioned earlier, i want to add a top-level road to the scene, so I decided to simply add a duplicate set of methods like so:
Well, modify the createLevel method and add duplicate methods for the other two, like so:

Code:
- (void)createLevel {
    [self createGround1];
   [self createGround3TopLevel];
}

-(void)createGround3TopLevel{
    //row 1, col 1
    int num = 6;
    b2Vec2 verts[] = {
        b2Vec2(-946.1f / PTM_RATIO, -21.9f / PTM_RATIO),
        b2Vec2(-479.4f / PTM_RATIO, -21.9f / PTM_RATIO),
        b2Vec2(-340.8f / PTM_RATIO, -2.1f / PTM_RATIO),
        b2Vec2(-127.3f / PTM_RATIO, 98.3f / PTM_RATIO),
        b2Vec2(-127.3f / PTM_RATIO, -27.6f / PTM_RATIO),
        b2Vec2(947.5f / PTM_RATIO, -21.9f / PTM_RATIO)
    };
    [self createGroundEdgesWithVertsTopLevel:verts numVerts:num spriteFrameName:@"ground3.png"];   
}

- (void)createGroundEdgesWithVertsTopLevel:(b2Vec2 *)verts numVerts:(int)num spriteFrameName:(NSString *)spriteFrameName {
    CCSprite *groundTopLevel = [CCSprite spriteWithSpriteFrameName:spriteFrameName];
    groundTopLevel.position = ccp(groundMaxX+groundTopLevel.contentSize.width/2,groundTopLevel.contentSize.height*1.25);
    [groundSpriteBatchNode addChild:groundTopLevel];
   
    b2PolygonShape groundShape;
    b2FixtureDef groundFixtureDef;
    groundFixtureDef.shape = &groundShape;
    groundFixtureDef.density = 0.0;
   
    for(int i = 0; i < num - 1; ++i) {
        b2Vec2 offset = b2Vec2(groundMaxX/PTM_RATIO +
                               groundTopLevel.contentSize.width/2/PTM_RATIO,
                               groundTopLevel.contentSize.height/2/PTM_RATIO);
        b2Vec2 left = verts[i] + offset;
        b2Vec2 right = verts[i+1] + offset;
        groundShape.SetAsEdge(left, right);
        groundBody->CreateFixture(&groundFixtureDef);
    }
   
    groundMaxX += groundTopLevel.contentSize.width;
}


So it is my understanding it draws the first level piece and sets groundMaxX as the rightmost edge, then strings the next piece after it at that new starting groundMaxX.

What is happening is 2-fold:
Its placing one piece after another, so it really just placed my first piece, ground1, at the start and then it sorta placed my second piece, ground3, right after it and a bit above.

What I need is to actually place my pieces like so:
Attachment:
groundpieces.png
groundpieces.png [ 10.03 KiB | Viewed 476 times ]


The other thing that is happening is that its placing the sprite up there correctly but the vertices are not correctly placed. Here is another attachment showing that. Here you can actually see the result; it placed piece1 where it should go (you can catch a glimpse of the green rectangle on the left corner of the screenshot) and then it placed the second piece body divorced from sprite. The sprite is probably where it should be but the ground is still a little off.
Attachment:
Screen Shot 2012-04-17 at 9.06.15 AM.png
Screen Shot 2012-04-17 at 9.06.15 AM.png [ 46.56 KiB | Viewed 476 times ]


Im trying to visualize the best way to fix this. Any tips?


Top
 Profile  
 
PostPosted: Tue Apr 17, 2012 9:37 am 
Offline

Joined: Fri Mar 09, 2012 1:43 pm
Posts: 69
Ok, I got it...I forgot I was using the original groundBody and I needed a second one. So I added a second groundBody and a second groundMaxX as well. I then modified my code with this:

Code:


- (void)createGround {
    b2BodyDef groundBodyDef;
    groundBodyDef.type = b2_staticBody;
    groundBodyDef.position.Set(0, 0);
    groundBody = world->CreateBody(&groundBodyDef);
   
    //2nd groundbody to ride on top for TopLevel
    b2BodyDef groundBodyDef2;
    groundBodyDef2.type = b2_staticBody;
    groundBodyDef2.position.Set(200/PTM_RATIO, 100/PTM_RATIO);
    groundBody2 = world->CreateBody(&groundBodyDef2);

}
- (void)createGroundEdgesWithVertsTopLevel:(b2Vec2 *)verts numVerts:(int)num spriteFrameName:(NSString *)spriteFrameName {
    CCSprite *groundTopLevel = [CCSprite spriteWithSpriteFrameName:spriteFrameName];
    groundTopLevel.position = ccp(groundMaxXTopLevel+groundTopLevel.contentSize.width/2,(groundTopLevel.contentSize.height)*1.15);
    [groundSpriteBatchNode addChild:groundTopLevel];
   
    b2PolygonShape groundShape;
    b2FixtureDef groundFixtureDef;
    groundFixtureDef.shape = &groundShape;
    groundFixtureDef.density = 0.0;
   
    for(int i = 0; i < num - 1; ++i) {
        b2Vec2 offset = b2Vec2(groundMaxXTopLevel/PTM_RATIO + groundTopLevel.contentSize.width/2/PTM_RATIO,
                               groundTopLevel.contentSize.height/2/PTM_RATIO);
        b2Vec2 left = verts[i] + offset;
        b2Vec2 right = verts[i+1] + offset;
        groundShape.SetAsEdge(left, right);
        groundBody2->CreateFixture(&groundFixtureDef);
    }
   
    groundMaxXTopLevel += groundTopLevel.contentSize.width;
}

- (void)createLevel {
    [self createGround1];//flat
    [self createGround3TopLevel];
}


And of course I modified my ccTouchBegan code to recognize the new collisionType in order to call the car's jump method. And now it works...


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: Exabot [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group