Page 1 of 2

OOP Help

Posted: Mon Apr 13, 2009 5:26 pm
by thejahooli
I'm just starting to write my programs in an OO design, but I need some help on how I would be able to acess a class from another class, even when it has not been created.
e.g. If i need to be able to draw a character to the screen from my character class using a function from my graphics class.
I think that I might need to use a pointer to the graphics class in my character class but I'm not totally sure how to impliment it.

maybe like this

Code: Select all

class Graphics
{
public:
	//Methods
	DrawSprite(int x, int y, SDL_Surface* source);
private:
	//Data
};

class Character
{
public:
	Character(Graphics * gameGraphics);
private:
	Graphics ** graphics;
};

Character::Character(Graphics* gameGraphics)
{
	graphics = &gameGraphics;
}

This is probably not right so could someone please give me some ideas if it isn't

Re: OOP Help

Posted: Mon Apr 13, 2009 5:59 pm
by dandymcgee
You would either have to instantiate an object of the Graphics class and pass it to the Character class (similar to what you're example looked like), or use inheritance so that Character was derived from Graphics. Depending on how you're using the Graphics class this may or may not be a good idea.

Example with Inheritance:

Code: Select all

CODE: SELECT ALL
class Graphics
{
public:
   //Methods
   DrawSprite(int x, int y, SDL_Surface* source);
private:
   //Data
};

class Character: public Graphics
{
public:
   Draw();
private:
   //private variables
};

Character::Draw()
{
   DrawSprite( x, y,  source );
}
If you're using the Graphics class as your renderer, you may want to consider a singleton pattern. Then you would just store a pointer to the instance in your Character class.

Re: OOP Help

Posted: Mon Apr 13, 2009 6:25 pm
by wearymemory
I've never heard of a character drawing itself to the screen, but then again, I'm quaint with Java, and C++ not so much (therefore I may be wrong in saying this, and in that case I apologize), but OO shouldn't carry much of a difference between the two.

Keep graphics handling in the Graphics class, and character data in the Character class. Create an object of the class Character, and use the object's variables as needed to render the character. Your character should hold information on its location, and probably even its own sprite.

An example of doing this (could be):

Code: Select all

// Initialization.
Character test(Sprite("CharacterSprite.bmp"), 0, 0);

// In update loop
drawEntity(test.sprite, test.x, test.y);

Re: OOP Help

Posted: Mon Apr 13, 2009 6:55 pm
by RyanPridgeon
You will need to either pass them to each other, and design your functions in a way that they can take the classes as a parameter, or use another method such as a singleton.

A singleton is basically a class which holds an instance of itself. Some people frown upon it, but it's an easy solution and works well when used in the right situations.

Here is one method of using singletons (the one I use)

Code: Select all

#include <iostream>

class Graphics {
    public:

    // standard class functions:
    Graphics(){
    }
    void Speak(){
        std::cout << "hello!";
    }

    // the instance is held here
    static Graphics* get(){
        static Graphics* instance;
        if (!instance){
            instance = new Graphics();
        }
        return instance;
    }
};


int main(){

    // here is how you use it!
    Graphics::get()->Speak();
    return 0;
}

// RyanPridgeon

Re: OOP Help

Posted: Mon Apr 13, 2009 8:16 pm
by thejahooli
I sort of understand what you're saying. But if anyone could possibly go into a bit more detail on singletons or tell me a good place to read on them.
I understand what they do I would just appreciate some more knowledge on implimentation.

Re: OOP Help

Posted: Mon Apr 13, 2009 9:02 pm
by Arce
You could make your "graphics" class abstract and implement it through the character? Or have some kind of hierarchy where each drawable object inherits from a "graphics" parent that contains attributes relating to drawing (image, size, alpha, whatever), so you can simply downcast and pass to a draw function, or overwrite/define a draw method.

I know not too much help, just tossing out ideas without too much time to read the full topic. ;p

The idea is to make a method in the draw class that expects some kind of abstract object. Then, as you pass the specific objects, (character, npc, background, etc) which are all different classes, you can simply downcast to the "drawable" object and the draw can treat them all the same.

If you choose this method (good OOP) be weary of the diamond hierarchy problem if you're using C++ (google it if you haven't already run into it). If you're pretty new to inheritance, I'd either suggest taking the singleton approach (less "proper OOP") or acquainting yourself with it via tutorials (read up on abstract vs concrete inheritance, virtual inheritance and methods, multiple inheritance) then return here and try to implement this idea. Ultimately, it really depends on how much of a "good OOP" you're going for. This is probably the most "proper" way of the above listed. ;p

edit: Yeah, this is pretty much exactly what Dandy was saying, shoulda read, haha. ;p

Re: OOP Help

Posted: Mon Apr 13, 2009 10:52 pm
by Ginto8
Arce wrote:You could make your "graphics" class abstract and implement it through the character? Or have some kind of hierarchy where each drawable object inherits from a "graphics" parent that contains attributes relating to drawing (image, size, alpha, whatever), so you can simply downcast and pass to a draw function, or overwrite/define a draw method.

I know not too much help, just tossing out ideas without too much time to read the full topic. ;p

The idea is to make a method in the draw class that expects some kind of abstract object. Then, as you pass the specific objects, (character, npc, background, etc) which are all different classes, you can simply downcast to the "drawable" object and the draw can treat them all the same.

If you choose this method (good OOP) be weary of the diamond hierarchy problem if you're using C++ (google it if you haven't already run into it). If you're pretty new to inheritance, I'd either suggest taking the singleton approach (less "proper OOP") or acquainting yourself with it via tutorials (read up on abstract vs concrete inheritance, virtual inheritance and methods, multiple inheritance) then return here and try to implement this idea. Ultimately, it really depends on how much of a "good OOP" you're going for. This is probably the most "proper" way of the above listed. ;p

edit: Yeah, this is pretty much exactly what Dandy was saying, shoulda read, haha. ;p
One of the main problems with the OO approach may present is problems with performance, or having to do some very convoluted OO magic to make it really work, which will end up decreasing both code readability and performance. In the end, singletons are much less of a drag on performance and there's very few real reasons not to use them, asides from when you're paid and have a huge team of debuggers that can't grasp the concept of singletons. :mrgreen: :lol:

Re: OOP Help

Posted: Tue Apr 14, 2009 12:21 am
by OverlordYertle
I think it's a really bad idea having the Character class draw itself. Seems like in the long run you're just going to cause more headaches than anything else. I understand you're trying to make sense of it and your willingness to learn is excellent. I feel though you're going to end up doing something more difficult just because of the mindset you might have right now.

I would suggest letting nothing handle the graphics except your graphics class. It will help prevent any sort of corruption or possible errors with drawing if all the drawing takes place in one spot. There's a lot of ways to boost the speed of what i'm about to say, but in it's most basic form i would say that after your game world steps get a list of all the objects you want drawn and send them to the graphics. Then the graphics can loop through all the objects and draw them.

You could also have an alert in your game world that the list is ready to be picked up. Just like a bool that's like "ready = true" then when you step the graphics you could send the list in and draw. For a basic example so you hopefully get the idea:

Code: Select all

while(!isOver){ //As long as the game is going
    vector<characters> pickUp; //A vector to hold all of the character information for drawings
    World.step(); //Step through the world movements
    pickUp = World.getToDraw(); //Get the list of things you want to draw
    Graphics.drawList(pickUp); //Send that list into your drawing class to print to the screen
}
I hope this helps. Ultimately you need to do what works for you, but i feel this is going to help you out in the end.

Re: OOP Help

Posted: Tue Apr 14, 2009 2:58 pm
by MarauderIIC

Re: OOP Help

Posted: Tue Apr 14, 2009 2:59 pm
by dandymcgee
OverlordYertle wrote:There's a lot of ways to boost the speed of what i'm about to say, but in it's most basic form i would say that after your game world steps get a list of all the objects you want drawn and send them to the graphics.
I'm fairly certain that passing a pointer would be a great deal faster than passing a vector and then iterating through it (although I could very be wrong :mrgreen: ). And I believe inheritance would be even faster, because your just calling the inherited function directly.

I'm not sure why everyone keeps saying it's a bad idea for a Character to draw itself.. that's not what he's doing at all. He's asking what the best way to tell the Graphics class to draw the character is.
Arce wrote:edit: Yeah, this is pretty much exactly what Dandy was saying, shoulda read, haha. ;p
You went into full detail, it may have been a bit more helpful to him. :lol:

Re: OOP Help

Posted: Tue Apr 14, 2009 5:33 pm
by wearymemory
dandymcgee wrote:
OverlordYertle wrote:There's a lot of ways to boost the speed of what i'm about to say, but in it's most basic form i would say that after your game world steps get a list of all the objects you want drawn and send them to the graphics.
I'm fairly certain that passing a pointer would be a great deal faster than passing a vector and then iterating through it (although I could very be wrong :mrgreen: ). And I believe inheritance would be even faster, because your just calling the inherited function directly.

I'm not sure why everyone keeps saying it's a bad idea for a Character to draw itself.. that's not what he's doing at all. He's asking what the best way to tell the Graphics class to draw the character is.
Arce wrote:edit: Yeah, this is pretty much exactly what Dandy was saying, shoulda read, haha. ;p
You went into full detail, it may have been a bit more helpful to him. :lol:
It is not everyone. And we were under the impression that the OP wanted OO help. In which case, it would be a bad idea to have the character draw itself (let alone have any sort of reference to the Graphics class, it's just not necessary!).

And if that wasn't what the OP meant, then I apologize for misinterpreting his or her question.

Re: OOP Help

Posted: Tue Apr 14, 2009 11:04 pm
by Falco Girgis
And you people do realize that inheriting virtual functions are slower, right? Vtables.

Re: OOP Help

Posted: Wed Apr 15, 2009 2:56 pm
by dandymcgee
GyroVorbis wrote:And you people do realize that inheriting virtual functions are slower, right? Vtables.
Nope I didn't. Thanks for pointing that out. 8-)

Re: OOP Help

Posted: Wed Apr 15, 2009 8:27 pm
by Arce
Though not by much? Probably O(1), O(n) if it's really gay. If anybody has time to google it lemme know. ;p

Re: OOP Help

Posted: Thu Apr 16, 2009 4:35 am
by fantastico
Arce wrote:Though not by much? Probably O(1), O(n) if it's really gay. If anybody has time to google it lemme know. ;p
I'm pretty sure it's O(1) in the sense that for any class hierarchy it takes only 1 table lookup at runtime to find the function to be executed.