The core code migration is relatively smooth, and the general process is as follows:
1. Create a project
1) cd cocos2d-x-3.0rc0;
2) Execute, set the environment variables that the engine depends on, and the script will write COCOS_CONSOLE_ROOT and ANT_ROOT to ~/.bash_profile; execute source ~/.bash_profile to make the environment variables take effect;
3) Create the projects directory under cocos2d-x-3.0rc0;
4) Use the cocos2d-console tool to create a new project: cocos new GameDemo -p -l cpp -d ./projects
5) cd ./projects/GameDemo, we can see that the project directory structure is as follows:
proj.ios_mac/ / proj.win32/ Resources/
6) Execute cocos compile -p android -j 4 –ap 19 -m release, and the apk of this Demo will be generated, roughly a cpp-empty-test;
2. Code migration
The main tasks of code migration include:
1) Change your name
Most class names with CC prefixes must be removed from the prefix;
The singleton method sharedXXXX of each major class is changed to getInstance;
2) Menu and button event processing
Change from menu_selector(GameScene::menuStartCallback) to CC_CALLBACK_1(GameScene::menuStartCallback, this);
3) Touch screen event handling
In Cocos2d-x 2.2.2, we directly use Layer's setTouchEnabled(true) and Override three touch screen event handling functions;
In the new version of the engine, we need to create an event Listener and register the Listener into the global EventDispatcher, such as:
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
Then implement the three event processing methods here.
After the core functions are migrated, GameDemo can run normally on the genymotion 4.4 Android emulator and real machine. It can maintain a frame rate of about 40 on the simulator, and the frame rate on the real machine has always been around 60. After playing for a while, I felt that the engine rendering performance has indeed improved, and this improvement can be felt intuitively on a real machine.
However, the good times didn't last long. I tried to run GameDemo on genymotion 2.3.7 Android, but the result this time was: black screen. I compiled the cpp-empty-test, which comes with Cocos2d-x 3.0rc0, and put it on the simulator to run, and got the same black screen result. Obviously, this may be a problem with rc0. The rough search results on Cocos2d-x forum are: Upgrading to the latest version can solve the problem of black screen. So I went to the official download of the latest release version of Cocos2d-x 3.0rc2. I would like to complain here: the size of the cocos2d-x engine package is too large, and it seems that there is no patch file provided, resulting in a package of hundreds of M required to be downloaded for each version. The official git repository is too big. I tried to clone several times and failed. In the end, I could only download the source code zip package.
After downloading and decompressing Cocos2d-x 3.0rc2, I first compiled cpp-empty-test and deployed it to Android 2.3.7 to run. This time, the "black screen" is indeed gone. It seems that rc2 has fixed this problem. Next is to port my GameDemo to rc2.
I replaced cocos2d under GameDemo with the unzipped "cocos2d-x 3.0rc2", then ran cocos compile, installed to the emulator line to run, the program failed to start, and I saw a line of error log from monitor logcat:
“ANativeActivity_onCreate not found”
How could it be? ANativeActivity_onCreate is provided by NDK's native_app_glue static library, how can it not be found?
So I opened GameDemo/cocos2d/cocos/2d/platform/android/ to check it out:
LOCAL_WHOLE_STATIC_LIBRARIES := cocos_png_static cocos_jpeg_static cocos_tiff_static cocos_webp_static
include $(BUILD_STATIC_LIBRARY)
$(call import-module,jpeg/prebuilt/android)
$(call import-module,png/prebuilt/android)
$(call import-module,tiff/prebuilt/android)
$(call import-module,webp/prebuilt/android)
The content is not included in native_app_glue, and I looked at the same location in cocos2d-x 3.0rc0, which has native_app_glue library dependencies. Could it be that I forgot about rc2? So I tried adding the native_app_glue dependency:
LOCAL_WHOLE_STATIC_LIBRARIES := android_native_app_glue cocos_png_static cocos_jpeg_static cocos_tiff_static cocos_webp_static
include $(BUILD_STATIC_LIBRARY)
$(call import-module,jpeg/prebuilt/android)
$(call import-module,png/prebuilt/android)
$(call import-module,tiff/prebuilt/android)
$(call import-module,webp/prebuilt/android)
$(call import-module,android/native_app_glue)
Try compiling again, but this time I failed to compile. The wrong build result is as follows:
/home1/tonybai/android-dev/adt-bundle-linux-x86_64/android-ndk-r9c/sources/android/native_app_glue/android_native_app_glue.c:232: error: undefined reference to 'android_main'
collect2: error: ld returned 1 exit status
make: *** [obj/local/armeabi/] Error 1
Judging from the results, the linker failed to find the function body definition corresponding to android_main in native_app_glue. Android_main is an implementation provided by the cocos2d-x 3.0 engine. So I went into the rc2 engine code again to find the reason, but the result surprised me: "NativeActivity was removed by the engine"! There is no more and below the cocos2d/cocos/2d/platform/android directory:
$ ls -F cocos2d/cocos/2d/platform/android
java/ jni/
We saw a new file:, open the file, and we found a name similar to the cocos2d-x 2.2.2 version: Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit. Has rc2's engine entry code for Android platform fall back to the version design? So I quickly entered the /cocos2d/cocos/2d/platform/android/java/src/org/cocos2dx/lib directory and found out.
Sure enough, everything seems so familiar: , …. From then on, it can be concluded that the engine design of the Android platform in rc2 has returned to the version:
– Your GameActivity needs to integrate Cocos2dxActivity;
- GLThread (rendering thread) is born when mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer())
– Deadly loop call
– The engine logic is executed in it.
Going back to the performance of the engine designed in version 2.2.2 will give people an intuitive improvement like rc0, even if the renderer is newly written? The results of the real machine test show that there is no intuitive feeling of improvement. Is it the difference between Native Thread (created by pthread_create) and Java Thread? I don't know, let's experience it slowly in the future.
Another thing to mention: put Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit in project jni into the engine. It is basically unchanged code, and it is indeed better to put it in the engine. The design regression of rc2 also has certain benefits. First, the previous understanding of the engine was still applicable, and second, the method suitable for third-party tools integrated in version 2.2.2 should also be suitable for version 3.0rc2, so the porting cost is estimated to be smaller. In this way, for the new 3.0 engine, the focus is on the changes in the renderer, event distribution mechanism and physics engine.
In fact, NativeActivity was removed in rc1, and this major change made people unpredictable. Such a big change and such a short release, people have expressed some concerns about the quality of the current 3.0 engine, at least the Android version of the engine. I don’t know what the code in this section will look like in the official version of 3.0, so let’s wait and see.
BTW, the rc2 version cpp-empty-test has a frame count of less than 10 frames on the Android 2.3.7 emulator, and my demo is only 5 frames. On the 4.4 emulator, it can reach 40 frames, which is not bad.