如何让游戏手柄joystick的按键映射键盘keyboard按键,方便不支持手柄的pygame游戏可以通过简单设置后用手柄进行操控

近日下载了一款Justin Armstrong在github中的马里奥第一关的python游戏,点击作者名字,可以到作者的Github中下载源码。虽然Justin只开发了第一关,但是通过简易的调整,也可以玩出新花样,比如可以设置漫天的加命蘑菇,把每个砖块都设为无敌星,或者变更游戏背景画面,把魂斗罗的地面移到马里奥中,当然还可以增加一些隐形的问号罐,调整地面水沟的距离等,总之和小朋友玩的很愉快,惊喜连连。

但是也有一个比较麻烦的问题,就是这款游戏的代码中不支持游戏手柄,通过键盘来玩,还是不太适应,怎么办呢? 当然是改代码,把游戏手柄连接进来喽。

于是我查了很多的资料,可惜就是没有找到如何能方便的映射游戏手柄的事件,一般都是讲游戏手柄的初始化,按钮的代号,定义,如何调用等内容,比如:小黑LLB 的译文 Pygame 官方文档 - pygame.joystick,写得非常详细,虽然没能解决最终的问题,也给了我很多启发,非常感谢。

另一方面,由于原作者Justin Armstrong的代码已经很完善,各种逻辑关系,也非常合理,对马里奥的操作,都是通过对Keys的状态进行获取并处理的,所以,如果要加入手柄的参数传递,一定会较大幅度的变更原游戏中的代码,为了不要太麻烦,有没有什么好的办法呢?我想到应该可以通过映射键盘事件,来完成这个功能的传递。可是找了好多资料,却没有找到合适的内容,有一篇文章也讲了对pygame.key.get_pressed() 函数的疑惑,Confused by pygame key.get_pressed() method 里面对于这个函数的功能讲得很清楚,就是会返回一系列的布什尔值,我试着打印了一下,可以看一下:

import pygame as pg
print(pg.key.get_pressed())
# 打印这个函数,会输出以下内容,共计512个布尔值,其中为True的表示该键被按下
# 比如说回车键,是第41个的值为True
"""
pygame.key.ScancodeWrapper(False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)
"""
# 与此同时,也通过打印event事件,查看当前键盘的状态:
print(event)
"""
<Event(768-KeyDown {'unicode': '\r', 'key': 13, 'mod': 4096, 'scancode': 40, 'window': None})># 可以看到 scancode = 40, 也就是当前按钮的定位,由于计数是从0开始的,所以前文提到的是第41个。
"""

虽然了解了这个函数的功能和状态,也知道了与keys的关系,但是直接把这个结果,赋值给keys是行不通的,看来还得再想想其它办法。那就是如何更直接的传递手柄的按键给键盘呢,有没有一个可以模拟键盘按键的模块呢?最后在https://pypi.org/中找到了一个keyboard模块,通过 pip install keyboard 进行导入。
可以直接模拟键盘按键,主要用到两个功能,keyboard.press 代表按下,keyboard.release 代表松开。
由于手柄的按键识别很多地方都有讲,我这里不再浪费大家的时间,以下是这部分是源代码tools.py中增加游戏手柄按键映射的代码,供参考:

# python 3.10
import pygame as pg
# pip install keyboard
import keyboard# 初始化joystick
pg.joystick.init()
# 这里是按一个手柄进行操作,所以对应的是 pg.joystick.Joystick(0)
joystick = pg.joystick.Joystick(0)
joystick.init()"""
# 如果需要操作多个手柄,则需要循环进行检测,可以参考以下代码:
joystick_lists = [pg.joystick.Joystick(i) for i in range(pg.joystick.get_count())]
# 打印其中第一个手柄的名称
print(joystick_lists[0].get_name())
""""""# 这里是对键盘按键功能的定义,"""
keybinding = {'action':pg.K_j,  # 发射子弹'jump'  :pg.K_k,  'left'  :pg.K_a,'right' :pg.K_d,'down'  :pg.K_s
}"""# 接下来的部分,就是获取手柄按键,并对应以上的键盘按键。"""def event_loop(self):for event in pg.event.get():if event.type == pg.QUIT:self.done = Trueelif event.type == pg.KEYDOWN:self.keys = pg.key.get_pressed()self.toggle_show_fps(event.key)    # event.key 表示键盘按键的值,比如k 的值是107, 回车键的值是13,等 elif event.type == pg.KEYUP:self.keys = pg.key.get_pressed()"""# 以下增加游戏手柄的控制检测"""elif event.type == pg.JOYBUTTONDOWN:  # 检测到手柄上的键按下# print(event)if joystick.get_button(7)==1:   # get_button(7) 是我这个手柄上的start键keyboard.press('enter')     # 调用键盘中的回车键。if joystick.get_button(0)==1: # get_button(0) 是我这个手柄上的A键keyboard.press('k')         # 对应键盘的k键,也就是对应跳的功能。              if joystick.get_button(2)==1:   # get_button(2) 是我这个手柄上的X键keyboard.press('j')if joystick.get_button(1)==1:   # get_button(1) 是我这个手柄上的B键keyboard.press('k')if joystick.get_button(3)==1:  # get_button(3) 是我这个手柄上的Y键keyboard.press('j')elif event.type ==pg.JOYBUTTONUP:   # 检测到手柄上的键放开if joystick.get_button(7)==0:     # get_button(7) 是我这个手柄上的start键keyboard.press('enter')         # 手柄按键放天的时候,键盘中的回车键也要放开。if joystick.get_button(0)==0:keyboard.release('k')if joystick.get_button(2)==0:  keyboard.release('j')if joystick.get_button(1)==0:keyboard.release('k')if joystick.get_button(3)==0:  keyboard.release('j')                    elif event.type == pg.JOYHATMOTION:   # 检测到手柄上的十字方向键按下#该事件的返回值是一个元组类型的数据,有两个元素,分别表示左右,和上下if joystick.get_hat(0)[0]==-1:  # 检测到手柄上的十字方向键 左键按下keyboard.press('a')          # 调用键盘中按下a键的函数else:                         # 如果没有检测到手柄上的十字方向键 左键按下keyboard.release('a')      # 调用键盘中释放a键的函数if joystick.get_hat(0)[0]==1:  # 检测到手柄上的十字方向键 右键按下keyboard.press('d')else:keyboard.release('d')if joystick.get_hat(0)[1]==-1:  # 检测到手柄上的十字方向键 往下的按键按下keyboard.press('s')else:keyboard.release('s')elif event.type == pg.JOYAXISMOTION: # 检测到手柄上的方向轴按下if joystick.get_axis(0)<-0.3:    # 方向轴往左的偏移值get_axis(0)从0 到-1,这里设定到-0.3的时候调用按键。keyboard.press('a')else:keyboard.release('a')if joystick.get_axis(0)>0.3:  # 方向轴往右的偏移值get_axis(0)从0 到 1,这里设定到0.3的时候调用按键。keyboard.press('d')else:keyboard.release('d')if joystick.get_axis(1)>0.7:    # 方向轴往下的偏移值get_axis(1)从0 到 1,这里设定到0.7的时候调用按键。keyboard.press('s')else:keyboard.release('s')self.state.get_event(event)

以上就是关于游戏手柄与键盘映射的一个初步解决方案,供参考。如果您有更好的解决方案,望能分享。
若需要马里奥第一关的源代码请到作者的Github中下载,有任何疑问,请留言,谢谢!

如何让游戏手柄joystick的按键映射键盘keyboard按键,方便不支持手柄的pygame游戏可以通过简单设置后用手柄进行操控相关推荐

  1. 计算机键盘按键更改,键盘的按键如何更改

    键盘的按键如何更改 键盘可以对电脑进行一些简单的控制,键盘的使用可以简化我们对电脑的使用.那么键盘的按键如何更改呢?下面就让jy135小编来告诉大家呢,欢迎阅读. 1.首先,下载一个键盘映射工具.百度 ...

  2. ppsspp模拟java按键_ppsspp 手柄按键映射 北通 BTP

    PPSSPP Joystick 按键映射 某天感兴趣买了一个北通蝙蝠D2(BTP-BD2F)手柄,安装了PPSSPP模拟器.满脸的期待打开PPSSPP准备体验一下游戏的感觉,结果游戏手柄按映射不对,欲 ...

  3. ppsspp 手柄按键映射 北通 BTP

    PPSSPP Joystick 按键映射 某天感兴趣买了一个北通蝙蝠D2(BTP-BD2F)手柄,安装了PPSSPP模拟器.满脸的期待打开PPSSPP准备体验一下游戏的感觉,结果游戏手柄按映射不对,欲 ...

  4. qtscrcpy自定义按键_按键映射说明.md

    # 自定义按键映射说明 按键映射文件为json格式,新增自己的按键映射文件需要放在keymap目录中才可以被QtScrcpy识别. 按键映射文件的具体编写格式下面会介绍,也可以参考自带的按键映射文件. ...

  5. 手柄映射软件_【手柄教程】崩坏2手柄按键映射以及设置教程

    最近刚开始用雷电,喜欢这款模拟器可以自定义IMEI的功能.对一些手游的支持性也比别的模拟器要强废话不多说,干货送上我用的手柄映射软件是Xpadder.虽然这款软件比较老,但是软件的功能强大,对各个厂商 ...

  6. android 按键映射文件,按键映射专业版

    按键映射专业版,按键映射专业版可以用来自定义音量键, Home 键, 返回键以及最近的应用按键. 运行任意应用, 快捷方式或自定义操作.可对物理按键实行自定义单击, 双击和长按操作, 无需 Root ...

  7. 手柄映射键盘_创新设计的多模手柄,北通宙斯T6精英机械游戏手柄体验点评

    对于游戏玩家来说,手柄.机械键盘和鼠标这三大件算是周边标配.其中手柄也从早期功能单一的USB手柄变为了现在的多模手柄,从早期搭配PC使用到现在可以搭配XBOX.PS.Switch.手机等设备来使用,手 ...

  8. [ZZ]通过修改键盘映射替代损坏按键

    [ZZ]通过修改键盘映射替代损坏按键 我买的神舟笔记本电脑因为使用不当,致使Ctrl键与PageUp键损坏.而该电脑仅有键盘左下角一个Ctrl键,损坏之后给日常使用带来许多不便.由于 我装的是Wind ...

  9. (转)通过修改键盘映射替代损坏按键

    http://hi.baidu.com/kxw102/blog/item/aeef82fda272d1f6fd037fa1.html 通过修改键盘映射替代损坏按键 2009-12-20 05:22 通 ...

最新文章

  1. 山东春季高考计算机可以报考的本科学校,山东春季高考专业有哪些?可以报考的本科院校吗?...
  2. 李飞飞点赞「ARM」:一种让模型快速适应数据变化的元学习方法 | 开源
  3. MongoDB下载地址
  4. 关于标准规范的一些想法
  5. Linux引出环境变量的关键字,学习记录008-linux常用命令/设置系统and用户环境变量two(示例代码)...
  6. 在线JSON转CSV格式文件工具
  7. 图像语义分割(10)-DeepLabV3+: 用于图像语义分割的带有空洞可分离卷积的编解码结构
  8. vs2015升级旧工程报snprintf已有主体及“int8_t” 重定义
  9. python3ide安卓版官网下载_Pydroid3官方版-Pydroid3最新版下载v4.01 - 7230手游网
  10. win10/win11快速隐藏/显示桌面图标快捷方式
  11. 五阶最小二乘+迭代方法曲线拟合
  12. stm32f105固件包_STM32F105/107
  13. 为什么要用python处理excel-以Excel处理为目的学习python还是VBA?
  14. reg51.h、intrins.h这源文件
  15. 2023年如何做谷歌SEO优化?谷歌优化排名怎么做?
  16. 久坐伤身 关爱程序员,从自己做起
  17. GC0053-STM32单片机NTC热敏电阻温度采集及控制LCD1602
  18. 易鑫集团上半年经调整净利润1.23亿元 同比下降53%
  19. 淘客推广 25%高佣金产品旺季来袭
  20. java 调用 mahout_使用 Mahout 实现内容分类

热门文章

  1. python字典遍历的几种方式
  2. 论文调研——23.2.28
  3. DenseNet 算法
  4. 请碟仙儿│一个区块链思想实验
  5. python情感分析:基于jieba的分词及snownlp的情感分析!
  6. ubuntu下如何批量修改文件后缀名
  7. 那些年部署的服务器,cp2k环境部署安装
  8. QQ空间获取指定QQ号信息接口
  9. 管理运筹学软件计算机解咋看,管理运筹学 第3章 线性规划问题的计算机求解.ppt...
  10. 华为s9300 设备升级R019 兼容万兆业务板