发布时间:2025-12-09 16:30:49 浏览次数:7
近日下载了一款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是行不通的,看来还得再想想其它办法。那就是如何更直接的传递手柄的按键给键盘呢,有没有一个可以模拟键盘按键的模块呢?最后在https://pypi.org/中找到了一个keyboard模块,通过 pip install keyboard 进行导入。
可以直接模拟键盘按键,主要用到两个功能,keyboard.press 代表按下,keyboard.release 代表松开。
由于手柄的按键识别很多地方都有讲,我这里不再浪费大家的时间,以下是这部分是源代码tools.py中增加游戏手柄按键映射的代码,供参考: