OOP Help

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

User avatar
thejahooli
Chaos Rift Junior
Chaos Rift Junior
Posts: 265
Joined: Fri Feb 20, 2009 7:45 pm
Location: London, England

OOP Help

Post 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
I'll make your software hardware.
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: OOP Help

Post 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.
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
wearymemory
Chaos Rift Junior
Chaos Rift Junior
Posts: 209
Joined: Thu Feb 12, 2009 8:46 pm

Re: OOP Help

Post 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);
User avatar
RyanPridgeon
Chaos Rift Maniac
Chaos Rift Maniac
Posts: 447
Joined: Sun Sep 21, 2008 1:34 pm
Current Project: "Triangle"
Favorite Gaming Platforms: PC
Programming Language of Choice: C/C++
Location: UK
Contact:

Re: OOP Help

Post 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
Ryan Pridgeon
C, C++, C#, Java, ActionScript 3, HaXe, PHP, VB.Net, Pascal
Music | Blog
User avatar
thejahooli
Chaos Rift Junior
Chaos Rift Junior
Posts: 265
Joined: Fri Feb 20, 2009 7:45 pm
Location: London, England

Re: OOP Help

Post 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.
I'll make your software hardware.
User avatar
Arce
Jealous Self-Righteous Prick
Jealous Self-Righteous Prick
Posts: 2153
Joined: Mon Jul 10, 2006 9:29 pm

Re: OOP Help

Post 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
<qpHalcy0n> decided to paint the office, now i'm high and my hands hurt
User avatar
Ginto8
ES Beta Backer
ES Beta Backer
Posts: 1064
Joined: Tue Jan 06, 2009 4:12 pm
Programming Language of Choice: C/C++, Java

Re: OOP Help

Post 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:
Quit procrastinating and make something awesome.
Ducky wrote:Give a man some wood, he'll be warm for the night. Put him on fire and he'll be warm for the rest of his life.
OverlordYertle
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 12
Joined: Fri Mar 06, 2009 8:42 pm
Favorite Gaming Platforms: Dreamcast
Programming Language of Choice: C++

Re: OOP Help

Post 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.
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: OOP Help

Post by MarauderIIC »

I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: OOP Help

Post 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:
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
wearymemory
Chaos Rift Junior
Chaos Rift Junior
Posts: 209
Joined: Thu Feb 12, 2009 8:46 pm

Re: OOP Help

Post 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.
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: OOP Help

Post by Falco Girgis »

And you people do realize that inheriting virtual functions are slower, right? Vtables.
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: OOP Help

Post 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-)
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
User avatar
Arce
Jealous Self-Righteous Prick
Jealous Self-Righteous Prick
Posts: 2153
Joined: Mon Jul 10, 2006 9:29 pm

Re: OOP Help

Post 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
<qpHalcy0n> decided to paint the office, now i'm high and my hands hurt
fantastico
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 20
Joined: Fri Mar 20, 2009 4:37 am
Location: Germany

Re: OOP Help

Post 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.
Post Reply