pygameを用いたゲームパッド操作機能の実装
この記事の目的
pythonのライブラリpygameを用いてゲームパッドでユーザーの入力を読み込む処理を実装する。
使用したゲームパッド
ゲームパッド Logicool ロジクール F310r 国内正規品 3年間メーカー保証
参考となるサイト https://glorificatio.org/archives/1398
pygame
pygameとは
pythonのゲーム制作用ライブラリ 2Dの画面描画/音楽再生機能/ユーザー操作入力(マウス/キーボード/ゲームパッド)が充実しており、ゲーム以外にも処理結果の描画やUIとして利用することができる。
機能/使い方の詳細
インストール
windows (anacondaの場合)
pip install pygame
Ubuntu mateの場合
sudo apt-get install python-pygame
GUI描画(Hello World) とキーボード読み込み
初期化処理でスクリーンサイズなどを設定したあとで、30msec間隔をあけながらキーボードの状態を取得して 赤丸の位置を動かす処理は、下記のように記述できる。
#!/usr/bin/env python # -*- coding: utf-8 -*- import pygame from pygame.locals import * import sys SCREEN_SIZE = (640, 480) # 画面サイズ (横/縦) STEP = 10 #キーボード/ハットスイッチの反応の良さ if __name__ == '__main__': # Pygameを初期化 pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE) # SCREEN_SIZEの画面を作成 pygame.display.set_caption("window test") # Windowタイトルの設定 X_CENTER = int(SCREEN_SIZE[0]/2) Y_CENTER = int(SCREEN_SIZE[1]/2) [circle_x, circle_y] = [X_CENTER, Y_CENTER] #円の初期位置を設定 # 画面描画ループ while True: screen.fill((0,0,0)) # 画面を青色で塗りつぶす # イベント処理 for event in pygame.event.get(): #×ボタンによる終了 if event.type == QUIT: # 終了イベント sys.exit() # キーボード状態の取得 pressed_keys = pygame.key.get_pressed() # 押されているキーに応じて画像を移動 if pressed_keys[K_LEFT]: circle_x = circle_x - STEP if pressed_keys[K_RIGHT]: circle_x = circle_x + STEP if pressed_keys[K_UP]: circle_y = circle_y - STEP if pressed_keys[K_DOWN]: circle_y = circle_y + STEP #描画範囲の上下限チェック if circle_x< 0: circle_x = 0 elif circle_x > SCREEN_SIZE[0]: circle_x = SCREEN_SIZE[0] if circle_y< 0: circle_y = 0 elif circle_y > SCREEN_SIZE[1]: circle_y = SCREEN_SIZE[1] #描画 pygame.draw.circle(screen, (255,0,0), (circle_x,circle_y), 10) pygame.display.update() # 画面を更新 pygame.time.wait(30) # 30msec 待ち
コントローラの読み込み
ジョイスティックの初期化
下記処理を初期化部分に追加するとpygameでジョイスティックを初期化できる。
pygame.joystick.init() try: joy = pygame.joystick.Joystick(0) # create a joystick instance joy.init() # init instance print("Joystick Name: " + joy.get_name()) print("Number of Button : " + str(joy.get_numbuttons())) print("Number of Axis : " + str(joy.get_numaxes())) print("Number of Hats : " + str(joy.get_numhats()))
F310の場合、軸やボタン数を下記のように取得できる。
Joystick Name: Controller (Gamepad F310) Number of Button : 10 Number of Axis : 5 Number of Hats : 1
ジョイスティック(アナログバー)の読み込み
アナログバーは各軸について -1~1の小数値で得られる。 F310の場合axis(2)はLRキーの強さに対応する軸なので注意。 (下記は左スティックのみ有効としている)
#ジョイスティック(アナログバー左スティック)状態の取得 circle_x = int((joy.get_axis(0)+1) * X_CENTER) #joystick(横軸)の方向キーはは-1~1の範囲で取得できる circle_y = int((joy.get_axis(1)+1) * Y_CENTER) #joystick(縦軸)の方向キーはは-1~1の範囲で取得できる # axis(2)はL2/R2キーに対応 #ジョイスティック(アナログバー右スティック)状態の取得 #circle_x = int((joy.get_axis(3)+1) * X_CENTER) #joystick(横軸)の方向キーはは-1~1の範囲で取得できる #circle_y = int((joy.get_axis(4)+1) * Y_CENTER) #joystick(縦軸)の方向キーはは-1~1の範囲で取得できる
方向ボタン(ハットスイッチ)読み込み
方向ボタン(ハットスイッチ)は縦横軸それぞれを-1,0,1の離散値として取得できる
#方向ボタン (ハットスイッチ) hat_input = joy.get_hat(0) if hat_input[0] == -1: # circle_x = circle_x - STEP elif hat_input[0] == 1: circle_x = circle_x + STEP if hat_input[1] == 1: circle_y = circle_y - STEP elif hat_input[1] == -1: circle_y = circle_y + STEP
上記の3つの入力手段を切り替えることができるpygameのスクリプトをgithubに保存した。
次回は上記の処理をROSと結合して目標速度指令を送信し、turtlesimを動かす機能を実装する。