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.
Want your child to go further? Explore ItsMyBot’s Little Coder — structured coding courses designed for kids!

Empowering children with the right skills today enables them to drive innovation tomorrow. Join us on this exciting journey, and let's unlock the boundless potential within every child.
© ItsMyBot 2026. All Rights Reserved.