Java 设置动画球的边界

Java 设置动画球的边界,java,animation,Java,Animation,我有一个简单的类,它创建了一个框架,其中包含一些从侧面反弹的球。出于某种原因,球在画面的北面、西面和东面反弹得很好,但在从画面反弹之前,球会稍微越过南侧。我在设置边界时考虑了球的大小,这在x轴上效果很好,但在y轴上效果不好 import javax.swing.*; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import j

我有一个简单的类,它创建了一个框架,其中包含一些从侧面反弹的球。出于某种原因,球在画面的北面、西面和东面反弹得很好,但在从画面反弹之前,球会稍微越过南侧。我在设置边界时考虑了球的大小,这在x轴上效果很好,但在y轴上效果不好

import javax.swing.*;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;

public class BallBounceFrame
{

public static void main(String[] args)
{
    new BallBounceFrame();
}

JFrame frame;   
static int WIDTH = 500;
static int HEIGHT = 500;

public BallBounceFrame()
{   
    frame = new JFrame("Ball Bounce Frame");
    frame.setSize(WIDTH, HEIGHT);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setResizable(false);
    BallCanvas c = new BallCanvas(5);
    frame.add(c, BorderLayout.CENTER);
    frame.setVisible(true); 
    c.animate();
}

class BallCanvas extends JPanel
{

    private static final long serialVersionUID = 1L;

    ArrayList<Ball> balls = new ArrayList<Ball>();

    public BallCanvas(int ballNum)
    {
        for(int i = 0; i < ballNum; i++)
        {
            balls.add(new Ball(20));
        }
    }

    public void paint(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.RED);
        for(Ball b : balls)
        {
            b.move();
            g2.fill(b);
        }
    }

    public void animate()
    {
        while(true)
        {
            try
            {
                frame.repaint();
                Thread.sleep(10);
            }
            catch(Exception e)
            {
                System.out.println(e);
            }
        }
    }
}

class Ball extends Ellipse2D.Float
{
    private int xVel, yVel;
    private int size;
    private int WIDTH = BallBounceFrame.WIDTH;
    private int HEIGHT = BallBounceFrame.HEIGHT;

    public Ball(int size)
    {
        super((int) (Math.random() * (BallBounceFrame.WIDTH - 20) + 1), (int) (Math.random() * (BallBounceFrame.HEIGHT - 20) + 1), size, size);
        this.size = size;
        this.xVel = (int) (Math.random() * 5 + 1);
        this.yVel = (int) (Math.random() * 5 + 1);          
    }

    public void move()
    {
        if(super.x < 0 || super.x > WIDTH - size) xVel *= -1;
        if(super.y < 0 || super.y > HEIGHT - size ) yVel *= -1;
        super.x += xVel;
        super.y += yVel;
    }
}
}
import javax.swing.*;
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.RenderingHints;
导入java.awt.Shape;
导入java.awt.event.*;
导入java.awt.geom.Ellipse2D;
导入java.util.ArrayList;
公共类BallBounceFrame
{
公共静态void main(字符串[]args)
{
新的BallBounceFrame();
}
JFrame框架;
静态整数宽度=500;
静态内部高度=500;
公共BallBounceFrame()
{   
框架=新的JFrame(“球反弹框架”);
框架尺寸(宽度、高度);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(空);
frame.setresizeable(false);
BallCanvas c=新的BallCanvas(5);
框架。添加(c,边框布局。中心);
frame.setVisible(true);
c、 制作动画();
}
类扩展了JPanel
{
私有静态最终长serialVersionUID=1L;
ArrayList balls=新的ArrayList();
公共BallCanvas(int-ballNum)
{
for(int i=0;iWIDTH-size)xVel*=-1;
如果(super.y<0 | | super.y>高度-大小)yVel*=-1;
super.x+=xVel;
super.y+=yVel;
}
}
}

我认为,原因是xVel/yVel加入了move

当你接近边境时,你会检查你是否已经越过边境。如果不是,则添加速度


如果到边界的距离为10,速度为15,则将在边界帧上移动5。在下一步中,你将反转速度并反弹。在这种情况下,移动可能会被拆分。移动10,反向速度,移动5。

问题是宽度和高度都来自JFrame。尤其是窗口标题标题会降低面板的高度。可以将面板边界/大小传递给球的移动

@Override
public void paint(Graphics g)
{
    ...
        b.move(getSize());
    ...
}

public void move(Dimension panelSize)
{
    if (x < 0 || x > panelSize.getWidth() - size) xVel *= -1;
    if (y < 0 || y > panelSize.getHeight - size) yVel *= -1;
    x += xVel;
    y += yVel;
}
(通常也会在
BallBounceFrame
的末尾调用
pack()
,以进行布局计算。)

public void move(Dimension panelSize)
{
    x += xVel;
    y += yVel;
    if (x < 0) {
        x *= -1;
        xVel *= -1;
    } else if (x > panelSize.getWidth() - size) {
        x -= 2 * (x - panelSize.getWidth() - size);
        xVel *= -1;
    }
    if (y < 0) {
        y *= -1;
        yVel *= -1;
    } else if (y > panelSize.getHeight() - size) {
        y -= 2 * (y - panelSize.getHeight() - size);
        yVel *= -1;
    }
}
    \ |         (xVel == 5)
     \|
     /|\
    / | \
   /  |  \