Hey there DICers. This series of tutorials is meant for newer game programmers to show some basic game programming concepts through example. I'm going to walk you through creating as complete a 2D tile engine as I can muster, so hang on to your hats and lets get this started!
What we're making
For this series of tutorials we'll be making a 2D tile engine used in popular Top-Down RPGs, such as:
- Zelda: Link to the Past
- Dragon Warrior
- Shining Force
- Final Fantasy
- Chrono Trigger
Hopefully you're familiar with at least one of those games. We're going to make a top-down 2D tile engine.
I should elaborate on why we're using the word "engine" instead of "game". An engine is the backbone of any game. We're not going to cover the creation media and data assets such as artwork or music that make up the content of a game. Instead, we'll be programming a framework that will then allow us to add in content to make a fully playable game.
What we're using
The language we'll be using for the engine is C++. I like C++ for game programming because it is fast, extensible, and powerful. It is low-level enough that you can do all sorts of tricks close to the hardware, but high-level enough to allow for some really clever game design solutions.
Because I'm such a fan of Microsoft's Visual Studio, I will be using Visual C++ Express 2010 to make the engine. I highly recommend it, since it is free and quite simply awesome.
However, creating the engine from scratch with C++ would be time consuming and rather difficult. It would require low-level graphical and hardware knowledge which is too advanced of a subject for this tutorial. So instead we'll use a media API (Application Programming Interface) called SFML to help us with the graphical and audio implementations. We'll need SFML to run our example code. So head on over to http://www.sfml-dev.org and download a copy of SFML 2.0 (currently in beta). Follow this tutorial to get SFML set up for Visual Studio.
Setting Up
I'll spare you all the game design concepts and questions you should ask your self before starting a project like this and jump straight into getting a solution set up for our project.
First, create a new "Win32 Project" in visual studio, and make sure "Empty Project" is checked under "Application Settings". Now we do "Add->New Item" to the project and create a .cpp file named "Main.cpp".
Now we have to set up the project so it will compile and link correctly. Open up the project properties and do the following:
- Under "Linker->General->Additional Library Dependencies", add the "\lib\Debug" directory from your SFML binaries
- Under "Linker->Input->Additional Dependencies", add
- sfml-main-d.lib
- sfml-system-d.lib
- sfml-window-d.lib
- sfml-graphics-d.lib
- sfml-main-d.lib
- Under "Debugging->Working Directory", change the value to "$(OutDir)"
After that, your project should be ready to use SFML
Finally some code!
Okay, so now we can begin laying some ground work for our engine, as well as make sure that we set up our project correctly. The first thing we want to do is create a class that will represent our actual engine, so add a new header file called "Engine.h" and write the following code in it:
#ifndef _ENGINE_H
#define _ENGINE_H
#include <SFML\Graphics.hpp>
class Engine
{
private:
//SFML Render Window
sf::RenderWindow* window;
//Initializes the engine
bool Init();
//Main Game Loop
void MainLoop();
//Renders one frame
void RenderFrame();
//Processes user input
void ProcessInput();
//Updates all Engine internals
void Update();
public:
Engine();
~Engine();
void Go(); //Starts the engine
};
#endif
You can already see how the engine "flows". Almost every game engine requires some kind of loop to constantly update everything that is going on. In that loop, typically three things need to be done.
- Get any input, either from the user (via the keyboard or mouse), or from the operating system, and perform any actions needed.
- Update all of the engine internals, such as animations, character movements, etc.
- Present all this information to the user by rendering a graphical frame.
You can see that in the above class I have setup a framework for this list by adding class methods for getting input, updating, and rendering. These will all be called from the method "MainLoop". "window" is our way of communicating with the user via the RenderWindow class implemented by SFML. Now that we have the skeleton for the Engine class, let's flesh it out by adding a new code file named "Engine.cpp". Fill it with the following code:
#include "Engine.h"
#include <SFML\Graphics.hpp>
Engine::Engine()
{
}
Engine::~Engine()
{
}
bool Engine::Init()
{
window = new sf::RenderWindow(sf::VideoMode(800, 600, 32), "RPG");
if(!window)
return false;
return true;
}
void Engine::RenderFrame()
{
}
void Engine::ProcessInput()
{
sf::Event evt;
//Loop through all window events
while(window->PollEvent(evt))
{
if(evt.Type == sf::Event::Closed)
window->Close();
}
}
void Engine::Update()
{
}
void Engine::MainLoop()
{
//Loop until our window is closed
while(window->IsOpened())
{
ProcessInput();
Update();
RenderFrame();
}
}
void Engine::Go()
{
if(!Init())
throw "Could not initialize Engine";
MainLoop();
}
All we're doing for now is creating our RenderWindow, and then waiting for the user to close it. When we instantiate a new RenderWindow, we supply it with a VideoMode and a Title. The VideoMode's parameters are the width, height, and bit-depth of the window respectively. Once a RenderWindow has been created, SFML will keep it open until we tell it to close with the Close() method.
While the window is open, it constantly retrieves input from the user in the form of events, and stores the events in a queue until we retrieve them. So, at the beginning of our main loop we call ProcessInput, which polls the window until there are no more events in the queue. If we find an Event::Closed event, i.e. the user closed the window, then we call window->Close(), which then breaks our MainLoop (while(window->IsOpened())), and exits the program.
So, with that all ready, we need only to create our program's entry point, so add another code file called "Main.cpp", and put in the following code:
#include <Windows.h>
#include "Engine.h"
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
Engine* engine = new Engine();
try
{
engine->Go();
}
catch(char* e)
{
MessageBoxA(NULL, e, "Exception Occured", MB_OK | MB_IConerror);
}
}
Awesome, now we have our starting code. There's one more thing you need to do before this will run though. You must copy all the ".dll" files from SFML's "\lib\Debug" folder into your project's "Debug" folder. After you've done that, run the program, and admire the pretty blank window
Conclusion
Alright, that was a lot of talk with not a lot of satisfying results, but don't worry! There's more coming up so move on to the next tutorial!
Thanks to BronzeBeard and everyone else in #ogre3d for helping me get this together!





MultiQuote






|