Java 结束球的轨迹

Java 结束球的轨迹,java,swing,user-interface,graphics,2d,Java,Swing,User Interface,Graphics,2d,我有一个小的面板,通过改变它的x坐标,使球移动。 我希望球碰到画面的末端时向后移动。我的画面的宽度是300 根据fr.SetSize300300。 现在我对动画进行了如下编程: // when x == 300 // stop the timer 但是x=300似乎比它的宽度300大!这怎么可能。 **球从300 x 300帧中移出并变为不可见。 为什么会这样 这些是最终发生的情况的屏幕截图 第一张快照是移动球的快照,第二张快照显示球已经消失,第三张快照显示球在那个里 为什么会这样。?如何将

我有一个小的面板,通过改变它的x坐标,使球移动。 我希望球碰到画面的末端时向后移动。我的画面的宽度是300 根据fr.SetSize300300。 现在我对动画进行了如下编程:

// when x == 300
// stop the timer
但是x=300似乎比它的宽度300大!这怎么可能。 **球从300 x 300帧中移出并变为不可见。 为什么会这样

这些是最终发生的情况的屏幕截图

第一张快照是移动球的快照,第二张快照显示球已经消失,第三张快照显示球在那个里


为什么会这样。?如何将帧的端点设置为球的端点?

球的x坐标可能是它的左上边框吗?这就解释了为什么它会在框架外移动。还要考虑到你的框架周围有一些像素的装饰

也许你需要适应这样的环境

if (x == framewidth - decorationwidth - ballwidth) stopAnimation ();

x坐标指向图像的左上角?如果是这样,当x==300时,图像的其余部分将已经超出帧。你必须从等式中减去图像的宽度。

你需要考虑组件的可视大小。它不一定与您要求的尺寸相同

您可以使用getSize方法来确定组件的实际大小,但还需要调用getInsets来确定是否有任何空间已保留供borders使用。这将为您提供真实的可绘制区域:

public void paint(Graphics g) {
    Dimension size = getSize();
    Insets insets = getInsets();
    int available = size.width - insets.left - insets.right;
    // Draw stuff. Remember to offset by insets.left and insets.top!
    ...
}
还要记住,像Fillova这样的图形例程会向下绘制,并绘制到指定坐标的右侧,因此需要考虑球坐标的含义。它是球的中心,还是左边或右边?在计算球是否到达可绘制区域的侧面时,您可能需要减去球的宽度。

您必须为paintComponentGraphics g获得矩形

这就是条件


请注意,椭圆的x坐标和y坐标是椭圆的中心。因此,您需要从框宽中减去球宽。

请提供一些代码,以便我们可以查看。+1用于发布可测试的解决方案。我们都知道,红色球反弹得更快;顺便说一句-稍微调整源代码以退出JFrame上的\u关闭JFrame-以终止计时器线程。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class AnimationJPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private int cx = 0;
    private int cy = 150;
    private int cw = 20;
    private int ch = 20;
    private int xinc = 1;
    private int yinc = 1;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                AnimationJPanel panel = new AnimationJPanel();
                panel.setPreferredSize(new Dimension(400, 300));
                panel.animate();
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().add(panel);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public AnimationJPanel() {
        setLayout(new BorderLayout());
        JLabel label = new JLabel("This is an AnimationJPanel");
        label.setForeground(Color.RED);
        label.setHorizontalAlignment(SwingConstants.CENTER);
        add(label);
        setBackground(Color.BLACK);
        setForeground(Color.RED);
        setOpaque(true);
    }

    public void animate() {
        new Timer(15, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Rectangle oldCircle = new Rectangle(cx - 1, cy - 1, cw + 2, ch + 2);
                cx += xinc;
                cy += yinc;
                if (cx >= getWidth() - cw || cx <= 0) {
                    xinc *= -1;
                }
                if (cy >= getHeight() - ch || cy <= 0) {
                    yinc *= -1;
                }
                repaint(oldCircle);
                repaint(cx - 1, cy - 1, cw + 2, ch + 2);
            }
        }).start();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawOval(cx, cy, cw, ch);
    }
}
if ( end > (frameWidth-ballWidth) )  // end is any integer
  // stop the timer or do whatever