I spent the evening working on the project, and I was going to try to get the Ball to move in four directions. I thought that I should probably start by laying the groundwork and having Player and Ball inherit from a class called Entity.
My thinking was that Entity would control the movement of the object in question. It would set the position, move in a certain direction, and also control the KrSprite pointer. Then Player and Ball could inherit from Entity and have all of the functionality available, and I would be able to handle the code in one place instead of two or three.
My gosh, what a mess!
When I finally decided to give up and revert the changes, I realized that I might not want to inherit Entity. Perhaps it would be better if the Player and the Ball each own an Entity object. After all, each owns the KrSprite pointer currently, and essentially Entity acts as a wrapper. It will still require some reworking, but it might be easier than what I was trying to do.
Entity had pure virtual functions, and after Player inherited it and defined the functions, I was getting linking errors that I couldn’t figure out. The messages insisted that there were undefined references to the Kyra Sprite Engine’s functions, and that made no sense to me because they were defined nicely before I did anything to the code. I kept at it for some time, and by the time I gave up I have to admit that I still don’t understand what was wrong. Of course, I don’t exactly have the greatest grasp of the C++ language, and so I more than likely wasn’t using pure virtual functions correctly. I decided that I should think about it.
Reverting it was fairly easy with Subversion, so I am very thankful that I’m using this tool. I feel bad that I haven’t made any progress on the code, but I’m chalking it up to experience.
Never write code when you have no idea what you’re doing with it. I started to hack away and tried to do something without knowing how I was going to handle it beforehand. Now I’m backing away from the code and trying to write down some design ideas before progressing. If I take the functionality from Ball and Player and put it into its own class, I already know that aggregation is probably going to be better than inheritance. Of course, I should really try to write it down and figure out if that is the case before making the same mistake the other way. I don’t want to assume that if I was wrong with one choice that another choice is automatically correct. After all, Ball and Player are both going to be classes that provide the functionality to move the objects around. Why shouldn’t they inherit the implementation to do so?
I’ve already found one resource that suggests composition is the way to go: Game Object Structure: Inheritance vs. Aggregation.
In any case, I didn’t fail. I just found a way that doesn’t work. Or at the very least I found that there is a limit to the “just get something, anything, working” method of game development. B-\
2 replies on “Oracle’s Eye Development: Thanks for the Save, Subversion!”
I don’t agree. Sure, it’s smart to think before you act, but if you have no idea how to tackle the problem at hand, all the thinking in the world isn’t going to keep you from making mistakes. The very nice thing about using source control version is that you can mess up your code base completely, confident that you can always go back to a previous version.
Go experiment. Don’t be afraid to try solutions, even if you think they’re crazy. You’ll learn from them. That’s why you started this project in the first place, isn’t it?
By the way, I addressed your problem of composition and inheritance in detail on my own blog. I hope that helps you a bit.
Also, if you still have that messy code, I’d be happy to take a look at it and see if I can find out what went wrong with those pure virtual functions.
You’re right. I looked back on it and thought that I was pretending to develop software when I was really just trying some not-well-understood code without too much thought. The experience was good, and I’m definitely going to go into it tonight with a bit more knowledge.
As for your blog, thanks for addressing this issue. I actually have the Alexandrescu book, and I should probably reread it since I’m starting to do some things that aren’t really basic anymore. At one point I was trying to find help from Meyer’s Effective C++, and it did remind me to make sure the destructor was virtual, but it didn’t mention anything about using pure virtual functions.
The reason why the sprite and the movement would be combined in the same class is because Kyra’s sprite class has movement functions. Still, it makes sense that while the movement interface should be inherited, the sprite itself is owned by the current classes, and so any abstraction should probably be owned as well.
Thanks for the timely help!