Cocos2D-x Migrating Projects from V2 to V3
Revisions (Version, date) | Contributor | Notes |
v1.00, 16th August 2014 | Gav (GMTDev) | First version |
v1.01, 21st August 2014 | Gav (GMTDev) | Tidy up with more tables. CCObject. |
v1.02, 30th August 2014 | Gav (GMTDev) | Added a bit more to Tiled Maps section |
v1.03, 9th Sept 2014 | Gav (GMTDev) | Point updated, other additions |
This is an unofficial guide to migrating your Cocos2D-x version 2 project to version 3. I wrote this guide when converting Arrow Mania from Cocos2d-x version 2.2.5 to version 3.2; So realise some of the code may have changed in more recent versions. The Cocos2d-x team will undoubtedly have made changes (they always do, backward compatibility, not even in the same version 3 point releases, is not a feature of Cocos2d-x!!! Annoying I know!).
This guide assumes you have already created an empty v3 project and added you v2 source code and resources to the project. Compiling is bringing up errors and depreciation warnings.
A more official guide that was made for V3.0 can be found on the Cocos2D-x site here, though maybe this guide is better… you decide. Whichever guide you choose to follow, this is a pretty intensive task. A lot of changes were made from V2 to V3, a lot of old functions have been depreciated. The lists and text here aim to make the transition a little less painful and show you what has been replaced with what. All in all I’m sure you’ll agree at the end the improvements are worth the effort.
C++ 11
Probably the most important update to Cocos2D-x is that is it now C++ 11. C++ 11 is a vastly imporved implementation and it is well worth your time learning some of its features if you haven’t already done so. Here is a great little guide on CodeProject: http://www.codeproject.com/Articles/570638/Ten-Cplusplus-Features-Every-Cplusplus-Developer
Disclaimer / Warning – BACKUP!
This guide is provided “as is” and there is no guarantee it will work or that the information here is correct, use it at your own risk.
Backup your project and all its files before proceeding.
Section 1: Find And Replace
Once you have created a new project and added your project files you’ll see lots of warnings and errors due to depreciated code and new naming conventions used in Cocos2D-x. Don’t panic!
To make our find and replace changes we can use your IDE editors powerful find and replace tools. You want to search only inside your “Classes” folder so you don’t go changing any code in the Cocos source folder. Guides on how to find and replace with some of the common editors follow, you will be doing this using the “Table 1” and “Table 2” changes lists that are after the guides below.
XCode – Find and Replace Guide
Note the red boxes in the image below as use in the guide.
- Click the Find menu and select “Find and Replace In Project”.
- Be sure to select “Matching Case” (defaults to “Ignoring Case”).
- Be sure to change the “In” parameter to “In Classes”
- Enter your search term in the top box (e.g. CCSprite from Table 1) and enter your replacement in the bottom box (e.g. “Sprite” from Table 1), and hit Enter to tell XCode you’ve entered the text.
- Hit the “Replace All” button, for some weird reason you will need to click “Replace All” a second time to make the changes happen… so do that!
- Build to update your error list and move onto the next replacement.
Eclipse Find and Replace Guide
- A little finiky to use so use XCode if you can, but Eclipse does have search and replace to.
- With your project loaded, click the “Search” menu and click “File.
- In the Search dialog window, make sure “Case sensitive” is ticked.
- Under “File name patterns” enter “*.cpp, *.h”.
- Under Scope select Workspace.
- Enter your search text in the “Containing text” box (e.g. CCSprite).
- Click the “Replace” button, don’t worry it doesn’t do the replcae yet, just a search (not very logical I know).
- Now in the Replace dialog window, enter your replacement string (e.g. “Sprite”).
- Build to update your error list and move onto the next replacement.
Visual Studio Find and Replace Guide
<please add>
Table 1: Find and Replace Changes
The majority of these changes are essential or highly recommended changes you need to make to be able to compile.
No. | Cocos2D-x V2 | Cocos2d-x V3 | Notes |
1 | CCTouches | onTouches | Changes others like CCTouchesBegan/Moved/Ended |
2 | CCSet | Set | |
3 | CCTouch | Touch | |
4 | CCEvent | Event | |
5 | ccColor3B | Color3B | |
6 | setTouchEnabled | remove – no longer required | |
7 | m_sString | _string | std::string member and String (was CCString) |
8 | CCLayer | Layer | |
9 | CCNode | Node | |
10 | CCAction | Action | |
11 | CCFollow | Follow | |
12 | CCObject | CCObject has been removed and is no longer the base class of Cocos! If you have any of your own classes using CCObject (e.g. inheriting it like “class MyClass: CCobject”) just remove the use. | |
13 | actionWithTarget | initWithTarget | E.g. with “class CC_DLL Follow : public Action” |
14 | CCRectMake | Rect | CCRectMake(x,y,w,z) becomes Rect(x,y,w,z) |
15 | CCRect | Rect | |
16 | CCSize | Size | Changes others like CCSizeMake too |
17 | CCSpriteFrameCache | SpriteFrameCache | Do this and the next 2 in order. The effect will be to change CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName to
SpriteFrameCache::getInstance()->getSpriteFrameByName … as well as other related CCSpriteFrameCache calls. |
18 | SpriteFrameCache::sharedSpriteFrameCache() | SpriteFrameCache::getInstance() | See above |
19 | spriteFrameByName | getSpriteFrameByName | See above |
20 | CCSprite | Sprite | Changes CCSprite,CCSpriteFrame,etc |
21 | CCArray | . | |
22 | CCArray | ValueVector | CCArray/Array is depreciated. If you are leaving it in then note it longer initialises itself, you now need to call “myArray->init();” before adding objects. ValueVector is the replacement. Related to Map and Vector. |
23 | CCDictionary | ValueMap | e.g. myMap[“name”].asInt(); // returns and int for the map value item “name”
e.g. myMap[“name”].asString().c_str(); // returns a char string |
24 | CCString | Value | |
25 | ccp( | Point( | include ‘(‘ so we don’t change ccpAdd, etc |
26 | CCSizeMake | Size | |
27 | EAGLView.h | CCEAGLView.h | |
28 | CCEGLView::sharedOpenGLView() | Director::getInstance()->getOpenGLView() | |
29 | CCApplication | Application | |
30 | sharedApplication() | getInstance() | So now Application::getInstance() |
Table 2 – Find and Replace Changes
The following table is for calls that are depreciated, as in they will still work in V3.2 and can be done later, you will just get a warning.
No. | Cocos2D-x V2 | Cocos2d-x V3 | Notes |
1 | CocosDenshion::SimpleAudioEngine::sharedEngine() | CocosDenshion::SimpleAudioEngine::getInstance() | |
2 | CCDirector::sharedDirector() | Director::getInstance() | |
3 | CCDirector | Director | |
4 | objectAtIndex | getobjectAtIndex | |
5 | CCApplication::sharedApplication() | Application::getInstance() | |
6 | SpriteFrameCache::sharedSpriteFrameCache() | SpriteFrameCache::getInstance() | e.g. SpriteFrameCache::getInstance()->addSpriteFramesWithFile(“your.plist”); |
Section 2: Edit Code
The following sections describe code that needs hands on editing and examples of code for like multi-touch handling.
CCSpriteFrame / SpriteFrame
v2 | v3 |
CCSpriteFrame *frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“sprite.png”) | SpriteFrame *frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(“sprite.png”); |
// Scene Creation (In AppDelegate.cpp)
CCDirector* pDirector = CCDirector::sharedDirector(); CCScene *pScene = HelloWorld::scene(); pDirector->runWithScene(pScene); |
// Scene Creation (In AppDelegate.cpp)
Director *pDirector = Director::getInstance(); auto scene = HelloWorld::scene(); pDirector->runWithScene(scene); |
CCObject has been depreciated
CCObjust was Cococs2D-x v2’s base class but is no more. If you were using it in any of your own classes you will be needing to define the real class in its place and / or cast to other classes.
Key Input / keyBackClicked()
Keyboard handling has changed. keyBackClicked() is depreciated In v3 we now use onKeyReleased and look for the KeyCode KEY_ESCAPE. Here is what you need to do in order to receive keypresses as well as the KEY_ESCAPE (back) key:
In your scenes header file, define the onKeyPressed and onKeyReleased:
virtual void onKeyPressed(EventKeyboard::KeyCode code, Event* event);
virtual void onKeyReleased(EventKeyboard::KeyCode code, Event* event);
In your scenes init function, setup the listener:
auto keyboardListener = EventListenerKeyboard::create();
keyboardListener->onKeyPressed = CC_CALLBACK_2(HelloWorld::onKeyPressed, this);
keyboardListener->onKeyReleased = CC_CALLBACK_2(HelloWorld::onKeyReleased, this);
_eventDispatcher->addEventListenerWithFixedPriority(keyboardListener, -11);
_keyboardListener = keyboardListener;
In your scene cpp file, add your handlers:
void HelloWorld::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event){
CC_UNUSED_PARAM(keyCode);
CC_UNUSED_PARAM(unused_event);
}
void HelloWorld::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event) {
if (keyCode == EventKeyboard::KeyCode::KEY_ESCAPE){ // Act on back/escape key }
}
Add to your header file:
EventListenerTouchAllAtOnce *m_pListener;
virtual void onKeyPressed(EventKeyboard::KeyCode code, Event* event);
virtual void onKeyReleased(EventKeyboard::KeyCode code, Event* event);
Touches – Multi Touch: onTouchBegan, onTouchMoved, onTouchEnded
Your scenes header file:
virtual bool onTouchesBegan(Touch* touch, Event* event);
virtual void onTouchesMoved(Touch* touch, Event* event);
virtual void onTouchesEnded(Touch* touch, Event* event);
Your screnes cpp file, in your init:
// Adds Touch Event Listener
m_pListener = EventListenerTouchAllAtOnce::create();
m_pListener->onTouchesBegan = CC_CALLBACK_2(HelloWorld::onTouchesBegan, this);
m_pListener->onTouchesMoved = CC_CALLBACK_2(HelloWorld::onTouchesMoved, this);
m_pListener->onTouchesEnded = CC_CALLBACK_2(HelloWorld::onTouchesEnded, this);
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(m_pListener, -10);
Your screnes cpp file, add the handlers (or modify your v2). Note I am just giving onTouchesBegan code here, exaclty the same for onTouchesMoved and onTouchesEnded:
void HelloWorld::onTouchesBegan(const vector<Touch *> &touches, Event *event)
{
Touch* touch;
for( int iTouchCount = 0; iTouchCount < touches.size(); iTouchCount++ )
{
touch = touches.at(iTouchCount); //(CCTouch*)(*it);
cocos2d::Point touchPoint = touch->getLocationInView();
touchPoint = ConvertTouchCoords(touchPoint);
// int iTouchID = touch->getID(); // Hint: Use the touch ID to determine if it is the same touch in Moved and Ended
}
}
WARNING for iOS Users on V3.2 or below: You will need to add the “[eaglView setMultipleTouchEnabled:YES];” line after your didFinishLaunchingWithOptions function, put it just after the line “_viewController.view = eaglView;”. Note: this should be fixed in V3.3 and on.
CCPoint / Point
CCpoint becomes Point. All related “cpp” functions like (ccpMulti, ccpAdd) are depreciated and are replaced by their mathematical operations */-+
v2 | v3 |
CCPoint pt = ccp( x, y ); | Point pt = Point( x, y ); |
CCPoint p1 = ccpAdd( p2, p3 ); CCPoint p1 = ccpSub( p2, p3 ); CCPoint p1 = ccpMult( p2, p3 ); |
Point p1 = p2 + p3;
Point p1 = p2 – p3; Point p1 = p2 * p3; |
float distance = ccpDistance( pt1, pt2 ); | float distance = pt1.getDistance(pt2); |
ccpToAngle(pt); | pt.getAngle(); |
TMX Tile Maps
Note: CCFollow and CCCamera seem to be very different in V3 and currently I don’t have them working properly. Just a warning, there is talk of an improved CCCamera in an upcoming V3 release.
v2:
// Load a map and add it to the layer
TMXTiledMap* pMap = new TMXTiledMap;
pMap->initWithTMXFile(filename);
addChild(pMap, 0, kTagTileMap);
// or…
TMXTiledMap map;
map.initWithTMXFile(filename);
addChild(map, 0, kTagTileMap);
// Retrieve handle to the map
TMXTiledMap *pMap = (TMXTiledMap*) getChildByTag(kTagTileMap);
v3:
// Load a map and add it to the layer
auto map = cocos2d::experimental::TMXTiledMap::create(filename);
addChild(map, 0, kTagTileMap);
// Retrieve handle to the map
auto map = static_cast<cocos2d::experimental::TMXTiledMap*>( getChildByTag(kTagTileMap) );
// Note: As we are now using auto, we can’t have a copy of the pointer/handle in your class header
// as it is not static. We now can only get the handle back using the tag.
// i.e. Before you could have “TMXTiledMap* pMap” in your class, but you can’t have “auto *pMap”
Find and Replace Changes – Table for TMX Tile Maps
No. | Cocos2D-x V2 | Cocos2d-x V3 | Notes |
1 | CCTMX | TMX | Changes all TMX occurances like CCTMXObjectGroup,CCTMXLayer,etc. |
2 | tileAt | getTileAt |
v3 – Access Layer info and Get Map Size
auto layer = map->getLayer(“Layer 1”);
Size szMapInPoints = layer->getContentSize();
Size szMapInTiles = layer->getLayerSize();
v3 – Get Object Layer Information
auto group = map->getObjectGroup(“Object Layer 1”); // The name of the layer
auto& objects = group->getObjects();
Value objectsVal = Value(objects);
CCLOG(“%s”, objectsVal.getDescription().c_str());
std::string key;
std::string str;
for (auto& obj : objects) // Repeats this loop for all objects
{
ValueMap dict = obj.asValueMap();
Value objectsVal = Value(objects);
// name,type,x,y,width,height are in every object
std::string name = dict[“name”].asString();
std::string type = dict[“name”].asString();
float x = dict[“x”].asFloat();
float y = dict[“y”].asFloat();
float w = dict[“width”].asFloat();
float h = dict[“height”].asFloat();
// You can define your own types in the Tiled map editor for an object to, to retrieve
// its value do it the same as above using the name you gave it, then one of the Value
// function names like asInt()/asFloat()/asString()/etc
int myValue = dict[“myIntVal”].asInt();
}
Languages: getCurrentLanguage kLanguage becomes LanguageType
The “kLanguage” system has been replaced with the “LanguageType:” definition.
v2 | v3 |
switch( CCApplication::sharedApplication()->getCurrentLanguage() )
{ default: case kLanguageEnglish: break; case kLanguageArabic: break; case kLanguageFrench: break; } |
switch( Application::getInstance()->getCurrentLanguage() )
{ default: case LanguageType::ENGLISH: break; case LanguageType::ARABIC: break; case LanguageType::FRENCH: break; } |
Labels
V2 | V3 |
CCLabelTTF *myLabel;
myLabel = CCLabelTTF::create( text, fontName, fontSize ); myLabel>retain(); addChild( myLabel, ZORDER ); |
Label* myLabel;
myLabel = Label::createWithTTF(text, fontName, fontSize); myLabel>retain(); addChild( myLabel, ZORDER ); |
Other Online Guides
http://www.redtgames.com/blog/cocos2d-x-v2-to-v3-mapping-guide/
[catlist numberposts=30]
One thought on “Cocos2D-x Migrating Projects from V2 to V3 Guide”
Comments are closed.