Welcome to part 2 of how to make a bouncing object using vanillajs! 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!
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');
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 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, also called gravitation, in mechanics [is] the universal force of attraction acting between all matter.
Velocity [is the] distance traveled per unit time in one direction.
Lift 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.
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 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.
Fin
Top comments (0)