
Writing C ++ Games, Part 1/3 - Writing a Mini-Framework
- Tutorial
We write games in C ++, Part 2/3 - State-based programming
We write games in C ++, Part 3/3 - Classics of the genre
Hello, Habrahabr!
There are not many lessons on creating games on the hub, why not support domestic developers?
I present to you my lessons that teach you how to create games in C ++ using SDL!
In the next posts there will be more action, this is just preparation :)
I chose this library as the easiest and fastest to learn. Indeed, a lot of time will pass from the first read article on OpenGL or DirectX to the 100,000 reprint of the snake.
Now you can start.
Download SDL from the official site.
We create the Win32 project in Visual Studio, connect the SDL libs and includs (if you don’t know how to do this, then Google will help you!)
You also need to use multi-byte character encoding. To do this, go to Project-> Properties-> Configuration Properties-> Character Set-> Use Multi-Byte Encoding.
Create the main.cpp file
He is not doing anything yet.
King and God of the
Carcass - Game Game.h class
Game.cpp
We create the file Project.h, it will be very useful to us in the future
Change main.cpp
Already a little better, but still somehow not a lot.
We create already 2 classes - Graphics for rendering graphics and Image for rendering images.
Graphics.h
Image.h
Modify Project.h
SDL_Surface - a class from SDL for storing image information.
Consider Graphics
NewImage - there are 2 options for loading a picture. The first option just loads the picture, and the second after that also gives transparency to the picture. If we have a red background in the picture, then enter r = 255, g = 0, b = 0
DrawImage - also 2 options for rendering the picture. The first one draws the whole picture, the second only part of the picture. startX, startY - coordinates of the beginning of the part of the picture. endX, endY - end coordinates of the image part. This drawing method is used if image atlases are used. Here is an example of an atlas:

(image taken from the interesnoe.info web resource)
Consider Image
It just holds its surface and gives access to its private members to the Graphics class, and it changes the surface.
This is essentially a wrapper over SDL_Surface. It also gives the size of the
Graphics.cpp picture.
In the constructor, SDL is initialized and a screen is created.
The Flip function must be called every time after drawing the pictures, it represents the resultant on the screen and cleans the screen black for further rendering.
The rest of the functions are of little interest, I recommend that
Image.cpp himself figure it out
No, you are doing everything right, this file should be like that :)
You need to change Game.h, Game.cpp and main.cpp
Game.h
Here we add a pointer to Graphics and in Execute add the screen size of
Game.cpp
Nothing special, except skip the SDL_Quit function to clear SDL
main.cpp
Here we create a screen measuring 500 by 350.
We need to work with keyboard input.
Create Input.h
SDL_Event is a class of some event, we hold it in Input so as not to create an object of this class every cycle
Below are methods that are not of particular interest. Note: methods ending with Down are called when the key has been pressed, and with the ending Up when called.
Input.cpp
Here we process our event object in the Update function, and the rest of the functions simply check the type of event and its values.
We change now Game.h and Game.cpp
As you can see, we added a pointer to Input and created Graphics and Input
Game.cpp return methods
This was the first lesson. If you get to this place, I congratulate you! You have the will inherent in the programmer :) See the links at the beginning of the article for subsequent lessons in order to learn a lot more!
For all questions, contact the PM, and if you are not lucky to be registered on the hub, write to the email izarizar@mail.ru
We write games in C ++, Part 3/3 - Classics of the genre
Hello, Habrahabr!
There are not many lessons on creating games on the hub, why not support domestic developers?
I present to you my lessons that teach you how to create games in C ++ using SDL!
What you need to know
- At least a basic knowledge of C ++ (we will use Visual Studio)
- Patience
What is this part about?
- We will create a framework for all games, we will use SDL as a renderer. This is a library for graphics.
In the next posts there will be more action, this is just preparation :)
Why SDL?
I chose this library as the easiest and fastest to learn. Indeed, a lot of time will pass from the first read article on OpenGL or DirectX to the 100,000 reprint of the snake.
Now you can start.
1.1. The beginning of time
Download SDL from the official site.
We create the Win32 project in Visual Studio, connect the SDL libs and includs (if you don’t know how to do this, then Google will help you!)
You also need to use multi-byte character encoding. To do this, go to Project-> Properties-> Configuration Properties-> Character Set-> Use Multi-Byte Encoding.
Create the main.cpp file
#include
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
return 0;
}
He is not doing anything yet.
King and God of the
Carcass - Game Game.h class
#ifndef _GAME_H_
#define _GAME_H_
class Game
{
private:
bool run;
public:
Game();
int Execute();
void Exit();
};
#endif
Game.cpp
#include "Game.h"
Game::Game()
{
run = true;
}
int Game::Execute()
{
while(run);
return 0;
}
void Game::Exit()
{
run = false;
}
We create the file Project.h, it will be very useful to us in the future
#ifndef _PROJECT_H_
#define _PROJECT_H_
#include
#include "Game.h"
#endif
Change main.cpp
#include "Project.h"
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
Game game;
return game.Execute();
}
Already a little better, but still somehow not a lot.
1.2. Graphics
We create already 2 classes - Graphics for rendering graphics and Image for rendering images.
Graphics.h
#ifndef _GRAPHICS_H_
#define _GRAPHICS_H_
#include "Project.h"
#include "Image.h"
class Image;
class Graphics
{
private:
SDL_Surface* Screen;
public:
Graphics(int width, int height);
Image* NewImage(char* file);
Image* NewImage(char* file, int r, int g, int b);
bool DrawImage(Image* img, int x, int y);
bool DrawImage(Image* img, int x, int y, int startX, int startY, int endX, int endY);
void Flip();
};
#endif
Image.h
#ifndef _IMAGE_H
#define _IMAGE_H
#include "Project.h"
class Image
{
private:
SDL_Surface* surf;
public:
friend class Graphics;
int GetWidth();
int GetHeight();
};
#endif
Modify Project.h
#ifndef _PROJECT_H_
#define _PROJECT_H_
#pragma comment(lib,"SDL.lib")
#include
#include
#include "Game.h"
#include "Graphics.h"
#include "Image.h"
#endif
SDL_Surface - a class from SDL for storing image information.
Consider Graphics
NewImage - there are 2 options for loading a picture. The first option just loads the picture, and the second after that also gives transparency to the picture. If we have a red background in the picture, then enter r = 255, g = 0, b = 0
DrawImage - also 2 options for rendering the picture. The first one draws the whole picture, the second only part of the picture. startX, startY - coordinates of the beginning of the part of the picture. endX, endY - end coordinates of the image part. This drawing method is used if image atlases are used. Here is an example of an atlas:

(image taken from the interesnoe.info web resource)
Consider Image
It just holds its surface and gives access to its private members to the Graphics class, and it changes the surface.
This is essentially a wrapper over SDL_Surface. It also gives the size of the
Graphics.cpp picture.
#include "Graphics.h"
Graphics::Graphics(int width, int height)
{
SDL_Init(SDL_INIT_EVERYTHING);
Screen = SDL_SetVideoMode(width,height,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
}
Image* Graphics::NewImage(char* file)
{
Image* image = new Image();
image->surf = SDL_DisplayFormat(SDL_LoadBMP(file));
return image;
}
Image* Graphics::NewImage(char* file, int r, int g, int b)
{
Image* image = new Image();
image->surf = SDL_DisplayFormat(SDL_LoadBMP(file));
SDL_SetColorKey(image->surf, SDL_SRCCOLORKEY | SDL_RLEACCEL,
SDL_MapRGB(image->surf->format, r, g, b));
return image;
}
bool Graphics::DrawImage(Image* img, int x, int y)
{
if(Screen == NULL || img->surf == NULL)
return false;
SDL_Rect Area;
Area.x = x;
Area.y = y;
SDL_BlitSurface(img->surf, NULL, Screen, &Area);
return true;
}
bool Graphics::DrawImage(Image* img, int x, int y, int startX, int startY, int endX, int endY)
{
if(Screen == NULL || img->surf == NULL)
return false;
SDL_Rect Area;
Area.x = x;
Area.y = y;
SDL_Rect SrcArea;
SrcArea.x = startX;
SrcArea.y = startY;
SrcArea.w = endX;
SrcArea.h = endY;
SDL_BlitSurface(img->surf, &SrcArea, Screen, &Area);
return true;
}
void Graphics::Flip()
{
SDL_Flip(Screen);
SDL_FillRect(Screen,NULL, 0x000000);
}
In the constructor, SDL is initialized and a screen is created.
The Flip function must be called every time after drawing the pictures, it represents the resultant on the screen and cleans the screen black for further rendering.
The rest of the functions are of little interest, I recommend that
Image.cpp himself figure it out
#include "Image.h"
int Image::GetWidth()
{
return surf->w;
}
int Image::GetHeight()
{
return surf->h;
}
No, you are doing everything right, this file should be like that :)
You need to change Game.h, Game.cpp and main.cpp
Game.h
#ifndef _GAME_H_
#define _GAME_H_
#include "Project.h"
class Graphics;
class Game
{
private:
bool run;
Graphics* graphics;
public:
Game();
int Execute(int width, int height);
void Exit();
};
#endif
Here we add a pointer to Graphics and in Execute add the screen size of
Game.cpp
#include "Game.h"
Game::Game()
{
run = true;
}
int Game::Execute(int width, int height)
{
graphics = new Graphics(width,height);
while(run);
SDL_Quit();
return 0;
}
void Game::Exit()
{
run = false;
}
Nothing special, except skip the SDL_Quit function to clear SDL
main.cpp
#include "Project.h"
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
Game game;
return game.Execute(500,350);
}
Here we create a screen measuring 500 by 350.
1.3. Enter
We need to work with keyboard input.
Create Input.h
#ifndef _INPUT_H_
#define _INPUT_H_
#include "Project.h"
class Input
{
private:
SDL_Event evt;
public:
void Update();
bool IsMouseButtonDown(byte key);
bool IsMouseButtonUp(byte key);
POINT GetButtonDownCoords();
bool IsKeyDown(byte key);
bool IsKeyUp(byte key);
byte GetPressedKey();
bool IsExit();
};
#endif
SDL_Event is a class of some event, we hold it in Input so as not to create an object of this class every cycle
Below are methods that are not of particular interest. Note: methods ending with Down are called when the key has been pressed, and with the ending Up when called.
Input.cpp
#include "Input.h"
void Input::Update()
{
while(SDL_PollEvent(&evt));
}
bool Input::IsMouseButtonDown(byte key)
{
if(evt.type == SDL_MOUSEBUTTONDOWN)
if(evt.button.button == key)
return true;
return false;
}
bool Input::IsMouseButtonUp(byte key)
{
if(evt.type == SDL_MOUSEBUTTONUP)
if(evt.button.button == key)
return true;
return false;
}
POINT Input::GetButtonDownCoords()
{
POINT point;
point.x = evt.button.x;
point.y = evt.button.y;
return point;
}
bool Input::IsKeyDown(byte key)
{
return (evt.type == SDL_KEYDOWN && evt.key.keysym.sym == key);
}
bool Input::IsKeyUp(byte key)
{
return (evt.type == SDL_KEYUP && evt.key.keysym.sym == key);
}
byte Input::GetPressedKey()
{
return evt.key.keysym.sym;
}
bool Input::IsExit()
{
return (evt.type == SDL_QUIT);
}
Here we process our event object in the Update function, and the rest of the functions simply check the type of event and its values.
We change now Game.h and Game.cpp
#ifndef _GAME_H_
#define _GAME_H_
#include "Project.h"
#include "Graphics.h"
class Graphics;
#include "Input.h"
class Input;
class Game
{
private:
bool run;
Graphics* graphics;
Input* input;
public:
Game();
int Execute(int width, int height);
Graphics* GetGraphics();
Input* GetInput();
void Exit();
};
#endif
As you can see, we added a pointer to Input and created Graphics and Input
Game.cpp return methods
#include "Game.h"
Game::Game()
{
run = true;
}
int Game::Execute(int width, int height)
{
graphics = new Graphics(width,height);
input = new Input();
while(run)
{
input->Update();
}
delete graphics;
delete input;
SDL_Quit();
return 0;
}
Graphics* Game::GetGraphics()
{
return graphics;
}
Input* Game::GetInput()
{
return input;
}
void Game::Exit()
{
run = false;
}
1.4. Summary
This was the first lesson. If you get to this place, I congratulate you! You have the will inherent in the programmer :) See the links at the beginning of the article for subsequent lessons in order to learn a lot more!
For all questions, contact the PM, and if you are not lucky to be registered on the hub, write to the email izarizar@mail.ru