Need some help about how to structure a 2D game

Started by
11 comments, last by slayemin 11 years, 6 months ago
Hello everybody!

I'm making my first game. I'm a quite experienced C programmer, but I never went through games/graphics rendering, so I need some help from you.

From making this game, I want to learn both how a game is structured and works (in practice, because in theory I already know how games work) and OOP in C++.
I know Java, Python and PHP, but this is my first (serious) experience with C++.

So, this is what I have:
- Visual C++ 2012 Express
- Some GDI+ tests (please, finish reading the post tongue.png)
- A lot of ideas on how to implement things
- A lot of difficulties, most of them are about timing and drawing

First of all, let me explain why I'm using GDI+: because It is easy. I will probably re-implement the rendering part of the game once it is finished with a better library, but I gave a look at SDL and Allegro and I couldn't even figure out how to draw a line (just kidding, I'm not that bad, but everything is more immediate with GDI+, and it is fully object-oriented).

The game is about planes: there will be some planes on the screen, there will be physics and collisions, the planes will shot other planes on the screen.

So here's the idea: I made (read: thought about making) some classes: Body (abstract), which has 3 fields (id, position), PhysicBody (abstract, inherits id and position from Body, and has acceleration field), ControllableBody (abstract, provides virtual methods to add acceleration/change the position) and on top of this last class I will implement Joystick input and computer-controlled planes/bodies, and a generic Plane class (with all the properties of the plane)

So for example I have a plane called "Simple plane", controllable by the player, and I would implement it like this:
djasidhasodhas62447.png

But here comes the first problem: I would have to create 2 copies of each kind of plane, one inheriting from PlayerControllableBody (class which takes the input from joystick/keyboard) and the other one from AIControllableBody (class which generates the input real-time moving and making shoot the enemy planes).

So this is not a good solution.

The second thing which blocks me is, how I already say, the timing: I'm building this into a standalone Win32 application, so I've got the message loop... Not so good for a game, no?

So please, I need your help on these points. Programming is my passion. I'm 15, and I would like to program 3D video games when I'll grow up. I know that I will have to work hard, and I will do one step at a time to reach my objective.

Thanks in advance guys, I really count on you biggrin.png

And sorry for my English ;)
Advertisement
I can address only your first problem with a solution that I am currently using (successfully). Rather than creating two separate classes (PlayerControllableBody and AIControllableBody) you can abstract the "Controller" into another object, and let the ControllableBody use it.


class ControllableBody {
private:
Controller * controller;
public:
ControllableBody(Controller * controller);
};

/**
Interface for controllers.
*/
class Controller {
public:
virtual ~Controller() { }
};

/**
A controller that uses an AI script.
*/
class AIController : public Controller {
public:
virtual ~AIController() { }
};

/**
A controller that uses joystick input.
*/
class JoystickController : public Controller {
public:
virtual ~JoystickController() { }
};

/**
A controller that recieves instructions over a network.
*/
class NetworkController : public Controller {
public:
virtual ~NetworkController() { }
};


This allows your different control implementations to vary without affecting the objects you want to control. It also allows you to change how an object is being controlled at runtime, by swapping the pointer to another controller.

I am using this pattern, which is essentially a form of the Strategy Pattern, in a platformer/jump and run game right now. Here is one such controller's interface:


class HeroActionController {
public:
virtual ~HeroActionController() { }
virtual bool shouldMoveUp() const = 0;
virtual bool shouldMoveRight() const = 0;
virtual bool shouldMoveDown() const = 0;
virtual bool shouldMoveLeft() const = 0;
virtual bool shouldJump() const = 0;
virtual bool shouldShootWeapon() const = 0;
virtual bool shouldChargeWeapon() const = 0;
virtual bool shouldSlide() const = 0;
};


So within your ControllableBody, you can "ask" the controller if something should happen, and then act based off of that input.
Right, I think that's the most clever way to do it. Thank you very much!
And about the other classes/layers?
To address your second issue; that of timing, event loops, Win32 API...

I have never written a game without some abstraction over window creation and event management. I've written games with Allegro, SDL, and SFML. Being that Allegro and SDL are C APIs, for writing a game in C++ using C++ concepts and conventions, I would recommend you giving SFML a shot. It's what I am currently using and find the API easy to use and pretty much non-restrictive.

You can easily create a window and set up a game loop with something as simple as this:


#include <SFML/Window.hpp>
#include <SFML/Clock.hpp>
int main()
{
sf::Window window(sf::VideoMode(400, 300), "Sweet Ninja Power");
sf::Clock clock;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed) {
window.close();
}
}
sf::Time elapsed = clock.restart();
update(elapsed);
render(window);
}
return 0;
}


Of course, you can write a more "correct" game loop to take things like lag into consideration, but I hope this gives you the general idea. In my experience it helps to have tools that let you write a solution at a higher level, and when you need to dig deeper you can. I feel like SFML provides several of those high-level tools.
Seems very good! Thank you biggrin.png I will check it out and I'll let you know smile.png
UPDATE: uhm, I can't find neither sf::Clock.restart() method and sf::Time class :(
You have to include SFML_DYNAMIC; in your PROJECT SETTINGS for those to work. You can't include it like a normal include file, you have to do it in your projects setting (On the SFML documentation they tell you how). If you don't want to look at the getting started section of the documentation, just google it.

I'm a game programmer and computer science ninja !

Here's my 2D RPG-Ish Platformer Programmed in Python + Pygame, with a Custom Level Editor and Rendering System!

Here's my Custom IDE / Debugger Programmed in Pure Python and Designed from the Ground Up for Programming Education!

Want to ask about Python, Flask, wxPython, Pygame, C++, HTML5, CSS3, Javascript, jQuery, C++, Vimscript, SFML 1.6 / 2.0, or anything else? Recruiting for a game development team and need a passionate programmer? Just want to talk about programming? Email me here:

hobohm.business@gmail.com

or Personal-Message me on here !

Also, try using an enum to hold gamestates for smaller games.
enum GameState{MainMenu,
Playing,
Credits,
GameOver,
Closing
};

I'm a game programmer and computer science ninja !

Here's my 2D RPG-Ish Platformer Programmed in Python + Pygame, with a Custom Level Editor and Rendering System!

Here's my Custom IDE / Debugger Programmed in Pure Python and Designed from the Ground Up for Programming Education!

Want to ask about Python, Flask, wxPython, Pygame, C++, HTML5, CSS3, Javascript, jQuery, C++, Vimscript, SFML 1.6 / 2.0, or anything else? Recruiting for a game development team and need a passionate programmer? Just want to talk about programming? Email me here:

hobohm.business@gmail.com

or Personal-Message me on here !


I can't find neither sf::Clock.restart() method and sf::Time class


Were you trying SFML 1.6? I recommend using SFML 2 instead. The release candidate is pretty solid; I have been using it with much success. The API has changed a bit between 1.6 and 2, so that could account for missing classes/methods/etc.

One piece of advice I would give is that you don't want to over-design your game. If you're coming from the C world, write your first iteration as something close to a procedural program, then iterate on that. It's important to have something working to build on, otherwise you could end up designing forever but never building anything that works.
I'd also suggest taking a look at my old blog (found in my sig and here). I detail the steps to make a 2d game using SFML, and I also use a 2d physics engine, chipmunk-physics. Using a 2d physics library makes physics a breeze, and I won't make a game without it now.

Good Luck!

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

Ok now I'm using SFML 2. Just a little question: how do I draw a rectangle filled with gradient color?

EDIT: also, I've written this little test program... But why the rectangle doesn't move to the left when it goes out of the screen on the right?
The forum editor is messing up my indentation, so I'm using Pastebin. http://pastebin.com/embed_iframe.php?i=yShxR10s

This topic is closed to new replies.

Advertisement