Book Image

SFML Game Development By Example

By : Raimondas Pupius
Book Image

SFML Game Development By Example

By: Raimondas Pupius

Overview of this book

Simple and Fast Multimedia Library (SFML) is a simple interface comprising five modules, namely, the audio, graphics, network, system, and window modules, which help to develop cross-platform media applications. By utilizing the SFML library, you are provided with the ability to craft games quickly and easily, without going through an extensive learning curve. This effectively serves as a confidence booster, as well as a way to delve into the game development process itself, before having to worry about more advanced topics such as “rendering pipelines” or “shaders.” With just an investment of moderate C++ knowledge, this book will guide you all the way through the journey of game development. The book starts by building a clone of the classical snake game where you will learn how to open a window and render a basic sprite, write well-structured code to implement the design of the game, and use the AABB bounding box collision concept. The next game is a simple platformer with enemies, obstacles and a few different stages. Here, we will be creating states that will provide custom application flow and explore the most common yet often overlooked design patterns used in game development. Last but not the least, we will create a small RPG game where we will be using common game design patterns, multiple GUI. elements, advanced graphical features, and sounds and music features. We will also be implementing networking features that will allow other players to join and play together. By the end of the book, you will be an expert in using the SFML library to its full potential.
Table of Contents (21 chapters)
SFML Game Development By Example
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Opening a window


As you probably know, drawing something on screen requires a window to be present. Luckily, SFML allows us to easily open and manage our very own window! Let's start out as usual by adding a file to our project, named Main.cpp. This will be the entry point to our application. The bare bones of a basic application look like this:

#include <SFML/Graphics.hpp>

void main(int argc, char** argv[]){
    
}

Note that we've already included the SFML graphics header. This will provide us with everything needed to open a window and draw to it, so without further ado, let's take a look at the code that opens our window:

#include <SFML/Graphics.hpp>

void main(int argc, char** argv[]){
  sf::RenderWindow window(sf::VideoMode(640,480), "First window!");

  while(window.isOpen()){
    sf::Event event;
    while(window.pollEvent(event)){
      if(event.type == sf::Event::Closed){
        // Close window button clicked.
        window.close();
      }
    }
    window.clear(sf::Color::Black);
    // Draw here.
    window.display();
  }
}

Tip

SFML uses the sf namespace, so we have to prefix its data types, enumerations, and static class members with an "sf::".

The first thing we did here is declare and initialize our window instance of type RenderWindow. In this case, we used its constructor, however it is possible to leave it blank and utilize its create method later on by passing in the exact same arguments, of which it can take as little as two: an sf::videoMode and an std::string title for the window. The video mode's constructor takes two arguments: the inner window width and height. There is a third optional argument that sets color depth in bits per pixel. It defaults to 32, which is more than enough for good rendering fitting our purposes, so let's not lose sleep over that now.

After the instance of our window is created, we enter a while loop that utilizes one of our window methods to check if it's still open, isOpen. This effectively creates our game loop, which is a central piece of all of our code.

Let's take a look at a diagram of a typical game:

The purpose of a game loop is to check for events and input, update our game world between frames, which means moving the player, enemies, checking for changes, and so on, and finally draw everything on the screen. This process needs to be repeated many times a second until the window is closed. The amount of times varies from application to application, sometimes going as high as thousands of iterations per second. Chapter 2, Give It Some Structure - Building the Game Framework will cover managing and capping the frame rate of our applications as well as making the game run at constant speeds.

Most applications need to have a way to check if a window has been closed, resized, or moved. That's where event processing comes in. SFML provides an event class that we can use to store our event information. During each iteration of our game loop, we need to check for the events that took place by utilizing the pollEvent method of our window instance and process them. In this case, we're only interested in the event that gets dispatched when a mouse clicks on the close window button. We can check if the public member type of class Event matches the proper enumeration member, in this case it's sf::Event::Closed. If it does, we can call the close method of our window instance and our program will terminate.

Tip

Events must be processed in all SFML applications. Without the event loop polling events, the window will become unresponsive, since it not only provides the event information to the user, but also gives the window itself a way to handle its internal events as well, which is a necessity for it to react to being moved or resized.

After all of that is done, it's necessary to clear the window from the previous iteration. Failing to do so would result in everything we draw on it stacking and creating a mess. Imagine the screen is a whiteboard and you want to draw something new on it after someone else already scribbled all over it. Instead of grabbing the eraser, however, we need to call the clear method of our window instance, which takes a sf::Color data type as an argument and defaults to the color black if an argument isn't provided. The screen can be cleared to any of its enumerated colors that the sf::Color class provides as static members or we can pass an instance of sf::Color, which has a constructor that takes unsigned integer values for individual color channels: red, green, blue, and optionally alpha. The latter gives us a way to explicitly specify the color of our desired range, like so:

window.clear(sf::Color(0,0,0,255));

Finally, we call the window.display() method to show everything that was drawn. This utilizes a technique known as double buffering, which is standard in games nowadays. Basically, anything that is drawn isn't drawn on the screen instantly, but instead to a hidden buffer which then gets copied to our window once display is called. Double buffering is used to prevent graphical artifacts, such as tearing, which occurs due to video card drivers pulling from the frame buffer while it's still being written to, resulting in a partially drawn image being displayed. Calling the display method is mandatory and cannot be avoided, otherwise the window will show up as a static square with no changes taking place.

Tip

Remember to include SFML library .dll files in the same directory as your executable relies, provided the application has been dynamically linked.

Upon compilation and execution of the code, we will find ourselves with a blank console window and a black 640x480 px window sitting over it, fewer than 20 lines of code, and an open window. Not very exciting, but it's still better than E.T. for Atari 2600. Let's draw something on the screen!