• Advertisement
Sign in to follow this  

writing good game classes

This topic is 4789 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

I am having some problems with game design. I have a simple layout but it doesn't seem to hold up once i begin to write the code for my classes. Here is a very general example design that I would eventually put much more detail into...
WorldManager <- Engine -> InputSystem
    |               |
    V               V
 Objects,          OpenGLWindow
 Textures,
  Menus,
 GameStates,
 Sounds
 etc...
Even a game structure as general as this seems to fall apart when I begin coding because the OpenGLWindow needs to know about the InputSystem and the GameStates need access to the Engine for example. I want to make reusable, flexible classes for my game but I can't seem to keep my subsystems as independant from one another as I would like.

Share this post


Link to post
Share on other sites
Advertisement
i use d3d not ogl but here is what i have done


// game.h

class Game : public Graphics
{

protected:

Font arialFont;

Input input;
Camera camera;

int loadScene();
void unloadScene();

void updateScene(float frameTime);

void renderScene();

public:

int run();

};




// graphics.h

class Graphics
{

protected:

WNDCLASSEX m_wc;
HWND m_hWnd;

LPDIRECT3D9 m_pd3d;
LPDIRECT3DDEVICE9 m_pd3dDevice;

LPD3DXSPRITE m_pd3dxSprite;

std::vector<LPDIRECT3DTEXTURE9> m_pd3dTextures;

public:

HWND getWindow() { return m_hWnd; }
LPDIRECT3DDEVICE9 getDevice() { return m_pd3dDevice; }
LPD3DXSPRITE getSprite() { return m_pd3dxSprite; }
LPDIRECT3DTEXTURE9 getTexture(int i) { return m_pd3dTextures; }

void init(UINT width, UINT height, D3DFORMAT format, BOOL windowed);
void cleanup();

void resizeScene(UINT width, UINT height);

void beginScene(D3DCOLOR color=0x000000);
void endScene();

void flip();

void takeScreenShot(LPCTSTR pDestFile);

void setWorldMatrix(D3DXMATRIX worldMatrix);

void loadTexture(std::string file);
void loadTexture(std::string file, LPDIRECT3DTEXTURE9* ppTexture);

void enableBlending(D3DBLEND srcBlend, D3DBLEND destBlend);
void disableBlending();

void enableLighting(D3DCOLOR ambient);
void disableLighting();

};

Share this post


Link to post
Share on other sites
It's better not to couple your subsystems together too tightly. The typical way to do something like this is using an event system - wherever a subsystem A needs to respond to changes in some other subsystem B, subsystem B sends a message to the event system indicating something specific has happened, perhaps with some relevant data. During initialisation, subsystem A registers with the event system an interestin any message with that type. So, when that particular thing happens, subsystem B tells the event system, and the event system tells subsystem A.

In this way, rather than your input system being tied up with the front end system, the game logic system, the game console etc, every subsystem is coupled only to the event system (where possible).

Share this post


Link to post
Share on other sites
i guess inheriting the Engine from the 'Graphics' or 'OpenGLWindow' would be a lot easier. I didn't know if this was poor design because an Engine is not a Graphics Window.

Share this post


Link to post
Share on other sites
I previously never used inheritance with this but decided to try it out

I would always have class Graphics a member of class Game and call the access functions like getDevice(), getSprite()

here is a list of my classes

AnimationSequence
Camera
Entity
Font
Frustum
Game
Graphics
Input
Mesh
MultiAnimSprite
Skybox
SkyTexture
Sprite
Timer

here is what my WinMain looks like


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{

// Enter game loop
Game game;
game.run();

// Exit to Windows
return 0;
}




edit:

check out this article

[Edited by - eFoDay on January 7, 2005 10:31:42 PM]

Share this post


Link to post
Share on other sites

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
Timmer test_timmer;
Player test_player;
DS_System GameSytem;

//Initialise system
srand(GetTickCount());
console.InitSystem();
if(!console.OpenWindow(SCREEN_X,SCREEN_Y))return -1;


//Init Game System
if(!GameSytem.load_config("system_cfg.txt"))QuitGame(-1);

//Player init
test_player.load_config("player_cfg.txt");
test_player.init(10,10,RIGHT,15);

while(console.System())
{
//Check for Quit Key
if(console.key(GameSytem.QUIT_KEY))break;

//Time Updates
if(GameSytem.update())
{
test_player.update();
}

//Draw the frame
screen = (Gfx_Screen*)console.GetVirtualScreen();
clear_screen();

test_player.render();

if(console.key(GameSytem.CONSOLE_KEY))grid();

console.Update();

}

console.CloseWindow();
console.DeinitSystem();

//Warning elimination for unused variables,I hate such warnings,since they cover really important stuff
hInstance;
hPrevInstance;
lpCmdLine;
nCmdShow;

return 0;
}




That's what my code looks like.Each entity is seperate and self-regulated.This code is for a snake game I am developing (I know way too much code,but it's a test run for my next one).

The player class handles a snake class and the input class.And the console class's job is to manage the window.Pretty basic and I dont know if it stands as an example for good design.

Comments anyone?

Share this post


Link to post
Share on other sites
Except for the fact that Timer is spelled with one 'm', you're fine [grin]

And if you want to get rid of those warnings, simply remove the identifiers from the function head:
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)

As long as the signature is the same the compiler doesn't give a rat's ass if you decide not to use a parameter or two (or four) [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by Zipster
Except for the fact that Timer is spelled with one 'm', you're fine [grin]

Hehe, [grin], happens I suppose ;)

Quote:
Original post by Zipster
And if you want to get rid of those warnings, simply remove the identifiers from the function head:
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)

As long as the signature is the same the compiler doesn't give a rat's ass if you decide not to use a parameter or two (or four) [smile]


Thanks a lot.I dint know one could do that.Let me try it out, but I have a fealing it wont work on Borland's compiler.(Btw the code compiles on Borland and on VC++ cleanly).

Share this post


Link to post
Share on other sites
The method that I'm using in my engine currently, is to write interfacing classes everywhere so as to make it API independant(for the most part). If I know that I need an image here, I write an image interface that has a virtual function of what I need. When it comes to everything needs to know about everything, encapsulate the crap out of what you need.

If the sound system needs to know about the input system, then have the sound system have a parent object that knows where the game manager is, have the game manager provide the information about the input system.

Having a child->parent->etc structure isn't violating your class heirarchy. Not everything is completely and solely self-contained. All my tiles have a pointer to the ParentSystem which has access to a lot of data that's needed for what I do. Basically, have a heirarchy of child knows parent knows grandparent until you get what you need.

Share this post


Link to post
Share on other sites
Quote:
Original post by Tarviathun
The method that I'm using in my engine currently, is to write interfacing classes everywhere so as to make it API independant(for the most part). If I know that I need an image here, I write an image interface that has a virtual function of what I need. When it comes to everything needs to know about everything, encapsulate the crap out of what you need.

If the sound system needs to know about the input system, then have the sound system have a parent object that knows where the game manager is, have the game manager provide the information about the input system.

Having a child->parent->etc structure isn't violating your class heirarchy. Not everything is completely and solely self-contained. All my tiles have a pointer to the ParentSystem which has access to a lot of data that's needed for what I do. Basically, have a heirarchy of child knows parent knows grandparent until you get what you need.

If I were to post my thoughts on the subject, they would be completely useless because you've pretty much already said everything I would say [cool]

Share this post


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

  • Advertisement