繁体   English   中英

如何将Java Timer与毫秒实时关联,并相应地更新时间变量?

[英]How can I relate the Java Timer to milliseconds in real time, and update a time variable accordingly?

我一直在做一些关于弹丸运动的代码。 我启动了一个计时器t并为其使用了构造函数10,每个动作事件我都将0.01添加到初始化为0.00的时间变量中,以模拟经过的时间。 使用这段时间,我可以计算高度/距离等。我无法找出2个问题:

1)在控制台上打印当前时间时,它会一直移到许多小数位,然后运行代码。 2)即使不应该增加高度,我也会觉得这是由于加速度的正负所致。

(我的面板是1920x1080,面板动画占用80像素-这就是为什么它是1000-50)(1000半径)

使用图片: http//imgur.com/a/UF9eL

根据响应:1)忘记将vy乘以t。 2)使用DecimalFormat截断值

感谢@G_H; @Brick; @汤姆; @Diginoise代码:

package projectV1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class Animate extends JPanel implements ActionListener {

double x = 0;
double time = 0.00;
String timeText2 = "0";
double y = 1000;
double velY = 0.0;
double velX = 0.0;
public static Timer t;

public Animate() { // Constructor
    super(); 
}

public void start(String acceleration, String initialVelocity, String angle){



    new Ball(acceleration, angle, initialVelocity);

    t = new Timer(10, this);
    t.start();

    }


@Override
 public void actionPerformed(ActionEvent e) {
    updateTime(); 
    move();


      }

 public void move(){ // HOlds the repaint method
        x = x + Ball.getVelX();
        Simulation.distanceText.setText(Double.toString(Ball.getDistance(time))); // Some of these are just checks for me in the gui
        Simulation.velocityText.setText(Double.toString(time));
        y = y- Ball.getVelY(time);
        Simulation.heightText.setText(Double.toString(Ball.getHeight(time)));



        repaint();
    }

 public void updateTime(){
     time= time + 0.01;

     System.out.println(Double.toString(time));  // Using this as a test to check the time output.
     timeText2 = Double.toString(time);
     Simulation.timeText.setText(timeText2);
     }


public void paintComponent(Graphics gg){
    super.paintComponent(gg);
    gg.drawRect(0, 0, 1920, 1000);
    Graphics2D g = (Graphics2D) gg;

     Ellipse2D.Double shape = new Ellipse2D.Double(x, y-50.0, 50, 50);
        g.fill(shape);

    // g.fillOval(x, y-50, 50, 50);

     }
}

``球类''中的代码

public Ball(String acceleration, String angle, String initialVelocity ) {

    Ball.acceleration = acceleration;
    Ball.initialVelocity = initialVelocity;
    Ball.angle = angle;
}


public static double getVelX(){ //  This stays constant throughout the program
    double velX = 0.0;
    int u = Integer.parseInt(initialVelocity);
    double ang = Double.parseDouble(angle);
    velX = u*(Math.cos(ang));
    return velX;

}

public static double getVelY(double time ){

    double velY = 0.0 ;
    double ang, acc = 0;
    int u = 0;
    ang = Double.parseDouble(angle);
    acc = Double.parseDouble(acceleration);
    u = Integer.parseInt(initialVelocity);

    velY = u*(Math.sin(ang))- (acc*time);
    return velY;
}

public static double getDistance(double time){
    double distance = 0;
    double ang = 0;
    int u = 0;
    ang = Double.parseDouble(angle);

    u = Integer.parseInt(initialVelocity);
    distance = (u*time)*(Math.cos(ang));

    return distance;


}
public static double predictedTime(){
    double ptime = 0;
    double ang = 0;
    ang = Double.parseDouble(angle);
    int u = Integer.parseInt(initialVelocity);
    ptime = ((u*u)*(Math.sin(ang)*Math.sin(ang))/(2*9.81));

    return ptime;
}

public static double getHeight(double time ){
    double height;
    double ang, acc;
    int u = 0;
    ang = Double.parseDouble(angle);
    acc = Double.parseDouble(acceleration);
    u = Integer.parseInt(initialVelocity);
    height = u*(Math.sin(ang))-(0.5*acc*(time*time));

    return height;


}

1)在控制台上打印当前时间时,它会一直移到许多小数位,然后运行代码。

这是由于小数的二进制表示。 假设我们尝试用小数表示1/3,则得到0.333333。扩展是无限的,没有有限的表示。 0.01(1/100)的有限表示形式为十进制,但没有二进制形式。 因此,如果您输入double d = 0.01; 知道内部二进制表示形式是一个近似值,而不是精确值。 您将需要将输出截断为带有小数位数的某个值。 类DecimalFormat以特定格式输出值。

2)即使不应该增加高度,我也会觉得这是由于加速度的正负所致。

检查这一部分: velY = u*(Math.sin(ang))- (acc*time);

u是一个竞争者。 sin(ang) acc*time只会增加。 因此,velY将线性变化是有道理的。 您已发布以下内容:

垂直位移公式

它表示Sy = Vy*t - 0.5*g*t² ,然后表示Vy = u*sin(ang) 等式的展开缺少时间分量。 应该是这样: velY = (u*(Math.sin(ang))- (acc*time)) * time; 或(理论上相同) velY = u*(Math.sin(ang))*time - (acc*time*time); 请注意, acc必须为1/2 g。 如果提供g作为加速度,则需要acc*time*time 垂直位移公式acc*time*time乘以0.5。

最后要注意的是,将各种字段放入Ball类的静态字段中,然后在构造函数中进行分配。 最好不要这样做。 使字段Ball的accelerationinitialVelocityangle 实例字段(它们可以是最终的,因为它们不会改变)(使它们成为最终值),并使方法变为非静态。 例如,这将允许您模拟多个球,因为它们的值对于它们而言仍然是本地的,而不是共享的类状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM