Skip to content

Commit bbb264a

Browse files
authored
Rewrite vibrator page (#209)
1 parent b9c35e5 commit bbb264a

File tree

1 file changed

+119
-12
lines changed

1 file changed

+119
-12
lines changed

wiki/input/vibrator.md

Lines changed: 119 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,139 @@
11
---
22
title: Vibrator
33
---
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.
55

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.
77

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.
961

1062
```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);
1268
```
1369

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
1587

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.
1789

1890
```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+
}
2096
```
2197

22-
As the parameter is given in milliseconds the example above will vibrate the phone for 2 seconds.
98+
## Detecting vibrator support
2399

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.
25101

26102
```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);
28105
```
29106

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+
31138

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

Comments
 (0)