简体   繁体   中英

Pixel perfect collision with Config.ALPHA_8

I've found this code of pixel perfect collision checking and used it in my code:

public  boolean isCollisionDetected(Bitmap bitmap1, int x1, int y1,
        Bitmap bitmap2, int x2, int y2) {
    Rect bounds1 = new Rect(x1, y1, x1 + bitmap1.getWidth(), y1
            + bitmap1.getHeight());
    Rect bounds2 = new Rect(x2, y2, x2 + bitmap2.getWidth(), y2
            + bitmap2.getHeight());

    if (Rect.intersects(bounds1, bounds2)) {
        Rect collisionBounds = getCollisionBounds(bounds1, bounds2);
        for (int i = collisionBounds.left; i < collisionBounds.right; i++) {
            for (int j = collisionBounds.top; j < collisionBounds.bottom; j++) {
                int bitmap1Pixel = bitmap1.getPixel(i - x1, j - y1);
                int bitmap2Pixel = bitmap2.getPixel(i - x2, j - y2);
                if (isFilled(bitmap1Pixel) && isFilled(bitmap2Pixel)) {
                    return true;
                }
            }
        }
    }
    return false;
}

private  Rect getCollisionBounds(Rect rect1, Rect rect2) {
    int left = (int) Math.max(rect1.left, rect2.left);
    int top = (int) Math.max(rect1.top, rect2.top);
    int right = (int) Math.min(rect1.right, rect2.right);
    int bottom = (int) Math.min(rect1.bottom, rect2.bottom);
    return new Rect(left, top, right, bottom);
}

private  boolean isFilled(int pixel) {
    return pixel != Color.TRANSPARENT;
}

And it worked perfectly, no problems what so ever. That until I set the images into Config_Alpha_8 using this code (because of ram problems):

    private Bitmap convert(Bitmap bitmap, Bitmap.Config config) {
    Bitmap convertedBitmap = 
                  Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), config);
    Canvas canvas = new Canvas(convertedBitmap);
    Paint paint = new Paint();
    paint.setColor(Color.BLACK);
    canvas.drawBitmap(bitmap, 0, 0, paint);
    return convertedBitmap;
}

Why Nothing wont happen, it does go inside isCollisioDetected, I've checked with logs! but it wont detect collision.. can anyone provide working function for checking pixel perfect collision of bitmap with config_alpha_8?

Calling getPixel() on a bitmap with ALPHA_8 configuration will always return zero. This seems to be a bug

You can work around this problem by storing the pixels of each bitmap as a byte array:

byte[] pixelData = getPixels(convert(bitmap, Bitmap.Config.ALPHA_8));

...

 public byte[] getPixels(Bitmap bmp) {
    int bytes = bmp.getRowBytes() * bmp.getHeight();
    ByteBuffer buffer = ByteBuffer.allocate(bytes);
    bmp.copyPixelsToBuffer(buffer);
    return buffer.array();
}

You will need to modify your collision detection function a little:

public  boolean isCollisionDetected(byte[] pixels1, Bitmap bitmap1, int x1, int y1,
            byte[] pixels2, Bitmap bitmap2, int x2, int y2) {

        int width1 =bitmap1.getWidth();
        int height1=bitmap1.getHeight();
        int width2 =bitmap2.getWidth();
        int height2=bitmap2.getHeight();

        Rect bounds1 = new Rect(x1, y1, x1 + width1, y1 + height1);
        Rect bounds2 = new Rect(x2, y2, x2 + width2, y2 + height2);

        if (Rect.intersects(bounds1, bounds2)) {
            Rect collisionBounds = getCollisionBounds(bounds1, bounds2);
            for (int i = collisionBounds.left; i < collisionBounds.right; i++) {
                for (int j = collisionBounds.top; j < collisionBounds.bottom; j++) {
                    byte bitmap1Pixel = pixels1[((j - y1) * width1) + (i - x1)];
                    byte bitmap2Pixel = pixels2[((j - y2) * width2) + (i - x2)];
                    if (isFilled(bitmap1Pixel) && isFilled(bitmap2Pixel)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

(... you might want to change the bitmap parameters into the respective width and height of the those bitmaps and call recycle().)

Android Config_Alpha_8 does not save color information, so when you draw the bitmap, adding the paint will do nothing, and all isFilled checks will return false.

Neat piece of code though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM