有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在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) 个答案

  1. # 1 楼答案

    所有Swing组件都有“边界”的概念。这是一个矩形区域,在该区域内“绘制”

    如果正确地控制了大小和位置,那么应该能够使用调用^{}返回的Rectanglecontains方法

    所以你的checkOverlap方法可能看起来像

    public void checkOverlap(BallComponent bc){
        if (getBounds().intersects(bc.getBounds())){
            bc.stopY();
            bc.stopX();
        }
    }
    

    您还需要确保在执行任何自定义绘制之前调用super.paintComponent,尤其是在使用从JComponent扩展的组件时。这将确保Graphics上下文为正确绘制做好准备

    更新

    有一连串的问题。基本上,你不是自己把组件放在父容器中(我以为你是这样做的),而是把每个组件放在父容器中,只“画”对象。。。这使生活更加困难

    相反,如果要使用组件,我会使用null布局(甚至可能使用JLayeredPane作为父容器)

    然后我会改变组件的物理位置,例如

    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.LayoutManager;
    import java.awt.Rectangle;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.geom.Ellipse2D;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.OverlayLayout;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class TestGame {
    
        public static void main(String[] args) {
            new TestGame();
        }
    
        public TestGame() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame();
                    JPanel panel = new JPanel();
                    panel.setLayout(null);
    
                    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();
    
                }
            });
        }
    
        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) {
            }
    
        }
    
        public class BallComponent extends JComponent {
    
            int xSpeed;
            int ySpeed;
    
            public BallComponent(int x, int y) {
                super();
                setBounds(x, y, 10, 10);
            }
    
            public void paintComponent(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;
    
                Ellipse2D.Double ball = new Ellipse2D.Double(0, 0, 9, 9);
                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() {
                int x = getX() + xSpeed;
                int y = getY() + ySpeed;
    
                setLocation(x, y);
    
                repaint();
            }
    
            public void stopY() {
                ySpeed = 0;
            }
    
            public void stopX() {
                xSpeed = 0;
            }
    
        }
    
        public class WallComponent extends JComponent {
    
            public WallComponent(int x, int y) {
                super();
                setBounds(x, y, 40, 40);
            }
    
            public void paintComponent(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;
    
                Rectangle wall = new Rectangle(0, 0, 40, 40);
                g2.setColor(Color.YELLOW);
                g2.fill(wall);
                g2.draw(wall);
            }
    
            public void checkOverlap(BallComponent bc) {
    
                System.out.println(" me: " + getBounds());
                System.out.println("you: " + bc.getBounds());
    
                if (getBounds().intersects(bc.getBounds())) {
                    bc.stopY();
                    bc.stopX();
                }
            }
        }
    }
    

    现在,您可以使用“绘制”对象,但在这种情况下,我会有一个BallWall的虚拟概念,可以在单个组件中绘制。这些对象需要提供有关位置和大小的信息,您可以再次使用Rectangle#intersects检查这些信息