top of page

Breakout : Physics Engine

Members: 1
Date: 2021
Duration: 3 weeks
Breakout Diagram.png

Brief

Breakout is a game built with a custom-made physics engine in C++. This started out as an AIE project with one key thing in mind, exaggeration. I really wanted to take a spin on the assessment and decided to make a game based on Atari's classic, Breakout, but with a bit more of a chaotic take. 

​

​

​

​

​

Systems

Level Layout

When I was sorting out the layout of the level, a realisation came to mind. I couldn’t control the behaviour of the ball. So, if I make the ball land on the edge of the platform, the behaviour would be the same every time. Usually, in Breakout, hitting the edge means the ball will bounce off in a wider angle. The truth is, that isn’t how Physics work. When an object collides against a flat surface, no matter the angle it begins in, it would return in the same angle. To get a better picture in mind, the incoming angle is always perpendicular to the aftermath angle. The Physics engine I’m currently using is a close resemblance to how physics should be replicated. So, the thought comes to mind. How do they do it?   

 

A way I did approach this is by altering the shape of the platform. I’ve got a class called Box, which creates a box object in the scene. So why not take advantage of that? I created a series of boxes and applied an offset and rotation to some of them, so that the overall shape would be something like this. A box with flat surfaces set with some surfaces being placed in steeper angles. As shown below:

Platform.PNG
Perpendicular example.png

Considering the angle returned is always perpendicular to the original angle, this method allows the player to better control the ball.

Layer System 

The next obstacle for this project was figuring which objects can collide against each other. Since I wanted to showcase as much of the physics engine as possible, I wanted the blocks to fly offscreen, phasing through the walls. It adds an exaggeration to the gameplay, which is the ideology I wanted to achieve. 

 

To achieve this, I would require a system that is similar to Unity’s layer collision matrix. It tells the object what it can interact with. For example, if I wanted a box and circle to interact with each other, I would enable their layer collision. However, if I wanted a box and another box to ignore each other, I would simply disable their collision, causing them to phase through each other. 

 

I first defined a vector of PhysicsObject pointers and called it m_layer. This is called whenever a new PhysicsObject is created. The vector adds a newly created PhysicsObject to a slot specified by the layer. 

m_layers.PNG
addActor.PNG

I then defined a 2 dimensional array of booleans called m_layerCheck. This is responsible for setting the collision between the two objects. After creating all objects for the scene, I call initialiseLayerMatrix, as seen below. The ball is set to layer 0, the player is set to layer 1, and so forth. 

m_layerCheck.PNG
initialisedLayerMatrix.PNG
setUpLayer.PNG

When an object hits another object, regardless whether their collision against each other is turned off, checkForCollision is called. This is where the layer system is utilised. The function cycles through all layers and using m_layerCheck, compares the two layers. If both the layers have collision enabled, then the function proceeds to apply the necessary physics. 

Garbage Collector 

The next step was polishing the game further and ensuring the gameplay was smooth. I tested the game and realised there were sudden frame drops, and they would increase dramatically the more power ups I collected. This was all happening because I never deleted the power up blocks after they had gone offscreen. As a result, each object that had gone offscreen, had their position updated every fixedUpdate. The objects are still moving, even out of the player’s sight. This was the result of the game’s poor performance. 

 

To counter the problem, I had set up a class called GarbageCollector, which is responsible for handling the deletion of objects. I have first defined two vectors that hold a collection of PhysicObject pointers, and called them m_objectCollector and m_layerCollector.

garbageCollector.PNG

I then have the GarbageCollector maintain the layers in m_layer, because I would need to change an object’s layer at runtime. For example, when the player’s ball hits a block, I change the block’s layer to a different layer so that the ball wouldn’t be able to hit it again. That block’s previous layer gets added to the GarbageCollector’s m_layerCollector. 

​

As for maintaining the PhysicObject itself, I call the garbage collector when the objects are no longer needed. For example, when the power up box collides against either the player or the ground, it gets added to the GarbageCollector’s m_objectCollector.

 

The GarbageCollector then cycles through both vectors and deletes the objects every update. 

Power Up System

With the basics of the gameplay all set up, the next step was to ensure gameplay felt good. How could that be done? I realised other iterations of Breakout use power ups as a way to make the gameplay more engaging. So why not give that a shot? Let’s crank up the gameplay.

 

When the level is created, I create multiple rows of blocks, all coloured differently. For the sake of simplicity, I have assigned all pink blocks to hold a power up. Every time I assign a power up to a pink block, a vector called, powerUpBoxes, gets added a new power up. 

powerBoxes push back.PNG

The powerUpBoxes vector holds a collection of power up boxes that have not yet been instantiated. So, if the player hits a pink block, it spawns a power up box from that collection, and it begins to fall towards the player. 

power up box instantiate.PNG

As for the power ups themselves, the game offers two different types of power ups. They are randomised during the level set up process. So, when the player collides against a power up box, the box gets destroyed and the power up is activated. Here, we determine what the power up was from the box we destroyed. 

setPlayerPowerUp.PNG

If it’s a zero, the power up is a big ball, and if it’s 1, the power up is a ghost ball. Don’t mind what 2 was. I was originally going to have three power ups, but I couldn’t come up with a cool yet simple power up. So, we’ll stick with two for this little project. 

 

A deeper dive into the power ups. The two functions, setBigBall and setGhostBall don’t share any commonalities besides being actual power ups.

 

setBigBall activates a timer and increases the ball’s radius. When the timer is up, the ball returns to its original radius.

 

The setGhostBall function is a bit more complex. It creates a new GhostBall, an object just like the player’s ball except it's pink. Actually, not only pink, but the player is allowed to lose them. There is no game over from accidentally letting them pass. Once they do pass, they are removed from a vector called ghostBallList, which is used to keep track of them.

 

There is no limit to these power ups. If you’re lucky enough, you can get the ball to remain big for what seems like a ridiculous amount of time, or spawn heaps of ghost balls, provided you can keep track of them all.

Demo

bottom of page