Remove box2d bodies after collision deduction android?
- by jubin
Can any one explain me how to destroy box2d body when collide i have tried but my application crashed.First i have checked al collisions then add all the bodies in array who i want to destroy.I am trying to learning this tutorial
My all the bodies are falling i want these bodies should destroy when these bodies will collide my actor monkey but when it collide it destroy but my aplication crashed.I have googled and from google i got the application crash reasons we should not destroy body in step funtion but i am removing body in the last of tick method.
could any one help me or provide me code aur check my code why i am getting this prblem or how can i destroy box2d bodies.
This is my code what i am doing. Please could any one check my code and tell me what is i am doing wrong for removing bodies.
The code is for multiple box2d objects falling on my actor monkey it should be destroy when it will fall on the monkey.It is destroing but my application crahes.
static class Box2DLayer extends CCLayer {
protected static final float PTM_RATIO = 32.0f;
protected static final float WALK_FACTOR = 3.0f;
protected static final float MAX_WALK_IMPULSE = 0.2f;
protected static final float ANIM_SPEED = 0.3f;
int isLeft=0;
String dir="";
int x =0;
float direction;
CCColorLayer objectHint;
// protected static final float PTM_RATIO = 32.0f;
protected World _world;
protected static Body spriteBody;
CGSize winSize = CCDirector.sharedDirector().winSize();
private static int count = 200;
protected static Body monkey_body;
private static Body bodies;
CCSprite monkey;
float animDelay;
int animPhase;
CCSpriteSheet danceSheet = CCSpriteSheet.spriteSheet("phases.png");
CCSprite _block;
List<Body> toDestroy = new ArrayList<Body>();
//CCSpriteSheet _spriteSheet;
private static MyContactListener _contactListener = new MyContactListener();
public Box2DLayer() {
this.setIsAccelerometerEnabled(true);
CCSprite bg = CCSprite.sprite("jungle.png");
addChild(bg,0);
bg.setAnchorPoint(0,0);
bg.setPosition(0,0);
CGSize s = CCDirector.sharedDirector().winSize();
// Use scaled width and height so that our boundaries always match the current screen
float scaledWidth = s.width/PTM_RATIO;
float scaledHeight = s.height/PTM_RATIO;
Vector2 gravity = new Vector2(0.0f, -30.0f);
boolean doSleep = false;
_world = new World(gravity, doSleep);
// Create edges around the entire screen
// Define the ground body.
BodyDef bxGroundBodyDef = new BodyDef();
bxGroundBodyDef.position.set(0.0f, 0.0f);
// The body is also added to the world.
Body groundBody = _world.createBody(bxGroundBodyDef);
// Register our contact listener
// Define the ground box shape.
PolygonShape groundBox = new PolygonShape();
Vector2 bottomLeft = new Vector2(0f,0f);
Vector2 topLeft = new Vector2(0f,scaledHeight);
Vector2 topRight = new Vector2(scaledWidth,scaledHeight);
Vector2 bottomRight = new Vector2(scaledWidth,0f);
// bottom
groundBox.setAsEdge(bottomLeft, bottomRight);
groundBody.createFixture(groundBox,0);
// top
groundBox.setAsEdge(topLeft, topRight);
groundBody.createFixture(groundBox,0);
// left
groundBox.setAsEdge(topLeft, bottomLeft);
groundBody.createFixture(groundBox,0);
// right
groundBox.setAsEdge(topRight, bottomRight);
groundBody.createFixture(groundBox,0);
CCSprite floorbg = CCSprite.sprite("grassbehind.png");
addChild(floorbg,1);
floorbg.setAnchorPoint(0,0);
floorbg.setPosition(0,0);
CCSprite floorfront = CCSprite.sprite("grassfront.png");
floorfront.setTag(2);
this.addBoxBodyForSprite(floorfront);
addChild(floorfront,3);
floorfront.setAnchorPoint(0,0);
floorfront.setPosition(0,0);
addChild(danceSheet);
//CCSprite monkey = CCSprite.sprite(danceSheet, CGRect.make(0, 0, 48, 73));
//addChild(danceSprite);
monkey = CCSprite.sprite("arms_up.png");
monkey.setTag(2);
monkey.setPosition(200,100);
BodyDef spriteBodyDef = new BodyDef();
spriteBodyDef.type = BodyType.DynamicBody;
spriteBodyDef.bullet=true;
spriteBodyDef.position.set(200 / PTM_RATIO,
300 / PTM_RATIO);
monkey_body = _world.createBody(spriteBodyDef);
monkey_body.setUserData(monkey);
PolygonShape spriteShape = new PolygonShape();
spriteShape.setAsBox(monkey.getContentSize().width/PTM_RATIO/2,
monkey.getContentSize().height/PTM_RATIO/2);
FixtureDef spriteShapeDef = new FixtureDef();
spriteShapeDef.shape = spriteShape;
spriteShapeDef.density = 2.0f;
spriteShapeDef.friction = 0.70f;
spriteShapeDef.restitution = 0.0f;
monkey_body.createFixture(spriteShapeDef);
//Vector2 force = new Vector2(10, 10);
//monkey_body.applyLinearImpulse(force, spriteBodyDef.position);
addChild(monkey,10000);
this.schedule(tickCallback);
this.schedule(createobjects, 2.0f);
objectHint = CCColorLayer.node(ccColor4B.ccc4(255,0,0,128), 200f, 100f);
addChild(objectHint, 15000);
objectHint.setVisible(false);
_world.setContactListener(_contactListener);
}
private UpdateCallback tickCallback = new UpdateCallback() {
public void update(float d) {
tick(d);
}
};
private UpdateCallback createobjects = new UpdateCallback() {
public void update(float d) {
secondUpdate(d);
}
};
private void secondUpdate(float dt) {
this.addNewSprite();
}
public void addBoxBodyForSprite(CCSprite sprite) {
BodyDef spriteBodyDef = new BodyDef();
spriteBodyDef.type = BodyType.StaticBody;
//spriteBodyDef.bullet=true;
spriteBodyDef.position.set(sprite.getPosition().x / PTM_RATIO,
sprite.getPosition().y / PTM_RATIO);
spriteBody = _world.createBody(spriteBodyDef);
spriteBody.setUserData(sprite);
Vector2 verts[] = {
new Vector2(-11.8f / PTM_RATIO, -24.5f / PTM_RATIO),
new Vector2(11.7f / PTM_RATIO, -24.0f / PTM_RATIO),
new Vector2(29.2f / PTM_RATIO, -14.0f / PTM_RATIO),
new Vector2(28.7f / PTM_RATIO, -0.7f / PTM_RATIO),
new Vector2(8.0f / PTM_RATIO, 18.2f / PTM_RATIO),
new Vector2(-29.0f / PTM_RATIO, 18.7f / PTM_RATIO),
new Vector2(-26.3f / PTM_RATIO, -12.2f / PTM_RATIO) };
PolygonShape spriteShape = new PolygonShape();
spriteShape.set(verts);
//spriteShape.setAsBox(sprite.getContentSize().width/PTM_RATIO/2,
//sprite.getContentSize().height/PTM_RATIO/2);
FixtureDef spriteShapeDef = new FixtureDef();
spriteShapeDef.shape = spriteShape;
spriteShapeDef.density = 2.0f;
spriteShapeDef.friction = 0.70f;
spriteShapeDef.restitution = 0.0f;
spriteShapeDef.isSensor=true;
spriteBody.createFixture(spriteShapeDef);
}
public void addNewSprite()
{
count=0;
Random rand = new Random();
int Number = rand.nextInt(10);
switch(Number)
{
case 0: _block = CCSprite.sprite("banana.png");
break;
case 1: _block = CCSprite.sprite("backpack.png");break;
case 2: _block = CCSprite.sprite("statue.png");break;
case 3: _block = CCSprite.sprite("pineapple.png");break;
case 4: _block = CCSprite.sprite("bananabunch.png");break;
case 5: _block = CCSprite.sprite("hat.png");break;
case 6: _block = CCSprite.sprite("canteen.png");break;
case 7: _block = CCSprite.sprite("banana.png");break;
case 8: _block = CCSprite.sprite("statue.png");break;
case 9: _block = CCSprite.sprite("hat.png");break;
}
int padding=20;
//_block.setPosition(CGPoint.make(100, 100));
// Determine where to spawn the target along the Y axis
CGSize winSize = CCDirector.sharedDirector().displaySize();
int minY = (int)(_block.getContentSize().width / 2.0f);
int maxY = (int)(winSize.width - _block.getContentSize().width / 2.0f);
int rangeY = maxY - minY;
int actualY = rand.nextInt(rangeY) + minY;
// Create block and add it to the layer
float xOffset = padding+_block.getContentSize().width/2+((_block.getContentSize().width+padding)*count);
_block.setPosition(CGPoint.make(actualY, 750));
_block.setTag(1);
float w = _block.getContentSize().width;
objectHint.setVisible(true);
objectHint.changeWidth(w);
objectHint.setPosition(actualY-w/2, 460);
this.addChild(_block,10000);
// Create ball body and shape
BodyDef ballBodyDef1 = new BodyDef();
ballBodyDef1.type = BodyType.DynamicBody;
ballBodyDef1.position.set(actualY/PTM_RATIO, 480/PTM_RATIO);
bodies = _world.createBody(ballBodyDef1);
bodies.setUserData(_block);
PolygonShape circle1 = new PolygonShape();
Vector2 verts[] = {
new Vector2(-11.8f / PTM_RATIO, -24.5f / PTM_RATIO),
new Vector2(11.7f / PTM_RATIO, -24.0f / PTM_RATIO),
new Vector2(29.2f / PTM_RATIO, -14.0f / PTM_RATIO),
new Vector2(28.7f / PTM_RATIO, -0.7f / PTM_RATIO),
new Vector2(8.0f / PTM_RATIO, 18.2f / PTM_RATIO),
new Vector2(-29.0f / PTM_RATIO, 18.7f / PTM_RATIO),
new Vector2(-26.3f / PTM_RATIO, -12.2f / PTM_RATIO) };
circle1.set(verts);
FixtureDef ballShapeDef1 = new FixtureDef();
ballShapeDef1.shape = circle1;
ballShapeDef1.density = 10.0f;
ballShapeDef1.friction = 0.0f;
ballShapeDef1.restitution = 0.1f;
bodies.createFixture(ballShapeDef1);
count++;
//Remove();
}
@Override
public void ccAccelerometerChanged(float accelX, float accelY, float accelZ) {
//Apply the directional impulse
/*float impulse = monkey_body.getMass()*accelY*WALK_FACTOR;
Vector2 force = new Vector2(impulse, 0);
monkey_body.applyLinearImpulse(force, monkey_body.getWorldCenter());*/
walk(accelY);
//Remove();
}
private void walk(float accelY) {
// TODO Auto-generated method stub
direction = accelY;
}
private void Remove()
{
for (Iterator<MyContact> it1 = _contactListener.mContacts.iterator(); it1.hasNext();) {
MyContact contact = it1.next();
Body bodyA = contact.fixtureA.getBody();
Body bodyB = contact.fixtureB.getBody();
// See if there's any user data attached to the Box2D body
// There should be, since we set it in addBoxBodyForSprite
if (bodyA.getUserData() != null && bodyB.getUserData() != null) {
CCSprite spriteA = (CCSprite) bodyA.getUserData();
CCSprite spriteB = (CCSprite) bodyB.getUserData();
// Is sprite A a cat and sprite B a car? If so, push the cat
// on a list to be destroyed...
if (spriteA.getTag() == 1 && spriteB.getTag() == 2) {
//Log.v("dsfds", "dsfsd"+bodyA);
//_world.destroyBody(bodyA);
// removeChild(spriteA, true);
toDestroy.add(bodyA);
}
// Is sprite A a car and sprite B a cat? If so, push the cat
// on a list to be destroyed...
else if (spriteA.getTag() == 2 && spriteB.getTag() == 1) {
//Log.v("dsfds", "dsfsd"+bodyB);
toDestroy.add(bodyB);
}
}
}
// Loop through all of the box2d bodies we want to destroy...
for (Iterator<Body> it1 = toDestroy.iterator(); it1.hasNext();) {
Body body = it1.next();
// See if there's any user data attached to the Box2D body
// There should be, since we set it in addBoxBodyForSprite
if (body.getUserData() != null) {
// We know that the user data is a sprite since we set
// it that way, so cast it...
CCSprite sprite = (CCSprite) body.getUserData();
// Remove the sprite from the scene
_world.destroyBody(body);
removeChild(sprite, true);
}
// Destroy the Box2D body as well
// _contactListener.mContacts.remove(0);
}
}
public synchronized void tick(float delta) {
synchronized (_world) {
_world.step(delta, 8, 3);
//_world.clearForces();
//addNewSprite();
}
CCAnimation danceAnimation = CCAnimation.animation("dance", 1.0f);
// Iterate over the bodies in the physics world
Iterator<Body> it = _world.getBodies();
while(it.hasNext()) {
Body b = it.next();
Object userData = b.getUserData();
if (userData != null && userData instanceof CCSprite) {
//Synchronize the Sprites position and rotation with the corresponding body
CCSprite sprite = (CCSprite)userData;
if(sprite.getTag()==1)
{
//b.applyLinearImpulse(force, pos);
sprite.setPosition(b.getPosition().x * PTM_RATIO, b.getPosition().y * PTM_RATIO);
sprite.setRotation(-1.0f * ccMacros.CC_RADIANS_TO_DEGREES(b.getAngle()));
}
else
{
//Apply the directional impulse
float impulse = monkey_body.getMass()*direction*WALK_FACTOR;
Vector2 force = new Vector2(impulse, 0);
b.applyLinearImpulse(force, b.getWorldCenter());
sprite.setPosition(b.getPosition().x * PTM_RATIO, b.getPosition().y * PTM_RATIO);
animDelay -= 1.0f/60.0f;
if(animDelay <= 0)
{
animDelay = ANIM_SPEED;
animPhase++;
if(animPhase > 2)
{
animPhase = 1;
}
}
if(direction < 0 )
{
isLeft=1;
}
else
{
isLeft=0;
}
if(isLeft==1)
{
dir = "left";
}
else
{
dir = "right";
}
float standingLimit = (float) 0.1f;
float vX = monkey_body.getLinearVelocity().x;
if((vX > -standingLimit)&& (vX < standingLimit))
{
// Log.v("sasd", "standing");
}
else
{
}
}
}
}
Remove();
}
}
Sorry for my english.
Thanks in advance.