使用BufferedImage(Java2D Api)的getRGB进行每像素冲突

时间:2010-10-28 21:30:02

标签: collision-detection java-2d

您好我正在制作2D平台游戏。 我想在我的播放器(一个矩形)和一个自由形式的地形(使用斜面,一个BufferedImage)之间进行逐像素碰撞。

我对这个概念有点困惑,检查我的矩形是否有任何部分 与地形相撞。

目前,我正在尝试查看我的地形的一部分是否包含非透明像素。 我将其与矩形中的每个坐标进行比较,看看它们是否相遇,但是我没有运气。

这是我的代码:

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

其中:terrain是我的bufferedImage x,y,width和height是我的玩家的矩形坐标

2 个答案:

答案 0 :(得分:1)

我认为你的游戏没有滚动?

至少你需要  玩家的位置 - 比如矩形左下角的x,y  球员的宽度,高度  地形位图

所以它会像那样:

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()。检查“如果不透明”也取决于api,所以它留给学生锻炼:)。

答案 1 :(得分:0)

假设您使用的是ARGB格式,最高8位代表alpha(透明度)通道。 像素完美碰撞

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

}

可碰撞界面

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