如何让 PS4 控制器的触发按钮变成 Android?
How to get the trigger Buttons of a PS4 Controller into Android?
我正在尝试将我的 PS4 控制器作为模型放入 Android 应用程序中。来自 Android 开发者页面的示例(游戏杆和数字按钮)对我来说效果很好。我用 Log.e 输出检查了这个。我不明白如何获得 R2 和 L2 的值。在开发者页面上是这样描述的:
Handle shoulder trigger presses (but provide alternative input methods). Some controllers have left and right shoulder triggers. If these triggers are present, Android reports a left trigger press as an AXIS_LTRIGGER event and a right trigger press as an AXIS_RTRIGGER event. On Android 4.3 (API level 18), a controller that produces a AXIS_LTRIGGER also reports an identical value for the AXIS_BRAKE axis. The same is true for AXIS_RTRIGGER and AXIS_GAS. Android reports all analog trigger presses with a normalized value from 0.0 (released) to 1.0 (fully pressed). Not all controllers have triggers, so consider allowing players to perform those game actions with other buttons.
添加这一行:
float rTrigger = historyPos < 0 ? event.getAxisValue(MotionEvent.AXIS_RTRIGGER) : event.getHistoricalAxisValue(MotionEvent.AXIS_RTRIGGER, historyPos);
到 processJoystickInput():float rtrigger 始终为 0.0
真的很期待把事情做好。
谢谢
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
boolean handled = false;
if ((event.getSource() & InputDevice.SOURCE_GAMEPAD)
== InputDevice.SOURCE_GAMEPAD) {
if (event.getRepeatCount() == 0) {
if (keyCode == 96)
Log.e("Taste:", "Square pressed");
if (keyCode == 97)
Log.e("Taste:", "Cross pressed");
if (keyCode == 98)
Log.e("Taste:", "Circle pressed");
}
if (handled) {
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
boolean handled = false;
if ((event.getSource() & InputDevice.SOURCE_GAMEPAD)
== InputDevice.SOURCE_GAMEPAD) {
if (event.getRepeatCount() == 0) {
if (keyCode == 96)
Log.e("Taste:", "Square released");
if (keyCode == 97)
Log.e("Taste:", "X released");
if (keyCode == 98)
Log.e("Taste:", "Circle released");
}
if (handled) {
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
// Check that the event came from a game controller
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) ==
InputDevice.SOURCE_JOYSTICK &&
event.getAction() == MotionEvent.ACTION_MOVE) {
// Process all historical movement samples in the batch
final int historySize = event.getHistorySize();
// Process the movements starting from the
// earliest historical position in the batch
for (int i = 0; i < historySize; i++) {
// Process the event at historical position i
processJoystickInput(event, i);
}
// Process the current movement sample in the batch (position -1)
processJoystickInput(event, -1);
return true;
}
return super.onGenericMotionEvent(event);
}
private void processJoystickInput(MotionEvent event,
int historyPos) {
InputDevice mInputDevice = event.getDevice();
// Calculate the horizontal distance to move by
// using the input value from one of these physical controls:
// the left control stick, hat axis, or the right control stick.
float lx = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_X, historyPos);
float rx = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_Z, historyPos);
float ly = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_Y, historyPos);
float ry = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_RZ, historyPos);
Log.e("LX:", lx + "");
Log.e("LY:", ly + "");
Log.e("RX:", rx + "");
Log.e("RY:", ry + "");
}
private static float getCenteredAxis(MotionEvent event,
InputDevice device, int axis, int historyPos) {
final InputDevice.MotionRange range =
device.getMotionRange(axis, event.getSource());
// A joystick at rest does not always report an absolute position of
// (0,0). Use the getFlat() method to determine the range of values
// bounding the joystick axis center.
if (range != null) {
final float flat = range.getFlat();
final float value =
historyPos < 0 ? event.getAxisValue(axis) :
event.getHistoricalAxisValue(axis, historyPos);
// Ignore axis values that are within the 'flat' region of the
// joystick axis center.
if (Math.abs(value) > flat) {
return value;
}
}
return 0;
}
}
我自己解决了这个问题。触发按钮匹配 Axis_RX 和 Axis_RY
我正在尝试将我的 PS4 控制器作为模型放入 Android 应用程序中。来自 Android 开发者页面的示例(游戏杆和数字按钮)对我来说效果很好。我用 Log.e 输出检查了这个。我不明白如何获得 R2 和 L2 的值。在开发者页面上是这样描述的:
Handle shoulder trigger presses (but provide alternative input methods). Some controllers have left and right shoulder triggers. If these triggers are present, Android reports a left trigger press as an AXIS_LTRIGGER event and a right trigger press as an AXIS_RTRIGGER event. On Android 4.3 (API level 18), a controller that produces a AXIS_LTRIGGER also reports an identical value for the AXIS_BRAKE axis. The same is true for AXIS_RTRIGGER and AXIS_GAS. Android reports all analog trigger presses with a normalized value from 0.0 (released) to 1.0 (fully pressed). Not all controllers have triggers, so consider allowing players to perform those game actions with other buttons.
添加这一行:
float rTrigger = historyPos < 0 ? event.getAxisValue(MotionEvent.AXIS_RTRIGGER) : event.getHistoricalAxisValue(MotionEvent.AXIS_RTRIGGER, historyPos);
到 processJoystickInput():float rtrigger 始终为 0.0
真的很期待把事情做好。
谢谢
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
boolean handled = false;
if ((event.getSource() & InputDevice.SOURCE_GAMEPAD)
== InputDevice.SOURCE_GAMEPAD) {
if (event.getRepeatCount() == 0) {
if (keyCode == 96)
Log.e("Taste:", "Square pressed");
if (keyCode == 97)
Log.e("Taste:", "Cross pressed");
if (keyCode == 98)
Log.e("Taste:", "Circle pressed");
}
if (handled) {
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
boolean handled = false;
if ((event.getSource() & InputDevice.SOURCE_GAMEPAD)
== InputDevice.SOURCE_GAMEPAD) {
if (event.getRepeatCount() == 0) {
if (keyCode == 96)
Log.e("Taste:", "Square released");
if (keyCode == 97)
Log.e("Taste:", "X released");
if (keyCode == 98)
Log.e("Taste:", "Circle released");
}
if (handled) {
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
// Check that the event came from a game controller
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) ==
InputDevice.SOURCE_JOYSTICK &&
event.getAction() == MotionEvent.ACTION_MOVE) {
// Process all historical movement samples in the batch
final int historySize = event.getHistorySize();
// Process the movements starting from the
// earliest historical position in the batch
for (int i = 0; i < historySize; i++) {
// Process the event at historical position i
processJoystickInput(event, i);
}
// Process the current movement sample in the batch (position -1)
processJoystickInput(event, -1);
return true;
}
return super.onGenericMotionEvent(event);
}
private void processJoystickInput(MotionEvent event,
int historyPos) {
InputDevice mInputDevice = event.getDevice();
// Calculate the horizontal distance to move by
// using the input value from one of these physical controls:
// the left control stick, hat axis, or the right control stick.
float lx = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_X, historyPos);
float rx = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_Z, historyPos);
float ly = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_Y, historyPos);
float ry = getCenteredAxis(event, mInputDevice,
MotionEvent.AXIS_RZ, historyPos);
Log.e("LX:", lx + "");
Log.e("LY:", ly + "");
Log.e("RX:", rx + "");
Log.e("RY:", ry + "");
}
private static float getCenteredAxis(MotionEvent event,
InputDevice device, int axis, int historyPos) {
final InputDevice.MotionRange range =
device.getMotionRange(axis, event.getSource());
// A joystick at rest does not always report an absolute position of
// (0,0). Use the getFlat() method to determine the range of values
// bounding the joystick axis center.
if (range != null) {
final float flat = range.getFlat();
final float value =
historyPos < 0 ? event.getAxisValue(axis) :
event.getHistoricalAxisValue(axis, historyPos);
// Ignore axis values that are within the 'flat' region of the
// joystick axis center.
if (Math.abs(value) > flat) {
return value;
}
}
return 0;
}
}
我自己解决了这个问题。触发按钮匹配 Axis_RX 和 Axis_RY