what i learned last week: how to make a bouncing object using vanillajs part 2 animation
Tags: javascript
Published: 2021-08-24 18:34:59

Welcome to part 2 of [how to make a bouncing object using vanillajs](https://dev.to/reyes2981/what-i-learned-last-week-how-to-make-a-bouncing-object-using-vanillajs-part-1-drawing-the-object-5eea)! As you may recall, I'm creating a clone of Flappy Bird and I want the player to be controlled with the `spacebar`. This means that within my program I need to model physics! 
<img width="100%" style="width:100%" src="https://media.giphy.com/media/12n5MNdTPHGMoM/giphy.gif?cid=ecf05e47ipbgycsbbgec7obfegq4ighoor1a0gitio4q0fwq&rid=giphy.gif&ct=g">
**CODE SO FAR**
```
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const x = canvas.width / 2;
const y = canvas.height / 2;

Class Player {
  constructor(x, y, radius, color) { 
        this.x = x
        this.y = y
        this.radius = radius 
        this.color = color 
  }

  draw() {
        ctx.beginPath()
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
        ctx.fillStyle = this.color
        ctx.fill()
  }

}

const player = new Player(100, 100, 30, 'blue');
```
**PLAYER IN BROWSER**
![player object](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c550aabt2zyk2uqvv23v.png)

The first thing I did is add a gravity, velocity and lift property to the constructor of my `Player` class. The reason why I'm adding these properties is because I want my `player` [object](https://en.wikipedia.org/wiki/Object_(computer_science)) to be affected by physics like they would in the real world.  
```
Class Player {
  constructor(x, y, radius, color, gravity, velocity, lift) { 
        this.x = x;
        this.y = y;
        this.radius = radius; 
        this.color = color; 
        this.gravity = gravity;
        this.velocity = velocity;
        this.lift - lift;
  }
```
_PHYSICS REFRESHER_

[Gravity](https://www.britannica.com/science/gravity-physics), also called gravitation, in mechanics [is] the universal force of attraction acting between all matter.
![gravity](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lts7luno67kgm2p9xa11.jpg)

[Velocity](https://www.vocabulary.com/dictionary/velocity) [is the] distance traveled per unit time in one direction.
![velocity](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jfjm3b7zus0dsgbjtuff.png)

[Lift](https://www.grc.nasa.gov/www/k-12/airplane/lift1.html) occurs when a moving flow of gas is turned by a solid object. The flow is turned in one direction, and the lift is generated in the opposite direction, according to Newton's Third Law of action and reaction. Because air is a gas and the molecules are free to move about, any solid surface can deflect a flow. For an aircraft wing, both the upper and lower surfaces contribute to the flow turning. Neglecting the upper surface's part in turning the flow leads to an incorrect theory of lift.
![lift](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/drw9x8p5750u0ffwwqna.gif)

Next, I created the `up` class method which runs every time the user presses the `spacebar`. To create a "bouncing" effect I added the `player`s velocity plus lift and saved it to `this.lift`.

```
  up() {
    this.velocity = this.velocity + this.lift;
  }
```
Alrighty, next I created the class method -- `update`. This is where I compare `Player` properties versus where I'm actually manipulating the property on the screen
```
update() {
   // Update the state of the world for the elapsed time since last render
}
```
For each frame within our animation loop I'm going to set the `velocity` of `player` to `this.gravity` and the y coordinate to `this.velocity`.
```
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const x = canvas.width / 2;
const y = canvas.height / 2;

Class Player {
  constructor(x, y, radius, color, gravity, velocity, lift) { 
        this.x = x;
        this.y = y;
        this.radius = radius; 
        this.color = color; 
        this.gravity = gravity;
        this.velocity = velocity;
        this.lift = lift;
  }

  draw() {
        ctx.beginPath()
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
        ctx.fillStyle = this.color
        ctx.fill()
  }

  update() {
        this.velocity += this.gravity;
        this.y += this.velocity; 
  }

}

const player = new Player(100, 100, 30, 'blue', 0.6, 0, -15);
```

Next, I created the function `animate` which is responsible for the looping of the `player` object. How do I do this?
```
function animate() {

}
```
Inside of `animate` I'm using the [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) method which tells the browser that you wish to perform an animation and requests that the browser calls a specified function to update an animation before the next repaint. **The method takes a callback as an argument to be invoked before the repaint**.
```
function animate() {  
  requestAnimationFrame();
}
```
In the above example, what do I need to pass into `requestAnimationFrame` if I want to create a moving object? 
```
function animate() {  
  requestAnimationFrame(animate);
}
```
Now when I instantiate the function `animate` a looping effect will be created.
```
function animate() {  
  requestAnimationFrame(animate);
}

animate();
```
Lastly, I need to add an `EventListener` so that the user can control the `player` by pressing on the `spacebar`. The first argument I pass in is `keyup`. The second argument is a callback function that runs the class method `up` everytime the user presses `spacebar`
```
addEventListener('keyup', event => {
    if (event.code === 'Space') {
      player.up();
    }
  
})
```
VOILA!
```
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const x = canvas.width / 2;
const y = canvas.height / 2;

Class Player {
  constructor(x, y, radius, color, gravity, velocity, lift) { 
        this.x = x;
        this.y = y;
        this.radius = radius; 
        this.color = color; 
        this.gravity = gravity;
        this.velocity = velocity;
        this.lift = lift;

  }
  draw() {
        ctx.beginPath()
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
        ctx.fillStyle = this.color
        ctx.fill()
  }
  up() {
    this.velocity += this.lift;
    console.log(this.velocity); 
  }
  update() {
        this.velocity += this.gravity;
        this.y += this.velocity; 
  }
}

const player = new Player(100, 100, 30, 'blue', 0.6, 0, -15);

function animate() {  
  requestAnimationFrame(animate);
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  player.draw();
  player.update();
}

animate();

addEventListener('keyup', event => {
    if (event.code === 'Space') {
      console.log('Space pressed');
      player.up();
    }
  
})
```
If you've been following along you should see something like the **blue** object below with similar animation.
<img width="100%" style="width:100%" src="https://media.giphy.com/media/kv1WNKj4J4Nn70ZALP/giphy.gif">

<img width="100%" style="width:100%" src="https://media.giphy.com/media/8qqUcJZr7Ju2SWqPpk/giphy.gif?cid=ecf05e47flntfwleg2f7qnmlanh34ifbbuewd1oqyiud6oes&rid=giphy.gif&ct=g">

_**Fin**_