2010-10-28 23 views
3

Bonjour Je travaille actuellement sur un jeu de plateforme 2D. Je voudrais avoir des collisions par pixel entre mon joueur (un rectangle) et un terrain libre (utilise des pentes, un BufferedImage).collision par pixel en utilisant getRGB d'un BufferedImage (Java2D Api)

Je suis un peu confus sur le concept de vérifier si une partie de mon rectangle entre en collision avec le terrain.

Actuellement, j'essaie de voir si une partie de mon terrain contient un pixel non transparent. Je compare cela à chaque coordonnée dans mon rectangle et voir si elles se rencontrent, mais je n'ai pas de chance.

Voici mon code:

public boolean rgbCollide() { 
    int a = terrain.getRGB(x, y); 
    System.out.println(a); 
    // Per-pixel Bitwise collision check 
    for (int i =0; i < width; i++) { 
     for (int j =0; j < height; j++) { 
      //Hmm what to do here...? 
     } 
    } 
    return false; 
} 

où: terrain est mon BufferedImage x, y, la largeur et la hauteur sont coordonnées de mon lecteur Rectangle

Répondre

1

Je suppose que votre jeu ne pas faire défiler?

Vous avez besoin d'au moins position du joueur - dire x, y du coin inférieur gauche du rectangle largeur, la hauteur du lecteur bitmap terrain

Il sera donc STH comme ça:

public boolean rgbCollide (
    terrain, 
    playerX, 
    playerY, 
    playerWidth, 
    playerHeight 
) { 

    int startX = max(playerX,0); 
    int endX = min(playerX + playerWidth, terrain.width()); 
    int startY = max(playerY-playerHeight,0); //because Y goes from top to bottom 
    int endY = min(playerY, terrain.height()); 

    for (int y = startY; y < endY; y++) { 
     for (int x = startX; x < endX; x++) { 
      if (terrain.getRGB(x, y) is not transparent) { 
       return true; 
      } 
     } 
    } 

    return false; 
} 

Je ne connais pas l'API java2d, donc peut-être que les méthodes width() et height() sont appelées différemment. La vérification "si non transparent" dépend aussi de l'API, donc il est laissé comme exercice à l'étudiant :).

0

En supposant que vous utilisez le format ARGB, les 8 bits les plus élevés représentent le canal alpha (transparence). Perfect Pixel Collision

public class RectanglePixelCollisionChecker implements CollisionChecker { 

    private static final RectangleCollisionChecker RECTANGLE_COLLISION_CHECKER = new RectangleCollisionChecker(); 
    /* 

      ax,ay ___________ax + a.width 
      |     | 
      |     | 
      | bx, by_________|__ bx + b.width 
      | |(INTERSECTION)|  | 
      |__|______________|  | 
      ay + height    | 
       |______________________| 
      by + height 
      */ 
    @Override 
    public boolean collide(Collidable collidable, Collidable collidable2) { 
     // check if bounding boxes intersect 
     if(!RECTANGLE_COLLISION_CHECKER.collide(collidable, collidable2)) { 
      return false; 
     } 

     // get the overlapping box 
     int startX = Math.max(collidable.getX(), collidable2.getX()); 
     int endX = Math.min(collidable.getX() + collidable.getWidth(), collidable2.getX() + collidable2.getWidth()); 

     int startY = Math.max(collidable.getY(), collidable2.getY()); 
     int endY = Math.min(collidable.getY() + collidable.getHeight(), collidable2.getY() + collidable2.getHeight()); 

     for(int y = startY ; y < endY ; y++) { 
      for(int x = startX ; x < endX ; x++) { 
       // compute offsets for surface 
       if((!isTransparent(collidable2.getBufferedImage(), x - collidable2.getX(), y - collidable2.getY())) 
         && (!isTransparent(collidable.getBufferedImage(), x - collidable.getX(), y - collidable.getY()))) { 
        return true; 
       } 
      } 
     } 
     return false; 
    } 

    private boolean isTransparent(BufferedImage bufferedImage, int x, int y) { 
     int pixel = bufferedImage.getRGB(x, y); 
     if((pixel & 0xFF000000) == 0x00000000) { 
      return true; 
     } 
     return false; 
    } 

} 

Rectangle Collision

public class RectangleCollisionChecker implements CollisionChecker { 

    @Override 
    public boolean collide(final Collidable c1, Collidable c2) { 
     if((c1.getX() + c1.getWidth() < c2.getX()) || (c2.getX() + c2.getWidth() < c1.getX())) { 
      return false; 
     } 
     if((c1.getY() + c1.getHeight() < c2.getY()) || (c2.getY() + c2.getHeight() < c1.getY())) { 
      return false; 
     } 
     return true; 
    } 

} 

Collidable Interface

public interface Collidable { 
    boolean collide(Collidable collidable); 
    int getX(); 
    int getY(); 
    int getWidth(); 
    int getHeight(); 
    BufferedImage getBufferedImage(); 
}