Physics Basics: Velocity, Acceleration & Gravity
What You'll Learn
Physics is what makes games feel real. Without it, your characters float unnaturally, balls don't bounce, and nothing feels satisfying to interact with.
In this tutorial, you'll learn:
- How velocity creates movement
- How acceleration changes velocity over time
- How to simulate gravity realistically
- Building a bouncing ball simulation from scratch
Velocity: The Foundation of Movement
Velocity is simply "how fast something moves and in what direction". In 2D games, we
represent it with two values: vx (horizontal) and vy (vertical).
const ball = {
x: 100,
y: 100,
vx: 3, // Moving right at 3 pixels per frame
vy: 2 // Moving down at 2 pixels per frame
};
function update() {
// Apply velocity to position
ball.x += ball.vx;
ball.y += ball.vy;
}
function gameLoop() {
update();
render();
requestAnimationFrame(gameLoop);
}
Velocity values can be negative! A negative vx means moving left, and a negative
vy means moving up.
Acceleration: Changing Velocity
Acceleration is the rate at which velocity changes. Just like velocity changes position, acceleration changes velocity.
This is what makes a car speed up, a ball fall faster, or a rocket lift off. The key insight: acceleration affects velocity, velocity affects position.
const ball = {
x: 100,
y: 100,
vx: 0,
vy: 0,
ax: 0.1, // Accelerating right
ay: 0 // No vertical acceleration
};
function update() {
// Apply acceleration to velocity
ball.vx += ball.ax;
ball.vy += ball.ay;
// Apply velocity to position
ball.x += ball.vx;
ball.y += ball.vy;
}
Gravity: Constant Downward Acceleration
Gravity is just acceleration that always pulls downward. In games, we typically use a
constant value like 0.5 or 0.98.
Real gravity is 9.8 m/s². In games, we use smaller values because we're measuring in pixels per frame, not meters per second.
const GRAVITY = 0.5; // Downward acceleration
const ball = {
x: 200,
y: 50,
vx: 2,
vy: 0, // Starts with no vertical velocity
radius: 15
};
function update() {
// Apply gravity (constant downward acceleration)
ball.vy += GRAVITY;
// Apply velocity
ball.x += ball.vx;
ball.y += ball.vy;
}
Notice how GRAVITY is added to vy every frame. This means:
- Frame 1: vy = 0.5
- Frame 2: vy = 1.0
- Frame 3: vy = 1.5
- ...and the ball falls faster and faster!
Bouncing: Reversing Velocity
When a ball hits the ground, its velocity reverses. But in the real world, bouncing loses energy. We simulate this with a bounce factor.
const GRAVITY = 0.5;
const BOUNCE = 0.8; // 80% energy retained on bounce
const GROUND = 350; // Y position of the ground
function update() {
// Apply gravity
ball.vy += GRAVITY;
// Apply velocity
ball.y += ball.vy;
// Check ground collision
if (ball.y + ball.radius > GROUND) {
ball.y = GROUND - ball.radius; // Reset position
ball.vy = -ball.vy * BOUNCE; // Reverse and reduce velocity
}
}
Interactive Demo
See all these concepts in action! Click "Reset" to drop a new ball.
Complete Code
Here's the full bouncing ball simulation you can copy and use:
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// Physics constants
const GRAVITY = 0.5;
const BOUNCE = 0.8;
const FRICTION = 0.99;
// Ball object
const ball = {
x: canvas.width / 2,
y: 50,
vx: 3,
vy: 0,
radius: 20,
color: '#00FFFF'
};
function update() {
// Apply gravity
ball.vy += GRAVITY;
// Apply friction (air resistance)
ball.vx *= FRICTION;
// Update position
ball.x += ball.vx;
ball.y += ball.vy;
// Ground collision
if (ball.y + ball.radius > canvas.height) {
ball.y = canvas.height - ball.radius;
ball.vy = -ball.vy * BOUNCE;
}
// Wall collisions
if (ball.x - ball.radius < 0 || ball.x + ball.radius > canvas.width) {
ball.vx = -ball.vx * BOUNCE;
ball.x = Math.max(ball.radius, Math.min(ball.x, canvas.width - ball.radius));
}
}
function render() {
// Clear canvas
ctx.fillStyle = '#0A0A12';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw ball with glow effect
ctx.shadowColor = ball.color;
ctx.shadowBlur = 20;
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
ctx.fillStyle = ball.color;
ctx.fill();
ctx.shadowBlur = 0;
}
function gameLoop() {
update();
render();
requestAnimationFrame(gameLoop);
}
gameLoop();
Challenge: Try These Modifications
- Multiple Balls: Create an array of balls with random starting positions
- Mouse Click: Spawn a new ball where the user clicks
- Variable Gravity: Use arrow keys to change gravity direction
- Ceiling Bounce: Make balls also bounce off the top
In the next tutorial, we'll learn about Collision Response – how to make objects push each other and react realistically when they collide!