2016-02-27 20:45:32 +00:00
|
|
|
package com.sagi.dayan.Games.Engine;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Created by sagi on 12/19/15.
|
|
|
|
*/
|
|
|
|
|
2016-03-12 10:24:42 +00:00
|
|
|
import com.sagi.dayan.Games.Elements.AnimatedSprite;
|
2016-02-27 20:45:32 +00:00
|
|
|
import com.sagi.dayan.Games.Elements.Sprite;
|
|
|
|
|
|
|
|
import java.awt.*;
|
|
|
|
import java.awt.image.PixelGrabber;
|
|
|
|
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
|
2016-03-12 10:24:42 +00:00
|
|
|
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);
|
2016-02-27 20:45:32 +00:00
|
|
|
|
|
|
|
//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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|