Jump to content

  • Log In with Google      Sign In   
  • Create Account

#Actualrip-off

Posted 20 November 2012 - 06:12 PM

But in that regard, should I make a game class/object that is separate from my current main class which currently just contains SDLstuff/graphics/eventhandling and such?Or do I just keep it all inside one huge main class?

You don't want to have any huge classes. Ideally, each class will be focused, it will have a "single responsibility". This is a good goal, but when you're starting out it isn't the only thing. It will come with time.

Some great articles on class design, the SOLID object oriented principles from "objectmentor":

For instance, what would be a good way of only calling the writing function for stuff that will actually be visible? I could just check the coordinates, but that would definitely add a lot of overhead every time I'm rewriting the screen.

It depends heavily on the game. Performing visibility tests in Pong would be a waste, while drawing every object to the screen wouldn't work on Minecraft. For small games or at the very beginning, drawing everything every frame usually works and doesn't take too long to write. I'd start there.

For instance, do I keep the drawing code in my game/graphics class and iterate through UIelements/gameobjects to get coordinates/textures and draw stuff that way, or do I add the actual drawing code to the gameobject classes themselves, then iterate through and call it in each of them?

For simpler games, I wouldn't worry about it. As the game gets more complex, separating the rendering from the logical game objects makes more sense.

What about the textures? Do I keep them in a separate container in the main class, thus allowing me to use the same texture for several objects, or do I store each object's texture inside the object thus leading to duplication but no time spent searching for the texture?

A typical solution is to have a class which holds an associative container to shared texture pointers (such as std::map<std::string, std::shared_ptr<Texture>>). This avoids the need to load a given resource twice.

The actual classes that do the rendering will request their texture(s) during initialisation, and store them locally. For instance, taking a PacMan example:
class Texture {
    // Immutable texture class...
};

typedef std::shared_ptr<Texture> TextureHandle;

class Loader {
    typedef std::map<std::string, TextureHandle> Cache;
public:
    TextureHandle load(const std::string &amp;name) {
        Cache::iterator it = cache.find(name);
        if(it == cache.end()) {
            TextureHandle texture = loadFromDisk(name);
            cache.insert(std::make_pair(name, texture));
            return texture;
        }
        return it->second;
    }
private:
    Cache cache;
};

class GhostRenderer {
public:
    GhostRenderer(const Loader &amp;loader) : texture(loader.load("ghost")) {
    }

    void draw(Renderer &amp;renderer, const Ghost &amp;ghost) const {
        renderer.drawQuad(ghost.bounds(), texture, ghost.colour());
    }

private:
    std::shared_ptr<Texture> texture;
};
I haven't compiled or tested this code.

Note there that for a game like Pac Man, separating the rendering code from the game object (while theoretically better) might not buy you much.

Maybe just store a pointer to a place in a container?

Handing out pointers that point to a location inside a container is typically brittle, both because raw pointers are usually unnecessary and frowned upon, and because modifications to the container could invalidate such pointers.

... but it has led me to question what the most efficient way ... in terms of performance ... but that would definitely add a lot of overhead ...

Performance/efficiency is a siren whose call has ensnared many a lost soul. In particular, inexperienced individuals often make questionable decisions based on their "hunches" about the speed of code.

First things first, you need something working before you can discover if it is fast enough. Think about a new car - would changing some panels make it more or less aerodynamic, or make no difference at all? There is no way to answer that question in general - it is 100% dependant on the nature of the car in question.

Most importantly, for small projects efficiency is often one of the easiest things you can "add later" as needed, particularly if you bootstrap yourself with naive data structures, algorithms and memory layouts. Larger projects presently more difficulties because some design decisions will end up propagating assumptions deep into a body of code, where it is more resistant to change.

As of right now, I haven't even started on the actual game.

Start.

The biggest threat to a game - any game - is not potential performance problems, nor is it architectural code issues, it is not having gameplay, mechanics and controls all implemented and working.

#1rip-off

Posted 20 November 2012 - 06:12 PM

But in that regard, should I make a game class/object that is separate from my current main class which currently just contains SDLstuff/graphics/eventhandling and such?Or do I just keep it all inside one huge main class?

You don't want to have any huge classes. Ideally, each class will be focused, it will have a "single responsibility". This is a good goal, but when you're starting out it isn't the only thing. It will come with time.

Some great articles on class design, the SOLID object oriented principles from "objectmentor":

For instance, what would be a good way of only calling the writing function for stuff that will actually be visible? I could just check the coordinates, but that would definitely add a lot of overhead every time I'm rewriting the screen.

It depends heavily on the game. Performing visibility tests in Pong would be a waste, while drawing every object to the screen wouldn't work on Minecraft. For small games or at the very beginning, drawing everything every frame usually works and doesn't take too long to write. I'd start there.

For instance, do I keep the drawing code in my game/graphics class and iterate through UIelements/gameobjects to get coordinates/textures and draw stuff that way, or do I add the actual drawing code to the gameobject classes themselves, then iterate through and call it in each of them?

For simpler games, I wouldn't worry about it. As the game gets more complex, separating the rendering from the logical game objects makes more sense.

What about the textures? Do I keep them in a separate container in the main class, thus allowing me to use the same texture for several objects, or do I store each object's texture inside the object thus leading to duplication but no time spent searching for the texture?

A typical solution is to have a class which holds an associative container to shared texture pointers (such as std::map<std::string, std::shared_ptr<Texture>>). This avoids the need to load a given resource twice.

The actual classes that do the rendering will request their texture(s) during initialisation, and store them locally. For instance, taking a PacMan example:

class Texture {
// Immutable texture class...
};

typedef std::shared_ptr<Texture> TextureHandle;

class Loader {
typedef std::map<std::string, TextureHandle> Cache;
public:
TextureHandle load(const std::string &name) {
Cache::iterator it = cache.find(name);
if(it == cache.end()) {
TextureHandle texture = loadFromDisk(name);
cache.insert(std::make_pair(name, texture));
return texture;
}
return it->second;
}
private:
Cache cache;
};

class GhostRenderer {
public:
GhostRenderer(const Loader &loader) : texture(loader.load("ghost")) {
}

void draw(Renderer &renderer, const Ghost &ghost) const {
renderer.drawQuad(ghost.bounds(), texture, ghost.colour());
}

private:
std::shared_ptr<Texture> texture;
};

I haven't compiled or tested this code.

Note there that for a game like Pac Man, separating the rendering code from the game object (while theoretically better) might not buy you much.

Maybe just store a pointer to a place in a container?

Handing out pointers that point to a location inside a container is typically brittle, both because raw pointers are usually unnecessary and frowned upon, and because modifications to the container could invalidate such pointers.

... but it has led me to question what the most efficient way ... in terms of performance ... but that would definitely add a lot of overhead ...

Performance/efficiency is a siren whose call has ensnared many a lost soul. In particular, inexperienced individuals often make questionable decisions based on their "hunches" about the speed of code.

First things first, you need something working before you can discover if it is fast enough. Think about a new car - would changing some panels make it more or less aerodynamic, or make no difference at all? There is no way to answer that question in general - it is 100% dependant on the nature of the car in question.

Most importantly, for small projects efficiency is often one of the easiest things you can "add later" as needed, particularly if you bootstrap yourself with naive data structures, algorithms and memory layouts. Larger projects presently more difficulties because some design decisions will end up propagating assumptions deep into a body of code, where it is more resistant to change.

As of right now, I haven't even started on the actual game.

Start.

The biggest threat to a game - any game - is not potential performance problems, nor is it architectural code issues, it is not having gameplay, mechanics and controls all implemented and working.

PARTNERS