2010-10-28 1 views
3

Здравствуйте, я сейчас работаю над 2D-платформерной игрой. Мне хотелось бы иметь пиксельные столкновения между моим игроком (Rectangle) и ландшафтом свободной формы (использует склоны, BufferedImage).за пиксельное столкновение с использованием getRGB из BufferedImage (Java2D Api)

Я немного запутался в концепции, чтобы проверить, сталкивается ли какая-либо часть моего прямоугольника с рельефом.

В настоящее время я пытаюсь выяснить, содержит ли часть моей местности непрозрачный пиксель. Я сравниваю это с каждой координатой в моем прямоугольнике и вижу, встречаются ли они, однако мне не повезло.

Вот мой код:

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; 
} 

где местность моя BufferedImage х, у, ширина и высота прямоугольника моего игрока координаты

ответ

1

Я предполагаю, что ваша игра не имеет прокрутки?

Вам нужно по крайней мере позицию игрока, - скажем х, у левого нижнего угла ширины прямоугольника , высота игрок местности растрового

Так будет STH так:

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; 
} 

Я не знаю java2d api, поэтому, возможно, методы width() и height() называются по-разному. Проверка «if not transparent» также зависит от api, поэтому он остается как упражнение для ученика :).

0

Предполагая, что вы используете формат ARGB, самые высокие 8 бит представляют собой альфа-канал (прозрачность). Pixel Идеальный Столкновение

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; 
    } 

} 

Прямоугольник Столкновение

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 Интерфейс

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