pygame几乎可以识别任意外接游戏操纵设备。
游戏手柄上的每个操作都会形成一个电信号被joystick类对象捕获到, joystick把这个信号归一化到[-1,1]区间,或者离散化为{0,1}。
以下程序创建一个弹出窗口,实时显示joystick捕获到的信号数值,便于查看joystick捕获到的信号对应于游戏手柄的哪个按钮/操作。
代码参考博客:Pygame详解(十七):joystick 模块_pygame joystick-CSDN博客
进行了注释解读。
import pygame# Define some colors ## 定义颜色
BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)# This is a simple class that will help us print to the screen
# It has nothing to do with the joysticks, just outputting the
# information.
## 这是一个简单的 class, 用于帮助我们把joystick的信息打印到屏幕上,便于查看哪个按键对应哪个变量。
## 这个类不对 joystick 做任何操作,仅仅打印它的信息。
class TextPrint:def __init__(self):self.reset()self.font = pygame.font.Font(None, 20)def print(self, screen, textString):textBitmap = self.font.render(textString, True, BLACK) ## 设置屏幕中显示的文字,并设置显示颜色screen.blit(textBitmap, [self.x, self.y]) ## 在screen 的指定位置打印文字。self.y += self.line_height ## 光标的位置下移一个行高的高度def reset(self):self.x = 10 ## 设置打印文字的初始 x 位置self.y = 10 ## 设置打印文字的初始 y 位置self.line_height = 15 ## 设置行高为15像素def indent(self): ## 光标位置右移10个空格self.x += 10def unindent(self): ## 光标位置左移10个空格self.x -= 10## 初始化 pygame
pygame.init()# Set the width and height of the screen [width,height]
size = [500, 750] ## 设置矩形框的大小
screen = pygame.display.set_mode(size) ## 获取pygame里面内置的 display 对象, 命名为screenpygame.display.set_caption("My Game") ## 设置screen窗口的标题# Loop until the user clicks the close button.
## 循环,直至用于点击弹出的窗口上的关闭按钮
done = False# Used to manage how fast the screen updates
## 用于管理screen更新的速度
clock = pygame.time.Clock()# Initialize the joysticks
## 初始化joystick
pygame.joystick.init()# Get ready to print
## 准备 print
textPrint = TextPrint()# -------- Main Program Loop -----------
# 主程序
while done==False:# EVENT PROCESSING STEP## 事件处理步骤for event in pygame.event.get(): # User did something # 当用户做了某件事时if event.type == pygame.QUIT: # If user clicked close ## 如果用户的操作不是 quit(在screen上显示)done=True # Flag that we are done so we exit this loop ## 当用户在screen上点击close时,把done设置为true,退出循环# Possible joystick actions: JOYAXISMOTION JOYBALLMOTION JOYBUTTONDOWN JOYBUTTONUP JOYHATMOTION# joystick 其他可能的动作:axis运动, ball运动, button按压运动,button弹起运动, hat运动if event.type == pygame.JOYBUTTONDOWN: ## 当发生按钮按下动作时,打印信息print("Joystick button pressed.")if event.type == pygame.JOYBUTTONUP: ## 当发生按钮弹起动作时,打印信息print("Joystick button released.")# DRAWING STEP ## 绘制步骤# First, clear the screen to white. Don't put other drawing commands# above this, or they will be erased with this command.## 首先, 把screen清空为白色,不添加其他任何绘制命令,或者其他所有的绘制命令被这个命令覆盖screen.fill(WHITE) ## 把screen填充为白色textPrint.reset() ## textPrint 是一个自己定义的类# Get count of joysticks ## 获取连接到当前机器上的joystick的个数joystick_count = pygame.joystick.get_count()textPrint.print(screen, "Number of joysticks: {}".format(joystick_count) ) ## 在 screen上打印信息,textPrint.indent() ## 在 screen上打印空格# For each joystick:## 对每个joystick执行以下操作for i in range(joystick_count):joystick = pygame.joystick.Joystick(i) ## 获取当前 joystick 对象joystick.init() ## 初始化当前joystick textPrint.print(screen, "Joystick {}".format(i) ) ## 打印 当前 joystick 编号到screen textPrint.indent() ## 打印空格# Get the name from the OS for the controller/joystickname = joystick.get_name() ## 获取joystick的名字textPrint.print(screen, "Joystick name: {}".format(name) ) ## 打印joystick的名字# Usually axis run in pairs, up/down for one, and left/right for the other.## 通常, axis成对运行,一个用于表示上下,另一个用于表示左右。axes = joystick.get_numaxes() ## 获取axis轴的个数textPrint.print(screen, "Number of axes: {}".format(axes) )textPrint.indent()for i in range( axes ): axis = joystick.get_axis( i ) ## 获取第 i 个 axis 的当前数值,取值范围一般在[-1,1]之间textPrint.print(screen, "Axis {} value: {:>6.3f}".format(i, axis) ) ## 把axis的编号和数值打印到窗口上textPrint.unindent()buttons = joystick.get_numbuttons() ## 获取按钮的个数textPrint.print(screen, "Number of buttons: {}".format(buttons) )textPrint.indent()for i in range( buttons ):button = joystick.get_button( i ) ## 获取第i个按钮的当前取值textPrint.print(screen, "Button {:>2} value: {}".format(i,button) )textPrint.unindent()# Hat switch. All or nothing for direction, not like joysticks.# Value comes back in an array.hats = joystick.get_numhats() ## 获取键帽的个数textPrint.print(screen, "Number of hats: {}".format(hats) )textPrint.indent()for i in range( hats ):hat = joystick.get_hat( i ) ## 打印当前键帽的数值/状态textPrint.print(screen, "Hat {} value: {}".format(i, str(hat)) )textPrint.unindent()textPrint.unindent()# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT## 所有绘制代码需要在这一行之前# Go ahead and update the screen with what we've drawn.## 用上面的命令更新 screen pygame.display.flip()# Limit to 20 frames per second## 更新间隔是 20帧/秒,帧率clock.tick(200)# Close the window and quit. ## 关闭窗口并退出
# If you forget this line, the program will 'hang' ## 如果您忘记了这一行,如果从IDLE运行,程序将在退出时“挂起”。
# on exit if running from IDLE.
pygame.quit ()
以下是我的一个使用示例:
import pygamepygame.init()
pygame.joystick.init()for i in range(10):joystick_count = pygame.joystick.get_count() ## 统计接入了几个jsystick摇杆/设备joystick = pygame.joystick.Joystick(0) ## 返回一个joystick设备类对象,与外接的一个joystick对接。joystick.init() ## 使用前需要对设备进行初始化stick_id = joystick.get_id()print(f"======{i}==========")print(f"游戏手柄的 名字是:{joystick.get_name()}")print(f"操纵轴的数量 numaxes = {joystick.get_numaxes()}") ## 获得 Joystick 操纵轴的数量。 7 个print(f"追踪球的数量 numballs = {joystick.get_numballs()}") ## 获得 Joystick 上追踪球的数量。 0 个print(f"按钮的数量 numbuttons = {joystick.get_numbuttons()}") ## 获得 Joystick 上按钮的数量。 34 个print(f"帽键的数量 numhats = {joystick.get_numhats()}") ## 获得 Joystick 上帽键的数量。 1 个## 打印每个操纵轴的数值for j in range(joystick.get_numaxes()): ## 获取第j个轴的数值value = joystick.get_axis(j) ## 获得操纵轴的当前坐标,其值是从 -1.0 到 1.0,0 在中间。 轴的数量必须是从 ## 0 到 get_numaxes() - 1 的数字。## 你可能需要考虑一些额外的盈余来处理抖动,偏移值是在 0 的上下游动。print(f"axis_{j}_value = {value}")## 打印每个按钮的状态for k in range(joystick.get_numbuttons()): value = joystick.get_button(k) ## 获取第k个按钮的数值print(f"button_{k}_value = {value}")