Reader small image

You're reading from  Beginning C++ Game Programming. - Second Edition

Product typeBook
Published inOct 2019
Reading LevelIntermediate
PublisherPackt
ISBN-139781838648572
Edition2nd Edition
Languages
Right arrow
Author (1)
John Horton
John Horton
author image
John Horton

John Horton is a programming and gaming enthusiast based in the UK. He has a passion for writing apps, games, books, and blog articles. He is the founder of Game Code School.
Read more about John Horton

Right arrow

Chapter 16: Building Playable Levels and Collision Detection

This chapter will probably be one of the most satisfying chapters of this project. The reason for this is that, by the end of it, we will have a playable game. Although there will still be features to implement (sound, particle effects, the HUD, and shader effects), Bob and Thomas will be able to run, jump, and explore the world. Furthermore, you will be able to create your very own level designs of any size or complexity by simply making platforms and obstacles in a text file.

We will achieve all this by covering the following topics:

  • Exploring how to design levels in a text file
  • Building a LevelManager class that will load levels from a text file, convert them into data that our game can use, and keep track of the level details such as spawn position, current level, and allowed time limit
  • Updating the game engine to use LevelManager
  • Coding a polymorphic function to handle collision detection for...

Designing some levels

Remember the sprite-sheet that we introduced in Chapter 14, Abstraction and Code Management – Making Better Use of OOP? Here it is again, annotated with numbers that represent each tile that we will build all our levels from:

The image has been placed on a grey background so that we can see the different details of the sprite-sheet better. The chequered background represents the level of transparency. So, all the tiles except for number 1 will reveal at least a little of the background behind them. Let's go over them now:

  • Tile 0 is completely transparent and will be used to fill in the gaps where there aren't any other tiles.
  • Tile 1 is for the platforms that Thomas and Bob will walk on.
  • Tile 2 is for fire tiles and 3 is for water tiles.
  • In terms of tile 4, you might need to look quite closely to see it. It has a white square outline. This is the goal of the level and is where Thomas and Bob must...

Building the LevelManager class

It will take several phases of coding to make our level designs work.

The first thing we will do is code the LevelManager header file. This will allow us to look at and discuss the member variables and functions that will be in the LevelManager class.

Next, we will code the LevelManager.cpp file, which will have all the function definitions in it. Since this is a long file, we will break it up into several sections to code and discuss them.

Once the LevelManager class is complete, we will add an instance of it to the game engine (Engine class). We will also add a new function to the Engine class, loadLevel, which we can call from the update function whenever a new level is required. The loadLevel function will not only use the LevelManager instance to load the appropriate level – it will also take care of aspects such as spawning the player characters and preparing the clock.

Now, let's get an overview of LevelManager by coding...

Coding the loadLevel function

To be clear, this function is part of the Engine class, although it will delegate much of its work to other functions, including those of the LevelManager class that we just built.

First, let's add the declaration for the new function, along with some other new pieces of code, to the Engine.h file. Open the Engine.h file and add the highlighted lines of code shown in the abbreviated snapshot of the Engine.h file, as follows:

#pragma once
#include <SFML/Graphics.hpp>
#include "TextureHolder.h"
#include "Thomas.h"
#include "Bob.h"
#include "LevelManager.h"
using namespace sf;
class Engine
{
private:
    // The texture holder
    TextureHolder th;
    // Thomas and his friend, Bob
    Thomas m_Thomas;
    Bob m_Bob;
    // A class to manage all the levels
    LevelManager...

Updating the engine

Open the Engine.cpp file and add the following highlighted code to load the sprite-sheet texture at the end of the Engine constructor:

Engine::Engine()
{
    // Get the screen resolution and create an SFML window and View
    Vector2f resolution;
    resolution.x = VideoMode::getDesktopMode().width;
    resolution.y = VideoMode::getDesktopMode().height;
    m_Window.create(VideoMode(resolution.x, resolution.y),
        "Thomas was late",
        Style::Fullscreen);
    // Initialize the full screen view
    m_MainView.setSize(resolution);
    m_HudView.reset(
        FloatRect(0, 0, resolution.x, resolution.y));
    // Initialize the split-screen Views
&...

Collision detection

We will handle collision detection using rectangle intersection and the SFML intersects function. What will be different in this project is that we will abstract the collision detection code into its own function. Thomas and Bob, as we have already seen, have multiple rectangles (m_Head, m_Feet, m_Left, and m_Right) that we need to check for collisions.

Coding the detectCollisions function

To be clear, this function is part of the Engine class. Open the Engine.h file and add a declaration for a function called detectCollisions. This is highlighted in the following code snippet:

    // Private functions for internal use only
    void input();
    void update(float dtAsSeconds);
    void draw();
    // Load a new level
    void loadLevel();
    bool detectCollisions(PlayableCharacter& character);
   ...

Summary

There was quite a lot of code in this chapter. We learned how to read from a file and convert strings of text into char values and then into int values. Once we had a two-dimensional array of int values, we were able to populate a VertexArray instance to show the level on the screen. We then used the same two-dimensional array of int values to implement collision detection. We used rectangle intersection, just like we did in the Zombie Arena project, although this time, for more precision, we gave each character four collision zones – one each to represent their head, feet, left, and right-hand sides.

Now that the game is totally playable, we need to represent the state of the game (score and time) on the screen. In the next chapter, we will implement the HUD, along with some much more advanced sound effects than we have used so far.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Beginning C++ Game Programming. - Second Edition
Published in: Oct 2019Publisher: PacktISBN-13: 9781838648572
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
John Horton

John Horton is a programming and gaming enthusiast based in the UK. He has a passion for writing apps, games, books, and blog articles. He is the founder of Game Code School.
Read more about John Horton