# ifndef _COLLISION_LISTENER_   
# define _COLLISION_LISTENER_   
# include <vector>   
# include "Box2D\Box2D.h"   
#include "Box2D\Dynamics\b2WorldCallbacks.h"   

class CollisionListener : public b2ContactListener   
{        
   std::vector<b2Contact*> _contacts;   

   public:        
   /// Called when two fixtures begin to touch.        
   virtual void BeginContact(b2Contact* contact);
   
   /// Called when two fixtures cease to touch.        
   virtual void EndContact(b2Contact* contact);

   //explicitly called from main every frame         
   void ResolveContacts();        

   bool ResolveContact( b2Contact * contact);   

};
# endif 

.cpp file

#include "CollisionListener.h"
#include "Physics/PhysicsSprite.h"   
void CollisionListener::BeginContact( b2Contact* contact )   
{        
   std::vector<b2Contact*>::iterator iter = std::find(_contacts.begin(), _contacts.end(), contact);        
   if (iter != _contacts.end())        
   {             
      _contacts.erase(iter);        
   }        
   _contacts.push_back(contact);   
}   
void CollisionListener::EndContact( b2Contact* contact )   
{        
   std::vector<b2Contact*>::iterator iter = _contacts.begin();        
   iter = std::find(_contacts.begin(), _contacts.end(), contact);        
   if( iter != _contacts.end())        
   {             
      _contacts.erase(iter);        
   }   
}   

//must be called every frame
void CollisionListener::ResolveContacts()   
{        
   std::vector<b2Contact*>::iterator iter;        
   for (iter = _contacts.begin(); iter != _contacts.end();)        
   {             
      if(ResolveContact(*iter))             
      {                  
         iter  = _contacts.erase(iter);             
      }             
      else             
      {                  
         ++iter;             
      }        
   }   
}   

bool CollisionListener::ResolveContact( b2Contact * contact)   
{        
   PhysicsSprite * phySpriteA;        
   PhysicsSprite * phySpriteB;        
   b2Body * body = contact->GetFixtureA()->GetBody();        

   if(body != NULL && body->GetUserData() != NULL)        
   {             
    // do resolve             
     phySpriteA = (PhysicsSprite*)(body->GetUserData());         
   }        
   else        
  {             
    return true;        
  }        

   body = contact->GetFixtureB()->GetBody();        
   if(body != NULL && body->GetUserData() != NULL)        
   {             
     //do resolve             
     phySpriteB = (PhysicsSprite*)(body->GetUserData());         
   }        
   else        
  {             
     return true;        
  }        

//In your custom physics sprite class, you must have a GetObjectId() to determine the object 
  phySpriteA->CollidesWith(phySpriteB->GetObjectId(), phySpriteB);        
  phySpriteB->CollidesWith(phySpriteA->GetObjectId(), phySpriteA);        
  return true;   
}  
 

Initialize listener in main.cpp

 //initialize Collision listener        
_collisionListener = new CollisionListener();

//your physics world
 PhysicsEnvironment::getWorld()->SetContactListener(_collisionListener);  
//on update do this
_collisionListener->ResolveContacts(); 
Now whenever two objects collide the function collides with will be triggered in both the classes. Lets see an example from player class

Player.h

//virtual fns        
virtual void CollidesWith(ENUM_OBJECT object, PhysicsSprite * phySprite);  

Player.cpp

void Player::CollidesWith( ENUM_OBJECT object, PhysicsSprite * phySprite)  
{        
   switch (object)        
   {        
      case e_Crate:             
      {                
          //do add your logic here - when player collides with crate           
      }             
      break;   
     
     default:             
     break;        
    }   
}  

All the stuffs mentioned here are not explained in detail. If required put a comment, will reply asap. Happy Coding 🙂

Its so simple as that in Cocos2Dx using rapidJson( in-built json lib )

Lets see how to read json files in cocos2dx

std::ostringstream jsonFileName;

jsonFileName << "name.json";

std::string path = FileUtils::getInstance()->fullPathForFilename(fileName);

std::string jsonData = FileUtils::getInstance()->getStringFromFile(path);

 
rapidjson::Document document;

document.Parse<0>(jsonData.c_str());

Now you can get the contents of json file using its KEY

rapidJson::value content = document["your key"];

Its the basic for the localisation as well.

//------------------------------------------------LanguageManager.h

#include <string>

using std::string;

 
#include "cocos2d.h"

USING_NS_CC;

 
#include "../../cocos2d/external/json/document.h"

#include "../../cocos2d/external/json/rapidjson.h"

 
using namespace rapidjson; // library that we use for json parsing

 
class LanguageManager

{

    Document document; // current document with language data

    LanguageManager(); // constructor is private

    static LanguageManager* _instance;

public:

    static LanguageManager* getInstance();

    string getStringForKey(string key);

    static string getString(string key);

};

 

//-----------------------------------------------LanguageManager.cpp

#include "LanguageManager.h"

 
LanguageManager* LanguageManager::_instance = 0;

 
LanguageManager::LanguageManager()

{

    string fileName;

    // detect current language

//    switch(CCApplication::getInstance()->getCurrentLanguage())

    switch(LanguageType::JAPANESE)

    {

        case LanguageType::ENGLISH:

            fileName = "en.json";

            break;

        case LanguageType::RUSSIAN:

            fileName = "ru.json";

            break;

        case  LanguageType::CHINESE:

            fileName = "cn.json";

            break;

        case  LanguageType::FRENCH:

            fileName = "fr.json";

            break;

        case  LanguageType::ITALIAN:

            fileName = "it.json";

            break;

        case  LanguageType::GERMAN:

            fileName = "ge.json";

            break;

        case  LanguageType::SPANISH:

            fileName = "sp.json";

            break;

        case LanguageType:: DUTCH:

            fileName = "du.json";

            break;

        case  LanguageType::KOREAN:

            fileName = "ko.json";

            break;

        case  LanguageType::JAPANESE:

            fileName = "jp.json";

            break;

        case  LanguageType::HUNGARIAN:

            fileName = "hu.json";

            break;

        case  LanguageType::PORTUGUESE:

            fileName = "pt.json";

            break;

        case  LanguageType::ARABIC:

            fileName = "ar.json";

            break;

        case  LanguageType::NORWEGIAN:

            fileName = "nw.json";

            break;

        case  LanguageType::POLISH:

            fileName = "po.json";

            break;

        default:

            CCLOG("Unknown language. Use english");

            fileName = "en.json";

            break;

    };

 
    // below we open, read and parse language data file with rapidjson library

    string clearContent = FileUtils::getInstance()->getStringFromFile(fileName);

 
    document.Parse<0>(clearContent.c_str());

    if(document.HasParseError())

    {

        CCLOG("Language file parsing error!");

        return;

    }

}

 
LanguageManager* LanguageManager::getInstance()

{

    if(!_instance)

        _instance = new LanguageManager();

    return _instance;

}

 
string LanguageManager::getStringForKey(string key)

{

    /* Better Approach

     -------------------------------

 
     std::string ret;

     std::string ss;

     int n, size=100;

     bool b=false;

     va_list marker;

 
     std::string fmt = document[key.c_str()].GetString();

 
     while (!b)

     {

     ss.resize(size);

     va_start(marker, key);

     n = vsnprintf((char*)ss.c_str(), size, fmt.c_str(), marker);

     va_end(marker);

     if ((n>0) && ((b=(n<size))==true)) ss.resize(n); else size*=2;

     }

     ret += ss;

 
     return ret;

     */

 
    //Simple approach

    return document[key.c_str()].GetString();

}

 
string  LanguageManager::getString(string key)

{

    return getInstance()->getStringForKey(key);

}

 
//--------------------------------------------------------------

 
 
Sample Code:

-------------

 
    LanguageManager * man = LanguageManager::getInstance();

 
    std::string info = man->getStringForKey("Hello");

         TextField * txt = some text field reference

          txt->setText(info.c_str());

 
//----------------------------------------------------------------------------------------------------

 
Sample Json file

-------------------

 
{

    "Hello" : "language of ur choice using some translator"

}

 
//----------------------------------------------------------------------------------------------------

 

Cheers

Happy Coding 🙂

Download GLES-Render files and add it into your project.

In the main layer or wherever required add the following code during physics world initialisation


debug = new GLESDebugDraw(PTM_RATIO);
//Debug flags
uint32 flags = 0;
//flags += b2Draw::e_aabbBit;
flags += b2Draw::e_centerOfMassBit;
flags += b2Draw::e_jointBit;
flags += b2Draw::e_pairBit;
flags += b2Draw::e_shapeBit;
debug->SetFlags(flags);
world->SetDebugDraw(debug);

Then Override the draw call in the Layer where you added the physics world


void PhysicsEnvironment::draw(Renderer *renderer, const Mat4 &transform, bool transformUpdated)
{
CCNode::draw(renderer, transform, transformUpdated);
world->DrawDebugData();
}

Now you must be able to see the debug draw shapes

Note: At times your debug draw may not be visible due to low Z-Order so if you are not able to see the debug draw shapes, try to hide the sprites and check.

A quick post on how to use keyboard inputs in your cocos2dx projects

In the main.cpp, you can find a CCEGLView has been initialized. Call the function setWndProc() on that object by passing a CUSTOM_WND_PROC.

CUSTOM_WND_PROC is nothing but a function pointer as shown below :

 typedef LRESULT(*   
 CUSTOM_WND_PROC )(UINT message, WPARAM wParam, LPARAM lParam, BOOL *pProcessed)  

In Windows Programming all the key inputs are controlled by the following function

LRESULT wndProc (HWnd hwnd, UINT message, WPARAM wParam, LPARAM lParam)

by setting this as a callback while creating the window.


In Cocos2dx since we are not creating any windows explicitly, we have to just pass the callback function as CUSTOM_WND_PROC.

 LRESULT WndProc(UINT message, WPARAM wParam, LPARAM lParam, BOOL * process)  
 {  
      switch (message)  
      {  
      case WM_KEYDOWN:  
           switch (wParam)  
           {  
           case VK_UP:  
                input |= 1 << 1;  
                break;  
           case VK_DOWN:  
                input |= 1 << 2;  
                break;  
           case VK_LEFT:  
                input |= 1 << 3;  
                break;  
           case VK_RIGHT:  
                input |= 1 << 4;  
                break;  
           }  
           break;  
      case WM_KEYUP:  
           switch (wParam)  
           {  
           case VK_UP:  
                input ^= 1 << 1;  
                break;  
           case VK_DOWN:  
                input ^= 1 << 2;  
                break;  
           case VK_LEFT:  
                input ^= 1 << 3;  
                break;  
           case VK_RIGHT:  
                input ^= 1 << 4;  
                break;  
           }  
           break;  
      default:  
           break;  
      }  
      return 1;  
 }  

Now pass this function to setWndProc()

 CUSTOM_WND_PROC fn;  
 fn = keyCallBack;  
 view->setWndProc(fn);  


Thats all, now you can capture all the key inputs,

Happy Coding 🙂

1. Registering your App in Facebook

2. Adding the FB Graph API to project

Go to the FB Graph API download page, here: http://code.google.com/p/facebook-actionscript-api/downloads/list

Choose the SWC you need, depending on if you want to deploy your App on Web, Mobile or Desktop, or download the source ZIP files.

If you chose to download the source ZIP files and you’re using Flash Professional, just unzip it, open the api folder and put the com folder in your project folder’s root, next to your FLA. Then, if you’re building a Mobile or Desktop App, just open the related folder (desktopAPI or mobileAPI) and merge the files in the com folder into the pre-existing com folder.

If you’re using FlashDevelop or Flash Builder instead, just add the com folder in the src folder of your project hierarchy. Instead, if you downloaded the SWC file and you’re using Flash Builder, just put it in your libs folder. If using FlashDevelop, put it in your lib folder, right-click and select “Add to the Library”.

NOTE: If you are getting error JSON.decode no such property – change your actionscript settings player target to 10.2 or less

3. Login on FB:

The first thing we need to do is to init our FB app.

In this example we’ll examine how to use the Graph API on a Desktop app with FacebookDesktop.

Import the class:

import com.facebook.graph.FacebookDesktop;

In your Main class, store your app ID as a static constant:

static const APP_ID:String = “APP_ID”; // Just used a random but valid value

Then, as soon as the app is loaded, call the FB init method using the app ID:

FacebookDesktop.init(APP_ID, onInit);

The second parameter is a callback that will be called after complete initialization. This method requires two parameters, success and fail:

function onInit(success:Object, fail:Object):void
{
 if (success)
 { 
   trace("Already logged in");
 }
 else
 {
   trace("Not logged in");
 }
}

If the user is already logged in on Facebook, the first trace statement will run. Otherwise, success will be null and “Not logged in” will be print in the Console.

In the second case, we need a way to let the user login into Facebook. You usually use a login button to do that. When the user clicks on it, if not logged in, you call the login method:

FacebookDesktop.login(onLogin);

A popup window will appear, letting the user login on Facebook.

onLogin is a callback method called after the login attempt, and requires two parameters just like onInit, success and fail:

function onLogin(success:Object, fail:Object):void
{
 if (success)
 {
  trace("Logged In\n");
 }
 else
 {
  trace("Login Failed\n");
 }
}

If the user succesfully login, the first trace will run, otherwise success will be null.

You can also let the user logout using the logout method:

FacebookDesktop.logout(onLogout);

And the onLogout callback:

function onLogout(success:Boolean):void 
{
 trace("Log out");
}

4. Permissions

When user login your app, by default, you only have access to its basic info, depending on its privacy settings, such as id, name, picture, gender, their locale and their Friend Connection.

There are two types of permissions. User and Friends permissions are not revokable and must be accepted in order to use your app. They include, among others, likes, interests, locations, notes and photos. Extended permissions, on the other hand, are requested after you authorize the app, in a second page, and the user can selectively accept all, some or none of them, so you must take into this account while designing your app. They include access to mail box, friend list, and the ability to read and publish on the user’s stream.

You can ask for additional permissions during authentication passing an Array to the login method., in this way:

var permissions:Array = [“user_about_me”, “friends_about_me”, “read_mailbox”];

FacebookDesktop.login(onLogin, permissions);

In this case I’m asking to access both user and its friends’ info, and to read its mailbox.

As you can see, extended permissions are listed separately.

You can also choose to ask for some extended permissions only when requested, and not on login.

To do that, use the requestExtendedPermissions method:


var permissions : Array = ["read_stream", "publish_stream"];
FacebookDesktop.requestExtendedPermissions(onRequestPermission, permissions);

We specify requested permissions using an Array, as before.The user will be asked to accept the new permissions:

We also set a callback function, onRequestPermission, to be called after the user input, in either case of success or refusal:

private function onRequestPermission(success:Object, fail:Object):void
{
 if(success)
 {
  trace("Permissions granted");
 }
 else
 {
  trace("Permissions not granted");
 }

>

You’ll find the updated list of permissions in this page: https://developers.facebook.com/docs/authentication/permissions/

I’m going to write tutorials on all the major topics i come across during development. Most of the tutorials will be based on Cocos2dx as I’m exploring it these days.

 

Happy Coding 🙂