Sign in to follow this  
Barbalute

Code Organization

Recommended Posts

I've got a few basic questions about code organization that I hope I can get some answers on. How much do you tend to handle within the class of something - that is to say, for example, do you handle the key input in the player class itself? What about drawing the player to the screen? If not, do you tend to have a separate class for handling all key input? Likewise for drawing? I've got a few more questions that have been sitting in the back of my head recently, but I can't remember them right now. Thanks for any responses.

Share this post


Link to post
Share on other sites
Speaking for me personally, I have a separate input class. It has a method called Update(), which is called every frame, at which point it polls all the keys on the keyboard & mouse and stores the results in an array.

I then pass a reference to that Input object to each other object that needs it. For instance, in the Player::Update() method, I'll pass a reference to the Input object, so that that method can call methods like Input::IsKeyDown().

I'm trying to work out the rendering right now myself. What I've done in the past is, I don't have any of the actual rendering code in the Player class. Instead, the GameObject class (an abstract class that the Player class, and all other game object classes, inherits from) has an AddToRenderingList() method (which all derived classes, including the Player class, must implement). This method takes a RenderList reference as a parameter. In this method, the object can choose to add one or more meshes to the RenderList. But nothing is actually rendered at this point. The point of this step is just to compile all the things that need to be rendered into one list, that can be sorted optimally before rendering. Then, during the render step, the Renderer iterates over the list, rendering each item, one at a time.

I'm glossing over a few details. I've found the above Render framework to be inflexible for large games. I'm trying to work out something else.

Share this post


Link to post
Share on other sites
It really depends on the flexibility/size/needs of your project.

Rendering for instance can be done various ways, but in larger engines there is probably scene culling and batching which may go on outside of the "player" or other objects. You can do anything from rendering code that loops through the game objects and tells them to render themselves to rendering code that loops though known visible game objects and asks them to queue their mesh with a render description of how to render it.

In other cases your object as it updated its position may have been through other means updating a scene graph which the renderer can then traverse and render any entities in the scene graph that are visible.

Input can be similar, especially when the player isnt the only thing making input decisions. What if it is a multiplayer game then only one player wants input, or if you are in a menu then the menu wants to test input. But what if the input is remapable, then you dont really want any code doing "IsKeyDown("W")" since W may or may not actually be the "forward" key based on mappings.

So... you can do what you mentioned, there is nothing wrong with that in certain circumstances. All depends on the goals/scope of your project.

Share this post


Link to post
Share on other sites
Quote:
Original post by Barbalute
How much do you tend to handle within the class of something
As little as possible -- Each class should do one thing only (and do it well).

If a player class is gathering input, processing the input, and rendering the output, then it should be split up into 3 separate classes.

However, you can then compose those small classes together to make complex classes.
e.g. Once you've got separate classes for gathering input, doing player logic based on the input, and rendering a player model, then you can construct the player class by joining these together:
class Player
{
public:
PlayerInput m_Input;
PlayerLogic m_Logic;
PlayerModel m_Model;

void Update( float deltaTime )
{
m_Input.Update();
m_Logic.MoveModel(deltaTime, m_Model, m_Input);
}
void Draw()
{
m_Model.Draw();
}
};

Share this post


Link to post
Share on other sites
Is the answer any different if you are making a 2D game?

For example, with one program I made, I created classes for buttons and windows, but the classes were also responsible for rendering themselves and accepting input. Is this also a bad idea or is it an exception to what you were saying?

Share this post


Link to post
Share on other sites
Thanks for all the replies everyone! It's really helpful to see how other people organize stuff like this. I'm not sure which method I'm going to use yet, but I really like a lot of the ideas in this thread and I'll play around with them and see what works best.

Any other ideas on this sort of thing?

Share this post


Link to post
Share on other sites
Quote:
Original post by Storyyeller
Is the answer any different if you are making a 2D game?
No, I'm just talking about software engineering in general.

But.... could be "yes" if you don't really care about having perfectly crafted software ;) (e.g. if you're not going to re-use the code later, or not keep patching it for years, etc...)
For a small 2D game, you could just do whatever makes it easier for you to get the code written. If lumping two different responsibilities into one class is going to save you time (in the short term) then go ahead.

Quote:
For example, with one program I made, I created classes for buttons and windows, but the classes were also responsible for rendering themselves and accepting input. Is this also a bad idea or is it an exception to what you were saying?
The Model/View/Controller pattern is often used for GUI-type systems, where you would break your big classes into three smaller classes:
* Model (i.e. data): Position, state(up/down), "on click" event, etc...
* View: The 2d pictures / animations / rendering
* Controller: The logic for making it act like a button (and gluing the Model and View together)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this