Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
14. November 2011

 

Chapter 8 of the GFS beginner C++ tutorial, Pang! is now live and can be accessed here.

 

 

This chapter represents a bit of a break from the norm, in that it deals with code design more than it does actual SFML and game implementation.  I actually had a great deal of fun writing this chapter, but the end result is very little usable code.  There is a companion post to this one that illustrates much better use of SFML’s audio classes, that should be up shortly.  That said, I think you could learn a great  deal from this post, it may even alter the way you program!

 

 

Instead this post introduces the concept of design patterns and illustrates a way to de-couple  your code, so you don’t end up littered with global and manager classes.  It covers a concept that I have never seen covered by a game tutorial before, but then, there might be a good reason for that! Winking smile

 

 

So give it a read and let me know what you think.  Would you like to see more posts like this, or would you like me to focus on more implementation specific aspects?

Programming


9. November 2011

 

 

Along with many others, I don’t really recommend C++ as someone’s first language for various reasons.  Sometimes concrete examples aren’t easy to come by off the tip of your tongue, so I figured the next time I encountered one of those things that make C++ so beginner unfriendly, I would post it.  Not the obvious stuff like memory leaks, dealing with the linker or exceptionally cryptic template errors, but the more benign stuff that add up to frustrate new and experienced users.  If you are a veteran C++ coder, you will probably spot the problem in a second or two, but this is the kind of thing that will trip up a beginner completely and is a complete nightmare to solve.

 

 

Consider the following C++ header file:

 

#pragma once #include "SFML/Audio.hpp" class SoundFileCache { public: SoundFileCache(void); ~SoundFileCache(void); const sf::Sound& GetSound(std::string) const; const sf::Music& GetSong(std::string); private: static std::map<std::string, sf::Sound> _sounds; static std::map<std::string, sf::Music> _music; }; class SoundNotFoundExeception : public std::runtime_error { public: SoundNotFoundExeception(std::string const& msg): std::runtime_error(msg) {} }

 

 

Pretty straight forward stuff right?  Two class declarations, nothing really funky going on.  Now consider the following implementation:

 

#include "StdAfx.h" #include "SoundFileCache.h" SoundFileCache::SoundFileCache(void) {} SoundFileCache::~SoundFileCache(void) {} const sf::Sound& SoundFileCache::GetSound(std::string soundName) const { std::map<std::string,sf::Sound>::iterator itr = _sounds.find(soundName); if(itr == _sounds.end()) { sf::SoundBuffer soundBuffer; if(!soundBuffer.LoadFromFile(soundName)) { throw new SoundNotFoundExeception( soundName + " was not found in call to SoundFileCache::GetSound"); } sf::Sound sound; sound.SetBuffer(soundBuffer); _sounds.insert(std::pair<std::string,sf::Sound>(soundName,soundBuffer)); } else { return itr->second; } } const sf::Music& SoundFileCache::GetSong(std::string soundName) { //stub }

 

 

Again, pretty standard code, ignore the fact GetSound and GetSong don’t return values, they aren’t the issue here.

 

 

Now consider the error:

 

error C2533: 'SFMLSoundProvider::{ctor}' : constructors not allowed a return type

 

 

If you are new to the expression ctor, it basically just shorthand for constructor. For the record, it’s Visual Studio Express 2010 and if you double click that error, it brings you to this line:

 

SoundFileCache::SoundFileCache(void) {}

 

 

So… what’s the problem?  By the error, it is quite obvious that the constructor doesn’t in fact return a value, so the message is clearly not the problem.

 

 

What then is the problem?  I’ll show you after this brief message from our sponsors… Smile

 

 

 

 

 

 

Welcome back… figured it out yet?  If not, I don’t blame you, the warning sure as hell didn’t help.  Here then is the offending code:

 

class SoundNotFoundExeception : public std::runtime_error { public: SoundNotFoundExeception(std::string const& msg): std::runtime_error(msg) {} } <-- Missing semicolon

 

So, forgetting a semi colon ( something you will do A LOT! ) results in a message that your constructor cannot return a value.  Now, once you’ve been coding C++ for a while this kind of stuff becomes pretty much second nature.  Getting nonsensical error messages?  Check your header for a missing include guard or semi colon become pretty much the norm.  But for a new developer, this is the beginning of a complete train wreck.

 

 

 

Think about if for a second, you just developed some of your first code, the error says you are returning something you aren’t, the compiler is pointing at your constructor and now you need to figure out just WTF is going on..  What do you do?  Many run off to a forum and post the error verbatim and hope for an answer ( which they will probably get, learning nothing in the process ). Hopefully you Google it using exact quotes, but even then you get forum answers like this where you have a bunch of other new developers fixating on the error message itself and leading the developer down a wild goose chase.  Fortunately a moderator stepped in and gave a proper explanation, but that doesn’t always happen.  Even worse, it is a legit error, you really can’t return from a ctor, so if you encounter it again in the future you may actually have a real problem but find yourself instead on a missing semi-colon hunt!

 

 

 

How would this work in Java, C#, Python or Ruby?  Well it wouldn’t, as no other modern language I can think of use header files any more.  For good reason too, they add a level of complexity for very little positive return.  It could be argued that separating interface from implementation is “a good thing”, but even that is munged up by the fact you can actually have you implementation in your header file.  Also don’t get me wrong, other languages have their faults too, just wait till you get forced to go on your first Java XML configured error hunt, you will be begging for C++ errors again!

 

 

 

This is just a classic example of the little things experienced developer forget the pain of experiencing in the first place!  As I said, once you’ve got a bit of experience this kind of stuff becomes second nature, but while you are learning this kind of error is absolutely horrific.  It’s little things like this that add up and make it so hard to recommend new developers start with C++.  When I say it isn’t pointers and memory management that make C++ difficult, I mean it.  It’s crap like this.

Programming


27. October 2011

 

Yeah, I really took my sweet time on this one, but things are better the longer you wait, no? Smile

 

 

In this chapter we get the ball rolling, literally.  Additionally we add collision detection and realistic rebounds.  On the C++ front, we introduce and discuss the various types of casts in C++.

 

For those of you that haven’t read it yet, the Pang C++ Tutorial table of contents is right here.

 

For those that have been following along, Pang Part 7 is here.  As always, full project source is included at the end.

 

 

And here Pang, the worlds most over-engineered pong clone in action!

 

pang7

Programming


25. September 2011

 

Ok, it actually has been live for a couple days and I forgot to post an update here, oops.

 

 

In this chapter we add animation to our PlayerPaddle class, including player keyboard input.  We cover off topics such as running at the same speed on multiple machines, dealing with protected member variables and using asserts.  Now, I’m off to write part 7.  I swear this is going to make the Guinness world record for the longest Pong tutorial ever!  I hope it’s been useful, please let me know any questions, recommendations or comments you have.

 

 

I proudly present Game From Scratch C++ Edition Part 6.


15. September 2011

 

I recently had a user who tried to run Pang on MacOS and there were a few incompatibilities.

 

So today, I fired up my trust old iMac and created my first ever C++ Application in XCode 4.1 and I have to say, it really wasn’t all that pleasant of an experience!

 

 

First off, about Pang.  There are a few small changes that don’t work on the iMac using GCC 4.2.  First is there is no tchar.h header file.  On the same thought, Microsoft’s _tmain is not portable and the entire targetver.h header file doesn’t work.  Reality is, none of these are really a big deal as we are not using any Windows specific features, nor are we supporting Unicode parameters to our main(), so it is all a pretty easy fix.  Simply delete all of these includes, remove targetver.h completely and change make to a traditional main().

 

 

Code wise, there was one gotcha.  GCC 4.2 does not support calling a nest enum’s name.  For example if you have the following:

struct Colour { enum DefinedColours { Red, Green, Blue }; };

 

You can’t do this:

Colour::DefinedColours::Red;

 

Instead you have to do this:

Colour::Red;

 

Which is a shame as I find the one much more readable than the other, but no big loss.  Going forward I will be compiling on both Windows using Visual Studio and Mac OS using XCode/GCC 4.2, so if you are following along using a Mac ( or GCC with CodeBlocks ) the code will be guaranteed to work.

 

 

Now, about XCode.  I will admit this is my first real experience with it.  I played around with 3.x when I first looked into iOS development but never really got a chance to try out 4.1.  I like the idea that they went to a single Window, as a VC developer  XCode 3.x was very alien.  That said, this is about where my likes end.

 

Nothing was intuitive, intellisense ( or whatever it is called in non-Microsoft parlance ) is SLOOOOOOOWWWWWW, the interface is extremely cluttered, the project/scheme system seems odd ( with time this might improve ), the debugging experience was not fun ( weird focus issues with my running application ).  Then worst of all, I had to spent a good 20 minutes figuring out where the hell my compiled application even ended up!

 

Through this experience, as a complete newbie I had to Google a lot and I noticed two trends.  First, all the documentation for earlier versions is useless… its like every single keyboard shortcut and menu was changed completely.  Second, the hate seems to be pretty universal!  Every time I would Google something, half of the answers would be “screw it, stick with 3.4” or similar.

 

That leads me to my question to you Mac C++ developers out there… Does Apple have a bit of a turd on their hands with XCode 4.x, or will it get better as I get used to it?  If not, what IDE are you all using for C++ development on Mac?

 

 

Anyways, long story short, from Pang part 5 on, Mac/GCC will compile unchanged out of the box.  That said, this tutorial is still going to focus on Visual C++ Express as the IDE of choice.

Programming


GFS On YouTube

See More Tutorials on DevGa.me!

Month List