Search code examples
javascriptcanvasprocessingp5.js

How to create a simple gravity engine on javascript


I'm trying to make a simple animation in javascript using P5.js library. I would like to make a ball appear at some height and then let it fall down and make it bounce until it comes to a stop.

I'm not looking for a external library, just P5.

My code is this:

function Ball() {
    this.diameter = 50;
    this.v_speed = 5;
    this.ypos = height/2 - 100;
    this.xpos = width/2;

    this.update = function(){
        this.ypos = this.ypos + this.v_speed;
        this.ypos = constrain(this.ypos, this.diameter/2, height-this.diameter/2);
    }

    this.show = function(){
        ellipse(this.xpos, this.ypos, this.diameter);
        fill(255);
    }
}

var ball;

function setup() {
    createCanvas(600, 600);
    ball = new Ball();
}

function draw() {
    background(0);
    ball.update();
    ball.show();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.js"></script>

Can someone help me? Thanks a lot


Solution

  • First you have to set the starting speed to 0 and define a gravity:

    this.v_speed = 0;
    this.gravity = 0.2;
    

    A working update method, which can be directly applied to your example, looks like this:

    this.starty = height/2 - 100;
    this.endy = height-this.diameter/2;
    
    this.update = function(){
    
        this.v_speed  = this.v_speed + this.gravity; 
        this.ypos = this.ypos + this.v_speed;
        
        if (this.ypos >= this.endy){
        this.ypos = this.endy;
            this.v_speed *= -1.0; // change direction
            this.v_speed = this.v_speed*0.9; 
            if ( Math.abs(this.v_speed) < 0.5 ) {
                this.ypos = this.starty;
            }
        }
    }
    

    The key is to reduce the speed and to change the direction when the ball bounces on the ground:

    this.v_speed *= -1.0;
    this.v_speed = this.v_speed*0.9;
    

    See also Bouncing Balls, struggling with getting more than 1 (processing).

    See the example, where I applied the suggestions to your original code:

    function Ball() {
        
      this.diameter = 50;
          this.v_speed = 0;
          this.gravity = 0.2;
          this.starty = height/2 - 100;
          this.endy = height-this.diameter/2;
          this.ypos = this.starty;
          this.xpos = width/2;
    
          this.update = function(){
    
              this.v_speed  = this.v_speed + this.gravity; 
              this.ypos = this.ypos + this.v_speed;
              
              if (this.ypos >= this.endy){
                this.ypos = this.endy;
                  this.v_speed *= -1.0; // change direction
                  this.v_speed = this.v_speed*0.9; 
                  if ( Math.abs(this.v_speed) < 0.5 ) {
                      this.ypos = this.starty;
                  }
              }
          }
    
          this.show = function(){
              ellipse(this.xpos, this.ypos, this.diameter);
              fill(255);
          }
    }
    
    var ball;
    
    function setup() {
        createCanvas(600, 600);
        ball = new Ball();
    }
    
    function draw() {
        background(0);
        ball.update();
        ball.show();
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>

    Demo