cocos2d-x-3.6 user interaction principle---------How to connect Java and C + + via JNI

Source: Internet
Author: User
Tags gety

user interaction refers to the user's click on the phone, swipe and shake the phone, and so on to get the corresponding feedback. Today learning COCOS2DX, encounter interaction problems, so write to share with you. I am using Android connection as an example, because currently I only have Android related development. Well, not much to say, look at the following steps:

The first step: in Android, the entry of the interactive operation is in Surfaceview or Glsurfaceview in ontouchevent time. This example code is located org.cocos2dx.lib---->cocos2dxglsurfaceview.java

Public boolean ontouchevent (final motionevent pmotionevent) {//These data is used in Action_move and Action_canc        EL final int pointernumber = Pmotionevent.getpointercount ();        Final int[] ids = new Int[pointernumber];        Final float[] xs = new Float[pointernumber];        Final float[] ys = new Float[pointernumber];            for (int i = 0; i < Pointernumber; i++) {Ids[i] = Pmotionevent.getpointerid (i);            Xs[i] = Pmotionevent.getx (i);        Ys[i] = pmotionevent.gety (i); } switch (Pmotionevent.getaction () & Motionevent.action_mask) {case Motionevent.action_pointer_down                : Final int indexpointerdown = pmotionevent.getaction () >> motionevent.action_pointer_index_shift;                Final int idpointerdown = Pmotionevent.getpointerid (Indexpointerdown);                Final float Xpointerdown = Pmotionevent.getx (Indexpointerdown); Final float Ypointerdown = pmotionevent.gety(Indexpointerdown);                        This.queueevent (New Runnable () {@Override public void run () {                    Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown (Idpointerdown, Xpointerdown, Ypointerdown);                }                });            Break Case Motionevent.action_down://There is only one finger on the screen final int iddown =                Pmotionevent.getpointerid (0);                Final float xdown = xs[0];                Final float ydown = ys[0];                        This.queueevent (New Runnable () {@Override public void run () {                    Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown (Iddown, Xdown, Ydown);                }                });            Break                    Case MotionEvent.ACTION_MOVE:this.queueEvent (New Runnable () {@Override PubLIC void Run () {Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionMove (IDs, XS, YS);                }                });            Break Case MotionEvent.ACTION_POINTER_UP:final int indexpointup = pmotionevent.getaction () >> motionevent.                Action_pointer_index_shift;                Final int idpointerup = Pmotionevent.getpointerid (Indexpointup);                Final float Xpointerup = Pmotionevent.getx (Indexpointup);                Final float Ypointerup = pmotionevent.gety (Indexpointup);                        This.queueevent (New Runnable () {@Override public void run () {                    Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp (Idpointerup, Xpointerup, Ypointerup);                }                });            Break Case MOTIONEVENT.ACTION_UP://There is only one finger on the screen final int idup = Pmot IonEvent.getpointerid (0);                Final float xUp = xs[0];                Final float yUp = ys[0];                        This.queueevent (New Runnable () {@Override public void run () {                    Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp (Idup, XUp, yUp);                }                });            Break                    Case MotionEvent.ACTION_CANCEL:this.queueEvent (New Runnable () {@Override public void Run () {Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionCancel (IDs, XS,                    YS);                }                });        Break    } return true; }

Step Two: Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown (Iddown, Xdown, Ydown) The method of the related statement is org.cocos2dx.lib------>cocos2dxrender.java, the code is as follows:

private static native void Nativetouchesbegin (final int id, final float x, final float y);    private static native void Nativetouchesend (final int id, final float x, final float y);    private static native void Nativetouchesmove (final int[] IDs, final float[] XS, final float[] ys);       private static native void Nativetouchescancel (final int[] IDs, final float[] XS, final float[] ys); public void Handleactiondown (final int id, final float x, final float y) {cocos2dxrenderer.nativetouchesbegin (ID,    x, y);  } public void Handleactionup (final int id, final float x, final float y) {cocos2dxrenderer.nativetouchesend (ID,    x, y); } public void Handleactioncancel (final int[] IDs, final float[] XS, final float[] ys) {Cocos2dxrenderer.nativet    Ouchescancel (IDs, XS, YS); } public void Handleactionmove (final int[] IDs, final float[] XS, final float[] ys) {Cocos2dxrenderer.nativetou    Chesmove (IDs, XS, YS); }


Step three: private static native void Nativetouchesbegin (final int id, final float x, final float y) This is the local method that invokes the C + + content statement. This content is packaged in the libs/armeabi/cocos2dcpp.so file in Android Engineering. So we must load this. So file when using these methods. The code location is in the org.cocos2dx.lib--->cocos2dxactivity.java, which reads as follows:

protected void Onloadnativelibraries () {        try {            applicationinfo ai = Getpackagemanager (). Getapplicationinfo ( Getpackagename (), packagemanager.get_meta_data);            Bundle bundle = Ai.metadata;            String libname = bundle.getstring ("Android.app.lib_name");            System.loadlibrary (libname);        } catch (Exception e) {            e.printstacktrace ();        }    }
The bundle.getstring ("Android.app.lib_name") file is to locate the. so file. and its related content in the Android project Androidmanifest.xml, the content is as follows:

<?xml version= "1.0" encoding= "Utf-8"? ><manifest xmlns:android= "http://schemas.android.com/apk/res/ Android "package=" Org.cocos.CocosProject4 "android:versioncode=" 1 "android:versionname=" 1.0 "android:i nstalllocation= "Auto" > <uses-sdk android:minsdkversion= "9"/> <uses-feature android:glesversion= "         0x00020000 "/> <application android:label=" @string/app_name "android:icon=" @drawable/icon ">              <!--tell cocos2dxactivity the name, so--and <meta-data android:name= "Android.app.lib_name"                  Android:value= "Cocos2dcpp"/> <activity android:name= "org.cocos2dx.cpp.AppActivity" Android:label= "@string/app_name" android:screenorientation= "Landscape" android:theme= "@android: Style/theme.notitlebar.fullscreen" android:configchanges= "orientation" > <inten T-filter> <action android:Name= "Android.intent.action.MAIN"/> <category android:name= "Android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> <supports-screens android:anydens                      Ity= "true" android:smallscreens= "true" android:normalscreens= "true" Android:largescreens= "true" android:xlargescreens= "true"/> <uses-permission Android  : Name= "Android.permission.INTERNET"/></manifest>

Fourth Step: cocos2dcpp.so file generation, because the native method is here. It is generated in the Android.mk file of the Jni file in Android project (related content reference link). The native method is located in the file path Cocos2d-x-3.6/cocos/platform/android/jni/touchesjni.cpp, which reads as follows:

#include "base/ccdirector.h" #include "base/cceventkeyboard.h" #include "base/cceventdispatcher.h" #include "platform /android/ccglviewimpl-android.h "#include <android/log.h> #include <jni.h>using namespace Cocos2d;extern  "C" {jniexport void Jnicall java_org_cocos2dx_lib_cocos2dxrenderer_nativetouchesbegin (jnienv * env, jobject thiz, Jint        ID, jfloat x, jfloat y) {intptr_t idlong = ID;    Cocos2d::D irector::getinstance ()->getopenglview ()->handletouchesbegin (1, &idlong, &x, &y); } jniexport void Jnicall java_org_cocos2dx_lib_cocos2dxrenderer_nativetouchesend (jnienv * env, jobject thiz, Jint ID, j        float x, jfloat y) {intptr_t idlong = ID;    Cocos2d::D irector::getinstance ()->getopenglview ()->handletouchesend (1, &idlong, &x, &y);  } jniexport void Jnicall java_org_cocos2dx_lib_cocos2dxrenderer_nativetouchesmove (jnienv * env, jobject thiz, JintArray IDs, Jfloatarray xs, Jfloatarray ys) {int size = env-&Gt        Getarraylength (IDS);        Jint Id[size];        Jfloat X[size];        Jfloat Y[size];        Env->getintarrayregion (IDs, 0, size, id);        Env->getfloatarrayregion (XS, 0, size, x);        Env->getfloatarrayregion (ys, 0, size, y);        intptr_t Idlong[size];        for (int i = 0; i < size; i++) idlong[i] = Id[i];    Cocos2d::D irector::getinstance ()->getopenglview ()->handletouchesmove (size, Idlong, x, y); } jniexport void Jnicall java_org_cocos2dx_lib_cocos2dxrenderer_nativetouchescancel (jnienv * env, jobject thiz, JINTARR        Ay IDs, Jfloatarray xs, Jfloatarray ys) {int size = env->getarraylength (IDS);        Jint Id[size];        Jfloat X[size];        Jfloat Y[size];        Env->getintarrayregion (IDs, 0, size, id);        Env->getfloatarrayregion (XS, 0, size, x);        Env->getfloatarrayregion (ys, 0, size, y);        intptr_t Idlong[size];        for (int i = 0; i < size; i++) idlong[i] = Id[i]; CocoS2d::D irector::getinstance ()->getopenglview ()->handletouchescancel (size, Idlong, x, y); }       }

Fifth step: cocos2d::D irector::getinstance ()->getopenglview ()->handletouchesbegin (1, &idlong, &x, &y) How does this approach work, and the file location isCocos2d-x-3.6/cocos/platform/ccglview.cpp, as in the following:

void glview::handletouchesbegin (int num, intptr_t ids[], float xs[], float ys[]) {intptr_t id = 0;    float x = 0.0f;    Float y = 0.0f;    int unusedindex = 0;        Eventtouch TouchEvent;        for (int i = 0; i < num; ++i) {id = ids[i];        x = Xs[i];        y = ys[i];        Auto ITER = G_touchidreordermap.find (ID);            It is a new touch if (iter = = G_touchidreordermap.end ()) {Unusedindex = Getunusedindex ();            The touches is more than max_touches?                if (Unusedindex = =-1) {Cclog ("The touches is more than max_touches, Unusedindex =%d", unusedindex);            Continue } touch* touch = G_touches[unusedindex] = new (Std::nothrow) touch (); Touch->settouchinfo (Unusedindex, (X-_                        viewportrect.origin.x)/_scalex, (Y-_viewportrect.origin.y)/_scaley); Ccloginfo ("x =%f y =%f", Touch->getlocationinview (). x,Touch->getlocationinview (). y);            G_touchidreordermap.insert (Std::make_pair (ID, unusedindex));        Touchevent._touches.push_back (Touch);        }} if (touchevent._touches.size () = = 0) {cclog ("touchesbegan:size = 0");    Return    } Touchevent._eventcode = Eventtouch::eventcode::began;    Auto Dispatcher = Director::getinstance ()->geteventdispatcher (); Dispatcher->dispatchevent (&touchevent);}

Sixth step: use. First, add the listener to _eventdispathcer (in the CCNote.cpp file), as shown in the following example:

Auto listener = Eventlistenertouchallatonce::create ();    Listener->ontouchesbegan = Cc_callback_2 (Particledemo::ontouchesbegan, this);    listener->ontouchesmoved = Cc_callback_2 (particledemo::ontouchesmoved, this);    listener->ontouchesended = Cc_callback_2 (particledemo::ontouchesended, this);    _eventdispatcher->addeventlistenerwithscenegraphpriority (listener, this);
The next is what we actually do to make the interaction change, the code is as follows:

void Particledemo::ontouchesbegan (const std::vector<touch*>& touches, Event  *event) {    ontouchesended (touches, event);} void particledemo::ontouchesmoved (const std::vector<touch*>& touches, Event  *event) {    return ontouchesended (touches, event);} void particledemo::ontouchesended (const std::vector<touch*>& touches, Event  *event) {    Auto Touch = Touches[0];    Auto location = Touch->getlocation ();    Auto pos = Vec2::zero;    if (_background)    {        pos = _background->converttoworldspace (Vec2::zero);    }    if (_emitter! = nullptr)    {        _emitter->setposition (location-pos);    }}

The above code is the content in Particletest, and the Dispathcer will eventually pass the parameters to the _mitter to be changed, that is, the movement of the particle emitter.


Well, the above is the process, of course, to fully understand, it is necessary to cultivate internal strength, how to do, you understand ~



Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

cocos2d-x-3.6 user interaction principle---------How to connect Java and C + + via JNI

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.