Cocos2d-x Android Environment Setup
Cocos2d-x environment Building is relatively simple, but small problem is still a lot, I try to cover a comprehensive number.
Download software
Cygwin, NDK (ADT): C + + Related
If you don't have an Android development environment before, you'll need Android Sdk,eclipse
Cocos2d-x Source
My environment for the NDK R7,cygwin1.7,android SDK is 2.2 and 3.0. In addition, I am through the real machine debugging, not in the simulator, it is estimated that I T410 graphics card problems.
Install Cygwin, path settings in Cygwin file
Add the following code in the Cygwin\home\administrator. Bash_profile
1:android_ndk_root=/cygdrive/e/adt/android-ndk-r7c
2:export Android_ndk_root
3:ndk_root=/cygdrive/e/adt/android-ndk-r7c
4:export Ndk_root
LIBGNUSTL_STATIC.A from the android-ndk-r7c\sources\cxx-stl\gnu-libstdc++\libs\ in the NDK Armeabi Copy to Cocos2d-1.0.1-x-0.13.0-beta\helloworld\android\obj\local\armeabi, this from the solution should be the STL reference inconsistency caused by the problem, but the compilation will be error " PNG.A can not find ", but the path is not really a problem, so compared to the pit dad, in short, this is done, I did not how to dig.
Enter the Cocos2d-1.0.1-x-0.13.0-beta\helloworld\android directory to modify the following to the specified path
1:ndk_root_local=/cygdrive/e/adt/android-ndk-r7c
2:cocos2dx_root_local=/cygdrive/f/cocos2d-1.0.1-x-0.13.0-beta
Cygwin into the Cocos2d-1.0.1-x-0.13.0-beta\helloworld\android directory, execute./build_native.sh, compile C++,jni interface for Android Java to use, if successful To build libhelloworld.so dynamic Library in Libs, we've done so much work for it.
Import Cocos2d-1.0.1-x-0.13.0-beta\helloworld\android project in Eclipse, familiar with the android look on it, in fact, this is a Java project in itself, we just the operation is just a part of the JNI, For the Java call implementation.
Execute build Project in Eclipse, build R.java
Run
Make
The NDK make is a package based on the GNU made, so let's analyze what the/build_native.sh has done. Basically, it's about resource copying and code compilation.
Copy of the resource in my Cygwin found a problem, the copy of the file is wrong, and can not be deleted I did not delve into, I manually copied a bit. Consistent with the shell, it is easy to understand and no longer delve into.
Ndk-build Compile the HelloWorld project, compile the android.mk under the Jni folder, and makefile basically similar, specify the files that need to be compiled, include the path, rely on the project cocos2dx_static, compile, For example, the makefile of HelloWorld is roughly as follows:
Local_path: = $ (call My-dir)
Include $ (clear_vars)
Local_module: = helloworld_shared
Local_module_filename: = Libhelloworld
Local_src_files: = helloworld/main.cpp \
.. /.. /classes/appdelegate.cpp \
.. /.. /classes/helloworldscene.cpp
Local_c_includes: = $ (Local_path)/. /.. /classes
Local_whole_static_libraries: = cocos2dx_static
Include $ (build_shared_library)
$ (call IMPORT-MODULE,COCOS2DX)
Local_path: = $ (call My-dir): Specifies that the current path is Local_path
Include $ (clear_vars): Clears interference from environment variables other than Local_path
Local_module&local_module_filename: module name & Build library Name
Local_src_files: Compiled C + + Source
Local_whole_static_libraries: Dependent static libraries
Build_shared_library: Generated as a shared library. Because the Android dynamic library is used for JNI, it is called a shared library, and the static library is used only by other C + + libraries.
$ (call import-module,<name>): The directory list of modules <name> that are referenced by the NDK_MODULE_PATH environment variable and automatically included in the ANDROID.MK
In this way, a compilation environment Include,library,target basic specification, then compile the final target file, and makefile the idea of no difference, In addition, the need to compile the cocos2dx.a, static library, is through the Cocos2d folder make compiled, this script is more complicated, but the idea is not different. More NDK make can refer to: "Android make"
JNI interaction
After the C + + interface is encapsulated, we begin to look at the Java code to see the final implementation of the process and effect, the Java code is as follows:
Java layer of the framework is also very simple, there is no more accelerometer and music, sound and other analysis, only related to the display of the analysis. The Java level process is as follows:
As above, if you are familiar with the development of the Android interface, you can learn from the base class that the Java level is displayed through activity, Glsuffaceview. Here is not detailed, if interested, you can look at the "Analysis game development with view or Surfaceview", view similar to the traditional two-dimensional static interface, data-driven display, and Surfaceview is similar to three-dimensional mechanism, real-time rendering. Because Cocos2d is OpenGL, it's also a good explanation.
The whole framework is actually a lot to say, but I do not know much about Java, so some things do not necessarily see through, there are inevitably some problems.
Renderer
The renderer class is responsible for rendering the driver for each frame, calling 1 and 2 inside the step, invoking the Nativerender within the 2 to achieve a frame of rendering, while Glsurfaceview is responsible for UI interaction monitoring.
The benefit of this mechanism is that in Java the renderer renderer is called by a separate thread, so there is no interactivity between the UI, which guarantees the user experience (the user's event is glsurfaceview-monitored and ultimately responds via renderer to the C + + level). It also ensures that the rendering process is anti-jamming and is still rendered through the C + + level. , the JNI package used in the entire display process is as follows:
private static native void Nativetouchesbegin (int id, float x, float y); private static native void nativetouchesend (int id, float x, float y);p rivate static native void Nativetouchesmove (int[] I D, float[] x, float[] y);p rivate static native void Nativetouchescancel (int[] ID, float[] x, float[] y);p rivate static NAT Ive boolean nativekeydown (int keycode);p rivate static native void Nativerender ();p rivate static native void Nativeinit (in t W, int h);p rivate static native void Nativeonpause ();p rivate static native void Nativeonresume ();
JNI Encapsulation
The JNI package has two main parts, one is Cocos2d's own JNI encapsulation, which is mainly to call Cocos2d's JNI interface in Java, and one is the HelloWorld's own JNI interface encapsulation. This piece is originally I am more interested in the place, because the JNI package is still quite cumbersome one thing, finally found that cocos2d in essence there is no difference, the trouble is to be encapsulated. 2nd, Cocos2d is mainly the game engine, so basic all functions are implemented by C + + level, a frame of rendering, event processing, while the Java layer is mainly responsible for the logical processing, finally through the JNI call C + + interface to achieve. 3rd, cocos2d itself encapsulated is still very concise, this point I think is still very elegant, in the design of this piece, is based on the logic of Java Division, I think this is very desirable, although cocos2d is C + + to do it, However, in order to ensure the consistency of the various platforms to enforce the same interface, but in the JNI layer in accordance with the application of the SDK in the specific platform to encapsulate, so as to reduce the difficulty of implementation, improve the ease of use of the code, the sacrifice is the application platform interface of the local inconsistency. The JNI layer is mainly the interface encapsulation of the event passing and the window rendering part, for the game developer, the core part can be done under the Windows platform, then the specific event is delivered in the Android part, and the rendering part is implemented directly by the standard example of cocos2d. Greatly simplifies the developer's own encapsulation of JNI work.
Window bindings
Window bindings I do not understand very well, first of all, I think cceglview_android is just a virtual window, and no real function, just to facilitate the understanding of the architecture.
void Java_org_cocos2dx_lib_cocos2dxrenderer_nativeinit (jnienv* env, Jobject thiz, Jint W, Jint h) { if (! Cocos2d::ccdirector::shareddirector ()->getopenglview ()) { Cocos2d::cceglview *view = &cocos2d:: Cceglview::sharedopenglview (); View->setframewidthandheight (W, h); If you want to run in WVGA with HVGA resource, set it //View->create (480,; Please change it to (+ 480) If you ' re in portrait mode. Cocos2d::ccdirector::shareddirector ()->setopenglview (view); Appdelegate *pappdelegate = new Appdelegate (); Cocos2d::ccapplication::sharedapplication (). Run ();} } void Java_org_cocos2dx_lib_cocos2dxrenderer_nativerender (jnienv* env) {
Function one is called when the Java layer calls onsurfacecreated function, to get the Glview window for the next rendering, and this view window is not similar to Windows handle binding, And then the second is the Java ondrawframe render each frame when the call, and ultimately call the underlying director rendering, complete a frame drawing (the details can be referred to "cocos2d-x HelloWorld example Analysis (a)").
How to understand this window binding way, to ensure that I now call the GL function, can be drawn in the window, there is no similar handle from Java to JNI, the entire C + + level of view is only a width and height properties of the structure, So what I understand is that glsurfaceview.renderer is encapsulated in its own thread by default and has already done its own binding with OpenGL. This I think it should be a reliable, and the real-time of their own to render each frame, the following is no matter, you are willing to tune the Java interface line, your own tune GL rendering can also. This is also very good, do not need me to worry about this matter, as long as I know the height of the width of the location information, I directly render.
Text
The drawing of other graphic images is not related to the system. The entire rendering process, but also cross-platform, a platform for integration, mainly the environment, communication between different languages, view mapping these, the front is also elaborated, but the text has a certain special, in Windows using CDC, in Linux is FreeType, How is it implemented under Android? I think cocos2d is a good idea: C + + is drawn through JNI in the Java layer, generating a bitmap to C + + and then mapping. This advantage is simple, the disadvantage is that if the text is too much, the loss of efficiency or some, in fact, I think if there is a chance, or use FreeType to draw should also be able to try.
Of course, also learned a trick, C + + calls the Java way, in the JNI also provides, hehe, the code is posted below:
BOOL Getbitmapfromjava (const char *text, int nwidth, int nheight, ccimage::etextalign ealignmask, const char * pfontname, Float fontSize) {jnimethodinfo methodinfo;if (! Jnihelper::getstaticmethodinfo (MethodInfo, "Org/cocos2dx/lib/cocos2dxbitmap", "Createtextbitmap", "(Ljava/lang/ String; LJAVA/LANG/STRING;IIII)) {Cclog ("%s%d:error to get MethodInfo", __file__, __line__); return false; } jstring Jstrtext = Methodinfo.env->newstringutf (text); Jstring Jstrfont = Methodinfo.env->newstringutf (pfontname); Methodinfo.env->callstaticvoidmethod (Methodinfo.classid, Methodinfo.methodid, JstrText, JstrFont, (int) fontSize , Ealignmask, nwidth, nheight); Methodinfo.env->deletelocalref (Jstrtext); Methodinfo.env->deletelocalref (Jstrfont); Methodinfo.env->deletelocalref (METHODINFO.CLASSID); return true;} static bool Getstaticmethodinfo_ (Cocos2d::jnimethodinfo &methodinfo, const char *classname, const char *methodname, const CHAR *paramCode) {Jmethodid methodid = 0; JNIEnv *penv = 0; if (! GETENV (&penv)) {break; } Jclass ClassID = Getclassid_ (ClassName, penv); Methodid = Penv->getstaticmethodid (ClassID, MethodName, Paramcode);
Referring to the comments inside, C + + driver Java implementation of the drawing, after the completion of Java drawing, call JAVA_ORG_COCOS2DX_LIB_COCOS2DXBITMAP_NATIVEINITBITMAPDC interface, to achieve a copy of memory, and S_ The m_pdata in BMPDC is used to save and perform the next texture mapping to complete the transfer of the rectification process.
Summarize
Introduction finished, the whole process, cocos2d use of the technology is not mysterious, is mainly a familiar process. The most commendable is that the JNI encapsulation comparison uses, itself does the game development, the basic all functions will be in the C + + closed implementation, only need to provide a specification Java shell to be able, Both platforms are efficient. In addition, is cocos2d on the various platform language choice, which is convenient for Java, which uses C + + to keep the platform consistent, are doing is still very reasonable.