Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
9. March 2012

 EDIT: DO not use the included binaries, instead look at the link from the Pang tutorial series to your right!

 

I have gotten a few emails or messages on this topic, enough so that I figure I will put together a post on the subject.  In my PANG! SFML C++ game tutorial, I show how to configure for debug builds but not release.

 

 

So, first and foremost, you are going to need to compile SFML 1.6 for release mode if you don’t already have the release libraries.  You can either download the SFML 1.6  source code here and compile them for release, in either DLL or static mode.  To do so, in Visual Studio 2010 after importing the project ( from SFML-1.6\build\vc2008 ) go ahead and delete the samples folder in the Solution Explorer. Then select the Build Menu, go to the Configuration Manager, then select the build you want to make:

 

Untitled

 

 

You either want to build Release DLL or Release Static, depending on if you are compiling static or dynamic.  If that is completely alien to you what the difference is, dynamic means you will ship the SFML Dll’s with your application, which will contain the SFML related code.  Static on the other hand, will compile all of the SFML related code into your EXE file, making it quite large but easier to distribute.  Either works, but if you ran into the dreaded ATI bug, static fixes it.  On the other hand, if you don’t use all parts of the SFML library, dynamic can be a whole lot smaller.

 

 

If you can’t be bothered building the DLLs, I have compiled them for you.  This archive contains the .lib/dll files for both static and dll versions of SFML compiled for Visual Studio 2010.

 

 

Now that you have the proper lib and dll files, the instructions are basically identical to this part of the tutorial.   The only thing you have to do different is, when in your projects properties before adding libraries, you need to select Release Build.

 

image

 

 

Also, when you specify the library names, you do not include –d at the end.  So for example, instead of adding sfml-system-d.lib, you add sfml-system.lib.  Repeat this for each library.

 

Now you should be able to build the release version of your game without problem.  This again is accomplished using Build->Configuration Manager, like so:

 

image

 

 

Simply switch to release rebuild and done.

Programming


28. February 2012

 

 

Picking up where our last section left off, by the end of this chapter you will be able to send a high score across the wire and process it in node.  In order to do this, we need to create a common format both our client and server understand.  In this particular case we are going to use JSON.  If you have done any recent web program, you are probably familiar with JSON already.  Basically JSON is a micro-format designed for transferring data on the web with a lighter footprint than XML.  All told it is a pretty simple format, here is the JSON we are going to use for storing high scores:

 

 

{ "Scores" : [ {"Name" : "Mike", "Score" : 2}, {"Name" :"Bob", "Score" : 14}, {"Name" :"Steve", "Score" : 12}, {"Name" :"John", "Score" : 10}, {"Name" :"Henry", "Score" : 8} ] }

Click here to download Highscores.txt

 

This JSON represents an object named “Scores” composed of an array of 5 objects that in turn are made up of a string field “Name” and a integer field “Score”.  Javascript and JSON go together like peanut butter and jam, but what about C++?  Well, you could encode your data into a string with very little effort ( one of the big advantageous of JSON ), but “little effort” is still effort, and I’m a lazy guy!  Therefore we are going to use an existing library.  I wanted a light weight and extremely simple JSON library, so I went with the aptly named SimpleJSON.  Installation really couldn’t be simple, just add the 4 cpp files ( 2 headers, 2 source ) to your project and you are done.

 

 

Now lets take a look at our SFML client.  It is going to be a simple command line utility for now, from a dos prompt simply pass in the name and high score as parameters, and it will send them across to the node server.  Lets take a look at Scoreboard.cpp:

 

#include "SFML/Network.hpp" #include "JSON.h" #include <iostream> int main(int argc, char* argv[]) { if(argc != 3) { std::cout << "Invalid usage, proper format is player name then score, for example:" << std::endl; std::cout << "Scoreboard \"Player Name\" 42" << std::endl; return -1; } sf::IPAddress ip("127.0.0.1"); sf::SocketUDP socket; sf::Packet packet; JSONObject data; data[L"action"] = new JSONValue(L"AddScore"); data[L"name"] = new JSONValue(std::wstring(argv[1],argv[1] + strlen(argv[1]))); data[L"score"] = new JSONValue(atof(argv[2])); JSONValue * val = new JSONValue(data); data.clear(); std::wstring dataString = val->Stringify(); delete val; std::string notSoWide; notSoWide.assign(dataString.begin(),dataString.end()); packet.Append(notSoWide.c_str(),notSoWide.length()); unsigned short port = 1000; if(socket.Send(packet,ip,port) != sf::Socket::Done) { std::cout << "An error ocurred sending packet" << std::endl; } socket.Close(); return 0; }

Click here to download scoreboard.cpp

 

 

One annoyance of the library I chose for JSON is it works with UTF-8 wide strings, but the string that we send we want encoded as standard ascii, so there is a bit of gunk as we create the JSON object using wide character strings, then after turning it into a JSON string, we encode it back to ascii.  Otherwise the code is quite straight forward.

 

 

First we verify we got the proper number of command line arguments, declare our various SFML and JSON related variables.  We are setting the ip address to 127.0.0.1, which is the loopback address, or the equivalent of saying “this machine”.  Next we build up our JSON string.  If you have worked with XML before, the process will be very familiar. We create a JSONObject named data, which is essentially a map of key value pairs of other JSONValues.  When then populate it with our data, then in turn use it as the parameter in creating a new JSONValue.  All the heavy lifting is done in JSONValue’s constructor.  Stringify() is the method that does the actual re-encoding returning a std::wstring.  Of course, we actually want a std:string, so we create one.  Obviously in time sensitive code, we would alter SimpleJSON to use std::string instead.  Our end result is a JSON string that looks like this:

 

{"action":"AddScore","name":"Bob Dole","score":23}

 

 

Now that we have our data in JSON encoded string format, it’s time to send it.  We simply append our string data to our packet and send it using our Socket.  If an error occurs, report it.  Otherwise, we are done, close our Socket and exit.  If you strip away all the wide character string annoyances, the process is actually quite straight forward.

 

 

Now lets take a look at the Node side of things.  The code is fairly long, so instead of walking through it I have simply commented it.  If you have any questions not covered by the comments, fire away.  So here is the contents of Server.js

 

var dgram = require('dgram'), fileSystem = require('fs'), highScores, server; //Load high scores from file fileSystem.readFile("HighScores.txt", 'utf8', function(err,data){ if(err){ //Error occurred loading file, spit out error message then die console.log("Error occurred loading file"); process.exit(); } console.log("Loading high scores from file"); try{ // use JSON to turn file contents back into a Javascript array object highScores = JSON.parse(data); }catch(e) { // Exception occurred parsing file contents as JSON, error out and die. console.log("Exception occured parsing data"); process.exit(); } // Now sort the high scores by score, high to low highScores.Scores.sort(function(a,b){ return b.Score - a.Score; }); // Display the sorted high scores to the console console.log(highScores); }); //Alternative way to read file in NodeJS //file.on("error",function(exception){ // process.exit(); // } //); //file.on("data",function(data){ // fileData = data; // } //); //file.on("close",function(){ // highScores = JSON.parse(fileData); //}); //Create a UDP socket server = dgram.createSocket('udp4'); console.log("Socket created"); // Add a handler for incoming traffic on the socket. This will be called each time something connects to the socket server.on("message",function (msg,rinfo) { //console.log(parseInt(msg).toString()); console.log(rinfo); // SFML sends two packets, one with the size of the following packet ( as a 4 byte number ) // We don't need it, so as a crude-hack, we ignore any 4 byte packets if(rinfo.size != 4) { console.log("Received message:" + msg.toString()); // Socket data comes in as a JSON encoded array of objects, turn back into a JS object var jsonData,i; try{ jsonData = JSON.parse(msg); } catch( exception ) { console.log("Invalid JSON request received"); return; // Non lethal error, just stop processing packet } // The action parameter determines what you should do with this packet switch(jsonData.action) { // action==AddScore, add the score to the highscore array if it's higher than an existing score case "AddScore": console.log("AddScore called\n"); // Make sure highscore has been initialize... order can be a weird thing in node if(highScores != undefined){ // Loop through current highScores ( which should be sorted ) // and insert score if a lower match found for(i=0;i < highScores.Scores.length;++i) { if(highScores.Scores[i].Score < jsonData.score){ highScores.Scores.splice(i,0,{"Name" : jsonData.name, "Score" : jsonData.score}); console.log("Inserted highscore by: " + jsonData.name); break; // match found, stop looping } } } // Display newly created highscore array console.log(highScores.Scores); break; } } // // }); // Called when socket starts listening for packets. besides logging, currently serves no purpose server.on("listening", function () { var address = server.address(); console.log("server listening " + address.address + ":" + address.port); }); // Finally, bind the server to port 1000. 1000 was randomly chosen. Think of this as saying GO! // Now we are listening for UDP connections on port 1000 server.bind(1000);

Click here to download server.js

 

 

Now start the server at the command line ( node server.js ) and run the client from a different command line.  It should look like this:

 

image

 

 

As you can see, we are successfully sending data from SFML over a socket to our node based server.  In the next part, we will look at sending data the other way.

 

 

You can download the complete project right here.  The scripts are in a sub-folder named NodeJS.

 

 

Click for part 3

Programming


31. January 2012

 

 

As I mentioned earlier, I have recently discovered Node.JS.  Quick version, Node is a server side Javascript engine, allowing you to easily create applications on the server.  Obviously you could use SFML on both the client and the server but many people find Javascript a much faster language to work with.  The libraries bundled with Node make this task extremely easy.

 

We are going to create a very simple “High score” system, allowing users to push their score to the server as well as get a list of the current high scores.

 

 

 

You may notice Node referred to as Node, Node.js and NodeJS, which is correct?  Beats the hell out of me!  I frankly just use them all, so if you notice me switching terms, remember they are all referring to the same thing.  I am assuming you are using Windows 7 and Visual Studio for this tutorial, but there are no reasons you can’t use different OSes or IDEs.

 

 

First off, lets get Node installed, which you can download here.  Run the installer and node will be installed to your machine.  Really that’s about it.  Optionally you can add the install directory to your PATH environment variable, in my case it was C:\Program Files(X86)\nodejs, this will save you a ton of key strokes later and for the following instructions I will assume you have performed this step.

 

 

Now that you have installed node, we can create our server; you are about to see how laughably easy this is using Node.  Create a file server.js in your editor of choice, in my case I am using JetBrain WebStorm ( on a 30 day trial ) and have been impressed so far, but you can use any text editor including Notepad.  In server.js add the following code:

 

var dgram = require('dgram'); var server = dgram.createSocket('udp4'); console.log("Socket created\n"); server.on("message",function (msg,rinfo) { console.log("Received message"+ msg.toString()); }); server.bind(9000);

 

 

And… that’s it.  A perfectly functioning UDP server, not that it does much yet.  To run the code, in a command prompt, change to the directory you saved server.js to and simply type “node server.js”.  To stop node from running, press CTRL + C twice.

 

dgram is a built in Node library for creating datagram sockets.  When we create the socket with tell it to use udp4, that is to say UDP connection for IP v 4.  Then we add an on “message” handler that for now simply echos whatever data it receives.

 

 

Now lets make a C++ client to talk to our server.  If you are unfamiliar with how to configure SFML, take a look at part 1 of my C++ with SFML tutorial.  In this case we aren’t going to need to link the graphics or audio libraries, which greatly cuts down the size of our project.  If you have trouble setting up a project or simply don’t want to, you can download a pre-configured project here.  Simply open the solution and run.

 

Once you have created and configured a new project, lets add our code.  In my case I created a file called Scoreboard.cpp and added the following code.

 

#include "SFML/Network.hpp" int main(int argc, char* argv[]) { if(argc <2) return-1; sf::IPAddress ip("127.0.0.1"); sf::SocketUDP socket; sf::Packet packet; packet.Append(argv[1],strlen(argv[1])); socket.Send(packet,ip,9000); return0; }

 

 

Extremely simple code again.  The app is simply going to send a string you specify on the command line over a UDP socket, so first we check to make sure you specified a string. Then you create the IP address that represents your server’s location.  In this case you are using 127.0.0.1 which is a special reserved IP address called a loopback, which basically means “this machine”.  In an actual production environment, you would use an external IP address or DNS entry like “gameserver.mydomain.com”.

 

Next we declare our Socket and  Packet.  Think of a Packet as the “stuff” we are sending across the wire.  Next we fill that picket with the string the user passed in on the command line.  The Socket represents the connection to the remote server.  When we say socket.Send() we are saying send packet, on ip IpAddress using port 9000.  Finally we simply exit.

 

You can now run this from the command line using ScoreBoard.exe “The text you want to send”  <—The quotes are critical, or it will end up looking like multiple parameters instead of a single string.  Additionally you could specify the string in your debug settings, then you can simply press F5 to run your code.  To set this value, right click your solution and select Properties, then on the left hand side choose “Command Arguments” and specify your string (quoted again ) there, like this:

 

image

 

 

Now your primitive client and server are up and running.  Start your server first.  Open a command prompt, CD to the directory you created server.js in and type “node server.js” ( no quotes ).   Note, if you didn’t set your PATH to include the path to nodejs, this wont work and instead you will have to fully resolve the path to node.  Now run your SFML application, either using F5 if you specified a Command Argument, or from the command line.

 

Now you should see:

 

image

 

 

Congratulations!  You just created a fully function client and server!  You may have noticed we actually received two socket connections there, an empty one, then our string.  What’s going on here?  Well, SFML sends Packets in two parts, the first contains only the size, the second contains the actually data.  Why?  Beats me.  Not really a big deal, as you will soon see.

 

 

Now, in the next part we will actually make them do something!

 

 

Click here to download the pre-configured Visual Studio project.

Click here to download Server.js.

 

 

Click for part 2

Programming


13. January 2012

 

 

 

Sadly SFML only included precompiled binaries for 1.6 and even in that case, they don’t support Visual Studio 2010.  If you need to build SFML 2.0 for use with Visual Studio 2010, use the following step.

 

 

Go to this page and download the SFML 2.0 snapshot.

 

 

It’s a tar.gz file, if using 7zip, it means you will have to extract it twice.  Extract it to a folder somewhere on your hard drive, the results should look like this:

 

image

 

 

 

Now you need CMake.  Download and install it from here.

 

 

One installed, the next step is slightly tricky.  CMake needs to be run with the environment variables for Visual Studio properly set so it can locate your compiler.  This means you need to launch if from the command prompt provided by Visual Studio.  If you are using Visual Studio Express, in the start menu launch the Visual Studio Command Prompt.

 

 

image

 

 

 

Now that you’ve launched the command prompt, change directory to your cmake executable folder.  In my case it was c:\Program Files (x86)\Cmake 2.8\bin.  CD to that directory then run cmake-gui.exe.

 

 

 

image

 

 

 

The CMake GUI will now pop up.  Click “Browse Source” and navigate to the folder you extracted SFML2 to.  Then click “Browse Build” and navigate to where you want it to create all the project files, like I have below.  Once done, click configure.

 

 

 

image

 

 

If the directory you selected  doesn’t exist, the following dialog will appear:

 

 

image

 

 

Simply click Yes.

 

 

Now you are going to be prompted for what kind of project to generate, assuming you are using Visual Studio 2010 Express, select Visual Studio 10 then Finish, as follows:

 

 

 

image

 

 

 

If everything went ok, it will look like this:

 

 

image

 

 

 

The default settings are most likely what you want, now click Generate.  If all things go correctly, your project files will have been generated in the folder you specified in “Where to build the binaries”.  Here is mine:

 

 

 

image

 

 

 

Now simply double-click SFML.sln.

 

 

Visual Studio will load, now all you need to do is select the menu item Build->Build Solution in Visual Studio.

 

 

Voila!  You just built SFML 2.0 using CMake and Visual Studio 2010.  Look for the binary files in the lib folder.  Keep in mind the include and extlib files are required too, and are in the directory you extracted to earlier.

 

 

If that didn’t work for you, you can simply download this version I've compiled.  Keep in mind, SFML 2.0 is under constant development, so this version was only current as of 1/13/2012.  This archive also included the Include folder as well as the extlib folder, which is all you should require to get started with SFML2.

Programming


31. December 2011

 

 

As the title says, the 9th part of our C++ game programming using SFML tutorial is now live. In this chapter we implement a caching solution for dealing with SFML game audio files. Along the way we learn a bit about C++ exception handling as well as touch on the subject of C++ templates. We also implement our second paddle and give it the most basic of artificial intelligence.

 

 

 

As the majority of this chapter is audio related, this image really isn’t all that impressive, but here is our current game in action.  We are very near to a complete game at this point and have covered most of the basics of C++!

 

 

pang9b

 

 

 

 

You can access part 9 by clicking here.  If you haven’t read any of the tutorial yet, you can access the table of contents here.  Again, any and all feedback appreciated.

Programming


GFS On YouTube

See More Tutorials on DevGa.me!

Month List