Uops. Sorry guys, but I'm moving this blog to a new location. It is the following:
http://www.plungeinteractive.com/blog
We will post there with other colleagues from work (Plunge Interactive), so the good news are that the blog will have more content :-)
I hope I'll see you there! :-)
Jesús Bosch
Game Programming
Tuesday, August 28, 2012
Tuesday, August 7, 2012
Parsing JSON from C++ (and maybe from Cocos2D-X)
So you want to use portable JSON parsers in your projects right? As you will notice there are many free JSON parsers for C++ out there. I've chosen rapidjson since a colleague recommended it to me because of it's easy of use, speed and simplicity.
It's very easy to get started, but I'll share my experience with you. In order to get it to work, download the free parser, then copy the rapidjson folder inside your project (it might be into the libs folder if it is a Cocos2D-X project).
Then add the following includes to your code:
Now we are ready to parse the JSON, in the rapidjson download you have several samples, but I didn't find any that allows me to parse a JSON like this:
[{"id":"u7","score":"1007"},{"id":"u6","score":"1006"},{"id":"u5","score":"1005"},{"id":"u4","score":"1004"},{"id":"u3","score":"1003"},{"id":"u2","score":"1002"},{"id":"u1","score":"1001"}]
So my code snipet will be useful to parse something like that. Just the following:
Easy right? Note that the GetParseError method gives us detailed information about the problems that we might have regarding to the JSON format. If you have JSON validation problems, I recommend you to use a free online tool to make sure you are creating it well, like JSONLint.
Enjoy your parsings!
PS: If you have a compilation error including using the json parser, please check out this link where I pasted the solution: http://www.cocos2d-x.org/boards/6/topics/14003
It's very easy to get started, but I'll share my experience with you. In order to get it to work, download the free parser, then copy the rapidjson folder inside your project (it might be into the libs folder if it is a Cocos2D-X project).
Then add the following includes to your code:
#include "document.h"
#include "rapidjson.h"
Now we are ready to parse the JSON, in the rapidjson download you have several samples, but I didn't find any that allows me to parse a JSON like this:
[{"id":"u7","score":"1007"},{"id":"u6","score":"1006"},{"id":"u5","score":"1005"},{"id":"u4","score":"1004"},{"id":"u3","score":"1003"},{"id":"u2","score":"1002"},{"id":"u1","score":"1001"}]
So my code snipet will be useful to parse something like that. Just the following:
Document document;
if(data != NULL && !document.Parse<0>(data).HasParseError())
{
for (SizeType i = 0; i < document.Size(); i++)
{
CCLog(document[i]["id"].GetString());
CCLog(document[i]["score"].GetString());
CCLog(document[i]["score"].GetString());
}
}
else {
CCLog(document.GetParseError());
}
Easy right? Note that the GetParseError method gives us detailed information about the problems that we might have regarding to the JSON format. If you have JSON validation problems, I recommend you to use a free online tool to make sure you are creating it well, like JSONLint.
Enjoy your parsings!
PS: If you have a compilation error including using the json parser, please check out this link where I pasted the solution: http://www.cocos2d-x.org/boards/6/topics/14003
Labels:
C++,
Cocos2D-X,
Communications,
JSON
Monday, August 6, 2012
Internet communications on Cocos2D-X with libCurl
curl is a command line tool for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, kerberos...), file transfer resume, proxy tunneling and a busload of other useful tricks.
libCurl provides two ways of getting access to the network, one is the single-syncronous thread communications (easy interface) and the "Multi", that allows asynchronous communications using a single thread (more info can be found in the official libcurl documentation web page).
In order to use libcurl in our project, you need to add an external framework, the libcurl.a file. It is located in your cocos2dx folder then platform\third_party\libraries\libcurl.a
So go to your project in XCode -> Targets -> Build Phases, and add the libcurl.a framework from the specified path.

Then, take the curl folder in the same location (that contains the header files), and copy it into your project "libs" folder.
After following your steps, you should be able to include the header "curl.h" and successfully compile your project. Then paste the following code somewhere in your code and make sure it is executed.
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_URL, "www.jesusbosch.com");
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
if (res == 0)
{
CCLOG("0 response (success)");
}
else
{
CCLog("code: %i",res);
}
}
else
{
CCLOG("no curl");
}
You should see now a "0 response (success)" text message in your Xcode log (supposing you have internet connection). If you try to disconnect your device / computer from the internet and run the code again, you should see a code different than 0 (you can see what each value means in the curl.h file). In my case I get the "6" value, what means: "CURLE_COULDNT_RESOLVE_HOST".
What curl_easy_perform did is basically download the content of the website (you should be able to see it in your output window on Xcode). But if we want to get the most of this set opt function, we do need to implement custom callbacks (they are defined in the libcurl documentation). To give you an example on how to recover the requested data would be:
void MyClass::testCURL()
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_URL, "www.jesusbosch.com");
curl_easy_setopt(curl, CURLOPT_NOPROGRESS ,1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriter);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
if (res == 0)
{
CCLOG("0 response (success)");
}
else
{
CCLog("code: %i",res);
}
}
else
{
CCLOG("no curl");
}
}
int MyClass::curlWriter
(char *data, size_t size, size_t nmemb, std::string *outputBuffer)
{
if (outputBuffer != NULL){
CCLOG("%s", data);
}
return size * nmemb;
}
The curlWriter function must be defined as static in the .h file in order to work.
As you will see this library is very powerful, but also can become quite complex. The good thing is that this library is very efficient, portable, and offers all you need related to communications.
Labels:
Cocos2D-X,
Communications,
curl,
Extensions,
libCURL
Saturday, August 4, 2012
Using the native Facebook SDK on Cocos2D-X iOS projects
Facebook integration is something common on any mobile game today. In order to do so, we need to remember that the iOS Facebook SDK is written in Objective-C. So in my opinion, the easiest way to communicate between Cocos2D-X and Facebook is using the native Objective-C based Facebook SDK for iOS, with no inventions.
This will allow us a deep integration between our game and Facebook. The bad side is obviously that if we want to go cross platform, for instance on Android, we will need to implement the Facebook "bridge" for Android with the Java SDK too. But nobody said that making cross-platform games was going to be easy right? And if they did they are liars :-)
This guide is not going to be useful for the Facebook integration only, it will work on any Objective-C native library, so we can get the full power of the native platform libraries (i.e. iAds, in-app purchases, third party libraries, etc.).
Ok then, the first thing we need to do is to setup our app on Facebook. I'll not going to explain this into detail, the Facebook Developers website has a great tutorial that does the job. Please follow these steps:
This will allow us a deep integration between our game and Facebook. The bad side is obviously that if we want to go cross platform, for instance on Android, we will need to implement the Facebook "bridge" for Android with the Java SDK too. But nobody said that making cross-platform games was going to be easy right? And if they did they are liars :-)
This guide is not going to be useful for the Facebook integration only, it will work on any Objective-C native library, so we can get the full power of the native platform libraries (i.e. iAds, in-app purchases, third party libraries, etc.).
Ok then, the first thing we need to do is to setup our app on Facebook. I'll not going to explain this into detail, the Facebook Developers website has a great tutorial that does the job. Please follow these steps:
- Create a Cocos2D-X project on XCode :-)
- (facebook tutorial) Step 1: Registering your iOS App with Facebook
- (facebook tutorial) Step 2: Installing the iOS SDK. You must then copy the downloaded SDK into our "libs" folder in our XCode project.
- (facebook tutorial) Modify the app property list file as specified in the tutorial.
After following those steps, we are ready to get access to Facebook from our C++ code. We just need to create a bridge between C++ and Objective-C. I have already explained this part in a previous post, so please, read it.
Ok, if you have followed the steps carefully, you will probably notice about two important problems:
- The Facebook delegates will not be fired if you call the Facebook API from a common Objective-C++ file. I am talking about login result delegates and so on.
- How do I callback to my C++ code once I have the execution? For instance, if I want to send a message to C++ informing about if the user has or has not logged in into Facebook, or if he has accepted the permissions request.
For the first problem, I have a solution. I am not sure if it is the best solution. I am not an expert on Objective-C, and I am sure that this can be done better. My solution consists on put all the calls to Facebook in the AppController.h and AppController.mm files, so we call them from our bridge.
I have noticed that if I don't put the Facebook calls there, the delegates are never fired. If you know more Objective-C than me and have a better solution, this is, to put the facebook calls in a file different than AppController.mm (that works but is really ugly), let me know via the comments below and I will update this tutorial to help others.
For the second problem I have also the solution, that consists on implementing a callback in C++. There are other options to do this, but I've found this one to be the easier.
In the next part of the tutorial I'll enter on the details of the implementation :-) If you want me to hurry up to write it let me know on twitter :-P my account is @jboschaiguade

Labels:
Cocos2D-X,
Facebook,
Objective-C
Thursday, August 2, 2012
How to use the CCListView extension for Cocos2D-X
There is a very useful class on the Cocos2D-X framework called CCListView. This class allows us to create a scroll of elements easily. The problem is that there are no examples or documentation about how to use this class, so here we go, a small introductory tutorial about using the magic CCListViewClass :-)
First of all, remember that CCListView is an extension, so we need to include it:
#include "extensions/CCListView/CCListView.h"
We will also need to use its namespace:
using namespace cocos2d::extension;
Using the class is not complex, we just need to initialize it, it has several properties and configurations that can be very useful. For instance I do it this way:
Note that we set several properties that are important:
First of all, remember that CCListView is an extension, so we need to include it:
#include "extensions/CCListView/CCListView.h"
We will also need to use its namespace:
using namespace cocos2d::extension;
Using the class is not complex, we just need to initialize it, it has several properties and configurations that can be very useful. For instance I do it this way:
CCSize size = CCSize(750, 400);
list = CCListView::create(CCListViewModeVertical);
list->setDelegate(this);
list->setContentSize(size);
list->setAnchorPoint(ccp(0,0));
list->setPosition(ccp(130, 100));
list->setSeparatorStyle(CCListViewCellSeparatorStyleNone);
this->addChild(list);
Note that we set several properties that are important:
- The create constructor allows us to set up the scroll vertically or horizontally
- We set the delegate in order to be able to handle several callbacks raised by our CCListView (note that your class must implement the CCListViewDelegate in order to get it to work).
- The content size is quite obvious, is the area that will show the scroll elements, out of that area the scroll elements are not rendered.
- The separator style is useful for debugging purposes (at least for me), but once you are sure about the height of each element, I recommend to remove it.
Then we need to create all the elements:
void FriendsList::CCListView_numberOfCells(CCListView *listView, CCListViewProtrolData *data)
{
data->nNumberOfRows = 20;
}
void FriendsList::CCListView_cellForRow(CCListView *listView, CCListViewProtrolData *data)
{
CCSize listItemSize = CCSize(list->getContentSize().width, 80);
CCListViewCell *cell = CCListViewCell::node();
cell->setOpacity(0);
cell->setContentSize(listItemSize);
cell->setSelectionColor(ccc4(255, 255, 255, 50));
data->cell = cell;
CCLabelTTF *labelCount;
labelCount = CCLabelTTF::create("HEY", "Arial", 16);
labelCount->setPosition(ccp(0, (cell->getContentSize().height * 0) + cell->getContentSize().height / 2));
labelCount->setAnchorPoint(ccp(0,0.5));
labelCount->setColor(ccc3(0, 0, 0));
cell->addChild(labelCount);
}
void FriendsList::CCListView_didClickCellAtRow(CCListView *listView, CCListViewProtrolData *data)
{
}
void FriendsList::CCListView_didScrollToRow(CCListView *listView, CCListViewProtrolData *data)
{
}
Note that in CCListView_numberOfCells we must set the total number of cells of our CCListView, in our example I've forced it to 20.
There is another important method here, the cellForRow, that will allow us to create each row element. In that example I am creating just a label on each row, but we could decide what to put on each row based on the information provided by the parameter data->nRow.
Another interesting detail is the setSetSelectionColor method on the CCListViewCell class, as it name says it will tint the selected row, what is very useful.
I think that this class is very powerful and easy to use, and it can be useful in many situations. I hope this small example helps someone to get started with it :-)
Please feel free to follow me on twitter to discuss more about Cocos2D-X and game development, I always love to do so :-) My twitter account is: @jboschaiguade
There is another important method here, the cellForRow, that will allow us to create each row element. In that example I am creating just a label on each row, but we could decide what to put on each row based on the information provided by the parameter data->nRow.
Another interesting detail is the setSetSelectionColor method on the CCListViewCell class, as it name says it will tint the selected row, what is very useful.
I think that this class is very powerful and easy to use, and it can be useful in many situations. I hope this small example helps someone to get started with it :-)
Please feel free to follow me on twitter to discuss more about Cocos2D-X and game development, I always love to do so :-) My twitter account is: @jboschaiguade
Labels:
C++,
CCListViewClass,
Cocos2D-X,
Extensions
Wednesday, July 25, 2012
Communication between C++ and Objective-C code
This article pretends to explain how to, in an easy way, communicate your C++ code with Objective-C in iOS projects. I will talk about Cocos2d-x, but it is also valid for just plain C++ and Objective-C.
Cocos2D-X is a cross platform game development framework that runs on iOS, Android and other devices. But even we can do anything related to a game with cocos, we will sometimes need to get access to platform specific APIs, like Facebook SDK, Admob or iAds.
In those cases we will need to implement those features using the device native language (Objective-C for iPhone or Java for Android). And while Cocos2D-X is a great engine, it lacks of tutorials... so today I am going to talk on how to communicate Objective-C with C++.
The process should be easy. As an example, I'll show a native iOS alert message from Cocos2D-X. In order to do this, follow these steps:
and
Now you would probably want to handle what was the option chosen by the user right? In order to do this you might use callbacks, you can find a post about them in my colleague Xavier's blog post :-)
Cocos2D-X is a cross platform game development framework that runs on iOS, Android and other devices. But even we can do anything related to a game with cocos, we will sometimes need to get access to platform specific APIs, like Facebook SDK, Admob or iAds.
In those cases we will need to implement those features using the device native language (Objective-C for iPhone or Java for Android). And while Cocos2D-X is a great engine, it lacks of tutorials... so today I am going to talk on how to communicate Objective-C with C++.
The process should be easy. As an example, I'll show a native iOS alert message from Cocos2D-X. In order to do this, follow these steps:
- Create a cpp file and a .h file. Call them iOsHelper.cpp and iOsHelper.h. These will be our bridge to Objective-C.
- An important detail: Click the iOsHelper.cpp file and in the "Identity and type" window on Xcode (normally at the top right of the screen), choose Objective C++ source as the type.
- Define the body of the h and the cpp files. It will be:
#import "iOSHelper.h"
#import "iOSHelper_objc.h"
namespace iOSBridge{
void iOSHelper::ShowAlert()
{
[iOSHelper_objc ShowAlert];
}
}
and
#ifndef FightNow_iOSHelper_h
#define FightNow_iOSHelper_h
namespace iOSBridge{
class iOSHelper {
public:
void ShowAlert();
};
}
#endif
- Now create an Objective-C class called iOSHelper_objc
@interface iOSHelper_objc : NSObject
+(void) ShowAlert;
@end
and
#import "iOSHelper_objc.h"
@implementation iOSHelper_objc
+(void) ShowAlert{
UIAlertView *alertDialog;
alertDialog = [[UIAlertView alloc]
initWithTitle:@"You!"
message:@"I know what you did!"
delegate:nil
cancelButtonTitle: @"OK"
otherButtonTitles: nil];
[alertDialog show];
[alertDialog release];
}
@end
Note that what we are doing is call the Objective-C function from a C++ class. This C++ class can be called from any of our Cocos2DX scenes for instance, so we are done :-)
As commented below (thanks guys for the comments) we need to instance the iOs "bridge" from our C++ class. One way to do it is the following:
Type* instanceName = [Type new];
[instanceName methodName:parameter];
[instanceName release];
As commented below (thanks guys for the comments) we need to instance the iOs "bridge" from our C++ class. One way to do it is the following:
Type* instanceName = [Type new];
[instanceName methodName:parameter];
[instanceName release];
Now you would probably want to handle what was the option chosen by the user right? In order to do this you might use callbacks, you can find a post about them in my colleague Xavier's blog post :-)
Hey, feel free to follow me on twitter if you are interested on discussing about Cocos2DX and game development :-) @jboschaiguade
Labels:
C++,
Cocos2D-X,
iPhone,
Objective-C
Monday, July 23, 2012
iOS game development: handling different screen resolutions
ASSETS SIZES
My favorite option for iOS game development is to use just the exact size for the assets that each device actually uses. It basically is (at the time of writing this article):
My favorite option for iOS game development is to use just the exact size for the assets that each device actually uses. It basically is (at the time of writing this article):
- iPhone 3G/iPod3: 480x320
- iPhone 4/iPo4: 960x640
- iPad 1,2: 1024x768
- iPad 3 (or "new iPad"...): 2048x1536
This gives us the top quality for each device and the best user experience. Since there is an important variety of necessary assets if we want to cover all the devices, I do not recommend to build universal versions. I recommend a version for the small devices, and then another for iPad, but that depends a lot on each game.
How does this work? You first need to enable the retina mode:
pDirector->enableRetinaDisplay(true);
You just need to have one call for each texture. For example: CCSprite::create("mypic.png"); and then Cocos2dX will actually look for the adequate file to the current iOS device. This is:
mypic.png
mypic-hd.png
mypic-ipad.png
mypic-ipadhd.png
And that's it! Cocos2DX will automatically load the necessary asset for the current platform, there is no need to check what is the platform in your own code, what is great.
But I have more! :-) You can actually change the predefined suffixes if you want to (not sure why anyone might want to do it, but you have the choice):
CCFileUtils::setiPadSuffix("-mysufix");
CCFileUtils::setiPadRetinaDisplaySuffix("-mysufix");
CCFileUtils::setiPhoneRetinaDisplaySuffix("-mysufix");
BUG: The problem comes when you want to create a game for iPad only. Cocos2D-X will always look for xxx.yyy file. This means that having your xxx.ipad.yyy and xxx.ipadhd.yyy is not enough, and if you don't put the xxx.yyy file in the project, the execution will fail.
POSITIONING ASSETS
Then, the next interesting thing is about positioning. All the small devices share a device width and heigh of 480x320 points, so you can use the same absolute positioning for them if you want. iPad and iPad hd will also share the 1024x760 points.
I don't like relative positionings... I prefer to control where is everything on the screen. But anyway, if anyone finds a good solution to use the same positioning system for iPhone and iPad please let me know :-)
Please feel free to follow me on twitter and share your thoughts :-) @jboschaiguade
POSITIONING ASSETS
Then, the next interesting thing is about positioning. All the small devices share a device width and heigh of 480x320 points, so you can use the same absolute positioning for them if you want. iPad and iPad hd will also share the 1024x760 points.
I don't like relative positionings... I prefer to control where is everything on the screen. But anyway, if anyone finds a good solution to use the same positioning system for iPhone and iPad please let me know :-)
Please feel free to follow me on twitter and share your thoughts :-) @jboschaiguade
Subscribe to:
Posts (Atom)