My First Raspberry Pi Game " Part 05 " Say something

November 22, 2012 [My First Raspberry Pi Game, Programming Languages, Python, Raspberry Pi, Tech, Videos]

Parts: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.

Writing your first ever computer program on the Raspberry Pi.

Embedded YouTube video

Today we will write some writing on that blank screen we made last time.

But first, a couple of tricks (we are doing magic after all). We're going to make our program know it is a Python program, without needing to be told. To do this we need to do 2 things.

First, open up LeadPad as normal and add this line at the very (very) top of the file. Make sure there are no empty lines above it:

#!/usr/bin/env python

That's a "hash" (or, for Americans, "pound") symbol, followed by an exclamation mark. Note that all the slashes are forward slashes, not backward.

This tells our Raspberry Pi that this is a Python program. Now we need to tell our Pi that this program is allowed to run by itself, instead of its name being passed to the python program like we have been doing before.

To do this, open up LXTerminal as before, and type exactly this (and press Return):

chmod +x redgreen.py

If all of this worked correctly, you should be able to run our program in a new way. Instead of typing python redgreen.py like we were before, we can type this in to LXTerminal:

./redgreen.py

That's a dot, followed by a forward slash, followed by the name of our program.

This means run the program in this directory (that is the "./" part) called "redgreen.py". Your Pi will look at redgreen.py and find the line we added that starts with "#!" and know to use Python to run it.

Now let's get on with writing something on the screen. Go back to LeafPad and change the line starting with screen_size = to be these 3 lines:

screen_width = 640
screen_height = 480
screen_size = screen_width, screen_height

This creates 3 variables - screen_width, screen_height and the one we had before screen_size, which is now made by putting the first 2 together. We're going to use screen_height later.

Just below those 3 lines, type this:

screen = None
ready_text = None

This gets 2 variables ready for us, and makes them empty. We're going to fill them in inside start.

Change the start function to look exactly like this:

def start():
    global screen, ready_text
    pygame.init()
    screen = pygame.display.set_mode( screen_size )
    font = pygame.font.Font( None, screen_height / 5 )
    ready_text = font.render( "Ready?", 1, pygame.Color( "white" ) )

The green lines above are the bits we've added. The line beginning global tells Python we want to work with those variables we got ready earlier inside this function, even though we created them outside it. (Without saying they were "global" we would be in danger of working with versions of them that only existed while we were inside the function, and disappeared as soon as we left.)

The font line makes a new font (a font is a typeface, or way of writing text). The first argument we passed was None because we don't care at the moment which font we use (e.g. "Arial" or "Times New Roman") - we are happy with the default. The second argument is for the size of the font we want, and we passed in screen_height / 5, which means the value of the screen_height variable we created near the top, divided by 5. The "/" character is how we write division in Python - it is supposed to look a bit like a fraction.

Finally, on the last line we create another variable called ready_text, which contains the "rendered" version of the word "Ready?", using the font we created, in white. "Render" means we create a picture showing the writing we wanted. We'll draw this picture onto the screen in a second.

Now that all our preparation is over, we can finally write a fuller version of the ready_screen function. Change it to look like this:

def ready_screen():
    textpos = ready_text.get_rect(
        centerx = screen.get_width() / 2,
        centery = screen.get_height() / 2
    )

    screen.blit( ready_text, textpos )
    pygame.display.flip()

The first 4 lines (textpos up to the closing bracket all on its own) are really all one "line of code" - they are like one sentence of our program, that happens to span multiple lines. In Python if we want to continue a sentence (we call it a "statement") we just leave a bracket unclosed. Python knows we have finished when we have closed all the brackets.

This "line" from textpost = up to ) creates a variable called textpos, which contains the place on the screen where we want to put our writing. We look inside ready_text (which is our rendered writing that we created above) for a function called get_rect that calculates a rectangle for us that is the right place on the screen to put the writing. The arguments we pass to get_rect are screen.get_width() / 2 and screen.get_height() / 2, which are telling it that it should calculate the rectangle by putting its centre in the middle of the screen. The middle of the screen is half-way across its width, and half-way down its height, which is why we are dividing the width and the height of the screen by 2.

Something worth noticing here is that the arguments to get_rect have names - we wrote centerx = and centery =. In Python we are allowed to give the names of arguments, or sometimes we can miss them out if we are happy just to put them in the right order. The get_rect function can actually take lots of different arguments, so it needs to know which ones you mean, which is why we named them.

Finally the last 2 lines do the real work. The screen.blit line tells PyGame to write the ready_text picture (the rendered writing) onto the screen at the position stored inside textpos. pygame.display.flip() is what we do to tell PyGame we've finished messing about with the screen, and we're ready for it to display what we've done.

[The word "blit" is an oddity from the olden days which I'm afraid you'll just have to memorise, and "flip" comes from the fact that behind the scenes there are really two screens - the one we are displaying, and the one we are working on. flip() switches them over, displaying the one we were working on, and making the other one ready to be worked on.]

If you've got this far, well done! With any luck, we're going to see the word "Ready?" on the screen in big letters.

Switch to LXTerminal again and type our new spell:

./redgreen.py

Don't move the mouse or press anything: a window should appear, with the word "Ready?" written in big white letters. When you press a key or move the mouse over it, it should disappear.

If something goes wrong, check back over the instructions carefully, and compare your file with this one: redgreen.py.