Welcome screen

To get the ball rolling, well create a welcome screen for our game. This is a nice and easy way to introduce some of the concepts and processes we will be using throughout.

Planning

Wireframe

Wireframes

A wireframe is like a blueprint or skeleton of a website or app. It’s a simple, basic outline that shows where different elements, like buttons, images, and text, will go on the screen. It focuses on the layout and arrangement of elements rather than the colors or details. It’s a helpful tool for visualizing and discussing ideas before creating the final design, just like making a rough sketch or draft of a drawing before adding all the details.

Below is a wireframe of our welcome screen.

Welcome screen wireframe

This wireframe shows three different parts of the program wee need to address:

  • the game window (blue text):

    • features of the window that will hold our game

    • need to change size and title

  • the WelcomeScreen room (orange text):

    • the main part of our window is taken up with the game surface which holds the WelcomeScreen Room

    • it contains a background image and the Title Object

  • the Title Object (green text):

    • represented by the placeholder (box with an x)

    • contains an image

    • has a key event to react to space being pressed

Class diagram

We now know how the screen will look, but let’s also consider the Class diagram. Check out Deepest Dungeon for a refresher on Class diagrams if you need it.

welcome screen class diagram

We can see that the WelcomeScreen class has two attributes:

  • background image

  • Title RoomObject

We can also see that the Title class has:

  • attribute: image

  • method: keypressed

So we can see that there are three tasks we need to complete to create our welcome screen:

  1. Adjust window values

  2. Create WelcomeScreen Room

  3. Create Title RoomObject

  4. Add Title RoomObject to WelcomeScreen Room

Let’s start.

Adjust window values

GameFrame/Globals.py

The window values reside in Globals.py in the GameFrame folder, so open it up.

To change the window size, adjust the SCREEN_WIDTH and SCREEN_HEIGHT:

7SCREEN_WIDTH = 1280
8SCREEN_HEIGHT = 800

Then change the window_name value:

15# - Set the Window display name - #
16window_name = 'Space Rescue'

Save the Globals.py file using control + S (Windows) command + S (macOS)

Create WelcomeScreen Room

Let’s check the GameFrame documentation to see how we can create a level.

Rooms/WelcomeScreen.py

So we need to create a new file in the Rooms folder called WelcomeScreen.py.

In this file we are going to create a WelcomeScreen class. This is going to be a sub-class of the Level class provided by GameFrame. So the first thing we need to do is to import the Level class from GameFrame:

1from GameFrame import Level

Now we can create our WelcomeScreen class. Following the instructions from the documentation add the following code.

1from GameFrame import Level
2
3class WelcomeScreen(Level):
4    """
5    Intial screen for the game
6    """
7    def __init__(self, screen, joysticks):
8        Level.__init__(self, screen, joysticks)

Lets break that down a bit:

  • line 3: defines our class → explicitly names it as a subclass of the Level class.

  • lines 4-6: a doc string that explains the class.

  • line 7: the __init__ method → called automatically when a WelcomeScreen object is made.

  • line 8 calling the __init__ method of the Level parent class → the WelcomeScreen class will inherent all the attributes and methods from Level.

Now save the WelcomeScreen.py file.

Testing WelcomeScreen

So we’ve made a welcome screen, let’s run the game and see what happens.

Open MainController.py and then click the play button in the top righthand corner.

play button

Well, that didn’t go to plan. You probably have the following error:

Traceback (most recent call last):
  File "d:\GIT\space_rescue_pygame\MainController.py", line 34, in <module>
    room = class_name(screen, joysticks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'module' object is not callable

Have a close look at this error. I guarantee this is not the last time you will see it, that’s why I purposely caused it.

Reading the error it is really obscure what the problem. Remember when looking at the file structure I said that if you add a new Room or Object you need to link it to GameFrame using the __init__.py file. This is the kind of error that occurs when you forget.

Rooms/__init__.py

To remedy this error, open the __init__.py file in the Rooms folder and add the following code:

1from Rooms.WelcomeScreen import WelcomeScreen

Save the __init__.py file, and run your program again using the MainController.py.

You should now have a screen like this:

Welcome Screen 1

Not very exciting, but it’s the correct size, and the window title reads Space Rescue, so that’s a start.

Adding the background

Let’s make it less boring by adding a background image. Again, check the GameFrame docs to see how we can do this.

You will see that there is a method set_background_image which takes an image file. So we will have to call this method, but when? Well, we want the background to appear as soon as the room is created, so, it needs to be called in the __init__ method.

Rooms/WelcomeScreen.py

Go back to the WelcomeScreen.py file and then add the highlighted code to the __init__ method.

 1from GameFrame import Level
 2
 3class WelcomeScreen(Level):
 4    """
 5    Intial screen for the game
 6    """
 7    def __init__(self, screen, joysticks):
 8        Level.__init__(self, screen, joysticks)
 9        
10        # set background image
11        self.set_background_image("Background.png")

Breaking that down:

  • line 10: structural comment to explain what is happening (really good habit to develop).

  • line 11:

    • self → remember in OOP the need to refer all actions to the current instance of the object (self)

    • set_background_iamge → a method inherited from the Level parent class.

    • "Background.png" → image file in the images folder (go to the folder and see if you can find it).

Save WelcomeScreen.py and then run the program again using MainController.py.

Create Title RoomObject

Note that we have a Room we can place the Title RoomObject inside it. So let’s check the GameFrame docs to see how to do this. This is a similar process to creating a Room:

  1. Create a new file in the Objects folder

  2. Import the parent class

  3. Initialise the class

  4. Add new file to the __init__.py file.

Notice that the RoomObject class has many more methods. These are used to implement the game logic.

Objects/Title.py

Open the Objects folder create a new file and call it Title.py.

In Title.py import the parent class using the following code:

1from GameFrame import RoomObject

Now create your Title class using the code below:

1from GameFrame import RoomObject
2
3class Title(RoomObject):
4    """
5    The object for displaying the title
6    """
7    def __init__(self, room, x, y):
8        RoomObject.__init__(self, room, x, y)

This code is very similar to the code to create a the WelcomeScreen class. It creates the class, initialises the class, and runs the parent class’ __init__ in order to inherent the attributes and methods.

Next we need to add an image to the object. Add the highlighted code below

 1from GameFrame import RoomObject
 2
 3class Title(RoomObject):
 4    """
 5    The object for displaying the title
 6    """
 7    def __init__(self, room, x, y):
 8        RoomObject.__init__(self, room, x, y)
 9        
10        # set image
11        image = self.load_image("Title.png")
12        self.set_image(image,800,350)

This is fairly different to how we added an image to the WelcomeScreen room, so let’s unpack it:

  • line 10: a structural comment

  • line 11: retrieves "Title.png" from the Images folder → stores it in the image variable

  • line 12: assigns the image variable to this (self) RoomObject

    • Note 800 and 350 this is the width and the height of the image

Determine image width and height

The easiest way to work out the height and width of an image is to open the image in VS Code and then look at the status bar at the bottom right of the screen.

image dets

Finally save Title.py.

Objects/__init__.py

Open the __init__.py in the Objects folder and add the following code:

1from Objects.Title import Title

Keeping workspace clean

During these tutorials, you will be moving between many different files, even files with the same name, but in different folder (eg. __init__.py).

To reduce the chance of working in the wrong file, get into the habbit of closing a file once you have finished with it.

Save __init__.py and close it.

Now run MainController.py to test your code. Nothing should change, because we haven’t added the RoomObject into the Room yet. This was just to check that there are no errors in your code so far.

Add Title RoomObject to WelcomeScreen Room

Now that we have made the Title RoomObject and the WelcomeScreen Room, we can put them together.

Rooms/WelcomeScreen.py

Open WelcomeScreen.py and add the code highlighted below:

 1from GameFrame import Level
 2from Objects.Title import Title
 3
 4class WelcomeScreen(Level):
 5    """
 6    Intial screen for the game
 7    """
 8    def __init__(self, screen, joysticks):
 9        Level.__init__(self, screen, joysticks)
10        
11        # set background image
12        self.set_background_image("Background.png")
13        
14        # add title object
15        self.add_room_object(Title(self, 240, 200))

Breaking that down:

  • line 2: imports the Title RoomObject we just created

  • line 14:

    • add_room_object → a Level method that adds RoomObjects to Rooms

    • Title(self, 240, 200) → creates a new Title RoomObject and tells it that it belongs to this room at the position of x of 240 and y of 200.

Pygame screen coordinates

Pygame screen coordinates start with (0,0) in the top lefthand corner and increase as you move right and down. For example, on our screen the top left is (0,0) whilst the bottom right is (1279,799)

Save WelcomeScreen.py and close it.

Testing

Now we have our welcome screen ready, it’s time to test it.

Open MainController.py and run it. Your screen should look like this:

welcome screen finished

Commit and Push

In case of fire... git

Now that we have finished a section of code and we have tested it to ensure it works, we should make a Git commit. Each commit creates an easy roll-back point. So if we break a our code, we can always return to a point that it worked.

To do this:

  1. In GitHub Desktop go to the bottom left-hand box and write into the summary Created WelcomeScreen.

  2. Click on Commit to main

  3. Click on Push origin

Now the work from this lesson is committed and synced with the online repo.

Completed file states

Below are all the files we used in this lesson in their finished state. Use this to check if your code is correct.

GameFrame/Globals.py

 1class Globals:
 2
 3    running = True
 4    FRAMES_PER_SECOND = 30
 5
 6    SCREEN_WIDTH = 1280
 7    SCREEN_HEIGHT = 800
 8
 9    SCORE = 0
10
11    # - Set the starting number of lives - #
12    LIVES = 3
13
14    # - Set the Window display name - #
15    window_name = 'Space Rescue'
16
17    # - Set the order of the rooms - #
18    levels = ["WelcomeScreen", "Maze", "ScrollingShooter", "BreakOut"]
19
20    # - Set the starting level - #
21    start_level = 0
22
23    # - Set this number to the level you want to jump to when the game ends - #
24    end_game_level = 4
25
26    # - This variable keeps track of the room that will follow the current room - #
27    # - Change this value to move through rooms in a non-sequential manner - #
28    next_level = 0
29
30    # - Change variable to True to exit the program - #
31    exiting = False
32
33
34# ############################################################# #
35# ###### User Defined Global Variables below this line ######## #
36# ############################################################# #
37
38    total_count = 0
39    destroyed_count = 0

Rooms/WelcomeScreen.py

 1from GameFrame import Level
 2from Objects.Title import Title
 3
 4class WelcomeScreen(Level):
 5    """
 6    Intial screen for the game
 7    """
 8    def __init__(self, screen, joysticks):
 9        Level.__init__(self, screen, joysticks)
10        
11        # set background image
12        self.set_background_image("Background.png")
13        
14        # add title object
15        self.add_room_object(Title(self, 240, 200))

Rooms/__init__.py

1from Rooms.WelcomeScreen import WelcomeScreen

Objects/Title.py

 1from GameFrame import RoomObject
 2
 3class Title(RoomObject):
 4    """
 5    The object for displaying the title
 6    """
 7    def __init__(self, room, x, y):
 8        RoomObject.__init__(self, room, x, y)
 9        
10        # set image
11        image = self.load_image("Title.png")
12        self.set_image(image,800,350)

Objects/__init__.py

1from Objects.Title import Title