Tower defence wall building in Python | Wireframe #70

Protect your castle in the style of Atari’s pioneering Rampart. Mark shows you how, in the latest edition of Wireframe magazine, available now.

As the eighties drew to a close, a new strategy genre emerged. The tower defence game involved building walls or barriers around your castle to prevent an enemy destroying it. One notable early entry in the genre was Rampart, released by Atari. The game took in two phases. In the building phase, the player filled holes in the walls around their fort and placed cannons. In the second phase, the player’s fort would be attacked from the sea by an armada of ships, and the player could fire back with their cannon. This cycle would continue until the player could no longer fill the gaps in the walls or they’d destroyed all the attacking ships.

Cannons ready, prepare for battle! It’s the original Rampart, developed by Atari in 1990.

For our Pygame Zero example, we’ll look at two tower defence mechanics: the wall building system and then the check to see if the keep has been enclosed by walls. To start coding, we’ll need a background – in this case, a shoreline section of land. We then need to define an invisible grid which will hold the details of where the walls are positioned. If we say that each wall segment is 40×40 pixels, on an 800×600 pixel window we can define a grid that is 20×15 squares in a two-dimensional list. In this list, we’ll start with all the squares set to 0 and then if we add a wall section, switch that square to 1. To define where we can and can’t build, we can load in a little black-and-white image and read pixels from that to set squares which are non-buildable as 3.

Our fort will take up four squares, so we set the top-left square of the fort’s position as 2 and the other three squares as 3. This will stop the player building walls over the fort. We track the mouse movement with the on_mouse_move() function and when we have the mouse x and y coordinates, we draw a single section of wall under the mouse pointer locked to the invisible grid. When we get an on_mouse_down() event, we check that the square we’re over is a 0, and if it is, we switch that to a 1.

Our tower defence game built in Python and Pygame Zero. You can build a series of walls to protect your fort.
Our homage to the tower defence genre. Build a series of walls to safely encircle your fort.

During the draw() function, if we draw a single wall section wherever there’s a 1 in our grid, we’ll see flat squares where the walls are. What we want, though, is for all the walls to join up with battlements around the outside. For this, we need to inspect the squares around each wall piece and change the image we use depending on how it’s connected to other wall pieces. We look at the squares above, to the right, below, and to the left, and make a string with zeroes if there’s no wall there, and ones if there is. This means we’ll get the string ‘0000’ if no walls connect, ‘1000’ if there’s a wall above, ‘0101’ if there are walls on the left and right of our current wall, and so on. This is then used to load the wall image – for example, ‘wall0101’.

In the second part of our example, we’ll detect whether the fort has been surrounded by walls. There are various ways to do this, but we’re going to use a ‘flood fill’ routine to test this. First, we make a copy of our grid list to test with. Then, starting at the fort location on our grid, we recursively test all the neighbouring squares. If we hit a wall, then we close that branch of the loop. This creates a sort of cascade of tests going outwards until either the side of the map is reached or we run out of squares to test because walls have been hit by all the code branches. If the edge of the map is reached, the wall has holes in it; otherwise, the fort is enclosed.

Those are our wall-building and test routines. To complete the tower defence-style game, you’ll need to add some cannons and ships to fight, but we’ll leave that part for you to have fun with.

An image of the Python and Pygame Zero code for our tower defence game.
Here’s Mark’s code for the beginnings of a tower defence game. To get it running on your system, you’ll first need to install Pygame Zero. Full instructions can be found here. For the full code, visit our github.

Get your copy of Wireframe #70

You can read more features like this one in Wireframe issue 70, available directly from Raspberry Pi Press – we deliver worldwide.

The grand finale: Wireframe #70, available now.

And if you prefer your magazines in digital form, you can also download Wireframe issue 70 as a free PDF!

No comments
Jump to the comment form

Leave a Comment