質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.44%
Pygame

Pygameは、ビデオゲームの製作用に設計されたクロスプラットフォームのPythonモジュールセットです。Pythonでコンピューターグラフィックスと音声を扱うためのライブラリが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Q&A

解決済

3回答

1412閲覧

Pygameとゲームパッドを用いた値の変更(ボタン長押しによって値が増減し続けるプログラム)

batakel

総合スコア1

Pygame

Pygameは、ビデオゲームの製作用に設計されたクロスプラットフォームのPythonモジュールセットです。Pythonでコンピューターグラフィックスと音声を扱うためのライブラリが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

0グッド

0クリップ

投稿2023/02/17 02:51

実現したいこと

  • Pygameとゲームパッドを用いた値の変更(ボタン長押しによって値が増減し続ける)

前提

Pythonで、ゲームパッドのボタン入力によって値が増減するプログラムを作成しております。
Pygameというモジュールを使用し、ゲームパッドのボタン入力(押した or 離した)を取得します。

下記コードで動作しないわけではないのですが、動作が不安定なため改善したいと考えております。
初めての質問となりますが、どうぞよろしくお願いいたします。

発生している問題・エラーメッセージ

  • 動作が安定しません。ボタンを押した際、処理が始まる場合とそうでない場合があります。

該当のソースコード

Python

1import pygame 2from pygame.locals import * 3import threading 4import time 5 6#Pygame関連の初期化 7pygame.init() 8pygame.joystick.init() 9joys = pygame.joystick.Joystick(0) 10joys.init() #ゲームパッドの初期化 11 12 13#ボタンを押した際に取得するe.buttonの値 14""" 15LBボタン:4 16RBボタン:5 17""" 18 19n1 = 512 #変更する値の初期値 20switch = 0 #ボタンから指が離れた状態の値を定義 21 22#ボタンを押したか離したかの判定 23def OnOff(): 24 while True: 25 global switch 26 for e in pygame.event.get(): 27 if e.type == pygame.locals.JOYBUTTONDOWN: #ボタンが押された場合 28 switch = 1 29 if e.type == pygame.locals.JOYBUTTONUP: #ボタンから指が離れた場合 30 switch = 0 31 32#0.5秒ごとに値をターミナルに表示 33def Display(): 34 while True: 35 print('現在値:{}'.format(n1)36 time.sleep(0.5) 37 38#ボタン押し離しの判定と現在値表示の開始 39Th1 = threading.Thread(target=OnOff) 40Th2 = threading.Thread(target=Display) 41Th1.start() 42Th2.start() 43 44#ボタン入力による値の変更 45while True: 46 for e in pygame.event.get(): 47 if e.type == pygame.locals.JOYBUTTONDOWN: 48 pushed = int(e.button) 49 50 if pushed == 4: 51 while switch == 1: #ボタンから指が離れるまで繰り返す 52 n1 += -1 53 if n1 < 0: 54 n1 = 0 #下限値の設定 55 time.sleep(0.2) #0.2秒ごとに1減少 56 57 if pushed == 5: 58 while switch == 1: #ボタンから指が離れるまで繰り返す 59 n1 += 1 60 if n1 > 1023: 61 n1 = 1023 #上限値の設定 62 time.sleep(0.2) #0.2秒ごとに1増加 63

試したこと

ボタン入力が受付けられる場合とそうでない場合があるのではと考え、以下の内容を試しましたが、改善できませんでした。
・値の増減を繰り返すtime.sleep(0.2)の前後にゲームパッド初期化(joys.init())を入れる
・各処理へのtime.sleep()の追加、および値の変更

補足情報(FW/ツールのバージョンなど)

Pythonのバージョン : Python 3.5.6
OS : Ubuntu 22.04 LTS 64ビット
メモリ : 16GB
プロセッサ : Intel® Core™ i7-10750H CPU @ 2.60GHz × 12

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

pygameは使ったことがないのですが、イベントの扱いに問題があるように思います。

pygame.event.get() はその時点で発生していたイベントを順に取りだすメソッドですが、これを メインループとOnOff()関数の両方で呼んでいます。
この実装だと、あるイベントはどちらかでしか取得できないはずなので、ボタン入力がどちらに入ったかによって受け付けられるかどうかが変っているのでしょう。

こういうイベント処理系のプログラムは、メインループでイベントの取得を行ない、イベントによって動作を振り分けるつくりにするのが一般的です。

投稿2023/02/17 04:43

TakaiY

総合スコア12955

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

batakel

2023/02/17 06:20

TakaiY様 ご回答いただきありがとうございました。解決しました。 ご指摘いただいた通り、pygame.event.get()をメインループとOnOff()関数の両方で使用しているのが原因だったようです。 お書きいただいた「メインループでイベントの取得を行ない、イベントによって動作を振り分けるつくりにする」という内容とは異なるかもしれませんが、下記のコードに修正したところ動作が安定しました。 本当にありがとうございました。 --- import pygame from pygame.locals import * import threading import time #Pygame関連の初期化 pygame.init() pygame.joystick.init() joys = pygame.joystick.Joystick(0) joys.init() #ゲームパッドの初期化 #ボタンを押した際に取得するe.buttonの値 """ LBボタン:4 RBボタン:5 """ n1 = 512 #変更する値の初期値 switch = 0 #ボタンから指が離れた状態の値を定義 #ボタンを押したか離したかの判定 def OnOff(): while True: global switch global e #追加箇所 for e in pygame.event.get(): if e.type == pygame.locals.JOYBUTTONDOWN: #ボタンが押された場合 switch = 1 if e.type == pygame.locals.JOYBUTTONUP: #ボタンから指が離れた場合 switch = 0 #0.5秒ごとに値をターミナルに表示 def Display(): while True: print('現在値:{}'.format(n1)) time.sleep(0.5) #ボタン押し離しの判定と現在値表示の開始 Th1 = threading.Thread(target=OnOff) Th2 = threading.Thread(target=Display) Th1.start() Th2.start() #ボタン入力による値の変更 while True: #for e in pygame.event.get(): #削除 if switch == 1: #修正 pushed = int(e.button) if pushed == 4: while switch == 1: n1 += -1 if n1 < 0: n1 = 0 time.sleep(0.2) if pushed == 5: while switch == 1: n1 += 1 if n1 > 1023: n1 = 1023 time.sleep(0.2)
guest

0

TakaiYさんのご指摘をもとに修正・解決したコードとなります。

Python

1import pygame 2from pygame.locals import * 3import threading 4import time 5 6#Pygame関連の初期化 7pygame.init() 8pygame.joystick.init() 9joys = pygame.joystick.Joystick(0) 10joys.init() #ゲームパッドの初期化 11 12 13#ボタンを押した際に取得するe.buttonの値 14""" 15LBボタン:4 16RBボタン:5 17""" 18 19n1 = 512 #変更する値の初期値 20switch = 0 #ボタンから指が離れた状態の値を定義 21 22#ボタンを押したか離したかの判定 23def OnOff(): 24 while True: 25 global switch 26 global e #追加箇所 27 for e in pygame.event.get(): 28 if e.type == pygame.locals.JOYBUTTONDOWN: #ボタンが押された場合 29 switch = 1 30 if e.type == pygame.locals.JOYBUTTONUP: #ボタンから指が離れた場合 31 switch = 0 32 33#0.5秒ごとに値をターミナルに表示 34def Display(): 35 while True: 36 print('現在値:{}'.format(n1)37 time.sleep(0.5) 38 39#ボタン押し離しの判定と現在値表示の開始 40Th1 = threading.Thread(target=OnOff) 41Th2 = threading.Thread(target=Display) 42Th1.start() 43Th2.start() 44 45#ボタン入力による値の変更 46while True: 47 #for e in pygame.event.get(): #削除 48 if switch == 1: #修正 49 pushed = int(e.button) 50 51 if pushed == 4: 52 while switch == 1: 53 n1 += -1 54 if n1 < 0: 55 n1 = 0 56 time.sleep(0.2) 57 if pushed == 5: 58 while switch == 1: 59 n1 += 1 60 if n1 > 1023: 61 n1 = 1023 62 time.sleep(0.2)

投稿2023/02/17 06:23

編集2023/02/17 06:25
batakel

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

TakaiY様

ご回答いただきありがとうございました。解決しました。
ご指摘いただいた通り、pygame.event.get()をメインループとOnOff()関数の両方で使用しているのが原因だったようです。

本当にありがとうございました。

投稿2023/02/17 06:18

編集2023/02/17 06:27
batakel

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.44%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問