Reading Time: 11 mins

Want to build games with realistic gravity, bouncing, and collisions? This comprehensive guide shows you exactly how to create physics-based games in Scratch using proven techniques that make your projects feel professional and fun to play.
Physics-based games simulate real-world mechanics like gravity, momentum, friction, and collisions. Instead of simply moving sprites with arrow keys, physics engines create natural, realistic movement that responds to forces.
Examples of physics-based games:
Why learn physics in Scratch? It transforms simple games into engaging experiences where movement feels real and unpredictable outcomes create replayability.
Before coding, understand these fundamental physics principles:
What it is: How fast and in what direction something moves
In Scratch:
set [x velocity] to (5) // Moving right at 5 pixels/frame
set [y velocity] to (-3) // Moving down at 3 pixels/frame
What it is: How velocity changes over time
In Scratch:
change [y velocity] by (-1) // Gravity pulls down
What it is: Forces that slow down movement
In Scratch:
set [x velocity] to ((x velocity) * (0.9)) // Reduces speed by 10%
What it is: What happens when objects touch
In Scratch:
if <touching [ground]?> then
set [y velocity] to (0) // Stop falling
end
Letβs build the simplest physics system β gravity that makes sprites fall.
// Create these variables for your sprite:
y velocity
when green flag clicked
set [y velocity] to (0)
forever
// Apply gravity
change [y velocity] by (-1)
// Move sprite
change y by (y velocity)
// Ground collision
if <touching [ground]?> then
set [y velocity] to (0)
// Position sprite on top of ground
repeat until <not <touching [ground]?>>
change y by (1)
end
end
end
What each part does:
change [y velocity] by (-1) β Gravity constantly pulls downchange y by (y velocity) β Applies the falling speedResult: Your sprite falls naturally and lands on platforms!
Build a complete physics system for platformer games with jumping, momentum, and collision.
x velocity // Horizontal speed
y velocity // Vertical speed
on ground // Boolean: touching ground or not
when green flag clicked
set [x velocity] to (0)
set [y velocity] to (0)
go to x: (-200) y: (0)
forever
// === HORIZONTAL MOVEMENT ===
if <key [right arrow] pressed?> then
change [x velocity] by (1)
end
if <key [left arrow] pressed?> then
change [x velocity] by (-1)
end
// Speed limit
if <(x velocity) > [8]> then
set [x velocity] to (8)
end
if <(x velocity) < [-8]> then
set [x velocity] to (-8)
end
// Apply horizontal movement
change x by (x velocity)
// Horizontal collision
if <touching [wall]?> then
change x by ((0) - (x velocity))
set [x velocity] to (0)
end
// Friction
set [x velocity] to ((x velocity) * (0.85))
// === VERTICAL MOVEMENT (GRAVITY) ===
change [y velocity] by (-1) // Gravity
// Apply vertical movement
change y by (y velocity)
// Ground collision
if <touching [ground]?> then
// Stop falling
repeat until <not <touching [ground]?>>
change y by (1)
end
set [y velocity] to (0)
set [on ground] to [true]
else
set [on ground] to [false]
end
// === JUMPING ===
if <<key [space] pressed?> and <(on ground) = [true]>> then
set [y velocity] to (15) // Jump strength
end
end
Features included:
Create objects that bounce realistically off surfaces.
when green flag clicked
set [x velocity] to (5)
set [y velocity] to (0)
forever
// Gravity
change [y velocity] by (-1)
// Movement
change x by (x velocity)
change y by (y velocity)
// Ground bounce
if <touching [ground]?> then
// Move out of ground
repeat until <not <touching [ground]?>>
change y by (1)
end
// Reverse and reduce velocity (bounce)
set [y velocity] to ((y velocity) * (-0.7))
// Stop bouncing if too slow
if <([abs v] of (y velocity)) < [2]> then
set [y velocity] to (0)
end
end
// Wall bounce
if <touching [wall]?> then
set [x velocity] to ((x velocity) * (-0.8))
end
// Air resistance
set [x velocity] to ((x velocity) * (0.99))
end
Physics principles:
-0.7 reverses direction and reduces energy (bounce loses height)abs function checks if bounce is too weak to continueLaunch objects that follow realistic arc trajectories.
Variables needed:
x velocity
y velocity
launch power
launch angle
// === AIMING PHASE ===
when green flag clicked
set [launch power] to (0)
forever
// Aim with mouse
point towards [mouse-pointer]
set [launch angle] to (direction)
// Charge power
if <mouse down?> then
change [launch power] by (1)
if <(launch power) > [20]> then
set [launch power] to (20)
end
end
end
// === LAUNCH ===
when [space] key pressed
set [x velocity] to ((launch power) * ([cos v] of (launch angle)))
set [y velocity] to ((launch power) * ([sin v] of (launch angle)))
broadcast [launch projectile]
// === FLIGHT PHYSICS ===
when I receive [launch projectile]
repeat until <touching [ground]?>
// Gravity
change [y velocity] by (-0.5)
// Movement
change x by (x velocity)
change y by (y velocity)
// Air resistance
set [x velocity] to ((x velocity) * (0.98))
// Rotation follows trajectory
point in direction ((90) + ([atan v] of ((y velocity) / (x velocity))))
end
How it works:
cos and sin convert angle to X/Y componentsMake sprites realistically climb and slide down ramps.
when green flag clicked
set [x velocity] to (0)
set [y velocity] to (0)
forever
// Basic movement code here...
change x by (x velocity)
// === SLOPE HANDLING ===
if <touching [ground]?> then
// Try to climb slope
set [slope height] to (0)
repeat (8)
change y by (1)
change [slope height] by (1)
// If not touching anymore, we climbed the slope
if <not <touching [ground]?>> then
stop [this script]
end
end
// Slope too steep - push back
change y by ((0) - (slope height))
change x by ((0) - (x velocity))
set [x velocity] to (0)
end
end
How slope detection works:
Combine all concepts into one reusable custom block.
Step 1: Create Custom Block
friction, bounce, gravityStep 2: Define the Block
define physics engine (friction) (bounce) (gravity)
// === GRAVITY ===
change [y velocity] by ((0) - (gravity))
// === APPLY MOVEMENT ===
change x by (x velocity)
change y by (y velocity)
// === HORIZONTAL COLLISION ===
if <touching [wall]?> then
repeat until <not <touching [wall]?>>
change x by (([abs v] of (x velocity)) / ((x velocity) * (-1)))
end
set [x velocity] to (0)
end
// === VERTICAL COLLISION ===
if <touching [ground]?> then
repeat until <not <touching [ground]?>>
change y by (1)
end
// Bounce
if <([abs v] of (y velocity)) > [2]> then
set [y velocity] to ((y velocity) * ((0) - (bounce)))
else
set [y velocity] to (0)
end
end
// === FRICTION ===
set [x velocity] to ((x velocity) * (friction))
Step 3: Use the Block
when green flag clicked
forever
physics engine (0.9) (0.7) (1) ::custom
// 0.9 = 90% friction (10% slowdown)
// 0.7 = 70% bounce (loses 30% energy)
// 1 = gravity strength
end
Advantages:
Prevent objects from falling infinitely fast.
// In your forever loop:
change [y velocity] by (-1) // Gravity
// Limit fall speed
if <(y velocity) < [-15]> then
set [y velocity] to (-15)
end
Allow jumping briefly after leaving platform (feels more responsive).
when green flag clicked
set [coyote timer] to (0)
forever
if <touching [ground]?> then
set [on ground] to (true)
set [coyote timer] to (5) // 5 frames grace period
else
set [on ground] to (false)
change [coyote timer] by (-1)
end
// Can jump if recently on ground
if <<key [space] pressed?> and <(coyote timer) > [0]>> then
set [y velocity] to (15)
set [coyote timer] to (0)
end
end
Register jump input slightly before landing.
when green flag clicked
set [jump buffer] to (0)
forever
// Detect jump button
if <key [space] pressed?> then
set [jump buffer] to (5) // Remember for 5 frames
else
change [jump buffer] by (-1)
end
// Land on ground
if <touching [ground]?> then
// If jump was pressed recently, jump now
if <(jump buffer) > [0]> then
set [y velocity] to (15)
set [jump buffer] to (0)
end
end
end
Examples: Cut the Rope, World of Goo
Key features:
Basic rope swing code:
when green flag clicked
set [rope length] to (100)
set [angle] to (0)
set [angular velocity] to (0)
forever
// Pendulum physics
set [angular velocity] to ((angular velocity) + (([sin v] of (angle)) * (0.1)))
change [angle] by (angular velocity)
// Damping (energy loss)
set [angular velocity] to ((angular velocity) * (0.99))
// Position at end of rope
set x to ((anchor x) + ((rope length) * ([cos v] of (angle))))
set y to ((anchor y) + ((rope length) * ([sin v] of (angle))))
end
Key features:
Basic car physics:
when green flag clicked
set [speed] to (0)
set [direction] to (90)
forever
// Acceleration
if <key [up arrow] pressed?> then
change [speed] by (0.5)
end
// Braking
if <key [down arrow] pressed?> then
change [speed] by (-0.8)
end
// Speed limits
if <(speed) > [10]> then
set [speed] to (10)
end
if <(speed) < [-5]> then
set [speed] to (-5)
end
// Steering (only works when moving)
if <key [right arrow] pressed?> then
change [direction] by ((speed) / (2))
end
if <key [left arrow] pressed?> then
change [direction] by ((0) - ((speed) / (2)))
end
// Movement
point in direction (direction)
move (speed) steps
// Friction
set [speed] to ((speed) * (0.95))
end
Examples: Angry Birds, Demolish
Key features:
Basic structure collapse:
// For each block in structure:
when I receive [impact]
if <(impact force) > [5]> then
// Break into pieces
repeat (5)
create clone of [debris]
end
hide
end
// Debris physics:
when I start as a clone
set [x velocity] to (pick random (-5) to (5))
set [y velocity] to (pick random (5) to (10))
show
repeat until <touching [ground]?>
physics engine (0.9) (0.5) (1) ::custom
end
wait (2) seconds
delete this clone
Symptoms: Character passes through solid platforms.
Cause: Moving too fast in one frame.
Solution: Pixel-perfect collision
// Instead of this:
change y by (y velocity)
// Do this:
repeat ([abs v] of (y velocity))
change y by (([abs v] of (y velocity)) / (y velocity))
if <touching [ground]?> then
change y by ((([abs v] of (y velocity)) / (y velocity)) * (-1))
set [y velocity] to (0)
stop [this script]
end
end
Symptoms: Sprite vibrates on ground.
Cause: Constant collision checks fighting with movement.
Solution: Collision tolerance
if <touching [ground]?> then
repeat until <not <touching [ground]?>>
change y by (1)
end
// Only stop if moving downward
if <(y velocity) < [0]> then
set [y velocity] to (0)
end
end
Symptoms: Character slides off moving surfaces.
Cause: Platform moves but character doesnβt inherit velocity.
Solution: Platform velocity transfer
// In platform sprite:
when green flag clicked
set [platform x velocity] to (2)
forever
change x by (platform x velocity)
if <on edge, bounce> then
set [platform x velocity] to ((platform x velocity) * (-1))
end
end
// In player sprite:
if <touching [platform]?> then
change x by (platform x velocity)
end
Symptoms: Objects bounce forever at same height.
Cause: Not losing energy on bounce.
Solution: Energy loss coefficient
if <touching [ground]?> then
set [y velocity] to ((y velocity) * (-0.7)) // Loses 30% energy
// Stop if bounce too weak
if <([abs v] of (y velocity)) < [1]> then
set [y velocity] to (0)
end
end
For custom blocks handling physics:
β
Enable in custom block settings
Benefit: Significant performance boost.
// Before creating clone:
if <(clone count) < [50]> then
create clone of [debris]
change [clone count] by (1)
end
// When deleting clone:
when I start as a clone
// ... physics code ...
delete this clone
change [clone count] by (-1)
Instead of complex costumes:
β Gravity feels right
β Collisions work properly
β Movement feels responsive
β Performance is good
Hereβs everything combined into one working game:
// === SETUP ===
when green flag clicked
set [x velocity] to (0)
set [y velocity] to (0)
set [on ground] to (false)
go to x: (-200) y: (50)
forever
handle movement ::custom
apply physics ::custom
end
// === MOVEMENT CUSTOM BLOCK ===
define handle movement
// Horizontal input
if <key [right arrow] pressed?> then
change [x velocity] by (1)
end
if <key [left arrow] pressed?> then
change [x velocity] by (-1)
end
// Speed limit
if <(x velocity) > [8]> then
set [x velocity] to (8)
end
if <(x velocity) < [-8]> then
set [x velocity] to (-8)
end
// Jumping
if <<key [space] pressed?> and <(on ground) = [true]>> then
set [y velocity] to (15)
end
// === PHYSICS CUSTOM BLOCK ===
define apply physics
// Gravity
change [y velocity] by (-1)
// Terminal velocity
if <(y velocity) < [-20]> then
set [y velocity] to (-20)
end
// Apply movement
change x by (x velocity)
change y by (y velocity)
// Horizontal collision
if <touching [wall]?> then
change x by ((0) - (x velocity))
set [x velocity] to (0)
end
// Vertical collision
set [on ground] to (false)
if <touching [ground]?> then
repeat until <not <touching [ground]?>>
change y by (1)
end
set [y velocity] to (0)
set [on ground] to (true)
end
// Friction
set [x velocity] to ((x velocity) * (0.85))
// Death condition
if <(y position) < [-180]> then
go to x: (-200) y: (50)
set [x velocity] to (0)
set [y velocity] to (0)
end
Essential physics concepts:
The physics formula:
Gravity + Velocity + Collision + Friction = Realistic Movement
Best practices:
Continue learning:
For young learners: At ItsMyBot, we teach physics concepts through engaging game projects designed for kids aged 5-15. From basic gravity to advanced collision systems, we break down complex concepts into fun, manageable lessons.
Beginner projects:
Intermediate projects:
Advanced projects:
Ready to master game development?
At ItsMyBot, we turn screen time into skill time through personalized, industry-level courses. From Scratch physics to Python game engines and roboticsβwe help kids aged 5-15 build real skills through hands-on creation.