Question about classes in C++

So yeah, I’m new to programming in general. But I need help organizing the structure of a game I’m trying to program for practice…
I got my graphics environment working (at least I think!)

I just need to know how to set up my classes…Or just how I should do this in general.

My game. Ever play the game, Intelligent Qube for PS1? Well I really loved it, and it seems simple enough to do. I will be doing a 2d top-down version. Here’s a basic overview for those of you who haven’t played it.
On second thought here’s a link to a video of the game to make it easier to understand.

link to video
Well it’s a really cool game, and I’d like to try to figure out how to make a clone so I can learn some things about it.

So I was trying to think of the way to structure the program, and I had a few ideas. One is pretty bad, and I would like to avoid it.

I could always go for one single 2d array that holds all of the data with various functions that would advance the blocks and destroy them depending on what the player does. This would be very boring and tedious I believe. I just did a test of this without graphics (text only) and it was cumbersome to ensure that the movement and everything worked right.

For example, to advance the blocks, I had to write two loops to check every block, and move the contents up to the next one. I need to learn how to use classes better, and would like to be able to involve them.

The best thing I can think of doing would be to create a “block” class and to use every variable possible inside.

Perhaps I can use the board as a way to communicate between the block and the player? That makes the most sense to me, but it seems clumsy. Would I need to have every cell of the board have a different state? THe possible ones are “Normal Block” “Death Block” “Green Block” “Blue Bomb” “Green Bomb” “Player 1” and any combination thereof. It seems tedious.

I’ve been having this problem. I know how to use classes but I don’t know how to use them in any way that makes my life easier. I keep running into situations where I want a nested class to work on things that are in it’s parent class. I could get around this by writing the functions in the main area of the class, but then why not just write the functions in the main function then?

Anyone want to enlighten me as to what I’m missing here?

ETA:

I suppose I could sum up my problem by saying, how do you work with various objects and the board? Let’s say if I were making a Super Mario clone. I want Mario to interact with a Goomba. How do I do that? Do I have all of the information as to where they both are stored in the board? Surely there is some way for the Mario object to send a message to the Goomba object telling the goomba that it is dead when he jumps on it, right?

In general you should identify the different kinds of elements which exist in the environment, e.g. blocks and the little man in the first game, Mario and Goombas in Super Mario, and create a class for each. You then need to identify the interactions possible between the elements, e.g. class A element can shoot class B or class C eats class D elements. These interactions are coded as methods on the element classes. Finally you need to place the elements in the game space. For your Intelligent Qube a 2D array may indeed be suitable (though I got bored of the video before I really worked out quite what was going on :frowning: ). As elements move within the game space they can interact with (i.e. invoke methods on) elements occupying the same or adjacent locations based on the rules of the game.

You should probably try to make each element as autonomous as possible rather than code some big-brother style super-controller. That is how things interact in the real world and it makes sense to reflect that in your virtual one.

I couldn’t work out what was going on in the video. But, I’d have a Block class, and a Player class at least.

The game board would be a std::vector of Block’s (it looks like the board resizes after every round). Each Block would have an intersect() method taking a const Player& as parameter, and returning true if the player is straggling that box (or fully inside it), and also some way of recording the block’s state (i.e. red bomb, blue bomb etc).

You need a main loop, then, to test each block in turn for interection with the player, then decide upon the players fate.

This design can probably be improved, but the best way of finding the best design is to make a rough design, code a prototype, and see what went wrong (IMO, YMMV).

I read that you should consider what things would change together if they were to change, and group them into a class. That is, a class contains methods and data fields in a tidy way so there are only a small number of ways you interact with those things from outside the class. Therefore, things that are logically intertwined enough that you need to consider them all together when messing with any of them should be grouped into a class, and when you are messing with other things you only have to think about the few connection points in and out of that class and can forget everything happening inside it.

just a quick question…

so if I make classes like this, and this is kind of what I have now…



class cb
{
    public:
        class badguy   // this is for the blocks, I have a hard time of thinking of names
        {                   // so help me if you can...
            public:
                int x;
                int y;
                bool state;        // if it is then this will be destroyed next time
                int type;           // 0 = empty, 1 = normal, 2 = green, 3 = black

                int GetX(){return x;};
                int GetY(){return y;};
                bool GetState(){return state;};
                void SetState(bool a){state = a;};
                int GetType(){return type;};
                void SetXY (int a, int b){x = a; y = b;};
                void SetType(int a){type = a;};
                void SetAllStates(int a, int b, bool c, int d)
                {
                    x = a;
                    y = b;
                    state = c;
                    type = d;
                };
        };

        class character
        {
            public:
                float x;
                float y;
                bool alive;
                bool droppedBomb;
                bool detonatedBomb;
                float getX (){return y;};
                float getY (){return x;};
                bool isAlive(){return alive;};
                bool isBombDropped(){return droppedBomb;};
                bool isDetonatedBomb(){return detonatedBomb;};
                void setXY (float a, float b){x = a; y = b;};
                void setAlive(bool a){alive = a;};
                void setDroppedBomb(bool a){droppedBomb = a;};
                void setDetonatedBomb(bool a){detonatedBomb = a;};
        };

        class surface
        {
            public:
                int sizeX;
                int sizeY;
                int numOfBlocks;
                int cell[MAXX][MAXY];

                void SetNumOfBlocks(int a){numOfBlocks = a;};
                int GetNumOfBlocks(){return numOfBlocks;};
                int GetCellValue(int x,int y){return cell[x][y];};
                void SetCellValue(int x,int y,int z){cell[x][y] = z;};
                void SetSizeX(int x){sizeX = x;};
                void SetSizeY(int y){sizeY = y;};
                int GetSizeX(){return sizeX;};
                int GetSizeY(){return sizeY;};
        };

        surface board;
        badguy block[32];
        character P1;
        character P2;
        // functions
        void InitializeBlocks();
        void advanceBlocks();
        void ReadWrite(const char*);    // actually a read in and initialize blocks function.
};



question, so here’s the setup:

I have cb::badguy // the blocks
cb::surface // the board
cb::character // the player

in main, I declare

cg Game;

which creates:
Game.block[32] (cb::badguy)
Game.P1 (cb::character)
Game.board (cb::surface)

so how do I have Game.block.SomeMethod(); interact with Game.P1.x?

the only way I could figure out how to do that was to have a something like Game.SomeOtherMethod(); to interact with it.

Is this a possible pointer situation? Do I need to have them interact on the same level with pointers?

Here’s my plan so far:
There will be a function that moves the blocks at the cb:: level. These blocks will check the board before they go, and also check the player’s position which will also be on the board. If it is sitting on top of the bomb when it is detonated then it disappears. If it crushes the guy etc…

I planned on using the board to store messages that needed to be sent.

But I’d rather have them interact more liberally like was mentioned above.

I would have a Game class that contains, among other things, an instance of a GameBoard or GameSpace class. The GameSpace class would have a size and whatnot. It would also have a container (think std::list) of Sprites. The Sprite class would hold spatial coordinates, visibility flags, etc. Inheriting from Sprite would be Character and Badguy (and PowerUpWhateverThingy, etc.)

A call to Game::Update() would, among other things, call GameSpace::Update() which would, among other things, call (virtual) Sprite::Update() (probably overridden by the daughter classes). This could happen before of after collision handling.

For collision handling, you’re simply going to have to ask whether each Sprite is interacting with another Sprite. You’d have a nested loop over the list of Sprites (this could sensibly happen in GameSpace::Update()), and you’d call Sprite::Interact(const Sprite&) or, if you prefer, the similar Sprite::Interact(const Sprite*). This would handle whatever needed to happen, asking what the relative positions are and modifying the first Sprite as needed. You could halve the loop time by having Interact() deal with both the calling Sprite and the argument Sprite at the same time: Sprite::Interact(Sprite&). You could also save loop time by keeping the baddies list separate from other sprites if, for example, the game never does any interactions baddie-to-baddie. But I don’t know the game rules. Remember the golden rule, though: Optimizing like this ahead of time is the way to madness. Just code it up in the most transparent and flexible way possible, and then, if performance is bad, run a profiler and find out why. Time sinks are almost never where you suspect, especially in C++.

Anyway, those are my first thoughts. Sounds like a fun project to learn on. Oh, yeah, in your example code: Good style would have you declare x, y, etc., as either protected or private rather than public. Things that interact with the class should not be allowed to access those data members directly. Imagine if you later decided later that you needed to store the coordinates in a two-vector object (say, Vector2 that has, say, Vector2::Norm() and other useful stuff defined.) If all other classes are accessing x through YourClass::GetX(), then you have to change only a couple of lines in YourClass to upgrade to Vector2. But if x is public, then you (if your slip up) or someone else (if your project expands) might be using YourClass::x all over the place. If you try to modify how you store the x,y data members, you’d have to change all that other code that uses x this way. Make data members public only if you have a very good reason for it. And if you think you do, there’s probably something else wrong in the design. Look up “encapsulation” for more on this important C++ concept.

thanks for the response, Pasta.

But real quickly, is it possible to have classes that are on the same level deal with each other without some kind of intermediary? It would obviously be far easier for the player and blocks to interact without even including the board. Is this impossible to do? for example…



class A
{
     class B
     {
      int x, y;
     };

     class C
     {
     int a, b;  
     };
};


if I wanted to have a method in A::C that copies a to A::b::x, how would I do that?

I realize I could do this by putting the function on the A::Some_Function() level and do it that way, but can I do it the way I want? I don’t mind using pointers, as long as it is worth it.

I’m somewhat new to C++, but I would think you could just do something like this, when you were declaring class C:


class C {
private:
  int a, b;
public:
  copy_a_to_Bx(B& someBobject) {
    someBobject.setX(a);
  }
};

Then, in main you have, let’s say myBobj, which is of type B, and myCobj, which is of type C. You can now just call:


myCobj.copy_a_to_Bx(myBobj);

You need the & because otherwise, it will make a copy of the B object, and change the x value of the copy, not the original object.

YMMV, obviously, but I don’t think it’s stylistically a good idea to have a method in one class whose sole purpose is modifying the member data of another. The whole point of a class is “data + operations on that data”.

There’s no need to have everything inside a method in C++.

I think you’ve hit the nail on the head in your OP. Programming is tedious, and OOP is no miracle cure.

The general guideline for programming, and the place where OOP or anything comes else into play, is to reduce the complexity of whatever it is on your screen. If you’re looking at your render code, you want a high-level view and you want to move the details into other functions. This heirchical view makes it easier to keep part of the program you’re working on in your head (and, especially, for someone else or you sometime in the future to read it). In the end, though, the complexity/tedium doesn’t really go away. Not unless you change programming paradigms or frameworks (e.g. move to .NET + Boo) or something else that’s drastic.

So, to be more specific, looping through every block in a boring way is probably what you’ll have to do no matter what. Only thing you can do is to parsel this out, so e.g. you put all the dirt into a Block.Update() and the loop itself takes up a neat two lines in your main function.

You’ll note that all of this makes less and less difference the smaller and simpler your program is. For very small functions, it’s sometimes neater to program in assembly! But it’s on big projects that OOP really makes a night-and-day difference.

This actually sounds like a good plan. It’s intuitive and will make thinking about your program much easier. To have different kinds of blocks, exploit inheritence and polymorphism. (Ie, you’ll have a loop that calls Update on every block using a base class pointer, and then each block magically executes its specific Update routine.) I think going down this path will really show you what OOP is about. In fact, I must say, that’s exactly how I started.

Again guys, I really appreciate your input here, it’s tremendously helpful.
Secondly, as for having methods to interact with all of the data… Well I dunno. I had decided to put in a lot of work with my classes to hopefully stumble upon what I think OOP should be all about. I don’t have any particular reason. I think of it mainly as a learning experience, so I’m not afraid to make mistakes here. I’ve always heard that the best way to program is to plan extensively and then to code. I would certainly agree with this, but I think that there are so many intricacies that I don’t know yet that I can’t really plan it all very well.

Bolding mine.

What does this mean exactly? I’ll tell you what I had planned, and maybe you could explain it to me in the context of that. Please excuse my terminology as I’m not sure that I know the right terms. I’m going to refer to the classes as they are declared in my main program, not the class definitions…

so in Main, I create an instance of class cb called Game
which in turn creates instances of the classes that it holds called block[24], there will be another class in Game called board, which contains an array called cell[6][32] (this is the board) and finally Game also creates a class called P1, which holds information about x/y positioning, etc. All the pertinent info.

I had planned on writing the method Game.AdvanceBlocks(). This will advance the blocks. This method will allow the blocks to advance and update their individual status based on what is going on with the board. So if the P1 class drops a bomb, it will be noted on the board. If a block is on top of the bomb when it is detonated (this is again sent through the board) then the method will set the block’s status to false…

Anyway, the method Game.AdvanceBlocks() will have access to all three types of data (board, player, blocks) and will be able to check the status of each and allow them to fully interact. I think I can make it work the way I’ve planned, but I’d like to know more about this and learn more.

I don’t know what a base class pointer is. Could you explain? I am trying to understand it from stuff I’m reading but it’s still a bit foggy.

Research c++ ‘inheritance’ and ‘polymorphism’. Basically, you’ve been thinking of objects as just structures+functions. To be honest, that’s what 95% of OOP is in everyday life. But in your case, you can exploit some of the “gee-wiz” features of c++ to good effect. What inheritance and polymorphism let you do is make specialized classes (like you said, “normal block”, “green block”, etc.) but treat them in a generic way. So you define the behaviors that any block should have. It should be able to, e.g., draw a picture of itself and update its state for the next frame. Each of the specialized blocks will do those things differently. Now you might think, “I could just have one block class that knows what kind of block it is, and i’ll use an if statement inside its Draw function to do the right thing.” That’s one way to do it. The more elegant way is to use base and derived classes and exploit polymorphism. Ie, let the compiler handle it. I’m not going to explain more, go read.

The definitive book on C++, the one I used to learn it, is this one:

(please don’t pay attention to the retarded cover)

However, you might want to consider learning C# because it’s a little more evolved in the OOP concepts. E.g., instead of “abstract base class” you have the keyword “interface” which makes about three times as much intuitive sense to a beginner. Plus, of course, you don’t have to manage memory and pointers.

Ugh, unfortunately, the program you are trying to write may be simple enough that setting up a class heirarchy and using advanced features will be a bunch of work with questionable gain. But I DON’T want to tell you to go find something more complex to do.

Basically, when you had your idea of making a model of the board and have all those different types of cells, and you thought it’d be simpler to just make one big array: Honestly, you may be right (in this particlar case). But for the sake of learning, structure your game as a model of the board like you said with an eye on making your game more sophisticated in the future (e.g., introducing new types of cells, blocks, interactions). This forward-thinking is also a big part of good programming, and another place where OOP shines.

Alex

Thanks for your very helpful input. I really appreciate it. I’ve learned about Inheritance and Polymorphism now, and I can see what you mean. I need to exploit inheritance so I can save myself some effort. I could have saved a lot of time there! I haven’t re-written anything yet though, but I had a different question.

You’re saying that I should exploit polymorphism to get each type of block to do it’s own thing. I’m still with you there. I just learned about this and it makes loads of sense.

Now just one last thing. How can I make the blocks aware of the location of the player? This is very important. I have designed a test that is similar to what I want to do here, but I wanted to run this by you to see if I could do this more elegantly.

I’ll just start and paste these test classes. Also note, that I didn’t use any kind of inheritance here as I wanted to keep it as simple as possible.



#include <iostream>

class Player
{
	public:
	int pos;
	int getPos(){return pos;};
};

class Block
{
	public:
	int pos;
	int getPos(){return pos;};
	
        // heres the stuff to get the player info
        Player* pPlayer;           
	int getPlayerPos();
	void SetPlayer(Player*);
};

void Block::SetPlayer(Player* a)
{
	pPlayer = a;
}

int Block::getPlayerPos()
{
	return pPlayer->getPos();
}
int main()
{
	Player p1;
	Block b1;
	
	b1.SetPlayer(&p1); // set pointer to p1.
	p1.pos = 5;           // set it to a value for testing
	
	cout << b1.getPlayerPos() << endl;
	cout << p1.pos;
}


The output for this code is:
5
5

which means that it is working. But is there a better way to do this? If I want these objects to work in an independent fashion, they’ll need to know information about the other stuff on the board. Is this the best way to do this?

In this case, because you have exactly one player, the simplest solution is just a global variable. In general, your game will have a lot of this kind of global state and it’s natural to either just make the variables global, or put them into one data structure that objects have a pointer to.

However, you have to also be considering something else. If all your objects up and down your code are using these global variables, it means your code is poorly factored. ‘Factored’ is a word that comes from the way mathematical equations get broken down into factors, which make manipulating and solving them far easier. Any change to your program at the high level will require lots of changes at the low, making it a) fragile b) hard to read or think about c) difficult to substantially change.

A good way to make code factored is to not require classes (or people writing those classes) to be thinking hard about external things. That is, someone might say a block should only know about itself, and if it needs to know where the player is, then make its Update function be Update(position_t currentPlayerPosition). This may be extreme, but heed the point. You may use these external references in the highest-level code, but when that code calls lower functions, draw the line and force the data to pass through arguments.

In general, you want to factor the code so that there’s a number of low-level functions that do one task, do it well, don’t care what the rest of your code looks like, and the rest of the code doesn’t care how they do it. This is factorization.

But on second thought, I see you already made a Block.getPlayerPos() function instead of accessing pPlayer directly. Not saying anything about this particular decision (every abstraction and wrapper also has a cost) but I think you get it : )

Oh, I want to say one more thing: ‘polymorphism’ is one of those dumb words that academics come up with, and it had a sort of symbolism to the original OOP movement. They thought about ‘objects’ (meaning ‘things’) that were in these taxonomical heirarchies, and it was all about metaphors for the real world. Polymorphism was meant to reflect how certain objects would have many (‘poly’) forms (‘morphs’). This all actually relates almost perfectly to what you’re doing now with writing a game that is filled with objects, objects that are often similar but have their own specializations. But all this philosophy relates less well to other problems, to more abstract programs that programmers usually write. However, inheritance is still very useful in those cases, but for a seemingly different reason. Inheritance allows you to set up contracts, specifying which methods or variables a class must have. By using inheritance and thus using repetition, you make your code more regular and simpler. Another way to call these base classes is ‘interfaces’, which I think might sum it up better.

Hey Alex.

Well, to be honest, I didn’t really succeed in my attempts, I suppose. I started off with a nice object-oriented approach, but I ended up doing things in a more procedural fashion because I just wanted to get it done. I did this all before I understood how inheritance and polymorphism works. The way I have it going now is I created an array of block objects, or an array of bomb objects. Then when I need to check what they are up to, I simply say block[a].GetStatus() in a for loop and am done with it.

I really wish I could do this better, but I noticed one problem that is holding me back from putting functionality into my objects. When it comes to drawing things, I have to do it in main, because with my graphics package I have to instantiate a specific class, and that creates the window.

But really I wanted this to be a good example of something I could show people to hopefully get an internship. Would this be a good idea to show people this? I’m pretty sure my mistakes will be obvious, but the fact that it does work must count for something, right? If you want to check out what I have so far I’d be more than happy to show you.

I’m just afraid that if I try to change it too much I’ll make it even worse…

It takes quite a while to really get how to effectively use inheritance and polymorphism in practice. I do a lot of application development in C# in my job (its only been 6 months of work experience in it however), and I’ve just now started to find some cases where I was able to use polymorphism well. However I do use interfaces as a contract kind of thing a fair amount.

The number one thing I’ve found to reduce my debugging headaches and making it easier to change things around later on is to look through all my code; find the longest and most convoluted method, and look for how it could be broken up into smaller pieces that would do some part of the task. Sometimes this takes a fair amount of work and shifting local variables and so on, but having complicated nested control structures can cause a lot of trouble.

So how I handle the classes, is eventually by breaking the overly big methods apart, I get a class that seems like its doing too much work. Then I go by what methods use what fields. If most of the methods only use some of the fields, I will often break up the class into two classes, putting the methods together with the fields they use. But I also create new classes when I have some task that needs to be done in association with a set of data.

Basically, when I first write up some new part of code, I only worry about making it work right and often end up writing a lot of code in a single function, but after a day or two I make a lot of changes. You can do a lot changing your code instead of rewriting it from scratch. I recently changed an application from single document interface to multiple document interface (MDI) and I was able to use the vast majority of the code even in my windowing classes, changing only some of my flow control code and windowing code.

I would recommend backing up your current code and then trying to make some changes to improve it as you encounter code that seems badly organized. Pick the low hanging fruit before you try to change something that will take a ton of effort to fix.

As far showing off your code, I think there’s nothing wrong with that as long as the program is running as intended and is close to bug-free.

Actually scratch that last post. There are quite a few things I can do here to make things better. So I will come back when I am stuck again!