英文:
{JAVA} Rectangle collision detection
问题
///////////////////////////////////////////////////////
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class f5 extends JPanel implements ActionListener {
static JFrame frame;
static Timer t;
static int x, velx, x2, velx2;
f5() {
t = new Timer(5, this);
x = 100;
x2 = 400;
velx = 2;
velx2 = 2;
frame = new JFrame();
frame.setSize(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle r1 = new Rectangle();
Rectangle r2 = new Rectangle();
g.setColor(Color.BLUE);
g.fillRect(x, 10, 50, 30);
g.setColor(Color.RED);
g.fillRect(x2, 10, 50, 30);
if(r1.intersects(r2)){
g.drawString("HIT!!!!!", 250, 200);
}
t.start();
}
public void actionPerformed(ActionEvent e) {
if(x < 0 || x > 450) {
velx = -velx;
}
if(x2 < 0 || x2 > 450) {
velx2 = -velx2;
}
x -= velx;
x2 += velx2;
repaint();
}
public static void main(String args[]){
new f5();
}
}
英文:
**Hi guys,i have 2 questions.
- why "Hit" word do not appear.
- what type of code i need to add to make these 2 rects collide and bounce each other based on my code.Just give me a hint . i'll do it myself.
Below is the code for question 1.
Thank you.**
///////////////////////////////////////////////////////
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class f5 extends JPanel implements ActionListener {
static JFrame frame;
static Timer t;
static int x, velx, x2, velx2;
f5() {
t = new Timer(5, this);
x = 100;
x2 = 400;
velx = 2;
velx2 = 2;
frame = new JFrame();
frame.setSize(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle r1 = new Rectangle();
Rectangle r2 = new Rectangle();
g.setColor(Color.BLUE);
g.fillRect(x, 10, 50, 30);
g.setColor(Color.RED);
g.fillRect(x2, 10, 50, 30);
if(r1.intersects(r2)){
g.drawString("HIT!!!!!", 250, 200);
}
t.start();
}
public void actionPerformed(ActionEvent e) {
if(x < 0 || x > 450) {
velx = -velx;
}
if(x2 < 0 || x2 > 450) {
velx2 = -velx2;
}
x -= velx;
x2 += velx2;
repaint();
}
public static void main(String args[]){
new f5();
}
}
答案1
得分: 0
-
矩形的坐标目前没有被定义,因此它们不会相交(比较始终返回
false
)。你只是在创建r1
和r2
,但没有定义任何内容。你应该使用构造函数new Rectangle(int x, int y, int width, int height)
对它们进行初始化。 -
一种方法是你可以创建一个类字段来存储矩形的坐标,重复检查它们的坐标以查看是否发生碰撞。
英文:
-
The coordinates of rectangles are not defined right now, so they won't intersect (the comparison always return
false
). You are just creatingr1
andr2
without defining anything. You should initialize them using constructornew Rectangle(int x, int y, int width, int height)
. -
One way is you can create a class field to store the coordinate of the rectangle, repeatedly check their coordinate to see whether they collide.
答案2
得分: 0
以下是翻译的内容:
你没有阅读过类 Rectangle
的无参数构造方法的 javadoc 吗?
> 构造一个新的矩形,其左上角位于坐标空间中的 (0, 0),宽度和高度都为零。
这意味着 r1
和 r2
的尺寸都是零,因此它们不能相交。在创建 r1
和 r2
时,你需要给它们指定尺寸。请注意,java.awt.Graphics
类中的 fillRect()
方法只是在屏幕上绘制区域,并与 r1
和 r2
无关。所以你需要将方法 paintComponent()
中的这两行代码:
Rectangle r1 = new Rectangle();
Rectangle r2 = new Rectangle();
改为:
Rectangle r1 = new Rectangle(x, 10, 50, 30);
Rectangle r2 = new Rectangle(x2, 10, 50, 30);
然后它们就会相交。
关于你的第二个问题。在方法 actionPerformed()
中,你需要检查矩形 r1
和 r2
是否相交,如果相交,你需要反转它们的移动方向,就像当其中一个矩形到达 JPanel
的边缘时所做的那样。为了实现这一点,你可以将 r1
和 r2
设为 f5
类的成员。
以下代码展示了如何实现你的两个需求,即确定矩形何时相交,以及当它们相交时使它们相互“弹跳”。
你只需要一个 Timer
实例,所以不应该在方法 paintComponent()
中每次都创建一个新的。你可以在 f5
类的构造函数中创建它一次。
请注意,f5
类的成员应该是实例成员,而不是静态成员。另外根据 Java 命名约定,类的名称应为 F5
。
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class F5 extends JPanel implements ActionListener {
private JFrame frame;
private Timer t;
private int x, velx, x2, velx2;
private Rectangle r1;
private Rectangle r2;
F5() {
t = new Timer(5, this);
x = 100;
x2 = 400;
r1 = new Rectangle(x, 10, 50, 30);
r2 = new Rectangle(x2, 10, 50, 30);
velx = 2;
velx2 = 2;
frame = new JFrame();
frame.setSize(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.setVisible(true);
t.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
r1 = new Rectangle(x, 10, 50, 30);
r2 = new Rectangle(x2, 10, 50, 30);
g.setColor(Color.BLUE);
g.fillRect(x, 10, 50, 30);
g.setColor(Color.RED);
g.fillRect(x2, 10, 50, 30);
}
public void actionPerformed(ActionEvent e) {
if (x < 0 || x > 450 || r1.intersects(r2)) {
velx = -velx;
}
if (x2 < 0 || x2 > 450 || r1.intersects(r2)) {
velx2 = -velx2;
}
x -= velx;
x2 += velx2;
repaint();
}
public static void main(String args[]) {
new F5();
}
}
英文:
Did you not read the javadoc for the no-arg constructor of class Rectangle
?
> Constructs a new Rectangle whose upper-left corner is at (0, 0) in the coordinate space, and whose width and height are both zero.
This means that r1
and r2
have zero size and hence they cannot intersect. You need to give r1
and r2
dimensions when you create them. Note that method fillRect()
, in class java.awt.Graphics
, simply paints a region of the screen. It has nothing to do with r1
and r2
. So you should change these two lines in method paintComponent()
Rectangle r1 = new Rectangle();
Rectangle r2 = new Rectangle();
to this:
Rectangle r1 = new Rectangle(x, 10, 50, 30);
Rectangle r2 = new Rectangle(x2, 10, 50, 30);
Then they will intersect.
Regarding your second question. You need to check, in method actionPerformed()
, whether the rectangles r1
and r2
intersect and if they do, you need to reverse the direction of movement – exactly as you do when one of the rectangles reaches the edge of the JPanel
. In order to do that, you could make r1
and r2
members of class f5
.
The below code shows how to achieve both your requests, i.e. determine when the rectangles intersect and have them "bounce" of each other when they do intersect.
You only require one instance of the Timer
, so you should not create a new one each time in method paintComponent()
. You can create it once, in the constructor of class f5
.
Note that the members of class f5
should be instance members and not static members. Also note that according to java naming conventions, the name of the class should be F5
.
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class F5 extends JPanel implements ActionListener {
private JFrame frame;
private Timer t;
private int x, velx, x2, velx2;
private Rectangle r1;
private Rectangle r2;
F5() {
t = new Timer(5, this);
x = 100;
x2 = 400;
r1 = new Rectangle(x, 10, 50, 30);
r2 = new Rectangle(x2, 10, 50, 30);
velx = 2;
velx2 = 2;
frame = new JFrame();
frame.setSize(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.setVisible(true);
t.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
r1 = new Rectangle(x, 10, 50, 30);
r2 = new Rectangle(x2, 10, 50, 30);
g.setColor(Color.BLUE);
g.fillRect(x, 10, 50, 30);
g.setColor(Color.RED);
g.fillRect(x2, 10, 50, 30);
}
public void actionPerformed(ActionEvent e) {
if (x < 0 || x > 450 || r1.intersects(r2)) {
velx = -velx;
}
if (x2 < 0 || x2 > 450 || r1.intersects(r2)) {
velx2 = -velx2;
}
x -= velx;
x2 += velx2;
repaint();
}
public static void main(String args[]) {
new F5();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论