Обнаружение столкновения Java между двумя объектами Shape?
Я хотел бы знать, как лучше всего определить, пересекает ли объект Shape другую фигуру.
В настоящее время у меня обнаружено обнаружение столкновений в моей игре, если оно включает в себя форму, пересекающую прямоугольник или наоборот. Проблема, с которой я сталкиваюсь, заключается в том, что метод intersects() в классе Shape может принимать только Rectangle или Point как параметр, а не другой Shape. Есть ли эффективный способ проверки, если два объекта Shape перекрываются каким-либо образом?
Один из способов, которым я попытался, состоял в том, чтобы использовать цикл for для создания области точек для проверки, были ли они в форме, а затем для создания массива объектов Point для отправки другой форме для тестирования, но это значительно снизило частоту кадров из-за всех ненужных сравнений.
Я смотрел и искал что-то похожее здесь, но ничего не нашел. Извините заранее, если это повторение.
Ответы
Ответ 1
Не тестировалось, но почему бы и нет:
import java.awt.geom.Area;
...
public static boolean testIntersection(Shape shapeA, Shape shapeB) {
Area areaA = new Area(shapeA);
areaA.intersect(new Area(shapeB));
return !areaA.isEmpty();
}
Область реализует форму, но добавляет некоторые потенциально полезные методы.
Ответ 2
Вы также можете использовать границы самой фигуры, а затем сравнить границы:
public boolean collidesWith(Shape other) {
return shape.getBounds2D().intersects(other.getBounds2D());
}
Это немного лучше на глазах.
Ответ 3
Хотя пользователь2221343 уже ответил на вопрос Monkeybro10, я подумал, что в некоторых случаях может быть полезно знать, что контур фигуры может сыграть свою роль, если вы используете его описанную технику:
Например, если вы нарисуете два многоугольника, их столкновения не будут обнаружены, если это произойдет только в точном контуре полигонов. Только если области, которые включены в контуры полигонов, будут перекрываться, обнаружение столкновения будет обнаружено.
Если вы заполните два полигона, но не нарисуйте их, столкновение будет обнаружено даже в контуре видимой области.
Я написал небольшой пример, чтобы показать, что я имею в виду. Либо раскомментируйте команду ничьей или заливки, и поднимите второй многоугольник вертикально на один пиксель, раскомментируя данную строку. Запустите код и посмотрите результат в JFrame. Если второй многоугольник поднят, и оба полигона видны только командой "fill", они пересекаются со своими контурами и обнаруживается столкновение. Если второй многоугольник не вставлен, и оба полигона видны командой "draw", они пересекаются со своими контурами, но столкновение не обнаруживается:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.geom.Area;
import javax.swing.JFrame;
public class Test {
private JFrame frame;
private Polygon polygon1;
private Polygon polygon2;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Test window = new Test();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Test() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame(){
private static final long serialVersionUID = 1L;
@Override
public void paint(Graphics g){
super.paint(g);
doDrawing(g);
}
};
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int nShape1 = 4;
int xPoly1[] = {30,50,50,30};
int yPoly1[] = {30,30,50,50};
polygon1 = new Polygon(xPoly1,yPoly1,nShape1);
int nShape2 = 4;
int xPoly2[] = {35,55,55,35};
int yPoly2[] = {50,50,70,70};
// uncomment next line to rise second polygon vertically by one pixel
//yPoly2[] = {49,49,69,69};
polygon2 = new Polygon(xPoly2,yPoly2,nShape2);
}
public synchronized void doDrawing(Graphics g){
g.setColor(new Color(255,0,0));
// if you draw the polygon, collision on the exact outline won't be detected.
// uncomment draw or fill command to see what I mean.
g.drawPolygon(polygon1);
g.fillPolygon(polygon1);
g.setColor(new Color(0,0,255));
// if you draw the polygon, collision on the exact outline won't be detected.
// uncomment draw or fill command to see what I mean.
g.drawPolygon(polygon2);
g.fillPolygon(polygon2);
Area area = new Area(polygon1);
area.intersect(new Area(polygon2));
if(!area.isEmpty()){
System.out.println("intersects: yes");
}
else{
System.out.println("intersects: no");
}
}
}