C++ / Simulation
2D Physics Engine
A small C++ physics engine I built to understand what happens behind the scenes when objects collide.
- Role
- Solo project
- Timeline
- Apr - Jul 2025
- Stack
- C++ · SFML
- Status
- Completed
I had used physics engines before. I wanted to know what was happening inside them.
After working with Unreal Engine and Godot, I started wondering how their physics actually worked behind the scenes. When my informatics class began a project phase, it gave me the perfect excuse to find out by building a small engine of my own.
I chose C++ simply because I enjoyed writing it. SFML handles the graphics, so I could spend my time on the physics.
Before writing anything, I read through Box2D-Lite, a good example of how small and simple a physics engine can be. I started with circles because they are the simplest useful shape: no corners and no rotation, so I could focus on movement and collisions.
Every frame, the engine checks each pair of circles. If the distance between their centres is smaller than their radii combined, they collide. By then they are usually already overlapping, so I first push them apart and then calculate the bounce from their speed, mass and bounciness.
In my first version, the circles kept gaining energy out of nowhere, which should never happen in a real collision. It turned out I was applying the impulse twice.
There are 4 worlds: a ball pit for gravity and bouncing, a collision counter, an empty sandbox where you can build ramps out of static circles, and a billiards setup with one big chain reaction. You can switch between them, pause, toggle gravity, spawn moving or static circles and clear everything. Each world has its own values for gravity, drag and bounciness.
The collision counter is my favourite. I got the idea from a 3Blue1Brown lesson: if a ball that is 100 times heavier slides towards a light ball in front of a wall, they collide exactly 31 times - the first 2 digits of π. With gravity and drag turned off and perfectly elastic collisions, my engine got 31 on the first try.
The engine only handles circles, so there are no polygons, rotation or friction. It also checks every circle against every other one, which gets slow with lots of objects. If I continued, I would add rotation and friction first, then spatial partitioning so bigger scenes still run smoothly.
Explore the source code