Monday 1 September 2014

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

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();
}
   II) Open the cocos2dRenderer.Cpp
In CreatGLResources method add the following line
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
}

No comments:

Post a Comment