Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Modifying the size of the body on collision — Gideros Forum

Modifying the size of the body on collision

ClaudioBAClaudioBA Member
edited February 2013 in Game & application design
Hello again, now im trying something with no success...
ive seen some answers like storing the shape on the fixture and then modify it, but isn't working for me ..

this approaches i have tried:

1) storing and modifying shape

if (bodyB.name == "char" and bodyA.name == "modify") then
local blockShape = b2.PolygonShape.new();
blockShape:setAsBox(11, 11,11, 11,0);
event.fixtureA.shape = blockShape

end

2) then i tried destroying the body but can't do it because the world is locked.
3) then i tried scale option, but just scales the sprite and not the body...
can anyone help me???

Thanks!

Dislikes: Yan

+1 -1 (+0 / -1 )Share on Facebook

Comments

  • john26john26 Maintainer
    edited February 2013 Accepted Answer
    This is the way Box2D works. The PolygonShape is only used when the fixture is first created. Box2D makes an internal copy of this and uses it that shape for the fixture from then on. The only think you can do is destroy the fixture and recreate it again.

    And the further complication is that you can't destroy bodies during collision events (not sure if you can destroy fixtures..?). So you just have to make a note of the body/fixture to be destroyed during the collision event, then destroy the body during the next enter_frame event. It's a nuisance but that's how Box2D works. If you do a web search you'll find 100s people with same problem even when running Box2D directly in C++.

    (Box2D is originally a C++ lib and available open source)

  • thanks for the response...
    could you enlighten me where to place the code to do this???
    i've read somewhere that i must mark the body for deletion in the collision but in which portion of the code i must place the destruction action and replacement?
    will the replacement of the fixture look fluid on the game??
    will this affect the speed of the game??

    Thanks!
  • paul_k_clarkpaul_k_clark Member
    Accepted Answer
    @ClaudioBA I just create a timer that start in zero or one millisecond to do the changes. This should have little impact on the speed and gets you around the problem.
  • ar2rsawseenar2rsawseen Maintainer
    Accepted Answer
    @ClaudioBA the hack provided by @paul_k_clark should work, guilty of using it myself, some times. :)

    But it also can be done in the look where you loop through all the bodies and move their representing sprites accordingly

    Or you can store references in a separate table and loop through it to remove bodies on each enter frame event
  • Thanks!!!! is working!!!!!! its ALIVE!!!!!!
  • im having an issue removing the body, i can remove the sprite but i cant get the body
    this is the code im using

    for i=1,stage:getNumChildren() do
    local sprite = stage:getChildAt(i)
    local body = sprite.body
    print(body)
    if body.toDestrioy == 1 then
    stage:removeChild(sprite)
    b2World:destroyBody(body)
    break
    end
    end

    im getting a nil body....
    something im forgetting??
  • Does every Sprite on the stage have a body?
  • Is there any error? because there could be almost anything, and we could not help you without knowing the error message.

    is if body.toDestrioy == 1 really toDestrioy and not toDestroy ?

    is b2World an instance of b2.World?

    And yes does all sprites have body?
  • this is the error im getting:

    character.lua:272: attempt to index local 'body' (a nil value)
    stack traceback:
    character.lua:272: in function

    Sorry about the toDestrioy typo, is toDestroy.

    Yes, b2World is an instance of b2.World

    and every sprite has a body.....
    still can't solve it
  • ar2rsawseenar2rsawseen Maintainer
    edited February 2013
    By the error it seems that not all children have body, so tell me if this check helps
    for i=1,stage:getNumChildren() do
        local sprite = stage:getChildAt(i)
        if sprite.body then
            local body = sprite.body
            print(body)
            if body.toDestroy == 1 then
               stage:removeChild(sprite)
               b2World:destroyBody(body)
               break
            end
        end
    end
    And what is exactly in character.lua at 272 line?
  • ClaudioBAClaudioBA Member
    edited February 2013
    thanks for the help, i finally got it to work (started a new clean project)... apparently there was a sprite without body in somewhere....

    but now im with another issue, i destroy the body, but now im trying to create a new body in the same position, but gideros just creates the sprite without the body (i think it doesnt have body because when i try to destroy it again it throws the same error again)....

    this is the code to destroy the body:

    if body.toDestroy == 1 then
    local bodyX = sprite:getX()
    local bodyY = sprite:getY()
    stage:removeChild(sprite)
    b2World:destroyBody(body)
    newPlatform(bodyX,bodyY)

    break
    end

    and the function to create the new body:

    function newPlatform(xPos, yPos)
    local plat = GCplatform.new(Texture.new("dirt.png"), xPos,yPos, 20, stage);
    end

    can anyone help me?
  • @ClaudioBA but I don't where you create new body again.
    I assume that inside newPlatform function you should also create new body from scratch and attach it to some sprite which will be added to the stage. :)
  • the GCplatform.new is where the sprite, body and fixture are created and attached to the stage.... i mean that is the function that i call in the beggining to create the body the first time...
  • so plat is a returned sprite with body?
    you can do
    print(plat.body)
    to see if it's there.

    And as I've mentioned before, you can always put if sprite.body then inside the look where you move bodies ;)
  • maybe the method is wrong.... this is the init method of the platform(copied from an example) :

    function GCplatform:init(texture, xPos, yPos, distance, parent)

    local bitmap = Bitmap.new(texture)
    self:addChild(bitmap)


    self:setPosition(xPos, yPos);

    self.body = b2World:createBody{type = b2STATIC_BODY,
    };
    self.body:setPosition(self:getPosition());
    local blockShape = b2.PolygonShape.new();
    blockShape:setAsBox(self:getWidth()/2, self:getHeight()/2,self:getWidth()/2, self:getHeight()/2,0);

    self.body.xSprite = bitmap

    self.body.name = "diggable"
    self.body.state = "1"
    local fixture = self.body:createFixture{shape = blockShape,
    friction = 1,
    restitution = 0,
    density = 1
    };
    fixture.shape = blockShape
    parent:addChild(self);
    end

    Likes: Apollo14

    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.