Android Libgdx and collision detection

2019-06-08 04:31发布

问题:

For my android game I use Libgdx and I detect the collision between Bob (Omino) and Plant (Pianta) with this code that works fine : Assets.class

pianta = new Animation(0.5f,new TextureRegion(items, 160, 384, 64, 96),
                              new TextureRegion(items, 224, 384, 64, 96));

Pianta.class

public class Pianta extends GameObject {
   public static final float PIANTA_WIDTH = 2;
   public static final float PIANTA_HEIGHT = 3;
   public static float stateTime;
   public Pianta(float x, float y) {
      super(x, y, PIANTA_WIDTH, PIANTA_HEIGHT);   
      stateTime = 0;
   }

    public void update(float deltaTime) {
           stateTime += deltaTime;
       }

}

World.class

Pianta pianta1_0 = new Pianta(x+10,2.2f);
piante.add(pianta1_0);

private void collisionPiante(){
      int len = piante.size();
      for(int i=0;i<len;i++){
         if(OverlapTester.overlapRectangles(piante.get(i).bounds,omino.bounds)){
            omino.ominoMorto();
         }
      }
   }

WorldRender.class

private void renderPiante() {
      TextureRegion keyFrame;
      int len = world.piante.size();
        for(int i = 0; i < len; i++) {
            Pianta pianta = world.piante.get(i);            
            keyFrame = Assets.pianta.getKeyFrame(Pianta.stateTime, Animation.ANIMATION_LOOPING);
            batcher.draw(keyFrame,pianta.position.x, pianta.position.y, 2, 3);
        }


   }

but if you watch the image 2 below, you can see that Bob hit but there isn't collision with stone (Pietra) !! This is the code :

Assets.class

pietra1 = new TextureRegion(items,288,416,128,64);

Pietra.class

public class Pietra extends GameObject {
   public static float PIETRA_WIDTH = 4;
   public static float PIETRA_HEIGHT = 2;
   public Pietra(float x, float y) {
      super(x, y, PIETRA_WIDTH, PIETRA_HEIGHT);
   }

}

World.class

Pietra pietra1_0 = new Pietra(x+25,2.2f);
pietre.add(pietra1_0);
private void collisionPietre(){
      int len2 = pietre.size();
      for(int l=0;l<len2;l++){
         if(OverlapTester.overlapRectangles(pietre.get(l).bounds,omino.bounds)){
            omino.ominoMorto();
         }
      }   
   }

WorldRender.class

private void renderPietre() {
      int len = world.pietre.size();
        for(int i = 0; i < len; i++) {
            Pietra pietra = world.pietre.get(i);            
           batcher.draw(Assets.pietra1,pietra.position.x, pietra.position.y, 4, 2);
        }
   }

OverlapTester

public class OverlapTester {
    public static boolean overlapRectangles (Rectangle r1, Rectangle r2) {
        if (r1.x < r2.x + r2.width && r1.x + r1.width > r2.x && r1.y < r2.y + r2.height && r1.y + r1.height > r2.y)
            return true;
        else
            return false;
    }

Someone can tell me why the collision with the plant works fine and with stone Bob hit even if there is no collision? as you can see the code is the same, the only difference is that the plant is an animated object while the stone isn't.

回答1:

Check your OverlapTester. This is how Libgdx does it in the Rectangle.java class:

/** @param rectangle the other {@link Rectangle}
 * @return whether this rectangle overlaps the other rectangle. */
public boolean overlaps (Rectangle rectangle) {
    return !(x > rectangle.x + rectangle.width || x + width < rectangle.x || y > rectangle.y + rectangle.height || y + height < rectangle.y);
}


回答2:

If I understood right overlapRectangles checks the case if rectangle is totally inside. It is not probably thing you want.

LibGDX has special functionality for collision checking. Please, check http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/math/Intersector.html



回答3:

You may wish to replace your OverlapTester with the Rectangle's helper function contains. For instance:

World Class

if(OverlapTester.overlapRectangles(piante.get(i).bounds,omino.bounds)){
    omino.ominoMorto();
}

Can be:

if (piante.get(i).bounds.contains(omino.bounds)) {
    omino.ominoMorto();
}