|
1 | 1 | ---
|
2 | 2 | title: Vibrator
|
3 | 3 | ---
|
4 |
| -While not strictly an input device, it nevertheless is a kind of a peripheral. We felt it belonged in the input model. |
| 4 | +While not strictly an input device, it nevertheless is a kind of peripheral. We felt it belonged in the input model. |
5 | 5 |
|
6 |
| -The vibrator allows you to vibrate the phone of a user. This can be used similar to more sophisticated force feedback functionality found commonly in game console controllers. |
| 6 | +The vibrator allows you to vibrate the user's mobile device. This can be used to provide feedback to the user in addition to or instead of sound effects. |
7 | 7 |
|
8 |
| -The vibrator is only available on Android and needs a special permission in the manifest file |
| 8 | +## Enabling support |
| 9 | + |
| 10 | +### Android |
| 11 | + |
| 12 | +On Android, vibration requires the following permission in `AndroidManifest.xml`, otherwise attempting to vibrate will crash the app: |
| 13 | + |
| 14 | +```xml |
| 15 | +<uses-permission android:name="android.permission.VIBRATE" /> |
| 16 | +``` |
| 17 | + |
| 18 | +This is a "normal" install-time permission, meaning it is automatically granted without the user agreeing to it. If publishing on the Google Play Store, this permission will be listed on your app's store page as "control vibration". |
| 19 | + |
| 20 | +### iOS |
| 21 | + |
| 22 | +On iOS, haptics need to be enabled in `IOSLauncher`: |
| 23 | + |
| 24 | +```java |
| 25 | +config.useHaptics = true; |
| 26 | +``` |
| 27 | + |
| 28 | +### GWT |
| 29 | + |
| 30 | +The GWT backend does not support vibration. However, it is quite simple to implement basic vibration with [platform-specific code](/wiki/app/interfacing-with-platform-specific-code). |
| 31 | + |
| 32 | +```java |
| 33 | +native void vibrateJsni(int milliseconds) /*-{ |
| 34 | + navigator.vibrate(milliseconds); |
| 35 | +}-*/; |
| 36 | +``` |
| 37 | + |
| 38 | +This only works in Chromium-based browsers on Android devices that are not in silent mode. Despite caniuse.com claiming Firefox for Android supports this, support has been disabled since Firefox 79 due to abuse. |
| 39 | + |
| 40 | +## Vibration |
| 41 | + |
| 42 | +### Simple |
| 43 | + |
| 44 | +The simplest form of vibration runs the motor for a period of time given in milliseconds. |
| 45 | + |
| 46 | +In this example, the device will vibrate for 1 second on supported Android and iOS devices: |
| 47 | + |
| 48 | +```java |
| 49 | +Gdx.input.vibrate(1000); |
| 50 | +``` |
| 51 | + |
| 52 | +On iPhones that lack Haptic Feedback or are running an iOS version earlier than 13, this will vibrate for 400ms no matter what argument is inserted. If you would rather it not do this, you can disable the fallback: |
| 53 | + |
| 54 | +```java |
| 55 | +Gdx.input.vibrate(1000, false); |
| 56 | +``` |
| 57 | + |
| 58 | +### Amplitude |
| 59 | + |
| 60 | +Some devices support setting the vibration amplitude, i.e. how intense the vibration is. This is on a scale of 0 to 255. |
9 | 61 |
|
10 | 62 | ```java
|
11 |
| -android.permission.VIBRATE |
| 63 | +// Vibrate for 1 second at half amplitude, no fallback |
| 64 | +Gdx.input.vibrate(1000, 127, false); |
| 65 | + |
| 66 | +// Vibrate for 1 second at full amplitude, with fallback |
| 67 | +Gdx.input.vibrate(1000, 255, true); |
12 | 68 | ```
|
13 | 69 |
|
14 |
| -See the [application configuration](/wiki/app/starter-classes-and-configuration) section if you are unsure how to specify permissions in your Android manifest. |
| 70 | +If the `fallback` boolean is `true`, Android devices without amplitude control will ignore the amplitude argument, and iPhones without iOS 13 or newer will ignore all arguments. |
| 71 | + |
| 72 | +### Preset |
| 73 | + |
| 74 | +libGDX provides three preset vibration intensities: |
| 75 | + |
| 76 | +```java |
| 77 | +Gdx.input.vibrate(Input.VibrationType.LIGHT); |
| 78 | +Gdx.input.vibrate(Input.VibrationType.MEDIUM); |
| 79 | +Gdx.input.vibrate(Input.VibrationType.HEAVY); |
| 80 | +``` |
| 81 | + |
| 82 | +These are delegated to the system, and as such should provide a consistent experience with other apps the user may have. This also means they will not work on all devices. |
| 83 | + |
| 84 | +This method requires at least Android 10 and a device with amplitude control, or iOS 13 with Haptic Feedback. On budget or older devices, it will do nothing. |
| 85 | + |
| 86 | +### Pattern |
15 | 87 |
|
16 |
| -Vibrating the phone works as follows: |
| 88 | +As of libGDX 1.12.0, vibration patterns, also known as waveforms, are no longer supported. For existing games that use this functionality, you can reimplement this into your `android` module or, for cross-platform support, parse the pattern on a separate thread. |
17 | 89 |
|
18 | 90 | ```java
|
19 |
| -Gdx.input.vibrate(2000); |
| 91 | +public void vibrate (long[] pattern, int repeat) { |
| 92 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) |
| 93 | + vibrator.vibrate(VibrationEffect.createWaveform(pattern, repeat)); |
| 94 | + else vibrator.vibrate(pattern, repeat); |
| 95 | +} |
20 | 96 | ```
|
21 | 97 |
|
22 |
| -As the parameter is given in milliseconds the example above will vibrate the phone for 2 seconds. |
| 98 | +## Detecting vibrator support |
23 | 99 |
|
24 |
| -More sophisticated patterns can be specified via the second `vibrate()` method: |
| 100 | +You may wish to detect whether a device supports vibration or amplitude control. |
25 | 101 |
|
26 | 102 | ```java
|
27 |
| -Gdx.input.vibrate(new long[] { 0, 200, 200, 200}, -1); |
| 103 | +boolean vibration = Gdx.input.isPeripheralAvailable(Input.Peripheral.Vibrator); |
| 104 | +boolean amplitude = Gdx.input.isPeripheralAvailable(Input.Peripheral.HapticFeedback); |
28 | 105 | ```
|
29 | 106 |
|
30 |
| -This will turn the vibrator on for 200 milliseconds, then turn it off for 200 milliseconds then on again for another 200 milliseconds. The second parameter specifies that the pattern should not be repeated. Refer to the [Javadocs](https://javadoc.io/doc/com.badlogicgames.gdx/gdx/latest/com/badlogic/gdx/Input.html#vibrate(int)) for more information. |
| 107 | +In the above example, each variable will be `true` under the following circumstances: |
| 108 | + |
| 109 | +|OS|`vibration`|`amplitude`| |
| 110 | +|--|-----------|-----------| |
| 111 | +|**Android**|The device supports vibration. This does not mean the app has permission to vibrate!|The device supports amplitude control vibration.| |
| 112 | +|**iOS**|`useHaptics` is `true` and the device has a phone form factor. This includes the iPod touch, which lacks a vibration motor.|`useHaptics` is `true` and the device supports vibration beyond the 400ms fallback.| |
| 113 | + |
| 114 | +Especially on Android, this can be useful for scenarios such as only displaying vibration settings to devices that support vibration, and providing your own fallbacks to less advanced vibration: |
| 115 | + |
| 116 | +```java |
| 117 | +if (Gdx.input.isPeripheralAvailable(Input.Peripheral.HapticFeedback)) { |
| 118 | + Gdx.input.vibrate(Input.VibrationType.MEDIUM); |
| 119 | +} else { |
| 120 | + Gdx.input.vibrate(50); |
| 121 | +} |
| 122 | +``` |
| 123 | + |
| 124 | +These values only reflect whether the device itself can vibrate. Devices without a built-in vibrator can still vibrate external peripherals. For that, see `Controller#canVibrate` in [gdx-controllers](/wiki/input/controllers). |
| 125 | + |
| 126 | +## Additional considerations |
| 127 | + |
| 128 | +When designing your game, you may wish to consider which devices are likely to support vibration. |
| 129 | + |
| 130 | +* Smartphones and smartwatches are practically guaranteed to have a vibration motor, though only the flagships tend to support amplitude control. |
| 131 | +* Tablets may or may not have vibration, depending on the model. Samsung and Lenovo tablets generally do, whereas iPads and the Pixel Tablet do not. |
| 132 | +* Larger devices such as Chromebooks and televisions almost never support vibration. |
| 133 | + |
| 134 | +Vibration can cause some users discomfort, so you should always allow them to disable it. This would typically be done from your game's settings or main menu. |
| 135 | + |
| 136 | +Some apps disable vibration when the user's device is in silent mode (on Android, using `AudioManager#getRingerMode`) but this is not an ideal approach as the user may want their device to vibrate for notifications but not for your game and vice-versa. |
| 137 | + |
31 | 138 |
|
32 |
| -[Prev](/wiki/input/compass) | [Next](/wiki/input/cursor-visibility-and-catching) |
| 139 | +[Prev](/wiki/input/compass) | [Next](/wiki/input/cursor-visibility-and-catching) |
0 commit comments