我有一个简单的类,它创建一个框架,其中有一些球从侧面反弹。由于某种原因,球从框架的北侧,西侧和东侧反射得很好,但是稍微越过南侧,然后从它弹回。我在设置边界时考虑了球的大小,这在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;
}
}
}
答案 0 :(得分:0)
我认为,原因是xVel / yVel加入了移动。
当你靠近边境时,你会检查你是否已越过边界。如果没有,则添加速度。
如果到边框的距离为10且您的速度为15,则您将在边界框架上移动5。在下一步中,您将反转速度并反弹。在这种情况下,此举可能会分开。移动10,反向速度,移动5。
答案 1 :(得分:0)
问题是WIDTH和HEIGHT来自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;
}
要将球保持在你可能考虑的范围内:
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)
\|
/|\
/ | \
/ | \
(在pack()
末尾通常还有一个马蹄莲BallBounceFrame
来进行布局计算。)