I had originally avoided using vibration in my game, because I had found several different posts trying to figure out exactly what you needed to do, and I wasn’t able to find any tutorials that really broke down the process, so I chugged some coffee and dug into the code that was linked on the official forums. forum post. I can’t overstate how helpful it was to have a sub 10 second turn around time, between using Visual Studio to write the code, cocos to compile it (cocos compile -p android) and then to push it to my android phone with adb (adb install -r debug.apk), and then monitoring what was happening with logcat (adb logcat *:w), filtering only for warnings, errors and anything higher). Before we jump into it though, here’s a rough summary:
- You need to add a header in your Classes/ folder where you just have the vibrate function declared but not defined.
- Add a vibration function definition in the proj.android/jni, in a .cpp file. I used proj.android/jni/hellocpp/main.cpp , which I believe is the default for a starter cocos2dxv3 project. In this method you call the method you’ve defined in your java, in this case it was defined as a static method on your Activity. The default was named AppActivity .
- make sure you’ve got the vibration permission on your proj.android/AndroidManifest.xml , <uses-permission android:name= android.permission.VIBRATE>”
So, in one of your standard C++ headers in the Classes/ folder, add
//Classes/any_header.h void vibrate(int milliseconds); and in the associated <tt>.cpp</tt> file, call it: //Classes/any_header.cpp void get_hit() { vibrate(200); }
In your
proj.android/AndroidManifest.xml , you’ll want to add that line
<manifest> ... <uses-permission android:name="android.permission.VIBRATE"/> </manifest>
In a cpp file the jni will deal with, say proj.android/jni/hellocpp/main.cpp , you’ll need to define the connection between the Java and C++ by calling the Java method:
//proj.android/jni/hellocpp/main.cpp /* this function should already exist though */ void cocos_android_app_init (JNIEnv* env, jobject thiz) { LOGD("cocos_android_app_init"); AppDelegate *pAppDelegate = new AppDelegate(); } /* this is the new one you're adding, where org/cocos2dx/cpp/AppActivity is the java file where your Activity with the vibrate static method is defined */ void vibrate(int milliseconds) { JniMethodInfo minfo; CCAssert(JniHelper::getStaticMethodInfo(minfo, "org/cocos2dx/cpp/AppActivity", "vibrate", "(I)V"), "Function doesn't exist"); minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID, (jint)milliseconds); minfo.env->DeleteLocalRef(minfo.classID); }
Finally, here’s the .java file where the android call to vibrate is made. Mine was proj.android/src/org/cocos2dx/cpp/AppActivity.java
/* default imports */ package org.cocos2dx.cpp; import org.cocos2dx.lib.Cocos2dxActivity; /* imports needed for vibration stuff */ import android.os.Vibrator; import android.content.Context; import android.app.ActivityManager; import android.util.Log; import android.os.Bundle; public class AppActivity extends Cocos2dxActivity { private static volatile Cocos2dxActivity mainActivity; public static void setMainActivity(Cocos2dxActivity activity) { mainActivity = activity; } public static Cocos2dxActivity getMainActivity() { if(mainActivity == null) { Log.w("MY_APP_NAME_GOES_HERE", "Warning : null main Activity"); } return mainActivity; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AppActivity.setMainActivity(this); } public static void vibrate(int milliseconds) { Vibrator v = (Vibrator) getMainActivity().getSystemService(Context.VIBRATOR_SERVICE); if (getMainActivity().getSystemService(Context.VIBRATOR_SERVICE) != null) { v.vibrate(milliseconds); } } }
Hope this helped you!