Controller game dilengkapi dengan fitur tambahan yang meningkatkan interaksi dan imersi pemain secara signifikan. Fungsi haptik, sensor gerak, dan cahaya pengontrol game Android sangat berperan dalam memperdalam dan memperkaya pengalaman bermain game. Setiap fitur secara unik merangsang indra pemain, sehingga mendorong interaksi yang lebih bermakna dan intuitif dalam game.
Untuk menyatakan bahwa aplikasi Anda mendukung pengontrol game, tambahkan fitur
android.hardware.gamepad ke manifes aplikasi Anda:
<manifest ...>
...
<uses-feature android:name="android.hardware.gamepad" android:required="false"/>
...
</manifest>
Sentuhan
Fitur haptik di pengontrol game Android adalah teknologi penting yang memberikan respons sentuh yang realistis selama gameplay.
Teknologi haptik memberikan sensasi fisik kepada pengguna melalui getaran atau gerakan. Misalnya, saat terjadi ledakan dalam game, pengontrol akan bergetar, sehingga pemain dapat merasakan dampaknya secara realistis. Selain itu, getaran halus dapat disinkronkan dengan suara karakter yang sedang berjalan atau berlari, sehingga menawarkan pengalaman yang lebih nyata. Jenis respons haptik ini memungkinkan pemain merasakan secara fisik berbagai peristiwa yang terjadi dalam game.
Teknologi ini memaksimalkan imersi pemain, memperkuat respons emosional, dan memperkaya dinamika game. Setelan haptik di pengontrol game Android tidak hanya memperluas kemungkinan kreatif bagi developer game, tetapi juga memberikan pengalaman bermain game yang lebih realistis kepada pemain.
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));
}
}
}
Untuk menggunakan getaran, aplikasi menetapkan fitur dan izin.
<manifest ...>
...
<uses-permission android:name="android.permission.VIBRATE"/>
...
</manifest>
Untuk mengetahui informasi selengkapnya tentang
VibratorManager dan
Manifes aplikasi.
Sensor gerakan
Salah satu teknologi paling inovatif yang meningkatkan pengalaman gameplay adalah pengontrol game Android yang dilengkapi sensor gerak. Teknologi ini mendeteksi secara akurat gerakan fisik pengguna dan menerjemahkan data tersebut menjadi tindakan dalam game, sehingga memberikan pengalaman bermain game yang lebih intuitif dan imersif. Dalam pengantar ini, kita akan mempelajari cara kerja fitur sensor gerak di pengontrol game Android.
Sensor gerak biasanya menggabungkan giroskop dan akselerometer untuk mendeteksi gerakan dan orientasi pengguna.
Aplikasi ini perlu menerapkan class pemroses akselerasi dan giroskop serta mendaftarkan pemroses ini dengan pengelola sensor pengontrol.
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) {
}
}
Untuk mengetahui informasi selengkapnya tentang
Sensor gerakan dan
SensorEventListener.
Lampu
Setelan warna lampu pada controller game Android menambahkan dimensi baru yang imersif ke gameplay melalui elemen visual.
Fitur warna cahaya memanfaatkan lampu LED bawaan di pengontrol untuk menampilkan berbagai warna, yang merespons secara dinamis berbagai skenario game. Misalnya, lampu dapat berkedip merah saat kesehatan pemain kritis atau bercahaya hijau setelah menyelesaikan misi tertentu, memberikan masukan visual berdasarkan peristiwa dalam game. Setelan warna terang ini memperdalam engagement pengguna, meningkatkan ketegangan dan keseruan game, serta membantu pemain lebih tenggelam dalam dunia game.
Fitur warna lampu di controller game Android memiliki fungsi lebih dari sekadar tujuan dekoratif—fitur ini berperan penting dalam mengatur suasana game dan meningkatkan pengalaman pengguna.
Kotin
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());
}
}
}
}
}
Untuk menggunakan lampu pengontrol, deklarasikan fitur gamepad dan izin LIGHTS
dalam manifes Anda:
<manifest ...>
...
<uses-permission android:name="android.permission.LIGHTS" />
...
</manifest>
Untuk mengetahui informasi selengkapnya tentang
LightsManager dan
Manifes aplikasi.
Touchpad pengontrol
Beberapa pengontrol game menyertakan touchpad yang dapat digunakan untuk berbagai tindakan dalam game, seperti menavigasi menu atau mengontrol karakter game dengan cara yang lebih intuitif.
Controller game dengan touchpad terintegrasi menawarkan kontrol perangkat langsung di Android. Menyentuh touchpad akan menghasilkan kursor mouse di layar, sehingga memungkinkan navigasi intuitif seperti mouse.