Share the process of migrating from Cocos2d x2 to Cocos2d x3

  • 2020-05-30 21:03:29
  • OfStack

The core code migration is relatively smooth, and the general process is as follows:

1. Create a project

1) cd cocos2d x - 3.0 rc0;
2) execute setup.py and set the engine-dependent environment variables. The script will write COCOS_CONSOLE_ROOT and ANT_ROOT into ~/.bash_profile; Execute source ~/.bash_profile to effect the environment variables;
3) create projects directory under cocos2d-x-3.0 rc0;
4) cocos2d - console tool is used to establish the new project: cocos new GameDemo - p com. tonybai. game. gamedemo - l cpp - d. / projects
5) cd./projects/GameDemo, we can see the project directory structure as follows:

bin/  Classes/  CMakeLists.txt  cocos2d/  proj.android/ 
      proj.ios_mac/  proj.linux/  proj.win32/  Resources/

6) cocos compile-p android-j 4, ap 19-m release, the apk of Demo will be generated, which is roughly 1 cpp-empty-test;

2. Code migration

The main work of code migration includes:
1) renamed
Most class names with an CC prefix are prefixed;
The singleton method sharedXXXX was changed to getInstance for each major class.

2) menu and button event processing
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's three touch-screen event handling functions.
In the new version of the engine, we need to set up the event Listener and register Listener with 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 handling methods.

After the transfer of core functions, GameDemo can operate normally in genymotion 4.4 Android simulator and on the real machine. The frame rate of GameDemo on the simulator can be maintained at about 40, and frame rate of 1 on the real machine can be kept at about 60. After playing 1, I feel that the engine's rendering performance has indeed improved, and this kind of improvement can be directly felt on the real machine.

I tried to run GameDemo on genymotion 2.3.7 Android, but the result was a black screen. After compiling Cocos2d-x 3.0rc0, cpp-empty-test was run on the simulator, and the same black screen result was obtained. Obviously, this may be a problem of rc0. A cursory search on Cocos2d-x forum shows that upgrading to the latest version will solve the black screen problem. So go to the official download the latest version of Cocos2d-x 3.0rc2. The cocos2d-x engine pack Size is too big and does not seem to provide any patch files, resulting in hundreds of M packages being downloaded for each release. The official git repository is also too big. After several failed attempts at clone, you can only download the source zip package.

Cocos2d-x 3.0rc2. After downloading and unpacking cpp-x 3.0rc2, cpp-empty-test was compiled and then deployed to Android 2.3.7. The "black screen" did disappear this time. The next step is to port my GameDemo to rc2.

I replaced cocos2d under GameDemo with "cocos2d-x 3.0rc2" after decompression, then ran cocos compile compile, install install run to the simulator line, the program failed to start, from monitor logcat see 1 line error log:

"ANativeActivity_onCreate not found"

How come? ANativeActivity_onCreate is provided by native_app_glue static library NDK, how could you not find it?

So open GameDemo cocos2d/cocos / 2 d platform/android/Android mk intend to check whether under 1:


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)

Android.mk did not include native_app_glue in the content of Android.mk, and then looked at the same location Android.mk in cocos2d-x 3.0rc0, which has the library dependency of native_app_glue. Did you forget about rc2? So I tried to add 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)

I tried to compile again, but this time I failed. The result of build error 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/libgamedemo.so] Error 1

As a result, the linker failed to find the function body definition for android_main in native_app_glue. android_main is an implementation of the cocos2d-x 3.0 engine. So I went back into the rc2 engine code to look for the cause, and the result surprised me: "NativeActivity has been removed by the engine!" cocos2d/cocos / 2 d/platform/android directory below has no nativeactivity. h and nativeactivity cpp:


$ ls -F cocos2d/cocos/2d/platform/android
Android.mk         CCApplication.h  CCDevice.cpp            CCFileUtilsAndroid.h  CCGLView.cpp  CCPlatformDefine.h  java/             jni/
CCApplication.cpp  CCCommon.cpp     CCFileUtilsAndroid.cpp  CCGL.h                CCGLView.h    CCStdC.h            javaactivity.cpp

We see a new file: javaactivity.cpp. When we open the file, we find a name similar to the version 2.2.2 of cocos2org_cocos2lib_Cocos2dxRenderer_nativeInit. Is the rc2 engine entry code for the Android platform back to the 2.x version of the design? So quickly into the/cocos2d/cocos / 2 d/platform/android/java/src/org/cocos2dx/lib record 1 eye to see what had happened.

Sure enough, the first cut looks familiar: Cocos2dxActivity.java, Cocos2dxGLSurfaceView.java, Cocos2dxRenderer.java... . From this it can be concluded that the engine design of the Android platform in rc2 has returned to 2.x version:
I wish to integrate your GameActivity with Cocos2dxActivity.
The GLThread(rendering thread) is born when new (new Cocos2dxRenderer()) is born
The hang loop calls Cocos2dxRenderer.onDrawFrame
The hang engine logic is executed in Cocos2dxRenderer.onDrawFrame.

Will the engine, which was designed in version 2.2.2, have the same intuitive performance boost as rc0, even if the renderer is new? Real machine test results show that there is no intuitive sense of lift. Is it the difference between Native Thread(created by pthread_create) and Java Thread? I don't know. Let's take it slow.

javaactivity.cpp moved the previous 2.2.2 version of Java_org_cocos_lib_lib_Cocos2dxRenderer_nativeInit into the engine, which is basically the same code, so it is better to put it in the engine. The design regression of rc2 also has a certain benefit. 1 is that the previous understanding of the engine still applies, and 2 is that the method suitable for the integration of the third tool in version 2.2.2 should also be suitable for version 3.0rc2, so that the cost of migration is estimated to be lower. For the new 3.0 engine, let's focus on the renderer, the event distribution mechanism, and the changes to the physical engine.

In fact, NativeActivity was removed from rc1, which is a relatively minor change. Such a big change, and such a short release, raises some concerns about the quality of the current 3.0 engine, or at least the Android version. We don't know what this piece of code will look like in the 3.0 release, but we'll see.

BTW, rc2 version cpp-empty-test has less than 10 frames on the Android 2.3.7 simulator, my Demo has only 5 frames, but on the 4.4 version, it can reach 40 frames, which is fine.


Related articles: