Les manettes de jeu sont équipées de fonctionnalités supplémentaires qui améliorent considérablement l'interaction et l'immersion des joueurs. Les fonctionnalités haptiques, les capteurs de mouvement et les fonctionnalités d'éclairage des manettes de jeu Android sont particulièrement utiles pour approfondir et enrichir l'expérience de jeu. Chaque fonctionnalité stimule les sens du joueur de manière unique, favorisant des interactions plus significatives et intuitives dans le jeu.
Pour déclarer que votre application est compatible avec les manettes de jeu, ajoutez la fonctionnalité android.hardware.gamepad au fichier manifeste de votre application :
<manifest ...>
...
<uses-feature android:name="android.hardware.gamepad" android:required="false"/>
...
</manifest>
Technologies haptiques
La fonctionnalité haptique des manettes de jeu Android est une technologie cruciale qui fournit un retour tactile réaliste pendant le jeu.
La technologie haptique transmet des sensations physiques à l'utilisateur par le biais de vibrations ou de mouvements. Par exemple, lorsqu'une explosion se produit dans le jeu, la manette vibre, ce qui permet au joueur de ressentir l'impact de manière réaliste. De plus, de légères vibrations peuvent être synchronisées avec le son d'un personnage qui marche ou court, offrant ainsi une expérience plus réaliste. Ce type de retour haptique permet aux joueurs de ressentir physiquement les différents événements qui se produisent dans le jeu.
Cette technologie maximise l'immersion des joueurs, amplifie les réactions émotionnelles et enrichit la dynamique du jeu. Les paramètres haptiques des manettes de jeu Android élargissent les possibilités créatives des développeurs de jeux, mais offrent également aux joueurs une expérience de jeu plus réaliste que jamais.
Kotlin
fun triggerVibrationMultiChannel(
deviceId: Int, leftIntensity: Int, leftDuration: Int,
rightIntensity: Int, rightDuration: Int) {
val inputDevice = InputDevice.getDevice(deviceId)
val vibratorManager = inputDevice!!.vibratorManager
if (vibratorManager != null) {
val vibratorIds = vibratorManager.vibratorIds
val vibratorCount = vibratorIds.size
if (vibratorCount > 0) {
// We have an assumption that game controllers have two vibrators
// corresponding to a left motor and a right motor, and the left
// motor will be first.
updateVibrator(vibratorManager.getVibrator(vibratorIds [0]), leftIntensity, leftDuration)
if (vibratorCount > 1) {
updateVibrator(vibratorManager.getVibrator(vibratorIds[1]), rightIntensity, rightDuration)
}
}
}
}
fun updateVibrator(vibrator: Vibrator?, intensity: Int, duration: Int) {
if (vibrator != null) {
if (intensity == 0) {
vibrator.cancel()
} else if (duration > 0) {
vibrator.vibrate(VibrationEffect.createOneShot(duration.toLong(), intensity))
}
}
}
Java
public void triggerVibrationMultiChannel(
int deviceId, int leftIntensity, int leftDuration,
int rightIntensity, int rightDuration) {
InputDevice inputDevice = InputDevice.getDevice(deviceId);
// Check if device exists to avoid NullPointerException
if (inputDevice == null) {
return;
}
VibratorManager vibratorManager = inputDevice.getVibratorManager();
if (vibratorManager != null) {
int[] vibratorIds = vibratorManager.getVibratorIds();
int vibratorCount = vibratorIds.length;
if (vibratorCount > 0) {
// We have an assumption that game controllers have two vibrators
// corresponding to a left motor and a right motor, and the left
// motor will be first.
updateVibrator(vibratorManager.getVibrator(vibratorIds[0]), leftIntensity, leftDuration);
if (vibratorCount > 1) {
updateVibrator(vibratorManager.getVibrator(vibratorIds[1]), rightIntensity, rightDuration);
}
}
}
}
public void updateVibrator(Vibrator vibrator, int intensity, int duration) {
if (vibrator != null) {
if (intensity == 0) {
vibrator.cancel();
} else if (duration > 0) {
vibrator.vibrate(VibrationEffect.createOneShot((long) duration, intensity));
}
}
}
Pour utiliser le vibreur, il définit une fonctionnalité et une autorisation.
<manifest ...>
...
<uses-permission android:name="android.permission.VIBRATE"/>
...
</manifest>
Pour en savoir plus sur VibratorManager et le fichier manifeste d'application.
Capteurs de mouvement
L'une des technologies les plus innovantes pour améliorer l'expérience de jeu est la manette de jeu Android équipée d'un capteur de mouvement. Cette technologie détecte précisément les mouvements physiques des utilisateurs et traduit ces données en actions dans le jeu, offrant ainsi une expérience de jeu plus intuitive et immersive. Dans cette introduction, nous allons découvrir le fonctionnement des fonctionnalités de capteur de mouvement dans les manettes de jeu Android.
Les capteurs de mouvement intègrent généralement des gyroscopes et des accéléromètres pour détecter les mouvements et l'orientation des utilisateurs.
Elle doit implémenter les classes d'écouteur d'accélération et de gyroscope, et enregistrer ces écouteurs auprès du gestionnaire de capteurs de la manette.
Kotlin
fun setIntegratedAccelerometerActive(deviceId: Int) {
val device = InputDevice.getDevice(deviceId)
val sensorManager = device?.sensorManager
val accelerometer = sensorManager?.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
if (accelerometer != null) {
val accelerometerListener =
GameControllerAccelerometerListener(accelerometer)
sensorManager?.registerListener(
accelerometerListener, accelerometer,
SensorManager.SENSOR_DELAY_GAME
)
}
}
fun setIntegratedGyroscopeActive(deviceId: Int) {
val device = InputDevice.getDevice(deviceId)
val sensorManager = device?.sensorManager
val gyroscope = sensorManager?.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
if (gyroscope != null) {
val gyroscopeListener = GameControllerGyroscopeListener(gyroscope)
sensorManager?.registerListener(
gyroscopeListener, gyroscope,
SensorManager.SENSOR_DELAY_GAME
)
}
}
class GameControllerAccelerometerListener(private val listenerAccelerometer: Sensor?) :
SensorEventListener {
override fun onSensorChanged(event: SensorEvent) {
if (listenerAccelerometer != null) {
synchronized(listenerAccelerometer) {
if (event.sensor == listenerAccelerometer) {
Log.d("Accelerometer",
"onSensorChanged " + event.values[0] + ", "
+ event.values[1] + ", " + event.values[2])
}
}
}
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
}
}
class GameControllerGyroscopeListener(private val listenerGyroscope: Sensor?) :
SensorEventListener {
override fun onSensorChanged(event: SensorEvent) {
if (listenerGyroscope != null) {
synchronized(listenerGyroscope) {
if (event.sensor == listenerGyroscope) {
Log.d("Gyroscope",
"onSensorChanged " + event.values[0] + ", " +
event.values[1] + ", " + event.values[2])
}
}
}
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
}
}
Java
public void setIntegratedAccelerometerActive(int deviceId) {
InputDevice device = InputDevice.getDevice(deviceId);
// Safe handling for null device or sensor manager
if (device == null) {
return;
}
SensorManager sensorManager = device.getSensorManager();
if (sensorManager == null) {
return;
}
Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (accelerometer != null) {
GameControllerAccelerometerListener accelerometerListener =
new GameControllerAccelerometerListener(accelerometer);
sensorManager.registerListener(
accelerometerListener, accelerometer,
SensorManager.SENSOR_DELAY_GAME
);
}
}
public void setIntegratedGyroscopeActive(int deviceId) {
InputDevice device = InputDevice.getDevice(deviceId);
if (device == null) {
return;
}
SensorManager sensorManager = device.getSensorManager();
if (sensorManager == null) {
return;
}
Sensor gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
if (gyroscope != null) {
GameControllerGyroscopeListener gyroscopeListener =
new GameControllerGyroscopeListener(gyroscope);
sensorManager.registerListener(
gyroscopeListener, gyroscope,
SensorManager.SENSOR_DELAY_GAME
);
}
}
public static class GameControllerAccelerometerListener implements SensorEventListener {
private final Sensor listenerAccelerometer;
public GameControllerAccelerometerListener(Sensor listenerAccelerometer) {
this.listenerAccelerometer = listenerAccelerometer;
}
@Override
public void onSensorChanged(SensorEvent event) {
if (listenerAccelerometer != null) {
synchronized (listenerAccelerometer) {
if (event.sensor == listenerAccelerometer) {
Log.d("Accelerometer",
"onSensorChanged " + event.values[0] + ", "
+ event.values[1] + ", " + event.values[2]);
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
public static class GameControllerGyroscopeListener implements SensorEventListener {
private final Sensor listenerGyroscope;
public GameControllerGyroscopeListener(Sensor listenerGyroscope) {
this.listenerGyroscope = listenerGyroscope;
}
@Override
public void onSensorChanged(SensorEvent event) {
if (listenerGyroscope != null) {
synchronized (listenerGyroscope) {
if (event.sensor == listenerGyroscope) {
Log.d("Gyroscope",
"onSensorChanged " + event.values[0] + ", " +
event.values[1] + ", " + event.values [2]);
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
Pour en savoir plus sur les capteurs de mouvement et SensorEventListener.
Lumières
Les paramètres de couleur de la lumière sur les manettes de jeu Android ajoutent une nouvelle dimension d'immersion au gameplay grâce à des éléments visuels.
La fonctionnalité de couleur de la lumière utilise des voyants LED intégrés à la manette pour afficher différentes couleurs, qui réagissent de manière dynamique à différents scénarios de jeu. Par exemple, les voyants peuvent clignoter en rouge lorsque la santé du joueur est critique ou s'allumer en vert à la fin d'une mission spécifique, fournissant ainsi un retour visuel basé sur les événements du jeu. Ces paramètres de couleur de lumière renforcent l'engagement utilisateur, augmentent le suspense et le plaisir du jeu, et aident les joueurs à s'immerger plus complètement dans l'univers du jeu.
Les fonctionnalités de couleur de lumière des manettes de jeu Android ne sont pas seulement décoratives. Elles jouent un rôle important dans l'ambiance du jeu et l'amélioration de l'expérience utilisateur.
Kotlin
fun changeControllerLightColor(deviceId: Int, color: Int) {
val device = InputDevice.getDevice(deviceId)
device?.let {
if (it.sources and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK) {
val lightsManager = device.lightsManager
lightsManager?.let { manager ->
manager.lights.forEach { light ->
val stateBuilder = LightState.Builder()
stateBuilder.setColor(color)
val requestBuilder = LightsRequest.Builder()
requestBuilder.addLight(light, stateBuilder.build())
val lightsSession = lightsManager.openSession()
lightsSession.requestLights(requestBuilder.build())
}
}
}
}
}
Java
public void changeControllerLightColor(int deviceId, int color) {
InputDevice device = InputDevice.getDevice(deviceId);
if (device != null) {
// Check if the device is a joystick.
// Note: Parentheses are required around the bitwise AND operation in Java
// because == has higher precedence than &.
if ((device.getSources() & InputDevice. SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK) {
LightsManager lightsManager = device.getLightsManager();
if (lightsManager != null) {
for (Light light : lightsManager.getLights()) {
LightState.Builder stateBuilder = new LightState.Builder();
stateBuilder.setColor(color);
LightsRequest.Builder requestBuilder = new LightsRequest.Builder();
requestBuilder.addLight(light, stateBuilder.build());
LightsManager.Session lightsSession = lightsManager.openSession();
lightsSession.requestLights(requestBuilder.build());
}
}
}
}
}
Pour utiliser les voyants de la manette, déclarez la fonctionnalité de manette de jeu et l'autorisation LIGHTS dans votre fichier manifeste :
<manifest ...>
...
<uses-permission android:name="android.permission.LIGHTS" />
...
</manifest>
Pour en savoir plus sur LightsManager et le fichier manifeste d'application.
Pavé tactile de la manette
Certaines manettes de jeu incluent un pavé tactile qui peut être utilisé pour diverses actions dans le jeu, comme parcourir les menus ou contrôler les personnages de manière plus intuitive.
Les manettes de jeu avec pavés tactiles intégrés permettent de contrôler directement l'appareil sur Android. Toucher le pavé tactile génère un pointeur de souris à l'écran, ce qui permet une navigation intuitive semblable à celle d'une souris.