Porting the Cocos 2d-x Games to windows phone 8/8.1 and Windows 8/8.1 platforms

Posted: November 19, 2014 in Uncategorized

Being a Big fan of Microsoft I am so happy to share my learnings. In this article i will demonstrate how to port an existing Cocos2d-x game written in C++ to windows platforms with step by step instructions. I’ll try to  cover all important aspects along with some tips.

Software requirements :

1)  Visual studio 2013

2)  Cocos 2d-x 2.3.2 frame work

 Process step by step :

1. Open the cocos 2d-x frame work and select the template folder (2.2.3 version on wards Google ad mob will work)

2. Open the template folder and  selcet the multi-platform-cpp folder and open it

3.  Select the proj.wp8-xaml and double click on it

4.  Open the HelloCpp.sln visual studio project.

5.   After opening the project add the classes and resources to the project as follows

  1.   Right click on the classes folder in HelloCppComponent and select the add then click followed by Existing Item  Navigate to classes and select the required classes and add them.
  2.   Copy the all resources in your game and right click on the Assets folder in HelloCpp

then select the show in explorer and paste the resources there.

Now the setup is finished and we have to handle the errors and other things.

6. Find any deprecated methods in your project  and replace them with new methods.

Example : Random instead of Rand function.

7. Check out the errors in out put or Error window and fix them one by one

Example: The methods which are used to create the GUI elements (Buttons, labels, Images, HUD) should be  declared such a way that should take atleast one arguement generally pass  CCObject *psender argument.

Audio support on Windows Phone :

1. Convert all the sound files into .wav format using the software like Audacity. and copy them to project resources folder.

2. Make sure .wav extension in code to play the audio. Find all as follows Ctrl+Shift+F,it will search in whole solution

then replace  .wav instead of.mp3.

3. As if you want to maintain the universal project use the the platform specific code


#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8 ||  CC_TARGET_PLATFORM ==CC_PLATFORM_WINRT

{

audioEngine->preloadEffect("sampleEffect.wav");

audioEngine->playBackgroundMusic("sampleBGSound.wav",true);

}

#else

{

audioEngine->preloadEffect("sampleEffect.mp3");

audioEngine->playBackgroundMusic("sampleBGSound.mp3",true);

}

#endif

Font support on Windows Phone :

For Windows Phone use the supported fonts rather than using the differrent one. use the platform specific code for

universal projects. check here for supported fonts


#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM ==CC_PLATFORM_WINRT

this->Gamelabel = CCLabelTTF::create("Score : ", "Arial", 20);

#else

this->Gamelabel = CCLabelTTF::create("Score : ", "Helvetica", 20);

#endif

Note: CC_PLATFORM_WP8 for Windows phone 8 and CC_PLATFORM_WINRT for windows 8 games.

5) Device back button: [mandotory for app certification]

1. To add the back button just have a virtual method in the base class and Override in the sub classes.

In AppDelegate class we have to set the layer and depends on the layer name call the back button if it’s null then call the application exit


void Layer::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event) //use the function like this:

void MyLayer::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)

{

if (keyCode == EventKeyboard::KeyCode::KEY_ESCAPE)

{

CCLOG("You pressed back button");

Director::getInstance()->end();

exit(0);

}

}

6) Background music continuous looping problem even App went to background State:

I)To fix this problem first of all  Open the AppDelegate.cpp


void AppDelegate::applicationDidEnterBackground()

{

CCDirector::sharedDirector()->pause();

CCDirector::sharedDirector()->stopAnimation();

// if you use SimpleAudioEngine, it must be pause

SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();

}

// this function will be called when the app is active again

void AppDelegate::applicationWillEnterForeground()

{

CCDirector::sharedDirector()->resume();

CCDirector::sharedDirector()->startAnimation();

// if you use SimpleAudioEngine, it must resume here

CocosDenshion::SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();

}

  1.    II) Open the cocos2dRenderer.Cpp

In CreatGLResources method add the following line

</pre>
mApp->applicationWillEnterForeground(); //Add this line to call the application activation state

void Cocos2dRenderer::CreateGLResources()

{

mApp->applicationWillEnterForeground(); //Add this line

}

In Disconnect method add the following line

mApp->applicationDidEnterBackground(); //Add this line to call the application background state

// purge Cocos2d-x gl GL resourses since the DirectX/Angle Context has been lost

void Cocos2dRenderer::Disconnect()

{

mApp->applicationDidEnterBackground();

}

7) Device Acceleration (tilt):

Add the following Files AcceleratorDelegate.h, AcceleratorDelegate.cpp

1) AcceleratorDelegate.h

#pragma once

class GameScene;

ref class AcceleratorDelegate sealed

{

public:

static property AcceleratorDelegate^ AcceleratorInstance

{

AcceleratorDelegate^ get()

{

static AcceleratorDelegate^ instance;

if (instance == nullptr)

instance = ref new AcceleratorDelegate();

return instance;

}

}

public:

virtual ~AcceleratorDelegate(void) { }

private:

AcceleratorDelegate(void);

// ~AcceleratorDelegate(void);

public:

void ReadingChanged(Windows::Devices::Sensors::Accelerometer^ sender, Windows::Devices::Sensors::AccelerometerReadingChangedEventArgs^ e);

private:

Windows::Devices::Sensors::Accelerometer^ m_accelerometer;

Windows::Foundation::EventRegistrationToken m_readingToken;

uint32 m_desiredReportInterval;

};

2)AcceleratorDelegate.cpp

#include “AcceleratorDelegate.h”

using namespace Windows::Devices::Sensors;

using namespace Windows::Foundation;

using namespace Platform;

AcceleratorDelegate::AcceleratorDelegate(void) //default constructor

{

m_accelerometer = Accelerometer::GetDefault();

if (m_accelerometer != nullptr)

{

// This value will be used later to activate the sensor.

uint32 minReportInterval = m_accelerometer->MinimumReportInterval;

m_desiredReportInterval = minReportInterval > 16 ? minReportInterval : 16;

m_readingToken = m_accelerometer->ReadingChanged::add(ref new         TypedEventHandler<Accelerometer^, AccelerometerReadingChangedEventArgs^>(this, &AcceleratorDelegate::ReadingChanged));

}

//end if m_accelerometer

}

void AcceleratorDelegate::ReadingChanged(Windows::Devices::Sensors::Accelerometer^ sender, Windows::Devices::Sensors::AccelerometerReadingChangedEventArgs^ e)

{

AccelerometerReading^ reading = e->Reading;

//X-reading->AccelerationX –>send as y value

//Y-reading->AccelerationY –> send as -x value

//Z-reading->AccelerationZ

}

***Note: This post is already published at myblog 

Thanks!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s