Box2D Forums

It is currently Thu May 23, 2013 9:18 pm

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Fri Jun 29, 2012 2:43 pm 
Offline

Joined: Fri Mar 09, 2012 1:43 pm
Posts: 69
How can I get the body associated with a ccsprite that is calling a method? The method being called received the CCNode as an argument. Now I just need to tell it that IF the ccnode, which is a ccsprite, has a b2body associated with it, then remove that body.


Top
 Profile  
 
PostPosted: Fri Jun 29, 2012 3:32 pm 
Offline

Joined: Tue Sep 25, 2007 2:22 pm
Posts: 483
In my game engine, I have a link back to the b2Body, and my world manager class in my root gameobject class.


Top
 Profile  
 
PostPosted: Fri Jun 29, 2012 7:21 pm 
Offline

Joined: Fri Mar 09, 2012 1:43 pm
Posts: 69
Yes but I mean I have to cycle through many bodies/sprites because they are asteroids that are spawned and then destroyed.


Top
 Profile  
 
PostPosted: Fri Jun 29, 2012 7:45 pm 
Offline

Joined: Fri Mar 09, 2012 1:43 pm
Posts: 69
I create a ship and some comets. The ship is created in the init method like so:

Code:
_player = [[[HopperShip alloc] initWithSpriteFrameName:@"SpaceFlier_sm_1.png" maxHp:50 healthBarType:HealthBarTypeGreen] autorelease];
b2BodyDef bodyDef;
        bodyDef.type = b2_dynamicBody;
        bodyDef.position.Set(_player.position.x/PTM_RATIO, _player.position.y/PTM_RATIO);
        shipBody = world->CreateBody(&bodyDef);
        bodyDef.userData = _player;

        b2PolygonShape shape;
        shape.SetAsBox(_player.contentSize.width/2/PTM_RATIO, _player.contentSize.height/2/PTM_RATIO);
       
        b2FixtureDef fixtureDef;
        fixtureDef.shape = &shape;
        fixtureDef.density = 0.0;
        fixtureDef.friction = 0.5;
        fixtureDef.restitution = 0.5;

        shipBody->CreateFixture(&fixtureDef);


This code creates the sprite & its respective shipBody. I added the bodyDef.userData = _player as you can see.

Then I create comets like this:

Code:
target = [WeakAndFastShipTarget target];
        b2BodyDef bodyDef;
        bodyDef.type = b2_dynamicBody;
        bodyDef.position.Set(target.position.x/PTM_RATIO, target.position.y/PTM_RATIO);
        cometBody = world->CreateBody(&bodyDef);
        bodyDef.userData = target;

        b2PolygonShape shape;
        shape.SetAsBox(target.contentSize.width/2/PTM_RATIO, target.contentSize.height/2/PTM_RATIO);
       
        b2FixtureDef fixtureDef;
        fixtureDef.shape = &shape;
        fixtureDef.density = 0.0;
        fixtureDef.friction = 0.5;
        fixtureDef.restitution = 0.5;
       
        cometBody->CreateFixture(&fixtureDef);


Again I set it to a reference called cometBody this time & set its bodyDef.userData = target

I added the box2d code later because I realized I needed it for better collision detection. I already have a method that removes the comet sprites once they exit the screen if they are not destroyed by the ship. Now I need to remove the corresponding b2body. I have a method that passes the CCNode, a comet CCSprite object, in order to remove that sprite and clean up. How do I get the associated b2body from that sprite?


Top
 Profile  
 
PostPosted: Fri Jun 29, 2012 7:55 pm 
Offline

Joined: Fri Mar 09, 2012 1:43 pm
Posts: 69
I did this:

Code:
- (void)spriteMoveFinished:(id)sender{
    //include finishShoot logic
    CCSprite *sprite = (CCSprite *)sender;//get the passed in sprite
       
    [self removeChild:sprite cleanup:YES];
    NSLog(@"child TRGT removed:OFFSCREEN");
    // hmm already removed it...or is this better?
    [_targets removeObject:sprite];
    NSLog(@"target removed:OFFSCREEN");
   
    //must cycle thru these sprites and get the body to remove it
    //in case the asteroid didnt get shot
   
    //BOX2D REMOVE BODY OF SPRITE
    b2Body *spriteBody = NULL;//create an empty body
    for(b2Body *b=world->GetBodyList(); b!=NULL; b=b->GetNext()) {//loop thru all bodies
        if (b->GetUserData() != NULL) {//if there is a userData attached to the body, which there is...
            //Box2DSprite *sprite = (Box2DSprite *) b->GetUserData();
            CCSprite *curSprite = (CCSprite*) b->GetUserData();//We know the userData we set is the sprite target object, so put it into curSprite
            if (sprite == curSprite) {//if the passed in sprite is the same as the box2d body gotten one....
                spriteBody = b; //put that body into the spriteBody null instance we created and breakOUT
                break;
            }
        }
    }
    if (spriteBody != NULL) {
        [self destroyBody:spriteBody];
    }
   
}


Top
 Profile  
 
PostPosted: Fri Jun 29, 2012 9:51 pm 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1517
Location: Tokyo
When you create the sprite and body, why not just set a reference to the body in the sprite? Then you would not need an expensive loop like that.

By the way, you should set up the bodyDef before using it:
Code:
//wrong
world->CreateBody(&bodyDef);
bodyDef.userData = _player; //this setting is ignored

//right
bodyDef.userData = _player;
world->CreateBody(&bodyDef);

If you want to set the user data after the body is created you can do body->SetUserData(...)


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

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users 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