Hudoyo Danumurti
Hudoyo Danumurti

Reputation: 75

Jquery, How to make smooth jump animation?

I make a game which is there's a ball and some blocks to hold that ball from falling. I use setInterval method to make the gravitation for the ball

setInterval(function(){
ball.offset({top: ballMoveY += gravitation});
$("p").html(ballMoveX + '<br>' + ballMoveY + '<br><br>' + blokPos + '<br><br>' + gravitation);
if (ballMoveY > blok4Y+20){alert('game over'); return ballMoveY = 0; return ballMoveX = 0};
if ((ballMoveY == blok1Y && ballMoveX < blok1X && ballMoveX > 2) ||
    (ballMoveY == blok2Y && ballMoveX < blok2X && ballMoveX > 15) || 
    (ballMoveY == blok3Y && ballMoveX < blok3X && ballMoveX > 110) || 
    (ballMoveY == blok4Y && ballMoveX < blok4X && ballMoveX > 325)){

    return gravitation = 0; 
}
else {return gravitation = 5;};
}, 5);

But I can't make the jump to be smooth. The jumping is start from the top point, not animate from bottom then up and then fall. I use spacebar keyup to trigger the ball to jump, and arrow keys to move the ball right and left. This is the jumping code:

$(window).keyup(function(e){
    if (e.which === 32 && gravitation == 0){
        return gravitation -= 200;
    }
})

Here's the full code https://jsfiddle.net/b2orwnrz/

Upvotes: 0

Views: 1533

Answers (2)

Julien Gr&#233;goire
Julien Gr&#233;goire

Reputation: 17144

Gravity is basically the rate of change of speed in time, so in order to simulate gravity, you would have to add a speed variable to your system. This speed would be changing according to gravity, and the speed would be used to change position of your object. And a jump is a instantaneous change of speed in a direction opposite to gravity.

Working that way would allow you to create a smooth jump effect, but would require you to modify a bit the rest of your code. But something like this should give you ideas:

   $(document).ready(function () {

        var ball = $("#ball");
        ballPos = ball.position();
        ballMoveX = ballPos.left;
        ballMoveY = ballPos.top;
        gravitation = 3, speed = 0; //You declare speed as well as gravitation. Setting speed to 0 is the equivalent of dropping a ball without any force.

        var blok1 = $("#blok1").offset();
        blok1Y = blok1.top;
        blok1X = parseInt(blok1.left) + parseInt($("#blok1").css("width"));
        var blok2 = $("#blok2").offset();
        blok2Y = blok2.top;
        blok2X = parseInt(blok2.left) + parseInt($("#blok2").css("width"));
        var blok3 = $("#blok3").offset();
        blok3Y = blok3.top;
        blok3X = parseInt(blok3.left) + parseInt($("#blok3").css("width"));
        var blok4 = $("#blok4").offset();
        blok4Y = blok4.top;
        blok4X = parseInt(blok4.left) + parseInt($("#blok4").css("width"));

        blokPos = blok1Y + '<br>' + blok2Y + '<br>' + blok3Y + '<br>' + blok4Y + '<br>' + '<br>' + blok1X + '<br>' + blok2X + '<br>' + blok3X + '<br>' + blok4X;


        setInterval(function () {
            speed += gravitation; //The speed changes according to the gravitation. 
                                  //You can modulate the speed at which this rate changes by changing gravitation value. 
                                 //But if you want to stay close to reality, gravitation should be constant.
            ball.offset({
                top: ballMoveY += speed // The position changes according to speed. 
                                        //Speed is basically difference of position in time. 
                                        //Since this difference of time is taken care of with setInterval, 
                                        //you set difference of position directly with speed.
            });
            $("p").html(ballMoveX + '<br>' + ballMoveY + '<br><br>' + blokPos + '<br><br>' + speed);
            if (ballMoveY > blok4Y + 20) {
                alert('game over');
                return ballMoveY = 0;
                return ballMoveX = 0
            };
            //Since your position values are less precise than before you need 
            //to validate if they're greater than, not equal. 
            //You'll see that for now, this makes a strange effect of 
            //stopping the ball not exactly at the right place.
            if ((ballMoveY > blok1Y && ballMoveX < blok1X && ballMoveX > 2) || (ballMoveY > blok2Y && ballMoveX < blok2X && ballMoveX > 15) || (ballMoveY > blok3Y && ballMoveX < blok3X && ballMoveX > 110) || (ballMoveY > blok4Y && ballMoveX < blok4X && ballMoveX > 325)) {
                speed = 0; // IF ball is on block its speed gets back to 0
                gravitation = 0;// Here, normally it should stop movement, not change the gravity, 
                                //but this can be done this way. But if you were the refactorfurther, 
                                //you should clear the interval when the ball is stopped 
                                //and start it on keydown callback.
                return speed = 0;// Not sure you need to return anything...
            } else {
                return gravitation = 3;
            };
        }, 50);




        $(window).keydown(function (e) {
            if (e.which === 39) {
                ball.offset({
                    left: ballMoveX += 5
                });
            }
            if (e.which === 37) {
                ball.offset({
                    left: ballMoveX -= 5
                });
            }


        })

        $(window).keyup(function (e) {
            console.log(e.which, gravitation);
            if (e.which === 32 && gravitation == 0) {
                return  speed = -30;// That's where your jump happens. A jump is a force in up direction. 
                                    //A one time force will have the effect of changing the speed on one moment. 
                                    //Once the speed has changed, the gravitation continues to have 
                                    //an effect and makes the ball slow down, then fall.
            }
        })

    })

https://jsfiddle.net/3rfpL420/4/

Upvotes: 2

Federico M. Rinaldi
Federico M. Rinaldi

Reputation: 353

Instead of trying to create your own functions you can use the animate function provided by jQuery for example:

$('#ball').animate({'bottom':20}, bouncetime, 'easeInQuad');

I've created an example here: http://jsfiddle.net/xtggqcg5/1/

For the easing I'm using the easeInQuad that's available through jQuery UI but you can add your own easing function.

Upvotes: 1

Related Questions