在java Swing中检测重叠对象
我试图制作一个程序,它有一个移动的球和一个平台,它将坐在上面。我也是java新手,我不知道当两个swing对象重叠时如何检测。我的代码如下所示,我想知道检测重叠对象的最佳方法是什么
键盘演示。爪哇:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class KeyDemo
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
JPanel panel = new JPanel();
LayoutManager overlay = new OverlayLayout(panel);
panel.setLayout(overlay);
final int FRAME_WIDTH = 800;
final int FRAME_HEIGHT = 600;
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("Move the Ball");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final WallComponent wc1 = new WallComponent(400, 400);
final BallComponent bc = new BallComponent(400, 300);
panel.add(wc1);
panel.add(bc);
frame.add(panel);
KeyboardController kc = new KeyboardController(bc);
frame.addKeyListener(kc);
frame.setVisible(true);
class AnimationListener implements ActionListener{
public void actionPerformed(ActionEvent event){
bc.tick();
//wc1.checkOverlap(bc);
}
}
ActionListener aListener = new AnimationListener();
final Timer timer = new Timer(1, aListener);
timer.start();
}
}
键盘控制器。爪哇:
import java.awt.*;
import java.awt.event.*;
public class KeyboardController implements KeyListener
{
BallComponent bComp;
public KeyboardController(BallComponent t)
{
bComp = t;
}
/** Handle the key pressed event from the text field. */
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == 38)
{
System.out.println("Pressed Up!");
bComp.moveUp();
}
if(keyCode == 37)
{
System.out.println("Pressed Left!");
bComp.moveLeft();
}
if(keyCode == 39)
{
System.out.println("Pressed Right!");
bComp.moveRight();
}
if(keyCode == 40)
{
System.out.println("Pressed Down!");
bComp.moveDown();
}
}
/** Handle the key released event from the text field. */
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == 38)
{
System.out.println("Released Up!");
bComp.stopY();
}
if(keyCode == 37)
{
System.out.println("Released Left!");
bComp.stopX();
}
if(keyCode == 39)
{
System.out.println("Released Right!");
bComp.stopX();
}
if(keyCode == 40)
{
System.out.println("Pressed Down!");
bComp.stopY();
}
}
public void keyTyped(KeyEvent e) {
}
}
球组件。爪哇:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class BallComponent extends JComponent
{
int xSpeed;
int ySpeed;
int x;
int y;
public BallComponent(int x, int y)
{
super();
this.x = x;
this.y = y;
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
Ellipse2D.Double ball = new Ellipse2D.Double(x-10,y-10,10,10);
g2.setColor(Color.RED);
g2.fill(ball);
g2.draw(ball);
}
public void moveLeft()
{
xSpeed=-1;
}
public void moveRight()
{
xSpeed=1;
}
public void moveUp()
{
ySpeed=-1;
}
public void moveDown()
{
ySpeed=1;
}
public void tick()
{
x=x+xSpeed;
y=y+ySpeed;
repaint();
}
public void stopY()
{
ySpeed=0;
}
public void stopX()
{
xSpeed=0;
}
}
墙组件。爪哇:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class WallComponent extends JComponent
{
int x;
int y;
public WallComponent(int x, int y)
{
super();
this.x = x;
this.y = y;
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
Rectangle wall = new Rectangle(x-40,y-40,40,40);
g2.setColor(Color.YELLOW);
g2.fill(wall);
g2.draw(wall);
}
public void checkOverlap(BallComponent bc){
if (this.contains(bc.getLocation())){
bc.stopY();
bc.stopX();
}
}
}
# 1 楼答案
所有Swing组件都有“边界”的概念。这是一个矩形区域,在该区域内“绘制”
如果正确地控制了大小和位置,那么应该能够使用调用^{} 返回的
Rectangle
的contains
方法所以你的
checkOverlap
方法可能看起来像您还需要确保在执行任何自定义绘制之前调用
super.paintComponent
,尤其是在使用从JComponent
扩展的组件时。这将确保Graphics
上下文为正确绘制做好准备更新
有一连串的问题。基本上,你不是自己把组件放在父容器中(我以为你是这样做的),而是把每个组件放在父容器中,只“画”对象。。。这使生活更加困难
相反,如果要使用组件,我会使用
null
布局(甚至可能使用JLayeredPane
作为父容器)然后我会改变组件的物理位置,例如
现在,您可以使用“绘制”对象,但在这种情况下,我会有一个
Ball
和Wall
的虚拟概念,可以在单个组件中绘制。这些对象需要提供有关位置和大小的信息,您可以再次使用Rectangle#intersects
检查这些信息