Arcadeでは、ゲームコントローラーを扱うための機能が用意されています。 一般的なゲームコントローラーであれば、arcade.get_controllers() を利用できます。
controllers = arcade.get_controllers()
しかし、コントローラーによっては、Arcadeが使用している pyglet によってHIDデバイスとして認識されていても、 標準的なコントローラーとしての「mapping」が登録されていない場合があります。 その場合、arcade.get_controllers() ではコントローラーを取得できないことがあります。
例えば、arcade.get_controllers()を実行すると
Warning: HIDDevice(name=4Axes 12Key GamePad) has no controller mappings.
という警告が表示され、
controllers = arcade.get_controllers() print(len(controllers))
の結果が 0 になる場合があります。このような場合は、Arcadeが内部で使用している pygletのJoystick API を直接利用する方法があります。
Arcadeと一緒にpygletを読み込みます。
import arcade import pyglet
Arcadeは内部でpygletを利用しているため、Arcadeのプログラムからpygletの入力機能を利用できます。
pygletでは、get_joysticks() を使って接続されているJoystickを取得できます。
joysticks = pyglet.input.get_joysticks()
print("Joystick数:", len(joysticks))
例えば、Joystick数: 1と表示されれば、Joystickが1台認識されています。
取得したJoystickを使用するには、open() を呼び出します。
joysticks = pyglet.input.get_joysticks()
if joysticks:
joystick = joysticks[0]
joystick.open()
複数のJoystickを扱う場合は、リストの要素をそれぞれ開きます。
joysticks = pyglet.input.get_joysticks()
for joystick in joysticks:
joystick.open()Joystickのボタンはイベントとして取得できます。
#joystick.event
def on_joybutton_press(joystick, button):
print("ボタンを押しました:", button)
#joystick.event
def on_joybutton_release(joystick, button):
print("ボタンを離しました:", button)
ボタンを押すと on_joybutton_press() が呼び出されます。 ボタンを離すと on_joybutton_release() が呼び出されます。 そのため、ボタンについては定期的に状態を調べるポーリング方式ではなく、イベント駆動方式で処理できます。
Joystickの軸が動いたときは、on_joyaxis_motion() が呼び出されます。
#joystick.event
def on_joyaxis_motion(joystick, axis, value):
print("軸:", axis)
print("値:", value)
例えばスティックを動かすと、
軸: x 値: 0.52
のようなイベントが発生します。axis は軸の名前、value はその軸の現在の値です。 一般的には、
x y z rx ry rz
などの軸があります。ただし、Joystickによって軸の数や割り当ては異なるため、 実際の値を確認することが重要です。
ArcadeのゲームでJoystickを利用する場合は、JoystickのイベントハンドラをArcadeのWindowに登録する方法が便利です。
import arcade
import pyglet
class GameWindow(arcade.Window):
def __init__(self):
super().__init__(800, 600, "Joystick Test")
joysticks = pyglet.input.get_joysticks()
if joysticks:
self.joystick = joysticks[0]
self.joystick.open()
self.joystick.push_handlers(self)
def on_joybutton_press(self, joystick, button):
print("ボタンを押しました:", button)
def on_joybutton_release(self, joystick, button):
print("ボタンを離しました:", button)
def on_joyaxis_motion(self, joystick, axis, value):
print("軸:", axis, "値:", value)
def on_draw(self):
self.clear()
game = GameWindow()
arcade.run()
ポイントは、self.joystick.push_handlers(self)です。 これによって、Joystickから発生したイベントを GameWindow で受け取れるようになります。 そのため、def on_joybutton_press(self, joystick, button): や、def on_joyaxis_motion(self, joystick, axis, value): を GameWindow のメソッドとして定義できます。
スティック入力の場合、callbackの中ですぐにゲーム処理を行うより、現在の入力状態を変数に保存する方法が便利です。例えば、
self.joystick_x = 0 self.joystick_y = 0
としておきます。 そしてcallbackで、
def on_joyaxis_motion(self, joystick, axis, value):
if axis == "x":
self.joystick_x = value
elif axis == "y":
self.joystick_y = value
とします。 これで、
スティックを動かす
↓
on_joyaxis_motion()
↓
joystick_x / joystick_y を更新
という処理になります。
保存した値は、Arcadeの on_update() でゲームに利用できます。 例えば、スプライトをスティックで移動する場合、
def on_update(self, delta_time):
self.player.change_x = self.joystick_x * 5
self.player.change_y = self.joystick_y * 5
self.player.update()
とできます。このように、入力を受け取る処理on_joyaxis_motion()と、ゲームを更新する処理 on_update()を分けると、プログラムを整理しやすくなります。
ゲームでは、ボタンとスティックでは扱い方が少し異なります。
ボタンは「押した」「離した」という瞬間的なイベントとして扱いやすい入力です。
def on_joybutton_press(self, joystick, button):
if button == 0:
print("ボタン0を押した")
例えば、
Aボタン → ジャンプ Bボタン → 攻撃 START → ゲーム開始
などに利用できます。
スティックは「現在どの方向に、どの程度倒されているか」という状態として扱うことが多い入力です。 そのため、
on_joyaxis_motion()
↓
現在値を変数に保存
↓
on_update()
↓
キャラクターを移動
という構造にすると扱いやすくなります
Joystickによって、軸やボタンの構成が異なる場合があります。 そのため、最初にJoystickの情報を確認するプログラムを作っておくと便利です。
import pyglet
joysticks = pyglet.input.get_joysticks()
print("Joystick数:", len(joysticks))
for i, joystick in enumerate(joysticks):
print() print("Joystick", i)
print("名前:", joystick.name)
print("Joystick:", joystick)
さらに、実際にスティックやボタンを操作して、
def on_joybutton_press(self, joystick, button):
print("ボタン:", button)
def on_joyaxis_motion(self, joystick, axis, value):
print("軸:", axis, "値:", value)
で値を確認すると、そのJoystickの入力構成を調べることができます。
| API | 用途 |
|---|---|
| arcade.get_controllers() | 標準的なControllerとして認識されたゲームコントローラ |
| pyglet.input.get_joysticks() | より汎用的なJoystickデバイス |
標準的なゲームコントローラーであれば、arcade.get_controllers()を利用するのが簡単です。しかし
HIDデバイスとして認識されている ↓ Controller mappingが存在しない ↓ arcade.get_controllers() が空
という場合には、pyglet.input.get_joysticks()を利用する方法があります。