Java,Steam控制器和我

您是否想过是否可以将现有的东西用于新的东西? 我看了一些所谓的“蒸汽控制器”(从现在开始为SC)的镜头,并看着我的游戏手柄。 问我自己是否有可能以类似蒸汽的方式使用它,我找到了一些Java库并创建了一个项目,今天想与您共享。

SteamController 当然,早在SC发行之前就已经有很多输入设备(尤其是游戏控制器),但是它具有一个新特性,使其与众不同。

它具有两个触摸板,它们可以模拟鼠标或键盘的输入,以便能够(实际上几乎)玩每个游戏。 如一些早期视频所示,通过使用这种兼容模式,即使像益智游戏“ Portal”之类的鼠标密集型游戏也似乎可以玩。
steamworkshop_webupload_previewfile_172072817_preview 作为游戏发烧友和Java程序员,我如何使用这样的东西(我已经拥有的XBOX控制器)来接近它?

一个名为“ StrangeCtrl”的小工具看到了世界的亮光。 与控制器对话需要一些JNI(例如,因为JVM中没有USB子系统),但是其余部分则是用纯Java编写的。 它位于系统托盘中,并且针对每个配置文件进行了手动配置,尽管也可以构建一个GUI。

它的依存关系是2.0.5版中的“ net.java.jinput.JInput”(仍适用于Windows 8.1)和我编写的一个小助手(“ com.xafero.SuperLoader” v0.1)。 现在,我将解释在此过程中采取的步骤。

第一步:我们如何让Java与我的控制器对话?

幸运的是,BSD许可的JInput项目正是这样做的。 例如,它连接到Microsoft的XInput接口,并用它获取的本机数据填充某些Java数据结构。 也涵盖Linux和Mac OS X,不用担心。

因此,我插入了游戏手柄(一个兼容XBOX的控制器),方法似乎很清楚:

  1. 得到控制器
  2. 得到他们的输入事件
  3. 并将它们转换为键盘和鼠标的虚拟事件。

三大操作系统的库的本机组件均以Java归档文件(至少每个Maven)提供。 但是,您可能已经知道,java.lang.System仅加载文件系统上直接可用的文件。

第二步:那么如何解决这个烦人的局限性呢?

快速搜索后,我发现wcmatthysen的“ mx-native-loader”似乎很有用,因为它声称可以提取JAR并加载本地内容。 但这没有用,因为JInput的库被打包到几个“ jinput-platform-***。jar”文件中,而不是像该加载器所建议的那样,被打包在META-INF / lib下的一个大块文件中。

因此,名为“ SuperLoader”的新帮助程序库可以在以下情况下工作:

  1. 为所有讨厌的本机库创建一个临时目录,例如,借助系统属性“ java.io.tmpdir”。 用户也可以直接指定它,因为它实际上并不重要。
  2. 从已经加载的JAR中获取所有讨厌的库; 遍历所有类路径的URL,并使用过滤器将其提取或排除其中的大多数。
  3. 扩展现有的库路径; 另一个库没有做的一件事,并且手动进行非常烦人,因此应扩展系统属性“ java.library.path”。
  4. 强制JVM更新系统路径; 可以通过将系统类加载器的“ sys_paths”字段重置为null来实现。 这迫使System类在您下次请求库时真正欣赏新情况。

现在,该应用程序将所有本机库预加载到一个临时文件夹中,例如,当要求JInput提供控制器列表时,不必为使用JAR文件而对其进行更改。 它完全可以像任何人一样使用System.loadLibrary。

第三步:可以模拟什么?

我们终于要阅读游戏手柄的事件了,那么我们该怎么办呢? 使用AWT的Robot类,自Java早期以来就可以模拟按键或鼠标移动等。 尽管机器人需要一个人来指定应该在其上工作的桌面,但它在多显示器系统上也可以正常工作。 唯一的区别是它生成的所有事件的偏移量–如果要单击PC屏幕的特定区域,这一点尤其重要。

到目前为止已实现的命令是:

  • MouseMoveCmd –水平或垂直移动鼠标一定量
  • MouseClickCmd –在当前屏幕位置单击给定的鼠标按钮
  • KeyComboCmd –按一些键并以相反的顺序释放它们

为了实现某种程度的可扩展性,有一个接口可以接受机器人生成虚拟事件,当前图形设备以及JInput给定的值:

public interface ICommand {void execute(Robot rbt, GraphicsDevice dev, float value);
}

它的抽象实现“ AbstractCmd”提供了一个接受一个字符串的构造函数。 作为处理的第一步,来自配置文件的原始字符串被一个空白分隔为一个字符串数组。

第四步:我们可以使用哪种配置格式?

有很多流行的格式,例如YAML,JSON等。但是Java已经为我们提供了一种简单的方法来实现这一目标。 因此,使用Java属性机制的XML变体来解析配置文件。 要使用与命令连接的字符串来构建实际地图,请使用类“ com.xafero.strangectrl.cmd.ConfigUtils”

  • 加载配置,
  • 遍历所有条目,
    • 通过每个条目的值搜索命令,
  • 并生成用于转换传入事件的实际地图。

第五步:实际工作

辅助类“ ControllerPoller”是一个定期执行的TimerTask,负责从任意数量的控制器中收集新的JInput事件,并将每个新内容通知调用者:

public void run() {
for (Controller controller : controllers) {
if (!controller.poll()) continue;
EventQueue queue = controller.getEventQueue();
Event event = new Event();
while (queue.getNextEvent(event))
callback.onNewEvent(this, controller, event);
}
}

调用方(在这种情况下,位于系统托盘中的所谓“ App”)仅实现回调接口,并在发生任何输入时免费获取所有信息:

public static interface IControllerCallback {
void onNewEvent(ControllerPoller p, Controller c, Event e);
}

“应用程序”的左侧是搜索与传入游戏手柄事件相关联的命令,并使用正确的参数执行这些命令。 现在我们可以用它来控制某些游戏,也许是波斯王子之类的旧游戏,或者是其他无法通过游戏手柄玩的游戏。 但是,让我们走开...

除了游戏以外的示例:如何为行动受限的人配置它?

为了仅显示另一个可能的应用领域,让我们为无法同时按下两个键的用户进行配置。 一个示例应用程序应该是Web浏览器。 在配置文件中,有以下设置:

<!-- Button A means now left mouse click -->
<entry key="Button 0">mouseClick 1</entry>
<!-- Button B will open a new tab -->
<entry key="Button 1">keyCombo CONTROL T</entry>
<!-- Button X will close an existing tab -->
<entry key="Button 2">keyCombo CONTROL W</entry>

此示例中的浏览器不必知道游戏控制器,因为操作系统将产生新的虚拟输入事件,并且将按要求运行。 通过使用Java并成为FOSS,该工具还可以进行自定义并且易于以各种方式理解(与模拟输入设备否则必须使用某些C / C ++代码相比)。

资源和链接

源代码位于https://github.com/xafero/StrangeCtrl 。 随时使用,共享或修改任何方面(根据GPL v3许可)。

有关更多信息,请参见:

  • JInput – https://java.net/projects/jinput
  • AWT机器人-http: //docs.oracle.com/javase/6/docs/api/java/awt/Robot.html

参考: Java,Steam控制器和Java,来自我们JCG合作伙伴 Xafero的Java Advent Calendar博客。

翻译自: https://www.javacodegeeks.com/2014/01/java-the-steam-controller-and-me.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/365974.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unknown column in field list_tf.feature_column的特征处理探究

1. 背景tf.estimator是tensorflow的一个高级API接口&#xff0c;它最大的特点在于兼容分布式和单机两种场景&#xff0c;工程师可以在同一套代码结构下即实现单机训练也可以实现分布式训练&#xff0c;正是因为这样的特点&#xff0c;目前包括阿里在内的很多公司都在使用这一接…

pytorch如何定义损失函数_对比PyTorch和TensorFlow的自动差异和动态模型

使用自定义模型类从头开始训练线性回归&#xff0c;比较PyTorch 1.x和TensorFlow 2.x之间的自动差异和动态模型子类化方法&#xff0c;这篇简短的文章重点介绍如何在PyTorch 1.x和TensorFlow 2.x中分别使用带有模块/模型API的动态子类化模型&#xff0c;以及这些框架在训练循环…

Gradle命令行便利

在我的《用Gradle构建Java的gradle tasks 》一文中&#xff0c;我简要地提到了使用Gradle的“ gradle tasks ”命令来查看特定Gradle构建的可用任务。 在这篇文章中&#xff0c;我将对这一简短提及进行更多的扩展&#xff0c;并查看一些相关的Gradle命令行便利。 Gradle可以轻松…

java封装实现Excel建表读写操作

对 Excel 进行读写操作是生产环境下常见的业务&#xff0c;网上搜索的实现方式都是基于POI和JXL第三方框架&#xff0c;但都不是很全面。小编由于这两天刚好需要用到&#xff0c;于是就参考手写了一个封装操作工具&#xff0c;基本涵盖了Excel表&#xff08;分有表头和无表头&a…

argmax函数_1.4 TensorFlow2.1常用函数

1.4 TF常用函数tf.cast(tensor,dtypedatatype)可以进行强制类型转换。tf.reduce_min(tensor)和tf.reduce_max(tensor)将计算出张量中所有元素的最大值和最小值。import tensorflow as tfx1 tf.constant([1., 2., 3.], dtypetf.float64)print("x1:", x1)x2 tf.cast(…

设计模式---数据结构模式之迭代器模式(Iterate)

一&#xff1a;概念 迭代模式是行为模式之一&#xff0c;它把对容器中包含的内部对象的访问委让给外部类&#xff0c;使用Iterator&#xff08;遍历&#xff09;按顺序进行遍历访问的设计模式。 在应用Iterator模式之前&#xff0c;首先应该明白Iterator模式用来解决什么问题。…

识别Gradle约定

通过约定进行配置具有许多优点&#xff0c;尤其是在简洁方面&#xff0c;因为开发人员不需要显式配置通过约定隐式配置的内容。 但是&#xff0c;在利用约定进行配置时&#xff0c;需要了解约定。 这些约定可能已经记录在案&#xff0c;但是当我可以编程方式确定约定时&#xf…

高校c语言题库,C语言-中国大学mooc-题库零氪

第1 周 程序设计与C语言简介1.1 程序设计基础随堂测验1、计算机只能处理由人们编写的、解决某些问题的、事先存储在计算机存储器中的二进制指令序列。第1周单元测验1、通常把高级语言源程序翻译成目标程序的程序称为( )。A、编辑程序B、解释程序C、汇编程序D、编译程序2、一个算…

场景法设计测试用例

在面向对象的软件开发中&#xff0c;事件触发机制是编程中经常遇到的。 &#xff08;一&#xff09;场景法原理 现在的软件几乎都是用事件触发来控制流程的。像GUI软件、游戏等。事件触发时的情景形成了场景&#xff0c;而同一事件不同的触发顺序和处理结果就形成了事件流。这种…

python中range函数是什么意思_python里range是什么

python range() 函数可创建一个整数列表&#xff0c;一般用在 for 循环中。函数语法&#xff08;推荐学习&#xff1a;Python视频教程&#xff09;range(start, stop[, step]) 参数说明&#xff1a; start: 计数从 start 开始。默认是从 0 开始。例如range&#xff08;5&#x…

android高德地图搜索地址,地点/周边搜索-Android平台-开发指南-高德地图车机版 | 高德地图API...

关键字搜索第三方通过该接口可传入关键字信息给auto&#xff0c;调起auto执行关键字搜索并跳转到搜索结果展现界面&#xff0c;官网版本都可支持参数说明参数说明是否必填类型ActionAUTONAVI_STANDARD_BROADCAST_RECV是stringKEY_TYPE协议ID:10036是intSOURCE_APP第三方应用名称…

Luogu 3626 [APIO2009]会议中心

很优美的解法。 推荐大佬博客 如果没有保证字典序最小这一个要求&#xff0c;这题就是一个水题了&#xff0c;但是要保证字典序最小&#xff0c;然后我就不会了…… 如果一条线段能放入一个区间$[l, r]$并且不影响最优答案&#xff0c;那么对于这条线段$[l, r]$&#xff0c;设$…

python编程求导数_面向对象编程 —— java实现函数求导

首先声明一点&#xff0c;本文主要介绍的是面向对象&#xff08;OO&#xff09;的思想&#xff0c;顺便谈下函数式编程&#xff0c;而不是教你如何准确地、科学地用java求出函数在一点的导数。 一、引子 defd(f) :defcalc(x) : dx 0.000001 #表示无穷小的Δx return (f(xdx) - …

BZOJ5093图的价值(斯特林数)

题目描述 “简单无向图”是指无重边、无自环的无向图&#xff08;不一定连通&#xff09;。一个带标号的图的价值定义为每个点度数的k次方的和。给定n和k&#xff0c;请计算所有n个点的带标号的简单无向图的价值之和。因为答案很大&#xff0c;请对998244353取模输出。题解因为…

python程序写诗_用Python作诗,生活仍有诗和远方

原标题&#xff1a;用Python作诗&#xff0c;生活仍有诗和远方 报 名 来源&#xff1a;TheodoreXu链接&#xff1a; https://segmentfault.com/a/1190000013154329 常听说&#xff0c;现在的代码&#xff0c;就和唐朝的诗一样重要。 可对我们来说&#xff0c;写几行代码没什么&…

华为鸿蒙手机beta版,鸿蒙2.0 Beta手机版来了!明年将全面支持华为手机

读创/深圳商报记者陈 姝备受关注的华为鸿蒙操作系统(HarmonyOS&#xff0c;以下简称鸿蒙)有了新进展。华为消费者业务软件部总裁王成录日前透露&#xff0c;将于12月16日在北京发布鸿蒙2.0手机开发者Beta版本。王成录在12月14日发微博称&#xff1a;“HarmonyOS正沿着我们在HDC…

Django 路由层

Django的下载与基本命令 下载Django&#xff1a;pip3 install django2.0.1创建一个django project: django-admin startproject luffy在mysite目录下创建应用&#xff1a;python manage.py startapp app01启动django项目:python manage.py runserver 8080 我们访问&#xff1a;…

caffe安装_目标检测之caffe-ssd模型训练与测试

最近把一个ssd网络的net..prototxt网络结构和自己生成的hdf5格式数据一起做训练时发现经常报错&#xff0c;因为ssd中一些层在caffe中并没有实现&#xff0c;需要自己写相应的.cpp,.cu文件重新编译&#xff0c;比较麻烦&#xff0c;而大家通常训练caffe-ssd都是基于原作者公开的…

Python之classmethod和staticmethod的区别

python中3种方式定义类方法&#xff0c;常规方式、classmethod修饰方式、staticmethod修饰方式。 class A(object):def foo(self, x):print(调用foo函数 (%s, %s)%(self, x))print(self:, self)classmethoddef class_foo(cls, x):print(调用class_foo函数 (%s, %s) % (cls, x))…

php开发微信图灵机器人

本着开源为原则&#xff0c;为这个世界更美好作出一份共享&#xff0c;我就给大家做个指路人&#xff0c;如果实用&#xff0c;记得给提供开源的朋友一些鼓励。 简单介绍一下实现思路&#xff0c;使用swoole扩展接管php运行&#xff0c;由于swoole只能在类UNIX上运行&#xff0…