Introduction
It was some time ago that I decided to create a modern computer game, so I started coding immediately. But there was a problem. What type of a game to build? What will be the story of my game? Where to find graphics for my game? Will it be a 2D or 3D game? And finally, how do I create the game at all?
My first work was a GDI based side-scrolling game. But then, the real game developers will never use Windows GDI to program a computer game. Why? It is a not so hard thing to learn and to use. Everyone can make a simple sprite moving around on the screen using keyboard keys or a mouse. So where was the problem then?
The Windows GDI is too slow to be a game programming option. But BitBlt()
works very fast, right? What do you need more to make a game?
Well, basically, you can make a game using just GDI. But GDI works with a Windows DDI (Device Driver Interface) when it must access a graphics card on your computer. Also, using MCI for sound playback adds another performance hit on your system. But, still, you may get away with a simple 2D scrolling game. What will happen if you want to build, say a strategy game, like the Age Of Empires? Or a 3D game of any kind? It just won't work with GDI. You must find another victim.
Then, I realised that I need DirectX and its components. But, I didn't know anything about it. Everyone said it is a very hard thing to learn by yourselves. Microsoft documentation, although it covers everything, is not the best way to go, I know that now.
Then, I took the search for a "computer game book" on Google. Many books came out, but one of them was different. It's name is well known to computer game developers all around the world - Tricks of the Windows Game Programming Gurus, by Andre LaMothe.
It has around 1000 pages, and covers each part of the game programming task. And there is not a single task in the list... So, here I will give you a short review of this book: what is inside, how it can be used, where to go next...
The book
Reading the book will take you directly to the first game programming question: What type of a game to create? So, you have to make a decision about the type of the first game you will create. It must be a simple game, just to learn the concepts of the game development process. OK, I said, it will be a 2D shooter game. 3D games are still out of my league, so I will not waste your time on that topic.
What will be the game story? Again, something simple, like an asteroid field you must get through, while destroying your enemies which will fight you back.
Game graphics? Well, either you'll steal someone's work, or you'll build your own. What tools to use? Some 3D modeler and painting program will be enough.
Sounds in the game? Try with some sound editing program to modify existing ones or create your own.
Now, we have all parts we need to put together and get the game, right? Almost, but we still need a glue to keep these things together, otherwise each will follow its own path to the oblivion. Here, the book starts to make a mixture which will get us out of this situation.
How does each game live, and how is each game organized? Each game has a beginning, the middle part, and the end. Two of these three things you can have done for you, since they cover DirectX components' loading and un-loading. So, that means that our main game stuff is in the middle part, right? Absolutely. So, what's inside that middle part? It's a million dollar secret that you have to find out. Let's start with a little help from the book.
What do we need to know before we start building the game? Some programming language is more than enough, and I prefer C++. We also need some basic knowledge of how the Windows system is organized: windows, controls, menus, resources etc. In our game, we will need just a single window - the main game window, some game resources mentioned above (sounds and graphics), and a game story. We will need neither standard nor custom controls, no menus, nothing more, but a good will and some extra time.
The main game window
Here, we will create the main game window, we need so much to continue. No MFC will be mentioned here, so if you don't like the Win32 SDK, then you could look for another game article that deals with that topic. By the way, you need no MFC to build a game. Let's create an empty Win32 Project in MS Visual Studio, and add a new main.cpp file with the following:
#define WIN_32_LEAN_AND_MEAN
#include "windows.h"
#include "windowsx.h"
#define WINDOW_CLASS_NAME "MyWindow_Class"
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
HWND g_hMainWnd = NULL;
HINSTANCE g_hInstance = NULL;
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT msg, WPARAM wParam, LPARAM lParam);
int Game_Init(void* pParms=NULL, int numParms=0);
int Game_Main(void* pParms=NULL, int numParms=0);
int Game_Shutdown(void* pParms=NULL, int numParms=0);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX winClass;
HWND hWnd;
MSG msg;
winClass.cbSize = sizeof(WNDCLASSEX);
winClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winClass.lpfnWndProc = WindowProc;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
winClass.hInstance = hInstance;
winClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.lpszClassName = WINDOW_CLASS_NAME;
winClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
g_hInstance = hInstance;
if (!RegisterClassEx(&winClass))
{
return (0);
}
if (!(hWnd = CreateWindowEx(NULL, WINDOW_CLASS_NAME, "Main Game Window",
WS_POPUP | WS_VISIBLE, 0, 0, 400, 300, NULL, NULL, hInstance, NULL)))
{
return (0);
}
g_hMainWnd = hWnd;
if (!Game_Init())
{
return (0);
}
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (!Game_Main())
{
break;
}
}
if (!Game_Shutdown())
{
return (0);
}
return (msg.message);
}
So, you see all three parts of our game here. Only Game_Main()
is interesting for me and you, because the other two (Game_Init()
and Game_Shutdown()
) can change in the future. We will write all the game logic in this single function call. Why? Because we need no more.
Message loop
This part is easy. We have provided above the main game window message filter function called WindowProc()
. Here it is:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
}
break;
default:
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}
break;
}
return (0);
}
We can process all keyboard or mouse inputs from the user in the body of this function, we can destroy the main game window, or create another, pause our game etc. All Win32 applications are exactly the same till this part. Now comes the game stuff.
Game parts
We have declared the three game functions above: Game_Init()
, Game_Main()
, and Game_Shutdown()
. Here they are:
int Game_Init(void* pParms, int numParms)
{
return (1);
}
int Game_Main(void* pParms, int numParms)
{
if (KEYDOWN(VK_ESCAPE))
{
PostMessage(g_hMainWnd, WM_CLOSE, 0, 0);
}
return (1);
}
int Game_Shutdown(void* pParms, int numParms)
{
return (1);
}
This is all that you need to create the main game window. You just need the game elements now...
Conclusion
You can build the example provided in this article and run it. You should see a black window 400x300 pixels large, which you can destroy by pressing the ESC key on your keyboard.