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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Pygame

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1516閲覧

ランダムなタイミングでheapq.heappushの処理を行わせたい

kappar

総合スコア12

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Pygame

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

1クリップ

投稿2020/07/06 06:49

前提・実現したいこと

python(pygame)を使ってキー押しで図形が動くものを作っています。
ランダムなタイミングで、キー押しと図形が動くまでのタイミングに遅延を持たせたいと思っています。不意にキー押しと図形の動くタイミングに遅延が生じてほしいです。

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

キー押しと図形が動くまでのタイミングに遅延を持たせることはできましたが、試行中ずっと遅延が生じてしまいます。
始まってから5秒後~25秒後の間にランダムなタイミングで遅延をもたせたいのですが、どのような方法があるかをご教授いただきたいです。
以下のコードは試行中常に0.5秒の遅延が生じています。

エラーメッセージ

該当のソースコード

python

1import pygame 2from pygame.locals import * 3import sys 4import time 5import heapq 6 7delay_inputs = [] 8 9start=time.time() 10 11BLACK = (0, 0, 0) 12RED = (255, 0, 0) 13WHITE = (255, 255, 255) 14 15pygame.init() #初期化 16screen = pygame.display.set_mode((640, 500)) #画面サイズ 17myclock = pygame.time.Clock() 18myclock.tick(30) 19pygame.display.flip() 20 21x =320 #circleの初期位置指定 22 23 24while True: 25 time.sleep(0.1) 26 screen.fill(BLACK) 27 pygame.draw.circle(screen, RED, (x, 400), 5) #円 28 pygame.display.update() 29 for event in pygame.event.get(): 30 if event.type==pygame.QUIT: 31 pygame.quit() 32 sys.exit() 33 now = pygame.time.get_ticks() 34 if delay_inputs and delay_inputs[0][0] <= now: 35 _, key_input = heapq.heappop(delay_inputs) 36 if key_input == "left": 37 x -= 5 38 elif key_input == "right": 39 x += 5 40 pressed_key=pygame.key.get_pressed() 41 if (pressed_key[K_LEFT] and x>0): 42 heapq.heappush(delay_inputs, (now+500, "left")) #ここで遅延時間 43 if (pressed_key[K_RIGHT] and x<640): 44 heapq.heappush(delay_inputs, (now+500, "right")) 45 if pressed_key[K_ESCAPE]: 46 pygame.quit() 47 sys.exit() 48 if time.time()-start>30: 49 pygame.quit() 50 sys.exit()

試したこと

pygame.time.set_timer を使ってみましたが、eventの書き方がよくわかりませんでした。
一応pygame.time.set_timerを使用してみたコードも載せておきます。

while文の中の
pygame.time.set_timer(heapq.heappush, random.randint(min_time, max_time))
において
TypeError: an integer is required (got type builtin_function_or_method)
というエラーが表示されます。

python

1import pygame 2from pygame.locals import * 3import sys 4import time 5import heapq 6import random 7 8delay_inputs = [] 9 10start=time.time() 11 12BLACK = (0, 0, 0) 13RED = (255, 0, 0) 14WHITE = (255, 255, 255) 15 16pygame.init() #初期化 17screen = pygame.display.set_mode((640, 500)) #画面サイズ 18myclock = pygame.time.Clock() 19myclock.tick(30) 20pygame.display.flip() 21 22x =320 #circleの初期位置指定 23 24 25while True: 26 time.sleep(0.1) 27 screen.fill(BLACK) 28 pygame.draw.circle(screen, RED, (x, 400), 5) #円 29 pygame.display.update() 30 for event in pygame.event.get(): 31 if event.type==pygame.QUIT: 32 pygame.quit() 33 sys.exit() 34 now = pygame.time.get_ticks() 35 if delay_inputs and delay_inputs[0][0] <= now: 36 _, key_input = heapq.heappop(delay_inputs) 37 if key_input == "left": 38 x -= 5 39 elif key_input == "right": 40 x += 5 41 pressed_key=pygame.key.get_pressed() 42 if (pressed_key[K_LEFT] and x>0): 43 heapq.heappush(delay_inputs, (now+500, "left")) #ここで遅延時間 44 min_time, max_time = 5000, 20000 # 5 seconds to 20 seconds 45 pygame.time.set_timer(heapq.heappush, random.randint(min_time, max_time)) 46 if (pressed_key[K_RIGHT] and x<640): 47 heapq.heappush(delay_inputs, (now+500, "right")) 48 min_time, max_time = 5000, 20000 # 5 seconds to 20 seconds 49 pygame.time.set_timer(heapq.heappush, random.randint(min_time, max_time)) 50 if pressed_key[K_ESCAPE]: 51 pygame.quit() 52 sys.exit() 53 if time.time()-start>30: 54 pygame.quit() 55 sys.exit() 56

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

ここにより詳細な情報を記載してください。

teamikl👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

始まってから5秒後~25秒後の間にランダムなタイミングで遅延をもたせたいのですが、どのような方法があるかをご教授いただきたいです。

  • 「キー入力から」の遅延が5~25秒のランダムという事ですか?
  • 「プログラムが起動してから」5~25秒後に遅延が有効になるという事ですか?

前者であれば now+500 の +500の部分をランダムな値にするだけです。
後者の場合、アイデアの一つとしてですが、

  • 遅延時間を返す関数 getRandomDelay を実装し、ローカル変数 getDelay に代入します
  • 遅延なしの場合は遅延時間 +0 として、遅延時間 0 を返す関数 getNoDelay を実装します
  • 開始時の初期状態: getDelay = getNoDelay
  • 5秒後に "delay-random" として、getDelay = getRandomDelay
  • 25秒後に "delay-none" として getDelay = getNoDelay

python

1 2from functools import partial 3getNoDelay = lambda: 0 4getRandomDelay = partial(random.randint, 500, 2000) # 0.5秒~2秒の遅延 5getDelay = getNoDelay 6 7now = pygame.time.get_ticks() 8heapq.heappush(delay_inputs, (now+5000, "delay-random")) # 5秒後にランダム遅延を有効にする 9heapq.heappush(delay_inputs, (now+25000, "delay-none")) # 25秒後に遅延オフ (0ms 遅延) 10 11while True: 12 ... # 省略 13 14 if delay_inputs and delay_inputs[0][0] <= now: 15 _, key_input = heapq.heappop(delay_inputs) 16 if key_input == "left": 17 x -= 5 18 elif key_input == "right": 19 x += 5 20 elif key_input == "delay-random": 21 getDelay = getRandomDelay 22 elif key_input == "delay-none": 23 getDelay = getNoDelay

python

1heapq.heappush(delay_inputs, (now+getDelay(), "right"))

のように使います。getDelay関数は
delay_inputsで処理する遅延により 5秒後と25秒後に切り替わります。


注意点

起動時間は、ファイルの先頭に

start = time.time()

とありますが、pygame.time.get_ticks() と混ぜないように注意。
pygame.time.get_ticks() は pygame.init() からの経過時間(ms)です。


pygame.time.set_timer(heapq.heappush, random.randint(min_time, max_time))

set_timer については、一定時間毎に定期的にイベントを発生させるといった使い方をします。
直接関数を登録したりはしませんし、また heappush の使い方も違います。

set_timerにより生成されるイベントは

for event in pygame.event.get():

のイベントループ内で処理します。

一度のみのイベントにすれば遅延処理にも使えますが、
毎回タイマーを解除しなければならない為、コードが冗長になりがちです。

投稿2020/07/10 05:24

teamikl

総合スコア8664

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

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

kappar

2020/07/13 02:58

非常に丁寧にご回答いただきありがとうございます…! 教えていただいたもので無事に動きました! (返答が遅くなってしまい申し訳ございませんでした)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問