[英]My Java Bouncing Ball Bounces up with a larger velocity
I'm making a simple Java program to bounce a ball up and down.我正在制作一个简单的 Java 程序来上下弹跳球。 The problem is that the ball bounces up higher than its starting point with each bounce.问题是每次弹跳时,球的弹跳位置都高于其起点。 I expect the ball to bounce back up exactly to the height that it started from.我希望球能准确地反弹回它开始的高度。
The ball physics can be found in the circle class in the doPhysics() method where I suspect the problem can be found球物理可以在 doPhysics() 方法的 circle 类中找到,我怀疑可以找到问题
import java.awt.*;
import java.util.*;
public class Main{
public static Frame frame = new Frame();
public static Physics physics = new Physics();
public static ArrayList<Circle> circles = new ArrayList<Circle>(); //array for the points
public static void main(String args[]) {
Circle circle = new Circle(100, 300, 50, Color.BLACK);
circles.add(circle);
run();
}
public static void run() {
physics.timer.start();
}
}
import java.awt.*;
public class Circle {
private int x;
private int y;
private double xAccel= 0;
private double yAccel = 0;
private double xVel= 0;
private double yVel = 0;
private Color colour;
private int radius;
public Circle(int x, int y, int radius, Color colour) {
setX(x);
setY(y);
setRadius(radius);
setColour(colour);
}
public void draw(Graphics2D g2d) {
g2d.setColor(colour);
g2d.fillOval(x, y, radius*2, radius*2);
}
public void doPhysics() {
hitGround();
System.out.println(yVel);
yVel += Physics.getGravity();
y -= yVel;
}
public void hitGround() {
if(y + radius*2 > Frame.panel.h ) {
yVel = -yVel;
}
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setColour(Color colour) {
this.colour = colour;
}
public void setRadius(int radius) {
this.radius = radius;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Color getColour() {
return colour;
}
public int getRadius() {
return radius;
}
}
import java.awt.*;
import javax.swing.*;
class Frame extends JFrame {
public static Panel panel;
public Frame() {
panel = new Panel();
this.setTitle("Fun");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(panel);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
}
class Panel extends JPanel {
public int w = 500;
public int h = 500;
public Panel() {
this.setPreferredSize(new Dimension(w, h));
this.setBackground(Color.red);
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
for(Circle circle : Main.circles) {
circle.draw(g2d);
}
}
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class Physics implements ActionListener {
private static double gravity = -.1;
public Timer timer;
public Physics() {
timer = new Timer(1, this);
}
public static double getGravity() {
return gravity;
}
@Override
public void actionPerformed(ActionEvent e) {
for(Circle circle : Main.circles) {
circle.doPhysics();
}
Main.frame.repaint();
}
}
The problem is mainly caused by using integer values for position ( x
and y
).该问题主要是由使用整数值作为位置( x
和y
)引起的。 On each iteration the values are rounded and the errors get accumulated.在每次迭代中,值都会被四舍五入并累积错误。
Solution: declare double x
and double y
and only use the rounded integer values for drawing.解决方案:声明double x
和double y
并且只使用四舍五入的整数值进行绘制。
Above should reduce the problem, but not completely solve it.以上应该可以减少问题,但不能完全解决。 The code is doing a rough integration over time ¹ by using the velocity calculated after the time interval (see Numerical Integration ).该代码通过使用在时间间隔后计算的速度随着时间¹进行粗略积分(请参阅数值积分)。 This can be improved by doing an average of the velocities before and after it was changed.这可以通过对改变之前和之后的速度进行平均来改善。 Roughly:大致:
double preVel = yVel;
yVel += Physics.getGravity();
y -= (preVel + yVel)/2;
which can be simplified (pure math) to:可以简化(纯数学)为:
yVel += Physics.getGravity();
y -= yVel - Physics.getGravity()/2;
This should work fine since the acceleration is constant.这应该可以正常工作,因为加速度是恒定的。 Not the case if the acceleration is also changing.如果加速度也在变化,则情况并非如此。 And it is also susceptible to precision errors being accumulated over time.而且它也容易受到随着时间累积的精度误差的影响。
1 - see Numerical integration and Temporal discretization 1 - 见数值积分和时间离散化
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.