Far-Out/src/com/sagi/dayan/Games/Engine/CollisionUtil.java
2016-03-19 19:13:03 +02:00

110 lines
3.7 KiB
Java

package com.sagi.dayan.Games.Engine;
/**
* Created by sagi on 12/19/15.
*/
import java.awt.Rectangle;
import java.awt.image.PixelGrabber;
import com.sagi.dayan.Games.Elements.AnimatedSprite;
import com.sagi.dayan.Games.Elements.Sprite;
public class CollisionUtil {
/**
* Checks if a Sprite is colliding with another Sprite.
* @param otherSprite The Sprite to check a collission with.
* @param thisSprite another sprite
* @return true if the Sprites collide, otherwise false.
*/
public static boolean collidesWith(Sprite thisSprite, Sprite otherSprite) {
boolean isColliding=false;
Rectangle r1 = thisSprite.getBounds();
Rectangle r2 = otherSprite.getBounds();
r1.intersection(r2);
if(intersection(r1, r2)) {
isColliding = pixelPerfectCollision(thisSprite, otherSprite, r1, r2);
}
return isColliding;
}
private static boolean intersection(Rectangle r, Rectangle d) {
int rect1x = r.x;
int rect1y = r.y;
int rect1w = r.width;
int rect1h = r.height;
int rect2x = d.x;
int rect2y = d.y;
int rect2w = d.width;
int rect2h = d.height;
return (rect1x + rect1w >= rect2x &&
rect1y + rect1h >= rect2y &&
rect1x <= rect2x + rect2w &&
rect1y <= rect2y + rect2h);
}
/*
* pixelPerfectCollision(); first determines the area where the sprites collides
* AKA the collision-rectangle. It then grabs the pixels from both sprites
* which are inside the rectangle. It then checks every pixel from the arrays
* given by grabPixels();, and if 2 pixels at the same position are opaque,
* (alpha value over 0) it will return true. Otherwise it will return false.
*/
private static boolean pixelPerfectCollision(Sprite sprite1,Sprite sprite2, Rectangle r1, Rectangle r2) {
/*
* Get the X-values and Y-values for the two coordinates where the sprites collide
*/
int cornerTopX = (r1.x>r2.x)?r1.x:r2.x;
int cornerBottomX = ((r1.x+r1.width) < (r2.x+r2.width))?(r1.x+r1.width):(r2.x+r2.width);
int cornerTopY = (r1.y>r2.y)?r1.y:r2.y;
int cornerBottomY = ((r1.y+r1.height) < (r2.y+r2.height))?(r1.y+r1.height):(r2.y+r2.height);
//Determine the width and height of the collision rectangle
int width=cornerBottomX-cornerTopX;
int height=cornerBottomY-cornerTopY;
//Create arrays to hold the pixels
int[] pixels1 = new int[width*height];
int[] pixels2 = new int[width*height];
//Create the pixelgrabber and fill the arrays
PixelGrabber pg1 = new PixelGrabber(((AnimatedSprite)sprite1).getImageFrame(), cornerTopX-(int)sprite1.getLocX(), cornerTopY-(int)sprite1.getLocY(), width, height, pixels1, 0, width);
PixelGrabber pg2 = new PixelGrabber(((AnimatedSprite)sprite2).getImageFrame(), cornerTopX-(int)sprite2.getLocX(), cornerTopY-(int)sprite2.getLocY(), width, height, pixels2, 0, width);
//Grab the pixels
try {
pg1.grabPixels();
pg2.grabPixels();
} catch (InterruptedException ex) {
//Logger.getLogger(Sprite.class.getName()).log(Level.SEVERE, null, ex);
}
//Check if pixels at the same spot from both arrays are not transparent.
for(int i=0;i<pixels1.length;i++) {
int a = (pixels1[i] >>> 24) & 0xff;
int a2 = (pixels2[i] >>> 24) & 0xff;
/* Awesome, we found two pixels in the same spot that aren't
* completely transparent! Thus the sprites are colliding!
*/
if(a > 0 && a2 > 0) return true;
}
return false;
}
}