Java-弹跳弹丸-如何反转垂直速度?

时间:2018-12-05 05:53:00

标签: java animation graphics

我正在尝试用Java弹跳球,但是我正在努力弄清楚如何 当球击中视口时反转球速度的垂直分量。我的主要问题(可能是愚蠢的)是我不了解 当速度公式对负值求平方时,速度分量的方向(在这种情况下为-)会影响总速度。感谢您的帮助。

目前,我将弹丸击中视口时以一定的偏移量重新发射弹丸,但这存在角度错误的问题。

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;

public class Trajectory5 extends JComponent {
private static final long serialVersionUID = 1L;

Timer timer; double x; double y; double vy; double vx;
double t = 0; double a = 70; double v = 40;
double offsetx = 0; double offsety = 400;
double xmult = 0;

public Trajectory5() {
    setFocusable(true);
    timer = new Timer(1, new TimerCallback()); 
    timer.start();}

    @Override
    public void paintComponent(Graphics g) {
        g.fillOval((int) x, (int) y, 10, 10);
    }

    protected class TimerCallback implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            t += .01;
            x = ((int) v*Math.cos(Math.toRadians(a)) * t + offsetx) + -xmult;
            y = getHeight() - ((int) v * Math.sin(Math.toRadians(a)) * t-.5 * 9.8 * (Math.pow(t, 2))) - offsety;
            vy = v * Math.sin(Math.toRadians(a)) - (t * 9.8);
            vx = v * Math.cos(Math.toRadians(a));

            System.out.println(vy + " " + vx);

            if (y > getHeight()) {
                offsetx = x;
                offsety = 0;
                v = Math.sqrt(Math.pow(vx, 2)+Math.pow(vy, 2));
                t = 0;
            }
            repaint();
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame(); frame.setSize(1000, 800);
        Trajectory5 canvas = new Trajectory5();
        frame.add(canvas); frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

1 个答案:

答案 0 :(得分:0)

因此,这里的问题实际上是结构性的问题,您正在使它变得比所需的更为复杂。这真的比起编程问题更像是数学。

您的x和y坐标从某个位置开始,然后您必须根据某个因素进行调整。您将根据a)调整位置。当时的速度,以及c)。基于您使用的单位的任意分数

要逐步执行这些步骤,实际上取决于您在做什么,但是简单起见,假设您已经完成了vx和vy计算(可以自己弄清楚),actionPerformed看起来像:

public void a...{
    deltaX = vx * getTimeFraction();
    deltaY = vy * getTimeFraction();
    ...
}

deltaXdeltaY是您要移动球的实际距离。因此,要移动它,我们必须将其应用于实际的x和y变量。

public void a...{
    deltaX = vx * getTimeFraction();
    deltaY = vy * getTimeFraction();

    x += deltaX;
    y += deltaY;
}

这将分别移动x和y,deltaX和deltaY距离。请注意,如果deltaX为负数,它将向左移动;如果deltaY为负数,它将向下(或向上移动,具体取决于您确定为负数)

我们快完成了,因此我们现在必须定义getTimeFraction()

public double getTimeFraction(){
    return 1 / iterationsPerSecond;
}

iterationsPerSecond将被定义为您每秒所需的小动作。

这涵盖了所有动作,但是在此之前,您需要定义vx和vy是什么,因此最终结果将类似于:

public void a...{
    calculateVelocities();

    deltaX = vx * getTimeFraction();
    deltaY = vy * getTimeFraction();

    x += deltaX;
    y += deltaY;
}