গেম কন্ট্রোলারগুলোতে এমন কিছু অতিরিক্ত ফিচার থাকে যা প্লেয়ারের মিথস্ক্রিয়া এবং গেমে নিমগ্নতাকে উল্লেখযোগ্যভাবে বাড়িয়ে তোলে। অ্যান্ড্রয়েড গেম কন্ট্রোলারের হ্যাপটিক্স, মোশন সেন্সর এবং লাইটের কার্যকারিতা গেমিং অভিজ্ঞতাকে আরও গভীর ও সমৃদ্ধ করতে বিশেষভাবে সহায়ক। প্রতিটি ফিচার স্বতন্ত্রভাবে প্লেয়ারের ইন্দ্রিয়কে উদ্দীপ্ত করে, যা গেমের মধ্যে আরও অর্থপূর্ণ এবং স্বতঃস্ফূর্ত মিথস্ক্রিয়াকে উৎসাহিত করে।
স্পর্শকাতরতা
অ্যান্ড্রয়েড গেম কন্ট্রোলারের হ্যাপটিক্স ফিচারটি একটি অত্যন্ত গুরুত্বপূর্ণ প্রযুক্তি, যা গেম খেলার সময় বাস্তবসম্মত স্পর্শানুভূতি প্রদান করে।
হ্যাপটিক্স প্রযুক্তি কম্পন বা নড়াচড়ার মাধ্যমে ব্যবহারকারীকে শারীরিক অনুভূতি প্রদান করে। উদাহরণস্বরূপ, গেমে যখন কোনো বিস্ফোরণ ঘটে, তখন কন্ট্রোলারটি কেঁপে ওঠে, যা খেলোয়াড়কে এর প্রভাব বাস্তবসম্মতভাবে অনুভব করতে সাহায্য করে। এছাড়াও, কোনো চরিত্রের হাঁটা বা দৌড়ানোর শব্দের সাথে সূক্ষ্ম কম্পন সমন্বয় করা যেতে পারে, যা আরও জীবন্ত অভিজ্ঞতা প্রদান করে। এই ধরনের হ্যাপটিক ফিডব্যাক খেলোয়াড়দের গেমের মধ্যে ঘটে যাওয়া বিভিন্ন ঘটনা শারীরিকভাবে অনুভব করতে সক্ষম করে।
এই প্রযুক্তি খেলোয়াড়ের নিমগ্নতাকে সর্বোচ্চ পর্যায়ে নিয়ে যায়, আবেগীয় প্রতিক্রিয়াকে তীব্র করে এবং গেমের গতিশীলতাকে সমৃদ্ধ করে। অ্যান্ড্রয়েড গেম কন্ট্রোলারের হ্যাপটিক্স সেটিংস গেম ডেভেলপারদের জন্য সৃজনশীল সম্ভাবনাকে প্রসারিত করার পাশাপাশি খেলোয়াড়দের আগের চেয়ে অনেক বেশি বাস্তবসম্মত গেমিং অভিজ্ঞতা প্রদান করে।
কোটলিন
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))
}
}
}
জাভা
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));
}
}
}
ভাইব্রেট ব্যবহার করতে হলে একটি ফিচার ও পারমিশন সেট করতে হয়।
<application ...>
...
<uses-feature android:name="android.hardware.gamepad" android:required="true"/>
<uses-permission android:name="android.permission.VIBRATE"/>
...
</application>
VibratorManager এবং App manifest সম্পর্কে আরও তথ্যের জন্য।
গতি সেন্সর
গেম খেলার অভিজ্ঞতাকে উন্নত করে এমন সবচেয়ে উদ্ভাবনী প্রযুক্তিগুলোর মধ্যে একটি হলো মোশন সেন্সরযুক্ত অ্যান্ড্রয়েড গেম কন্ট্রোলার। এই প্রযুক্তি ব্যবহারকারীদের শারীরিক নড়াচড়া নির্ভুলভাবে শনাক্ত করে এবং সেই ডেটাকে গেমের ভেতরের কার্যকলাপে রূপান্তরিত করে, যা আরও স্বতঃস্ফূর্ত এবং নিমগ্ন গেমিং অভিজ্ঞতা প্রদান করে। এই ভূমিকায়, আমরা অ্যান্ড্রয়েড গেম কন্ট্রোলারের মোশন সেন্সর ফিচারটি কীভাবে কাজ করে তা আলোচনা করব।
ব্যবহারকারীদের নড়াচড়া ও অবস্থান শনাক্ত করার জন্য মোশন সেন্সরগুলোতে সাধারণত জাইরোস্কোপ এবং অ্যাক্সেলেরোমিটার যুক্ত থাকে।
এটিকে অ্যাক্সিলারেশন এবং জাইরোস্কোপ লিসেনার ক্লাসগুলো ইমপ্লিমেন্ট করতে হবে এবং এই লিসেনারগুলোকে কন্ট্রোলারের সেন্সর ম্যানেজারের সাথে রেজিস্টার করতে হবে।
কোটলিন
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) {
}
}
জাভা
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) {
}
}
মোশন সেন্সর এবং SensorEventListener সম্পর্কে আরও তথ্যের জন্য।
আলো
অ্যান্ড্রয়েড গেম কন্ট্রোলারের আলোর রঙের সেটিংস ভিজ্যুয়াল উপাদানের মাধ্যমে গেমপ্লেতে নিমগ্নতার একটি নতুন মাত্রা যোগ করে।
আলোর রঙের বৈশিষ্ট্যটি কন্ট্রোলারের অন্তর্নির্মিত এলইডি লাইট ব্যবহার করে বিভিন্ন রঙ প্রদর্শন করে, যা গেমিংয়ের বিভিন্ন পরিস্থিতির সাথে সাথে গতিশীলভাবে সাড়া দেয়। উদাহরণস্বরূপ, খেলোয়াড়ের স্বাস্থ্য সংকটজনক অবস্থায় থাকলে লাইটগুলো লাল হয়ে জ্বলে উঠতে পারে অথবা কোনো নির্দিষ্ট মিশন সম্পন্ন হলে সবুজ হয়ে জ্বলে উঠতে পারে, যা গেমের ভেতরের ঘটনাগুলোর উপর ভিত্তি করে একটি চাক্ষুষ প্রতিক্রিয়া প্রদান করে। আলোর রঙের এই সেটিংস ব্যবহারকারীর সম্পৃক্ততা বাড়ায়, গেমের উত্তেজনা ও আনন্দ বৃদ্ধি করে এবং খেলোয়াড়দের গেমের জগতে আরও সম্পূর্ণরূপে নিমগ্ন হতে সাহায্য করে।
অ্যান্ড্রয়েড গেম কন্ট্রোলারে হালকা রঙের বৈশিষ্ট্যটি শুধুমাত্র আলংকারিক উদ্দেশ্যের চেয়েও বেশি কিছু পূরণ করে—এটি গেমের আবহ তৈরি করতে এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে একটি গুরুত্বপূর্ণ ভূমিকা পালন করে।
কোটিন
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())
}
}
}
}
}
জাভা
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());
}
}
}
}
}
ভাইব্রেট ব্যবহার করতে হলে একটি ফিচার ও পারমিশন সেট করতে হয়।
<application ...>
...
<uses-feature android:name="android.hardware.gamepad" android:required="true"/>
<uses-permission android:name="android.permission.LIGHTS" />
...
</application>
LightsManager এবং App manifest সম্পর্কে আরও তথ্যের জন্য।
কন্ট্রোলার টাচপ্যাড
কিছু গেম কন্ট্রোলারে টাচপ্যাড থাকে যা গেমিংয়ের বিভিন্ন কাজের জন্য ব্যবহার করা যায়, যেমন মেনু নেভিগেট করা বা গেমের চরিত্রগুলোকে আরও স্বতঃস্ফূর্তভাবে নিয়ন্ত্রণ করা।
ইন্টিগ্রেটেড টাচপ্যাডযুক্ত গেম কন্ট্রোলারগুলো অ্যান্ড্রয়েডে সরাসরি ডিভাইস নিয়ন্ত্রণের সুবিধা দেয়। টাচপ্যাড স্পর্শ করলে স্ক্রিনে একটি মাউস পয়েন্টার তৈরি হয়, যা মাউসের মতো স্বতঃস্ফূর্ত নেভিগেশনের সুযোগ করে দেয়।