Search code examples
javalibgdxgame-physics

What am I doing wrongly in calculating the projection of a ball (java and libgdx)


I am working on an Angry Birds-like game where the user can drag a ball to launch it in the opposite direction with power proportional to the duration of the drag. However, I'm encountering two problems. Firstly, the ball doesn't go in the opposite direction of the drag motion. Secondly, the new x position of the ball doesn't seem correct; it appears to be too close to the initial point. I am currently setting the new y position to always be 0 for testing purposes. Please note that I only want to teleport the ball to its new position and will handle the trajectory later. This is the concerned code:

  `      private void renderGame() {
    batch.begin();
    batch.draw(background, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    if (inputProcessor.isShotCompleted()) {
        /// Calculate the new ball position based on the shot parameters
        float power = inputProcessor.getPower();
        float angle = inputProcessor.getAngle();
        float initialBallX = inputProcessor.getBallX();
        float initialBallY = inputProcessor.getBallY();
        // Calculate the initial velocity components
        float velocityX = power * BALL_SPEED * MathUtils.cos(angle);
        float velocityY = power * BALL_SPEED * MathUtils.sin(angle);
        // Calculate the time of flight
        float time = (2 * power * MathUtils.sin(angle)) / 9.8f;
        // Calculate the new ball position
        float newBallX = initialBallX + (velocityX * time);
        float newBallY = 0;
        // Update the ball's position
        inputProcessor.setBallX(newBallX);
        inputProcessor.setBallY(newBallY);
        ballX = newBallX;
        ballY = newBallY;
        // Reset shot completion flag
        inputProcessor.isShotCompleted = false;
    }
    else{
        // Draw the ball at its current position with rotation
        float ballX = inputProcessor.getBallX();
        float ballY = inputProcessor.getBallY();
    }
    // Update the rotation angle of the ball
    rotationAngle = (rotationAngle + Gdx.graphics.getDeltaTime() * 100) % 360;
    batch.draw(playerCharacter, ballX - BALL_RADIUS, ballY - BALL_RADIUS,
            BALL_RADIUS, BALL_RADIUS, BALL_RADIUS * 2,
            BALL_RADIUS * 2, 1, 1, rotationAngle);
    batch.end();
}`

Heres the link to my code I have a problem with posting it on stackoverflow with format errors: https://pastebin.com/WMRB229i Initial Position of ball The trajectory I want to change the ball to (blue dashes) and the strength of the drag (white line) Final Position of ball

Edit: In general, it seems to be going in the same direction as the white line even though it should be the opposite. Additionally, rather than throwing the ball, it just acts like it shoots it down directly even though I shot it up


Solution

  • X velocity should be based on the pull the ball experiences along X axis.
    Y Velocity should be the pull the ball experiences along Y axis.

    xPull = ballRestPositionX - ballPulledPositionX yPull = ballRestPositionY - ballPulledPositionY

    Xvelocity = xPull * powerFactor * -1. 
    Yvelocity = yPull * powerFactor * -1. 
    

    (power factor 3 should let the ball travel 3 times more in the direction if time is 1 sec)

    I don't think, sin(Q) or Cos(Q) are required at this point of time.

    This way you can calculate the peak only after time (t).

    time T is proportional to the length of pull. Longer one pulls, more time it will travel.

    timeOfTravlel = SQRT(Xpull^2 + yPull^2) * someFactor.
    

    So destination peak will be

    ballNewX = ballPulledPositionX + timeOfTravel * xVelocity
    ballNewY = ballPulledPositionY + timeOfTravel * yVelocity
    

    For trajectory, apply some gravity. Break time into slices. Reduce velocity against gravity in each time slice and as we move in time velocity becomes closer to gravity and touches ground. That will be giving you trajectory.

    Typically calculations should be out of render method, ideally at ClickEvent or Time based update events.