1
\$\begingroup\$

in my Game I Create object layers and interpret the shapes in the engine as collision objects...now I want when Player collide with object, after a few seconds object falls...this works properly but not display correctly and tiles are fixed and do not fall... I want to tiles are considered as objects also fall(replace)...how to replace tiles? here's my code

TMX file

<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" renderorder="right-down" width="500" height="50" tilewidth="20" tileheight="20" nextobjectid="19">
<tileset firstgid="1" name="map_tiles" tilewidth="20" tileheight="20" tilecount="48">
<image source="gfx/game/map_tiles.png" width="128" height="160"/>
</tileset>
<layer name="Tile Layer 1" width="500" height="50">
<data encoding="base64" compression="gzip">
   H4sIAAAAAAAAC+3YsQ2AMAxFQcsDBfafDjcRrZEQidAV17v8zxkRCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsIlRjnJucAsAAACwjh8BAAAA3HQyANBlNwAAAMAzWhoAmOwCAAAAeE+ns7U4AAAAfE+PAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPzDBbVpn02ghgEA
</data>
</layer>
<objectgroup name="Object Layer 1" width="500" height="50">
<properties>
<property name="sp" value="true"/>
</properties>
<object id="1" x="19" y="280" width="61" height="20"/>
<object id="2" x="80" y="361" width="60" height="20"/>
<object id="3" x="180" y="419" width="60" height="21"/>
<object id="4" x="261" y="480" width="60" height="21"/>
<object id="5" x="361" y="520" width="58" height="20"/>
</objectgroup>
<objectgroup name="Object Layer 2" width="500" height="50">
<properties>
<property name="fa" value="true"/>
</properties>
<object id="6" x="441" y="479" width="59" height="21"/>
<object id="7" x="541" y="439" width="59" height="21"/>
<object id="8" x="600" y="379" width="61" height="23"/>
<object id="9" x="680" y="321" width="61" height="20"/>
</objectgroup>
<objectgroup name="Object Layer 3" width="500" height="50">
<properties>
<property name="plat1" value="true"/>
</properties>
<object id="18" x="20" y="279" width="60" height="20"/>
</objectgroup>
</map>

GameScene:

if (group.getTMXObjectGroupProperties().containsTMXProperty(
                "sp", "true")) {

            for (final TMXObject object : group.getTMXObjects()) {
                final Rectangle rect = new Rectangle(object.getX()
                        + (5 * mapTileSize) / 3, mapHeight - mapTileSize
                        / 2 - object.getY(), object.getWidth(),
                        object.getHeight(), vbom);

                final Body body = PhysicsFactory.createBoxBody(
                        physicsWorld, rect, BodyType.StaticBody,
                        boxFixtureDef);
                rect.setVisible(true);
                this.attachChild(rect);
                body.setUserData("sp");
                physicsWorld.registerPhysicsConnector(new PhysicsConnector(
                        rect, body, true, false));
            }
        } else if (group.getTMXObjectGroupProperties().containsTMXProperty(
                "fa", "true")) {
            // This is our "wall" layer. Create the boxes from it
            for (final TMXObject object : group.getTMXObjects()) {
                final Rectangle rect = new Rectangle(object.getX()
                        + (5 * mapTileSize) / 3, mapHeight - mapTileSize
                        / 2 - object.getY(), object.getWidth(),
                        object.getHeight(), vbom);

                final Body body = PhysicsFactory.createBoxBody(
                        physicsWorld, rect, BodyType.StaticBody,
                        boxFixtureDef);
                rect.setVisible(true);
                this.attachChild(rect);
                body.setUserData("fa");
                physicsWorld.registerPhysicsConnector(new PhysicsConnector(
                        rect, body, true, false));
            }

contactListener:

if (x1.getBody().getUserData().equals("sp")
                        && x2.getBody().getUserData().equals("player")) {
                    engine.registerUpdateHandler(new TimerHandler(0.4f,
                            new ITimerCallback() {
                                public void onTimePassed(
                                        final TimerHandler pTimerHandler) {
                                    pTimerHandler.reset();
                                    engine.unregisterUpdateHandler(pTimerHandler);
                                    x1.getBody().setType(
                                            BodyType.DynamicBody);
                                }
                            }));


                }
                if (x1.getBody().getUserData().equals("fa")
                        && x2.getBody().getUserData().equals("player")) {
                    engine.registerUpdateHandler(new TimerHandler(0.2f,
                            new ITimerCallback() {
                                public void onTimePassed(
                                        final TimerHandler pTimerHandler) {
                                    pTimerHandler.reset();
                                    engine.unregisterUpdateHandler(pTimerHandler);
                                    x1.getBody().setType(
                                            BodyType.DynamicBody);
                                }
                            }));
                }
\$\endgroup\$
0
\$\begingroup\$

There are a few things you can try that might work for you.

Destroy the static body and create a new dynamic in it's place. This is pretty much guaranteed to work but if you drop static bodies often it might incur a performance problem. Still, this is the approach I would try first.

Manually toggle the active state on the body. I seem to remember there being a bug in Box2D when changing body type where the previously static body wouldn't realize that it needed to be active.

if (x1.getBody().getUserData().equals("sp") && x2.getBody().getUserData().equals("player")) {
  x1.getBody().setType(BodyType.DynamicBody); // Change type first
  x1.getBody().setActive(false);
  engine.registerUpdateHandler(new TimerHandler(0.4f, new ITimerCallback() {
      public void onTimePassed(final TimerHandler pTimerHandler) {
      pTimerHandler.reset();
      engine.unregisterUpdateHandler(pTimerHandler);
      x1.getBody().setActive(true); // Then, when timer expires flip the active flag
    }
  }));
}  

Force the waking up of the body by transforming it and then transforming it back. You can try moving the body temporarily to a place far away where it won't interfere with the rest of the world and then move it back.

if (x1.getBody().getUserData().equals("sp") && x2.getBody().getUserData().equals("player")) {
  engine.registerUpdateHandler(new TimerHandler(0.4f, new ITimerCallback() {
      public void onTimePassed(final TimerHandler pTimerHandler) {
      pTimerHandler.reset();
      engine.unregisterUpdateHandler(pTimerHandler);
      x1.getBody().setType(BodyType.DynamicBody);

      // Store current transform
      Vector2 position = x1.getBody().getPosition();
      float angle = x1.getBody().getAngle();

      // Set transform to place outside the actual world
      x1.getBody().setTransform(-1000, -1000, -1);

      // Restore transform
      x1.getBody().setTransform(position.x, position.y, angle);
    }
  }));
}

I'll see if I can dig out the original bug report that mentions this problem.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.