我正在尝试旋转一个检测碰撞的hitbox。我想要一个从左到右移动的非旋转矩形_1和一个从右到左移动的旋转矩形_2,我希望旋转的撞击框能够检测到碰撞而不管其方向如何。但是,仅当rectangle_1与未旋转的rectangle_2碰撞时才会检测到碰撞。如何使旋转命中框检测到碰撞?以下是代码:
主程序:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Timer;
public class Rectangles extends JPanel implements MouseListener{
public static final int SCREEN_WIDTH = 400;
public static final int SCREEN_HEIGHT = 400;
private static final int TIMER_RATE = 20;
public static void main(String[] args) throws Exception {
Rectangles game = new Rectangles();
game.setup();
}
public void setup() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new JScrollPane(this));
f.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
f.setLocation(200, 200);
f.setVisible(true);
this.addMouseListener(this);
this.setFocusable(true);
}
public Rectangles() {
rectangle_1 = new Rectangle_1();
rectangle_2 = new Rectangle_2();
gameover = false;
play();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.white);
g.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
g.setColor(Color.white);
draw((Graphics2D) g);
}
public void draw(Graphics2D g) {
if (gameover) {
rectangle_1.drawRectangle(g);
rectangle_2.drawRectangle(g);
return;
}
rectangle_1.drawRectangle(g);
rectangle_2.drawRectangle(g);
rectangle_1.move();
rectangle_2.move(1);
rectangle_2.rotateRectangle(g);
if (rectangle_2.collides(rectangle_1)) {
gameover = true;
}
}
public void play() {
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
repaint();
}
};
Timer timer = new Timer(TIMER_RATE, listener);
timer.start();
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
mouseAction(e.getX(), e.getY(), e.getButton());
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
/**
* Use this method to handle all mouse input. The main action here is to have the bird flap whenever the mouse is clicked.
*/
public void mouseAction(int x, int y, int button) {
if (button == 1) {
rectangle_1.flap();
}
}
private Rectangle_1 rectangle_1;
private Rectangle_2 rectangle_2;
private boolean gameover;
private int ticks = 0;
}
rectangle_1类:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
public class Rectangle_1 {
public Rectangle_1() {
x = 0;
y = 240;
rectangle = new Rectangle((int) x, (int) y, 25, 25);
}
public void drawRectangle(Graphics2D g) {
g.setColor(Color.blue);
g.draw(rectangle);
}
public void move() {
x = x + 1;
rectangle.setLocation((int) x, (int) y);
}
public void flap() {
z = 10;
rectangle.setLocation((int) x, (int) y);
}
public boolean collides(Rectangle r) {
return r.intersects(rectangle);
}
public Rectangle getRectangle() {
return rectangle;
}
private double x;
private double y;
private double z = 0;
private Rectangle rectangle;
}
rectangle_2类:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.*;
import java.awt.Rectangle;
public class Rectangle_2 {
public Rectangle_2() {
x = 375;
y = 200;
hitBox_1 = new Rectangle((int) x + 25, (int) y, 25, 100);
}
public void drawRectangle(Graphics2D g) {
g.setColor(Color.red);
g.draw(hitBox_1);
}
public void rotateRectangle(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = g2.getTransform();
AffineTransform saveTransform = g2.getTransform();
angle += 0.01;
at.rotate(angle, hitBox_1.getX() + hitBox_1.getWidth() / 2, hitBox_1.getY() + hitBox_1.getHeight() / 2);
g2.setTransform(at);
g2.setColor(Color.red);
g2.draw(hitBox_1);
g2.setTransform(saveTransform);
}
public void move(double dx) {
x = x - dx;
hitBox_1.setLocation((int) x, (int) y);
}
public boolean collides(Rectangle_1 r) {
return r.collides(hitBox_1);
}
@Override
public String toString() {
return "Pipe [x = " + x + ", y = " + y + ", hitBox_1 = " + hitBox_1 + "]";
}
public Rectangle getHitBox_1() {
return hitBox_1;
}
public Rectangle getHitBox_2() {
return hitBox_1;
}
public double getX() {
return x;
}
private double x;
private double y;
private double angle = 0;
private Rectangle hitBox_1;
}
答案 0 :(得分:1)
当且仅当至少有一个矩形在另一个矩形内有一个角点时,两个矩形会发生碰撞。
当且仅当从角点到矩形的两个相对边的距离都小于矩形边的长度时,角在另一个矩形内。
对于计算机图形学,有一种标准算法来计算2D和3D空间中的距离。 Google应该这样做。
答案 1 :(得分:0)
你永远不会旋转你的任何矩形 - 因此你没有检测到(未旋转的)矩形的碰撞...... ....
当您使用rotateRectangle
“旋转”矩形时,您只需绘制一个旋转的矩形,但绝不会自动旋转矩形......
//your source points
int[] xs = new int[]{0, 10, 10, 0};
int[] ys = new int[]{0, 0, 10, 10};
//create a polygon with these source points
Polygon p = new Polygon(xs, ys, 4);
//again: your source Points as double[]
double[] src = new double[]{
xs[0], ys[0],
xs[1], ys[1],
xs[2], ys[2],
xs[3], ys[3]};
//and destination points for rotating them
double[] dst = new double[8];
//to rotate them you need an affirm transformation (rotating around your center 5/5)
AffineTransform t = AffineTransform.getRotateInstance(0.1, 5, 5);
t.transform(src, 0, dst, 0, 4);
//and revert them back into int[]
int[] xTrans = new int[]{(int)dst[0], (int)dst[2],(int)dst[4],(int)dst[6]};
int[] yTrans = new int[]{(int)dst[1], (int)dst[3],(int)dst[5],(int)dst[7]};
//this would be your rotated polygon
Polygon pTrans = new Polygon(xTrans, yTrans, 4);
你可以使用方法java.awt.Polygon.intersects(Rectangle r)来检查你是否与你的矩形相交
如果您想要最简单的方法,您可以从矩形中简单地创建一个旋转的实例:
AffineTransform t = AffineTransform.getRotateInstance(0.1, 5, 5);
Shape s = t.createTransformedShape(rectangle);