• Advertisement
Sign in to follow this  

Need some help about how to structure a 2D game

This topic is 1917 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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 [img]http://public.gamedev.net//public/style_emoticons/default/tongue.png[/img])
- 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:
[img]http://rikkardo.altervista.org/_altervista_ht/img/10_12/djasidhasodhas62447.png[/img]

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 [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]

And sorry for my English ;) Edited by thedd

Share this post


Link to post
Share on other sites
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.

[CODE]
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() { }
};
[/CODE]

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:

[CODE]
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;
};
[/CODE]

So within your ControllableBody, you can "ask" the controller if something should happen, and then act based off of that input.

Share this post


Link to post
Share on other sites
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 [url="http://sfml-dev.org/index.php"]SFML[/url] 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:

[CODE]
#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;
}
[/CODE]

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.

Share this post


Link to post
Share on other sites
Seems very good! Thank you [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img] I will check it out and I'll let you know [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
UPDATE: uhm, I can't find neither sf::Clock.restart() method and sf::Time class :( Edited by thedd

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Also, try using an enum to hold gamestates for smaller games.
enum GameState{MainMenu,
Playing,
Credits,
GameOver,
Closing
};

Share this post


Link to post
Share on other sites
[quote name='thedd' timestamp='1349354921' post='4986744']
I can't find neither sf::Clock.restart() method and sf::Time class
[/quote]

Were you trying SFML 1.6? I recommend using [url="http://www.sfml-dev.org/download.php#2.0-rc"]SFML 2[/url] 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.

Share this post


Link to post
Share on other sites
I'd also suggest taking a look at my old blog (found in my sig and [url="http://2dgamemaking.blogspot.com/"]here[/url]). 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!

Share this post


Link to post
Share on other sites
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 Edited by thedd

Share this post


Link to post
Share on other sites
[quote name='thedd' timestamp='1349374140' post='4986826']
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. [url="http://pastebin.com/embed_iframe.php?i=yShxR10s"]http://pastebin.com/....php?i=yShxR10s[/url]
[/quote]

My bet is this line:
[code]
if (rectPos > window.getSize().x)
[/code]

If window.getSize().x returned unsigned, it may also make rectPos unsigned, and if rectPos == -50, when it's unsigned, it'll always be larger that x. Change the line to:

[code]
if (rectPos > (int)window.getSize().x)
[/code]

See if that helps

Share this post


Link to post
Share on other sites
Here's another idea/technique you could take into consideration: Use the MVC framework. Don't even worry about drawing or graphics.

I'm currently working on a game and all of my coding is in a Win32 Console application. Rather than getting bogged down in graphics, rendering, art assets, input controls, etc. I'm focusing exclusively on the game model. I can focus on the game play logic, game mechanics, object inheritance and class structure, object interactions, etc. without wasting time on platform/API specific code. I can change the game model at my leisure, advance to the next frame when I'm ready, examine how the game state changed, tweak more variables, run other tests, and verify whether everything worked as expected.

At the end, my game is all contained within a model. Then, when I port it over to a platform, I only have to worry about how to represent the state of the model (through graphical representation of objects, or "the view") and how to interact with the model (user input and controllers).

This seems to work pretty well with test driven development. I can try out all of the "happy" cases to make sure that they are functional, and then I can try all of the cases which should not be allowed via game logic (like casting a spell without mana, or shooting a gun without ammo).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement