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 Bitmap.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 won't happen, it does go inside isCollisionDetected
, I've checked with logs! But it won't detect collision... Can anyone provide working function for checking pixel perfect collision of Bitmap with Bitmap.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
) {
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++) {
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With