Tay điều khiển trò chơi được trang bị các tính năng bổ sung giúp cải thiện đáng kể khả năng tương tác và trải nghiệm nhập vai của người chơi. Các chức năng xúc giác, cảm biến chuyển động và ánh sáng của tay điều khiển trò chơi Android đặc biệt hữu ích trong việc làm sâu sắc và phong phú thêm trải nghiệm chơi game. Mỗi tính năng đều kích thích các giác quan của người chơi theo cách riêng, thúc đẩy các hoạt động tương tác có ý nghĩa và trực quan hơn trong trò chơi.
Xúc giác
Tính năng phản hồi xúc giác trong tay điều khiển trò chơi trên Android là một công nghệ quan trọng, mang đến phản hồi xúc giác chân thực trong quá trình chơi.
Công nghệ xúc giác truyền cảm giác vật lý đến người dùng thông qua các rung động hoặc chuyển động. Ví dụ: khi có một vụ nổ trong trò chơi, tay điều khiển sẽ rung lên, cho phép người chơi cảm nhận được tác động một cách chân thực. Ngoài ra, các rung động nhẹ có thể được đồng bộ hoá với âm thanh của một nhân vật đang đi bộ hoặc chạy, mang đến trải nghiệm chân thực hơn. Loại phản hồi xúc giác này cho phép người chơi cảm nhận được các sự kiện diễn ra trong trò chơi.
Công nghệ này tối đa hoá mức độ nhập vai của người chơi, khuếch đại phản ứng cảm xúc và làm phong phú thêm tính năng động của trò chơi. Chế độ cài đặt phản hồi xúc giác trong tay điều khiển trò chơi Android không chỉ mở rộng khả năng sáng tạo cho nhà phát triển trò chơi mà còn mang đến cho người chơi trải nghiệm chơi game chân thực hơn bao giờ hết.
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));
}
}
}
Để sử dụng chế độ rung, bạn cần thiết lập một tính năng và quyền.
<application ...>
...
<uses-feature android:name="android.hardware.gamepad" android:required="true"/>
<uses-permission android:name="android.permission.VIBRATE"/>
...
</application>
Để biết thêm thông tin về VibratorManager và Tệp kê khai ứng dụng.
Cảm biến chuyển động
Một trong những công nghệ cải tiến giúp nâng cao trải nghiệm chơi trò chơi là bộ điều khiển trò chơi Android được trang bị cảm biến chuyển động. Công nghệ này phát hiện chính xác các chuyển động vật lý của người dùng và chuyển dữ liệu đó thành hành động trong trò chơi, mang đến trải nghiệm chơi trò chơi trực quan và sống động hơn. Trong phần giới thiệu này, chúng ta sẽ khám phá cách hoạt động của các tính năng cảm biến chuyển động trong tay điều khiển trò chơi Android.
Cảm biến chuyển động thường kết hợp con quay hồi chuyển và gia tốc kế để phát hiện chuyển động và hướng của người dùng.
Nó cần triển khai các lớp trình nghe gia tốc và con quay hồi chuyển, đồng thời đăng ký các trình nghe này với trình quản lý cảm biến của bộ điều khiển.
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) {
}
}
Để biết thêm thông tin về Cảm biến chuyển động và SensorEventListener.
Đèn
Chế độ cài đặt màu đèn trên tay điều khiển trò chơi Android mang đến một trải nghiệm mới mẻ cho lối chơi thông qua các yếu tố hình ảnh.
Tính năng màu đèn sử dụng đèn LED tích hợp trong bộ điều khiển để hiển thị nhiều màu sắc, phản hồi linh hoạt theo các tình huống chơi game khác nhau. Ví dụ: đèn có thể nhấp nháy màu đỏ khi sức khoẻ của người chơi ở mức nguy kịch hoặc phát sáng màu xanh lục khi hoàn thành một nhiệm vụ cụ thể, cung cấp thông tin phản hồi trực quan dựa trên các sự kiện trong trò chơi. Những chế độ cài đặt màu sáng này giúp tăng mức độ tương tác của người dùng, tăng thêm sự hồi hộp và niềm vui khi chơi trò chơi, đồng thời giúp người chơi đắm chìm hoàn toàn vào thế giới trò chơi.
Các tính năng màu sáng trong bộ điều khiển trò chơi Android không chỉ đơn thuần là để trang trí mà còn đóng vai trò quan trọng trong việc thiết lập tâm trạng của trò chơi và cải thiện trải nghiệm người dùng.
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());
}
}
}
}
}
Để sử dụng chế độ rung, bạn cần thiết lập một tính năng và quyền.
<application ...>
...
<uses-feature android:name="android.hardware.gamepad" android:required="true"/>
<uses-permission android:name="android.permission.LIGHTS" />
...
</application>
Để biết thêm thông tin về LightsManager và Tệp kê khai ứng dụng.
Bàn di chuột trên bộ điều khiển
Một số tay cầm chơi game có bàn di chuột mà bạn có thể dùng cho nhiều hành động trong trò chơi, chẳng hạn như di chuyển trong trình đơn hoặc điều khiển nhân vật trong trò chơi một cách trực quan hơn.
Tay chơi trò chơi có bàn di chuột tích hợp giúp bạn điều khiển thiết bị trực tiếp trên Android. Khi bạn chạm vào bàn di chuột, con trỏ chuột sẽ xuất hiện trên màn hình, giúp bạn thao tác một cách trực quan như khi dùng chuột.