Как применить гравитацию при падении объекта?

У меня есть объект (который представляет собой мяч), расположенный в верхней части экрана, который падает прямо, когда я запускаю программу. Проблема в том, что мяч падает с постоянной скоростью, я хочу, чтобы он падал с ускорением под действием силы тяжести, и когда он достигнет земли, я хочу, чтобы он отскочил еще несколько раз, прежде чем перестанет двигаться. Может ли кто-нибудь помочь мне в этом?

Вот что я пробовал:

public class Balls
{
private double x;
private double y;
private double speed;
private double mass;
private final double gravity = -9.8;
private final double width = 100;
private double height = 100;
private final Board board;
private boolean isFalling = false;
private double distance_y;
private double distance_x = 0;

public Balls(double x, double y, double speed, double mass, Board board)
{
    this.x = x;
    this.y = y;
    this.board = board;
    this.speed = convertToMeterSpeed(speed);
    this.mass = mass;

}

private double convertToMeterSpeed(double speed)
{
    return speed / 3.6;
}

public void moveBall(long dt)
{

    double time = dt / 1e9; // seconds
    double diameter_y = height / 2.0;
    double radius = (diameter_y / 2.0);
    double velocity_y = speed * dt / 1e9;
    distance_y = board.getHeight() - y;

    if (distance_y - radius > 0)
    {
        isFalling = true;
    }

    if (isFalling)
    {
        if (distance_y >= height)
        {
            distance_y = distance_y + (0.5 * gravity * (time * time));  // represents the 1/2,
            distance_y = board.getHeight() - height;
            y += velocity_y;
        }

        else
        {
            isFalling = false;
        }

        try
        {
            Thread.sleep(10);
        }
        catch (InterruptedException e)
        {

        }
    }
}


public void render(Graphics2D g2d)
{
         g2d.fillOval((int) x, (int) y, (int) width, (int) height);

}
}

person papski    schedule 09.11.2011    source источник


Ответы (3)


скорость = v0 + gt ^ 2/2,

куда

v0 - начальная скорость

g = 9,81 на Земле.

t - время

Теперь вы можете рассчитать скорость в любой момент.

person AlexR    schedule 09.11.2011
comment
Это правильно? Разве это не формула v = u + (a * t) - person Ajil O.; 27.10.2017

Вероятно, вы захотите определить максимальную скорость (конечную скорость), чтобы ваш мяч не разгонялся до огромной скорости. Гравитация ускоряется со скоростью 9,8 м / с / с. Как только мяч ударяется о «землю», вы просто меняете скорость и обновляете текущее положение, чтобы заставить его отскочить, затем на следующей итерации сила тяжести будет применена снова, чтобы он снова опустился. В конце концов, скорость упадет до 0, поскольку мяч не так сильно отскакивает и остановится.

Вот (непроверенный) пример:

private static final double GRAVITY = 9.8;
private static final double TERMINAL_VELOCITY = 100;
private double speed;
private int current_y;

public void fallAndBounce() {
    speed = speed + GRAVITY;

    if (speed > TERMINAL_VELOCITY) { speed = TERMINAL_VELOCITY; }

    if (current_y >= bottomOfScreen)
    {
        //We have hit the "ground", so bounce back up. Reverse
        //the speed and divide by 4 to make it slower on bouncing.
        //Just change 4 to 2 or something to make it faster.
        speed = -speed/4; 
    } 
    current_y += speed; 
}
person Deco    schedule 09.11.2011
comment
вы имеете в виду, что я должен сделать итерацию? - person papski; 10.11.2011
comment
Ваш мяч, скорее всего, в настоящее время будет анимироваться во время какого-либо цикла, поэтому вам нужно добавить туда свое ускорение и отскок. - person Deco; 10.11.2011

Ваша проблема в том, что вы пытаетесь оживить падающий мяч, но вместо этого пишете алгоритм для определения его положения за определенное время.

Это означает, что вам следует исключить переменную времени dt полностью из уравнения и просто перемещать мяч при каждой итерации цикла следующим образом:

while (true)
{
    moveBall();
    render();
    try {
        Thread.sleep(10)
    } catch(InterruptedException e) {
        e.printStackTrace(); 
    }
}

Кроме того, немного измените переменные:

// Add this to your variables
private final double GRAVITY = -9.8;    // Final variables should be capitalized
private final double TERMINAL_VELOCITY = -30; // Whatever you want it to be 

Вот главное изменение:

public void moveBall()
{
    double diameter_y = height / 2.0;
    double radius = (diameter_y / 2.0);
    double velocity_y = speed * dt / 1e9;
    distance_y = board.getHeight() - y;

    if (distance_y - radius > 0)
    {
        isFalling = true;
    }

    if (isFalling)
    {
        if (height < distance_y)
        {
            if (velocity_y <= TERMINAL_VELOCITY)
                velocity_y += GRAVITY;  // implementing acceleration (gravity)
                                        // just means adding it to velocity.
            y += velocity_y;
        }

На самом деле, я не знаю, как это могло работать раньше.

person michaelsnowden    schedule 02.11.2013