Home » Linux » Fun » Raspberry Pi Pinball

DIY Raspberry Pi Powered Pinball Machine [Kitchen Build]

This article will show you how I built a DIY Raspberry Pi Powered Pinball game using GDevelop and an Arduino to add physical push-buttons to control the game.

GDevelop is a zero-code game development studio, so this article has almost no coding required.

I’ve been meaning to check out GDevelop for a while, so I’ve combined a simple GDevelop game with a 2-button Arduino game controller to make a little virtual pinball machine.  Here’s the finished product in action!

What We’re Building

As you can see in the above video, we are building a pinball game with a moving ball, moving flippers, and some on-screen elements that cause the displayed score to increase.

Raspberry Pi Pinball: Building the Game in GDevelop

First I’ll show you how I put the game together in GDevelop.  The game can be played in any web browser, so you can follow along even if you aren’t going to deploy it to a Raspberry Pi or build the arcade ‘machine’ itself.

As I mentioned, there is very little coding required to use GDevelop to make a game, so most of this article will be screenshot-orientated to show you how things are set up.

Installing GDevelop in Linux

Let’s get started by downloading GDevelop from:

https://gdevelop-app.com/download/

 

Download GDevelop for your Operating system - in our case, Linux.
Download GDevelop for your Operating system – in our case, Linux.
Following the instructions on the GDevelop download page to launch the game in Linux.
Following the instructions on the GDevelop download page to launch the game in Linux.
GDevelop running in Linux. That was easy.
GDevelop running in Linux. That was easy.

Creating the Pinball Game With GDevelop

GDevelop is really easy to use.  Your game is split into scenes (each one a separate visible play area) and you can drag and drop objects (game elements like players, enemies, and obsticles) onto the scene to place them.

Each object place has a set of properties which can be edited, and game logic can be added as events which respond to button presses or object collisions, or other conditions you may set.

Setting the Scene

This is the final goal - a pinball game set up in GDevelop.
This is the final goal – a pinball game set up in GDevelop.

Create a new GDevelop Project and call it Pinball.  You’ll be presented with a project with an empty scene called ‘New scene’ (simple a blank, black screen).

The following screenshots will show and explain how to set up the single scene used to create the pinball game.

Click on the menu icon in the top left of the screen to view game and scene options.
Click on the menu icon in the top left of the screen to view game and scene options.
Set a game and package name in the game properties.
Set a game and package name in the game properties.
Click on the (...) menu next to 'New scene' and view the scene properties.
Click on the (…) menu next to ‘New scene’ and view the scene properties, and set them appropriately for our Pinball game.
Create a global variable called 'Score' which will be used to keep track of the game score.
Create a global variable called ‘Score’ which will be used to keep track of the game score.

Adding the Game Objects

Now we need to add the game objects to the scene.  We’ll be adding 9 objects:

  • Ball
  • Apple
  • RFlip (Right Flipper)
  • LFlip (Left Flipper)
  • Bomb
  • Score
  • GreenLaser01 (Rotating obstacle)
  • TiledWall
  • TiledFloor

All of these objects were added from the asset store (mostly because I cannot draw).  The GDevelop asset store contains a bunch of objects and sprites you can use in your project for free.

You don’t have to use the same objects I have used.  I’ve simply found random game sprites that can work in a pinball context.  Sword sprites were used for the flippers, a random X shaped laser sprite was used for the rotating obstacle, apples for scoring objects, etc.

Adding new objects to the scene.
Adding new objects to the scene.
Browsing the asset store.
Browsing the asset store.

Setting Game Object Behaviour/Events

Below are screenshots showing how each game object is configured.  Note that some game objects have been renamed from their name used in the asset store.

Drag your objects into the play area to construct your pinball game – making walls, placing scoring objects, etc.

Then, edit the objects in the side bar to match those shown below to add the required game behavior to each object.

The behaviors will dictate things like collisions and physics, which will be used to make things move around when your game runs.

Ball

Ball properties.
Ball object properties.
Ball behaviors.
Ball behaviors.

Apple (Scoring Object)

Apple object.
Apple object properties.
Apple behaviors.
Apple behaviors.

RFlip (Right Flipper)

Right Flipper object.
Right Flipper object properties.
Right Flipper behavior.
Right Flipper behavior.

LFlip (Left Flipper)

Left Flipper object
Left Flipper object properties.
Left flipper behavior
Left flipper behavior.

Bomb (Ball Launcher)

Ball launcher object
Ball launcher object properties.
Ball launcher behavior
Ball launcher behavior.

Score

The score is a text object – drag it onto the play area.  Initially, it should be set to simply display the text ‘Score’ – the scene events added later will keep it up-to-date with the ‘Score’ global variable.

gdevelop pinball pi 9

Score object properties
Score object properties
Score object behavior.
Score object behavior.

GreenLaser01 (the Spinning Obstacle)

I could probably have named this object to something more useful, it escaped my notice until it was too late.

This object is just a random object from the asset store which I have set to rotate at the top of the play area to act as an obstacle.

Obstacle object properties.
Obstacle object properties.
Obstacle behaviour.
Obstacle behavior.

TiledWall

TiledWall is the object that will be used to make the side walls and roof of the pinball machine.  Drag 3 of them onto the scene and drag them to resize to create the walls.

TiledWall object properties.
TiledWall object properties.
TiledWall behaviors
TiledWall behaviors

TiledFloor

The TiledFloor object will also need to be resized to make the floor of the play area. It’s a separate object to the walls as it will have different behavior (that being to reset the ball position when the ball comes into contact with the floor) assigned in the scene behaviour later on.

TiledFloor object properties.
TiledFloor object properties.
TiledFloor object behavior.
TiledFloor object behavior.

The Scene is Populated – Adding Scene Events to Run the Game

The events attached to a scene can be used to dictate the overall game logic.  This pinball game is pretty simple, so there are only a few events to configure for the scene.

They will:

  • Add the joints to the flippers so that they rotate around the correct point
  • Add joints to the rotating GreenLaser01 object, which acts as a rotating obstacle
  • Keep the displayed in sync with the score variable
  • Move the flippers when keys are pressed
  • Move the ball to the starting position when they touch the floor (TiledFloor objects) of the game area
  • Launch the ball when it is in contact with the launcher (the Bomb object)
  • Increase the score when the ball contacts scoring objects (the Apple objects)
Here's how all of the scene events are configured to make the pinball game work.
Here’s how all of the scene events are configured to make the pinball game work.

Debugging and Testing

At any point, you can click on the little bug icon in the top left of the screen to test and debug your game.

Exporting Your Game

When you’re finished and happy with your pinball video game, you can export it so that it can be played outside of GDevelop.

There are a number of options – you can export to various devices and services.

I’ll be exporting to a Local folder so that I can copy the game to a USB stick and run it on a Raspberry Pi.

Exporting your game from GDevelop.
Exporting your game from GDevelop.
Export your game to a directory called 'pinball'.
Export your game to a directory called ‘pinball’.

GDevelop – What Just Happened?

There’s kind of a lot going on there!  All of the screenshots above show how I have populated GDevelop to create my pinball game.  It looks complicated, but there is no programming involved, just setting dropdowns and text fields.

For an explanation of what each field does, I recommend checking out the GDevelop documentation – they’ll be able to explain things better than I can!

Building the Pinball Machine: Hardware and Inputs

That takes care of the software side of things.  You can run the game now in GDevelop on your computer to try it out.

I decided to take things a step further and build a little cardboard arcade machine with buttons for the flippers, powered by a Raspberry Pi.

It’s a simple build process which should be achievable on your kitchen countertop with a few simple tools.

Raspberry Pi Pinball machine parts.
Raspberry Pi Pinball machine parts.

The parts used were:

  • Cardboard box
  • 2x push buttons
  • some wire
  • A pro-micro arduino clone (identifies itself as an Arduino Leonardo) to interface with the buttons
  • Glue gun
  • Raspberry Pi (You could also use your laptop or desktop computer if you don’t have a Pi)
  • 5 Inch HDMI LCD monitor

I won’t be building my Pi into the cardboard box – I keep mine mounted on a chopping board for easy access to the ports and to keep all of the wiring contained.

Game Buttons Schematic & Arduino Code

I wanted some real arcade style buttons on the side of the pinball machine, so I wired some to the Arduino in a simple circuit.

I probably could have wired the buttons the the GPIO pins on the Pi, but this solution is more universal, as the Arduino uses a USB connection it can also be plugged into a regular computer which doesn’t have GPIO pins if you aren’t using a Raspberry Pi.

Arduino Circuit for Buttons
Arduino Circuit for Buttons

The Arduino IDE software is used to write and upload code to your Arduino.  You can download it from:

https://www.arduino.cc/en/software/

Once the Arduino IDE is installed, upload the following code to your Arduino board.

//Pinball machine code for Arduino Pro Micro/Leonardo

//Import the Keyboard Library
#include <Keyboard.h>

//Define which pins the push-buttons are attached to
int lButtonPin = 2;
int rButtonPin = 3;

//Variables to keep track of the button state - 0 for not pressed, 1 for pressed
int lButtonState = 0;
int rButtonState = 0;

//Keyboard keys to map the buttons to
char lKey = 'z';
char rKey = 'x';

void setup() {
  //Set the button pins as inputs
  // PULLUP the input resistors so they read as high (1) unless grounded by the button being pressed
  pinMode(lButtonPin, INPUT_PULLUP);
  pinMode(rButtonPin, INPUT_PULLUP);

  //Wait 5 seconds before beginning - as this will emulate key presses, we might want the chance to re-flash code to the decice before it starts emulating keypresses
  delay(5000);
  
  //Initialize control over the keyboard
  Keyboard.begin();
}

void loop() {
  //Read the state of the buttons and set the button state.  Note that the inverse of the digitalRead result is assigned to buttonState with the use of the !
  //So, if the button pressed, it will digitalRead LOW (0), but the buttonState will be stored as 1
  lButtonState = !digitalRead(lButtonPin);
  rButtonState = !digitalRead(rButtonPin);

  //If buttonState is 1 for either button, emulate the keypress using the keyboard library
  if(lButtonState) Keyboard.press(lKey);
  if(rButtonState) Keyboard.press(rKey);

 // Delay 100ms then release any pressed keys
  delay(100);
  Keyboard.releaseAll();
}

The code is pretty simple – it tells the Arduino to emulate a keyboard.  When one of the push-buttons is pressed, the Arduino sends the corresponding key-press to the computer as if it has been pressed on the keyboard.  The same keys are mapped as the inputs in the game in the GDevelop scene events, so that a button press = action on screen.

Here's the little HDMI screen I'll be using in this project.
Here’s the little HDMI screen I’ll be using in this project.

Building the Pinball Machine

I’m going to run my Pinball machine from a Raspberry Pi 4 running Ubuntu Mate.

Installation instructions can be found here.

...and here's the Raspberry Pi 4 that will be controlling the action.
…and here’s the Raspberry Pi 4 that will be controlling the action.
The construction itself is pretty simple, I cut round holes in the sides for the buttons, and a big square hole in the top for the screen.
The construction itself is pretty simple, I cut round holes in the sides for the buttons, and a big square hole in the top for the screen. The Arduino is shown attached to the buttons.
Button!
Button!
Screen hole!
Screen hole!
Hot glue or any other adhesive can be used to hold everything in place.
Hot glue or any other adhesive can be used to hold everything in place.
hardware pinball pi 9
chopping board
seen keeping things tidy.” width=”1024″ height=”768″ /> Screen mounted in box. My Pi chopping board seen keeping things tidy.
There wasn't quite enough room for the power/HDMI cables coming out of the side of the screen, so I had to make a hole for them to poke out of the side.
There wasn’t quite enough room for the power/HDMI cables coming out of the side of the screen, so I had to make a hole for them to poke out of the side.
Setting the screen Rotation in the Linux terminal.
Setting the screen Rotation in the Linux terminal.

You’ll need to set the screen rotation to match the screen orientation using the below terminal commands:

xrandr -o left
xrandr -o right
xrandr -o normal

The screen rotation will reset when the system restarts, so you might have to add the rotate command you require to your login scripts to make it stick.

Loading the Pinball Game Code onto the Pinball Machine

That takes care of the hardware – let’s get this machine working!

The game application we exported from GDevelop earlier require a web server to run.  Install the Apache web server by running:

sudo apt install apache2

Copy the game files to your Raspberry Pi and ensure the directory they are in is called pinball.

The, simply copy that directory into the Apache web server’s directory:

sudo cp pinball /var/www/html

You’ll need to do this using the sudo command as administrative rights are required.

Ready to go! Navigate to

http://localhost/pinball

In the web browser on your Pi and the game will launch!

Be sure to press the F11 key to make things full screen for best effect.

Excuse the screen smudges.
Excuse the screen smudges.
Working pinball game!
Working pinball game!
A final look at the guts inside the box.
A final look at the guts inside the box.

A Good Jumping Off Point

I think this one turned out pretty well.  The game is a bit wonky but it’s a good first effort.

With more time, refinement and a better artist, a really sweet pinball machine could be put together based on this basic starting point.

You could use a bigger screen and make a more complex play area with more obstacles, add sound and video, GDevelop does a lot more than was explored in this article, so get creative!

If you come up with your own pinball game be sure to share it with us!

 

This project article wound up getting pretty involved – If I’ve skipped a step or left something out please let me know 🙂

SHARE:
Photo of author
Author
I'm Brad, and I'm nearing 20 years of experience with Linux. I've worked in just about every IT role there is before taking the leap into software development. Currently, I'm building desktop and web-based solutions with NodeJS and PHP hosted on Linux infrastructure. Visit my blog or find me on Twitter to see what I'm up to.

Leave a Comment