700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 如何让游戏手柄joystick的按键映射键盘keyboard按键 方便不支持手柄的pygame游戏可以

如何让游戏手柄joystick的按键映射键盘keyboard按键 方便不支持手柄的pygame游戏可以

时间:2023-01-29 03:29:26

相关推荐

如何让游戏手柄joystick的按键映射键盘keyboard按键 方便不支持手柄的pygame游戏可以

如何让游戏手柄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 pgprint(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是行不通的,看来还得再想想其它办法。那就是如何更直接的传递手柄的按键给键盘呢,有没有一个可以模拟键盘按键的模块呢?最后在/中找到了一个keyboard模块,通过 pip install keyboard 进行导入。

可以直接模拟键盘按键,主要用到两个功能,keyboard.press 代表按下,keyboard.release 代表松开。

由于手柄的按键识别很多地方都有讲,我这里不再浪费大家的时间,以下是这部分是源代码tools.py中增加游戏手柄按键映射的代码,供参考:

# python 3.10import pygame as pg# pip install keyboard import keyboard# 初始化joystickpg.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游戏可以通过简单设置后用手柄进行操控

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。