游戏手柄按键遥杆值检测

前言

本章讲述游戏手柄按键遥感值检测

1 环境
as 4.1.*

2 代码
MainActivity.java

package com.example.testthooth1;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.TextureView;
import android.view.View;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class MainActivity extends AppCompatActivity {

    private final  String TAG = MainActivity.class.getName() ;
    private TextView showtext ;
    private List<String> listshow ;
  //  private MutilTextView mutiltextview ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        showtext = (TextView)findViewById(R.id.showtext);
        listshow= new ArrayList<String>();
    }

    void showLog(String str){
        if(listshow.size() >= 50){
            listshow.remove(0);
        }
        listshow.add(str);
        showtext.setText(listshow.toString());
    }

    Dpad dpad = new Dpad();
    @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);
    }


    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if ((event.getSource() & InputDevice.SOURCE_GAMEPAD)
                == InputDevice.SOURCE_GAMEPAD){
            InputDevice mInputDevice = event.getDevice();
            String tcontext = "KeyEvent mInputDeviceid ="+mInputDevice.getId() +" KeyEvent="+event.getAction()+" keycode="+event.getKeyCode();
            Log.e(TAG,tcontext);
            showLog(tcontext);
            return  true;
        }

        return super.dispatchKeyEvent(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 x = getCenteredAxis(event, mInputDevice,
                MotionEvent.AXIS_X, historyPos);
        //左摇杆:
       float lx =  event.getAxisValue(MotionEvent.AXIS_X);
       float ly = event.getAxisValue(MotionEvent.AXIS_Y);

       //右摇杆
        float rx =  event.getAxisValue(MotionEvent.AXIS_Z);
        float ry = event.getAxisValue(MotionEvent.AXIS_RZ);

        //十字键
        float hx =  event.getAxisValue(MotionEvent.AXIS_HAT_X);
        float hy = event.getAxisValue(MotionEvent.AXIS_HAT_Y);

        int press = -1;
        if (Dpad.isDpadDevice(event)) {
            press = dpad.getDirectionPressed(event);
          //  Log.e(TAG,"Dpad="+press);
            switch (press) {
                case Dpad.LEFT:
                    // Do something for LEFT direction press
                    break;
                case Dpad.RIGHT:
                    // Do something for RIGHT direction press
                    break;
                case Dpad.UP:
                    // Do something for UP direction press
                    break;
                case Dpad.CENTER:
                    break;
                case Dpad.DOWN:
                    break;
            }
        }

        if (x == 0) {
            x = getCenteredAxis(event, mInputDevice,
                    MotionEvent.AXIS_HAT_X, historyPos);
        }
        if (x == 0) {
            x = getCenteredAxis(event, mInputDevice,
                    MotionEvent.AXIS_Z, historyPos);
        }
        // Calculate the vertical distance to move by
        // using the input value from one of these physical controls:
        // the left control stick, hat switch, or the right control stick.
        float y = getCenteredAxis(event, mInputDevice,
                MotionEvent.AXIS_Y, historyPos);
        if (y == 0) {
            y = getCenteredAxis(event, mInputDevice,
                    MotionEvent.AXIS_HAT_Y, historyPos);
        }
        if (y == 0) {
            y = getCenteredAxis(event, mInputDevice,
                    MotionEvent.AXIS_RZ, historyPos);
        }
        // Update the ship object based on the new x and y values
        //" NEW X="+x+" new y="+y+
        String tcontext = "MotionEvent mInputDeviceid ="+mInputDevice.getId() +" press="+press+  " 左摇杆("+lx+","+ly+")右摇杆("+rx+","+ry+")"+" 十字键("+hx+"."+hy+")";
        Log.e(TAG,tcontext);
        showLog(tcontext);
    }

    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;
    }

    public  void onClear(View v){
        showtext.setText("");
        listshow.clear();
    }
}

/*
JAVA FLOAT或DOUBLE保留两位小数
2015-06-26 09:28:46  By: shinyuu
shinyuu Java开发实战 0 43395 4
不管是Java Web项目还是Android项目、很多时候都需要使用到保留两位小数问题、经过查找、本文将给出几种方案、大家可根据项目需要自己决定使用那种方法


方案一、四舍五入
double f = 111231.5585;
BigDecimal b = new BigDecimal(f);
double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
//保留两位小数

方案二、DECIMALFORMAT
1、用DecimalFormat 返回的是String格式的、该类对十进制进行全面的封装、像%号、千分位、小数精度、科学计算等

float price=1.2;
//构造方法的字符格式这里如果小数不足2位,会以0补足
DecimalFormat decimalFormat = new DecimalFormat(".00");
//format 返回的是字符串
String p = decimalFomat.format(price);

例:new DecimalFormat("#.00").format(3.1415926)

#.00 表示两位小数 #.0000四位小数 以此类推...


方案三、STRING.FORMAT
double d = 3.1415926;
String result = String.format("%.2f");
 */

Dpad.java
抄自 Android官方培训课程

package com.example.testthooth1;

import android.view.InputDevice;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class Dpad {
    final static int UP       = 0;
    final static int LEFT     = 1;
    final static int RIGHT    = 2;
    final static int DOWN     = 3;
    final static int CENTER   = 4;

    int directionPressed = -1; // initialized to -1

    public int getDirectionPressed(InputEvent event) {
        if (!isDpadDevice(event)) {
            return -1;
        }

        // If the input event is a MotionEvent, check its hat axis values.
        if (event instanceof MotionEvent) {

            // Use the hat axis value to find the D-pad direction
            MotionEvent motionEvent = (MotionEvent) event;
            float xaxis = motionEvent.getAxisValue(MotionEvent.AXIS_HAT_X);
            float yaxis = motionEvent.getAxisValue(MotionEvent.AXIS_HAT_Y);

            // Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad
            // LEFT and RIGHT direction accordingly.
            if (Float.compare(xaxis, -1.0f) == 0) {
                directionPressed =  Dpad.LEFT;
            } else if (Float.compare(xaxis, 1.0f) == 0) {
                directionPressed =  Dpad.RIGHT;
            }
            // Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad
            // UP and DOWN direction accordingly.
            else if (Float.compare(yaxis, -1.0f) == 0) {
                directionPressed =  Dpad.UP;
            } else if (Float.compare(yaxis, 1.0f) == 0) {
                directionPressed =  Dpad.DOWN;
            }
        }

        // If the input event is a KeyEvent, check its key code.
        else if (event instanceof KeyEvent) {

            // Use the key code to find the D-pad direction.
            KeyEvent keyEvent = (KeyEvent) event;
            if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT) {
                directionPressed = Dpad.LEFT;
            } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT) {
                directionPressed = Dpad.RIGHT;
            } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) {
                directionPressed = Dpad.UP;
            } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) {
                directionPressed = Dpad.DOWN;
            } else if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER) {
                directionPressed = Dpad.CENTER;
            }
        }
        return directionPressed;
    }

    public static boolean isDpadDevice(InputEvent event) {
        // Check that input comes from a device with directional pads.
        if ((event.getSource() & InputDevice.SOURCE_DPAD)
                != InputDevice.SOURCE_DPAD) {
            return true;
        } else {
            return false;
        }
    }
}

activity_main.xml


<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/showtext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:lines="50"
        android:ellipsize="end"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/clear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBaseline_toBaselineOf="@id/showtext"
        android:text="清理"
        android:onClick= "onClear"
        android:layout_marginLeft="8dp"/>

androidx.constraintlayout.widget.ConstraintLayout>

3 说明
左右遥杆 十字键 取值
游戏手柄按键遥杆值检测_第1张图片
DPAD 具体取值 DPAD 可能是 key 也可能是 motion
游戏手柄按键遥杆值检测_第2张图片
4 demo工程
觉得有用 ,点个赞,加个关注

你可能感兴趣的:(android,android,java,游戏程序)