It has been recently brought to my attention that many people ask about game development, yet there aren't any articles on the topic. I've decided to shed some light on the general process of developing a game from start to finish. Keep in mind that that this is a generalization and WILL change from project to project.
Step 1: Choose Your Game Library
Unless you want to write your own library for all the dirty graphics/sound programming, you will probably want to get a game library. There are many game libraries out there. but they all offer the same base functionality (mostly...).
Features that any good library should have:
-Some system to load and play sound files
-Some system to load and display graphics
-At least some basic image manipulation (rotation, etc)
-Primitive drawing functions (circles, lines, rectangles, dots, etc)
-Functions to display text
-Multi-threading support
-Basic timer functions
Some game libraries include:
-Simple Fast Multi-Media Library (SFML):
http://www.sfml-dev.org/
-Simple DirectMedia Layer (SDL):
http://www.libsdl.org/
-Allegro:
http://www.allegro.cc/
-OpenGL (GFX only, however, there are wrapper libs like AllegroGL):
http://www.opengl.org/
-DirectX (Windows only):
http://msdn.microsoft.com/en-us/directx/
-Irrlicht (3d lib):
http://irrlicht.sourceforge.net/
Step 2: Define the Concept
All games start here, merely ideas in someone's head.
First, come up with an idea for a game. Once you have a simple idea, expand on it. For example, if it is a board game, what is the objective/How do you win? What will the rules be like? etc. If your game will have characters or a story, create them. Make sure you have a pretty well defined concept of what your game will be when its finished. The more complex the game, the better you should plan it out in the beginning so you don't have to worry about the game itself while your coding. Keep in mind that your game WILL evolve as you create it.
Step 3: Plan Your Engine
Here, you will plan out the various components your game engine will need and how everything will fit together. Depending on the complexity of your project, you may not need to do this step. This is also a good time to test various parts of your engine that you have never implemented in the past, just to make sure they work before you put them in the main project source. Also, you should begin to design the structure of your classes here as well(if you are using OOP, which you should be).
Keep in mind, however, that there are pre-made engines out there, available for use in all kinds of projects.
Step 4: Code Your Engine (if your making your own)
Now its time to actually start coding your engine. This doesn't necessarily mean the game itself, but rather, core rendering, physics, file handling and the like, functions and classes that will be used to construct your game. However, depending on the complexity of the game, the engine and game code may be the same. Also, a more complex game will probably require a resource manager. A resource manager does what it sounds like, it manages your resources (graphics, music, sounds, etc). It also keeps your code clean and helps to avoid memory leaks. See an excellent resource manager below by
Xander314. Try to give your entire engine some kind of compact, easy interface for use as well. That way, when you program your game, you don't have search through source to find functions names and the like. An easy way of doing this would be OOP.
Like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
//put related components into classes
class collisions {
bool check_col(obj1*, obj2*); //you should use a template for the objects
void handle_col(obj1*, obj2*); //so you can test players, bullets, bots with the same function
public:
void handle_all(); //handles EVERYTHING collision related
}Collision;
class rendering {
void bots();
void bullets();
void players();
public:
void draw_all(); //calls other functions for rendering
}Renderer;
//this allows collision management and rendering in your game loop to be as simple as:
Renderer.draw_all();
Collision.handle_all();
|
Resource Manager by
Xander314
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/*
ResourceManagerB.hpp - Generic template resource manager
(C) Alexander Thorne (SFML Coder) 2011
http://sfmlcoder.wordpress.com/
Manages loading and unloading of a resource type specified by a
template argument.
****************************************************************/
#include <map>
#include <string>
#include <exception>
typedef const std::string URI;
// exceptions
namespace Exceptions {
// thrown if user requests a resource URI not present in the manager's list
class URINotFound : public std::runtime_error
{
public:
URINotFound(const std::string& Message = "The specified URI was not found in the resource index.")
: runtime_error(Message) { }
};
// thrown if a resource allocation fails
class BadResourceAllocation : public std::runtime_error {
public:
BadResourceAllocation(const std::string& Message = "Failed to allocate memory for resource.")
: runtime_error(Message) {}
};
}
template <class Resource> class ResourceManagerB {
typedef std::pair<URI, Resource*> ResourcePair;
typedef std::map<URI, Resource*> ResourceList;
// the list of the manager's resources
ResourceList Resources;
public:
~ResourceManagerB() { UnloadAll(); }
// Load a resource with the specified URI
// the URI could represent, e.g, a filename
URI& Load(URI& Uri);
// unload a resource with the specified URI
void Unload(URI& Uri);
// unload all resources
void UnloadAll();
// get a pointer to a resource
Resource* GetPtr(URI& Uri);
// get a reference to a resource
Resource& Get(URI& Uri);
};
template <class Resource>
URI& ResourceManagerB<Resource>::Load(URI& Uri)
{
// check if resource URI is already in list
// and if it is, we do no more
if (Resources.find(Uri) == Resources.end())
{
// try to allocate the resource
// NB: if the Resource template argument does not have a
// constructor accepting a const std::std::string, then this
// line will cause a compiler error
Resource* temp = new (std::nothrow) Resource(Uri);
// check if the resource failed to be allocated
// std::nothrow means that if allocation failed
// temp will be 0
if (!temp)
throw Exceptions::BadResourceAllocation();
// add the resource and it's URI to the manager's list
Resources.insert(ResourcePair(Uri, temp));
}
return Uri;
}
template <class Resource>
void ResourceManagerB<Resource>::Unload(URI& Uri)
{
// try to find the specified URI in the list
ResourceList::const_iterator itr = Resources.find(Uri);
// if it is found...
if (itr != Resources.end())
{
// ... deallocate it
delete itr->second;
// then remove it from the list
Resources.erase(Uri);
}
}
template <class Resource>
void ResourceManagerB<Resource>::UnloadAll()
{
// iterate through every element of the resource list
ResourceList::iterator itr;
for (itr = Resources.begin(); itr != Resources.end(); itr++)
// delete each resource
delete itr->second;
// finally, clear the list
Resources.clear();
}
template <class Resource>
Resource* ResourceManagerB<Resource>::GetPtr(URI& Uri)
{
// find the specified URI in the list
ResourceList::const_iterator itr;
// if it is there...
if ((itr = Resources.find(Uri)) != Resources.end())
// ... return a pointer to the corresponding resource
return itr->second;
// ... else return 0
return 0;
}
template <class Resource>
Resource& ResourceManagerB<Resource>::Get(URI& Uri)
{
// get a pointer to the resource
Resource* temp = GetPtr(Uri);
// if the resource was found...
if (temp)
// ... dereference the pointer to return a reference
// to the resource
return *temp;
else
// ... else throw an exception to notify the caller that
// the resource was not found
throw Exceptions::URINotFound();
}
|