Designing a 2D Engine

Hello

(I hope this isnt too tedious, sorry. TL;DR - I have little idea how Games and their Engines work.) I started using SDL 3 weeks ago and made my first minesweeper, it was quite simple, based on the sdltutorials tutorials, but now I’ve decided to create a full minesweeper game (with main menu, game over screen, right-click flags and question marks, escape menu, etc.) and after that move onto some 2D RPG or perhaps a 2D TD game, reusing the Engine from the minesweeper game. Now I came here to ask for help, I saw the 2D engine tutorial by Seoushi in The Game Programming Wiki, and I understood how to create the State Manager and how it works, as well as the Input. I haven’t seen the Sound core yet, but for the moment I don’t need it. The Graphics Core is OpenGL, which I haven’t looked into, so I decided to make it the SDL way, however I came to a problem. I don’t understand how games work, I mean, I know there’s an engine, but is that engine generic? Like, is it universal so that you can use it in other games without changing it, or you have to adapt it to the game. And if you don’t have to adapt it, then how do you write the states, do you have to create other class called for example Game, specific for each game, that stores all info about it, like surfaces neede, sounds, algorithms, etc., where you have a function for each state(Main Menu, Configuration, Gameplay, Save Game, Load Game, etc.), and in main() you call the Engine’s state manager which then calls the Game’s state function. How do you handle Surface loading, in that tutorial I saw Seoushi had one function that loads a surface into memory, but what if you have many surfaces, do you have to create like an array of pointers to surfaces, and if yes, how do you implement that in the Engine, does it need an array declared in the Engine itself, for example, in the Graphics Core, or do you declare it in the Game class, and if you do it in the game class, how do you load all the surfaces through the Graphics Core, function, yes, but how do you pass the locations of the BMPs, the number of surfaces, color keys, etc., doing that with arguments would require more than 3-4 arguments. I’m puzzled by all this, my previous minesweeper was easy, just creating new .cpp and .h files for everything i needed, but designing a generic engine and linking its functions to each game’s functions is quite difficult for me. Also I don’t quite grasp the structure of a game, the basics are Input, Update, Render, and then what, is that infinite, or maybe if there is no input, then delay? What happens with animated games? Do they render forever? If I need a new game, how do I tell the core that I’m starting a new game, without it loading the surfaces yet again (probably loading could be out of the game loop)? Many questions like these are bugging me each time I try to write anything, and I can’t focus. Now I’m not asking you to answer every one of them, but if you could give me some directions, tutorials that explain in details, or anything. How did you learn to create Engines, how did you get used to structuring it, that kind of thing.
Thank you a lot in advance.

Wrtent

Most game engines aren’t generic, so for instance you couldn’t take minesweeper engine and apply it to Halo 3. A lot of commercial games will however write most of their engine from scratch but will then also licence an engine for the physics part.

If you’re only starting out, then an RPG will be a lot of work, and so will using OpenGL. I’d personally start off with something simple like a side scrolling shooter, as basic as you can make it (move your ship with the arrow keys and press space to fire a bullet).

For a very basic game the loop would be something like

Initialize SDL

Load up your images

Begin loop

Get the keyboard input

Move the player

Move the enemies

Check for collisions

End loop

Your graphics manager could contain an array of SDL_Surfaces which you can store your loaded images into. The image loading function could return the array index of the image you loaded and you can store that to recall it later.

static SDL_Surface *surfaces[20];
static int surfaceIndex = 0;

int loadImage(char *name)
{
	/* Load the image using SDL Image */

	int i;
	SDL_Surface *temp;
	SDL_Surface *image;

	temp = SDL_loadBMP(name);

	if (temp == NULL)
	{
		printf("Could not load image %s\n", name);
		
		exit(0);
	}

	/* Convert the image to the screen's native format */

	image = SDL_DisplayFormat(temp);

	SDL_FreeSurface(temp);

	if (image == NULL)
	{
		printf("Failed to convert image %s to native format", name);
		
		exit(0);
	}

	/* Put the image into your array */

	surfaces[surfaceIndex] = image;
	
	/* Keep a record of the index we just assigned the image to */
	
	i = surfaceIndex;
	
	/* Increment the internal counter */
	
	surfaceIndex++;
	
	/* Return the index of the newly created image */
	
	return i;
}

and when you want to get one of them back, you could call something like

SDL_Surface *getImage(int index)
{
	return surfaces[index];
}

So, if you loaded up your ship image, you could do something like

int shipImage = graphicsManager.loadImage("ship.bmp");

Then, when you want to retrieve the image for drawing, you could call

graphicsManager.getImage(shipImage);

How much SDL have you already done by the way?

Hello.

Sorry I had a busy week. About the SDL experience, I haven’t done much, mostly colorkey, loading, surface manipulating, haven’t started with animations yet (Getticks and more) and input. The problems I always have is the algorithms and structuring of the project. One question about what you posted. If I, for example, start creating a game and say I release it in beta, and then I begin fixing bugs and adding new content, do I have to manually increase the SDL_Surface* array every time I add a new image, like should it be hardcoded into the engine? I don’t know, it just bugs me everytime, isn’t everything supposed to be as simple as possible, just using the functions from the engine? Also, about the loop, a problem I’ve had is with rendering, when I write down some basic ideas of what the game should look like, I come up with 10 different render functions, meaning, I need lots of parameters. Lets say I have a function that renders parts of an image, I can use that to render something to the whole screen or just some parts, but what if I have to check for a condition, like for example, “Is mouse over Guardian Tower” if yes then render range, or maybe say I have an inventory that has gear slots which when pointed at get highlighted. But one thing here is important, if I have to render multiple surfaces, do I have to include all of them in the render function or should it be in a loop, and if I have to include them all, how do I tell the function that it must only render a few, not all, without using a bunch of IFs or switch? (just an idea - I could implement something like a call stack, just like te game states stack, that puts everything in there and the render function, which has a loop in it, renders it one by one in its loop). Sorry for the walls of questions, but I’ve just started with this, and it seems like programming 24/7, besides I recently started programming in C++ (well a year ago but I stopped for 10 months, to concentrate on other stuff). Really thanks for your help.

Wrtent

Dear Wrtent, Your problems seem mostly come from structuring the program. Most
of them are resolvable using OOP, what C++ fully supports. Also C++ offers
Abstract Containers which solve the problem of pre-allocating an array of surfaces.
You just need to declare a vector of surfaces, and add as many surfaces as you want
to it.

Considering game engines, I actually have been working on a home-made one for several
weeks named Simple Game Engine (SGE), and it has or is supposed to have support for
backgrounds, animated sprites, GUI, network, geometric elements, isometrics coordinate
system, sounds, timing, game objects and a level runner which runs the main loop of the game itself. SGE is fully object oriented, and uses SDL 1.2, and yes it is a generic engine, and You need to derive objects of your game (player, enemies, platforms, arrows…) from a particular class, and rewrite some virtual functions.

Edited :

I’ve found an excellent free host to put the SGE onto :smiley: : http://launchpad.net