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!