前一篇博客《使用BluetoothHidDevice将安卓手机同时模拟成鼠标和键盘》
本文源码下载地址:《通过蓝牙让安卓手机成为PC游戏方向盘手柄-支持旋转轮胎》源码
多文源码打包下载:
《仅通过蓝牙HID将安卓手机模拟成鼠标和键盘》+《蓝牙HID TouchScreen协议让你的安卓手机变成触摸屏》两份完整源码打包下载
《仅通过蓝牙HID将安卓手机模拟成鼠标和键盘》+《蓝牙HID TouchScreen协议让你的安卓手机变成触摸屏》+《通过蓝牙将安卓手机模拟成游戏方向盘-支持旋转轮胎》三份源码打包下载
【.04.21】源码在Android 12中运行注意事项:由于Android 12对蓝牙权限做了调整,取消了位置信息,增加了扫描、广告、连接权限,并且都是运行时动态权限,具体请参考https://developer./about/versions/12/features/bluetooth-permissions?hl=zh-cn
(/hurst/article/details/105346205)介绍了通过蓝牙将Android设备模拟成鼠标/键盘,但总归是个副产品,因为我一开始的想法是将Android机模拟成游戏手柄或方向盘,最后阴差阳错地实现了键鼠功能。经过一段时间的学习和研究后才实现了游戏方向盘的功能,所以才有了本文。先来一张图片看看,设备在《旋转轮胎》(又叫Spin Tires)的控制菜单中的效果。
如果我们的设备成功被Win10识别为游戏控制器的话,在游戏的控制设置页面就会看到我们自己的设备。那么在游戏控制页面可以看见,选择“方向盘”选项卡后出现方向盘设备选择的菜单,点击我们的设备名称就可以使用了。(图片是用手机拍摄的,因为游戏里无法使用Prt键截图,有知道如何DX截图的请指教)
下面看看游戏方向盘的简单Demo,打方向需要左右转动手机,左右两边的SeekBar代表油门和刹车,中间的8个按钮可以在游戏的控制页面设置不同的功能。离合器和换挡功能去掉了,测试发现还是自动挡开着舒服。力反馈FFB功能还在研究中。
下面看看在Win10中被正确识别的设备是什么样子的。
在测试我们APP的时候可以通过Win10的游戏控制器(控制面板->设备与打印机->设备(选择自己的手机名称)->右键->游戏控制器设置),可以方便地看到控制器的转向/刹车/按钮是否正常。
通过两个视频看看在游戏中的效果
体验《旋转轮胎》未知地图
在游戏的控制页面我们可以看到方向是通过X轴控制的,在程序实现时我是用手机的重力传感器获取手机转动的角度。代码的设定是,当手机逆时针转动85度轮胎就会向左打死,顺时针85度向右打死,-84~84度按比例锁定方向,不会像键盘的左右键那样要么向左打死或者向右打死。
/** 初始化传感器 */sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);sensorManager.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
/** 传感器事件onSensorChanged */double angleRate = 1000/85;int LatestAngle = 0;@Overridepublic void onSensorChanged(SensorEvent event) {if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {geomagneticArr = event.values; }if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {gArr = event.values;if (!HidUitls.IsConnected()){return; }SensorManager.getRotationMatrix(rArr, null, gArr, geomagneticArr);SensorManager.getOrientation(rArr, valuesArr);double degreeX= (int)Math.toDegrees(valuesArr[1]);int angle = (int)Math.round(-degreeX*angleRate);angle = angle>1000?1000:angle;angle = angle<-1000?-1000:angle;if(angle != LatestAngle){//设置方向盘角度HidConsts.SetSteeringAngle(angle);UtilCls.SLog(TAG,"angle:"+degreeX + " "+angle);LatestAngle = angle;}}}
油门和刹车目前就简单使用SeekBar来实现
SeekBar.OnSeekBarChangeListener SeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {if (!HidUitls.IsConnected()) {return;}int val = progress;switch (seekBar.getTag().toString()){case "Accelerator":HidConsts.SetAccelerator((byte)val);break;case "Brake":HidConsts.SetBrake((byte)val);break;}}@Override public void onStartTrackingTouch(SeekBar seekBar) {}@Override public void onStopTrackingTouch(SeekBar seekBar) {}};
最后在说明一下,用我们的APP连接电脑时,双方都会弹出配对确认框,第一次连接时间可能有几十秒,因为连接后电脑会对我们的手机进行附加设置并加载相应的驱动,之后的连接都是秒连的。当我们看看win10的右下角出现下面的消息框说明我们的设备基本能被识别为方向盘了。如果连接没有出现这样的消息,我们就取消配对,重新连一次。