はじめに
今回はpygameのイベントのうち、タッチ操作に対応しているFINGERDOWN、FINGERUP、FINGERMOTIONについて解説します。
マウスイベントとの違い
マウスイベントを使ってもタッチ操作は可能ですが、決定的に違う点として、マウスイベントでは複数の指での操作に対応できないことが挙げられます。しかし、FINGERDOWNなどはマルチタッチに対応しているため、複数箇所を同時にタップしたとしても、全ての座標を取得できます。
使い方
以下のようにイベントループの中で他のイベント同様に扱えばいいのですが、座標が0~1の値で返ってくるので、画面サイズをかけてあげる必要があります。
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.FINGERDOWN:
finger_id, finger_x, finger_y = event.finger_id, event.x*WIDTH, event.y*HEIGHT
eventの中身は以下のような感じで色々あるようですが、基本的には上の三つを使えば良さそうです。(FINGERUPとFINGERMOTIONも同様)
<Event(1792-FingerDown {'touch_id': 4067143, 'finger_id': 27202, 'x': 0.22265625, 'y': 0.84765625, 'dx': 0.0, 'dy': 0.0, 'pressure': 0.0, 'window': None})>
テンプレート
FINGERDOWNやFINGERUPだけならいいのですが、FINGERMOTIONを使うにあたって追従できるようにしたいので、管理用のクラスを使うと便利です。せっかくなのでテンプレートという形でまとめてみました。
import pygame, sys
pygame.init() # Pygameを初期化
WIDTH, HEIGHT = 256, 256
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 画面を作成
pygame.display.set_caption("テンプレート") # タイトルを作成
clock = pygame.time.Clock()
# 管理用のクラス
class Finger:
fingers = []
limit = 3
# 合致する指を返す
@classmethod
def search(cls, id):
for f in cls.fingers:
if f.id == id:
return f
return None
@classmethod
def reset(cls):
Finger.fingers = []
def __init__(self, id, x, y):
if len(Finger.fingers) >= Finger.limit:
return
self.id = id
self.x, self.y = x, y
Finger.fingers.append(self)
def update(self, x, y):
self.x, self.y = x, y
def remove(self):
Finger.fingers.remove(self)
def main():
# メインループ
while True:
screen.fill((255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# マルチタッチ対応
if event.type == pygame.FINGERDOWN:
finger_id, finger_x, finger_y = event.finger_id, event.x*WIDTH, event.y*HEIGHT
Finger(finger_id, finger_x, finger_y)
elif event.type == pygame.FINGERMOTION:
finger_id, finger_x, finger_y = event.finger_id, event.x*WIDTH, event.y*HEIGHT
finger = Finger.search(finger_id)
if finger is not None:
finger.update(finger_x, finger_y)
elif event.type == pygame.FINGERUP:
finger_id = event.finger_id
finger = Finger.search(finger_id)
if finger is not None:
finger.remove()
for f in Finger.fingers:
pygame.draw.circle(screen, (255, 0, 0), (f.x, f.y), 15)
clock.tick(60)
pygame.display.update()
if __name__ == '__main__':
main()
FINGERDOWN発生時に指を登録し、FINGERUPやFINGERMOTION発生時に、idが一致する指の座標を更新したり、削除を行うことで管理しています。イベントループ内で完結できない理由は、指を離さずにホールドするだけの状態だとイベントが発生しないためです。
FINGERイベントではマウスが反応しないので、タッチ操作に対応していないPCでは操作が確認できません。
最後に
ここまで読んで下さりありがとうございました。上手く使えばマウスイベントと比べて、扱える範囲がかなり広がると感じました。複数箇所が同時に押せる故に、意図しない挙動を誘発することも考えられるので、マウスイベントとどちらが適しているか、ゲームごとに考えて使う必要がありますね。
↓FINGERイベントを使って作成したゲームです。スマホから遊べるので、マルチタッチ可能なことを確認してみてください
参考