前提・実現したいこと
私は、pyxelを利用してゲームを作りたいと考えています。
発生している問題・エラーメッセージ
ご質問したいのは、以下の処理についてです。
・ゲームクリア、ゲームオーバーと表示したx秒後にゲームを終了させる
・ゲーム開始時点からy分経過したら「タイムアップ」と表示し、表示したx秒後にゲームを終了する
以上2点について、datetimeやtimeをインポートする、ということのほかにどのようなことをすれば良いのかがわからず、肝心の文が書けずにいます。
上記の処理を行うためにどのような文を加えると良いのか、お教えいただけるとありがたいです。
補足情報(FW/ツールのバージョンなど)
プログラミングの経験が少なく、こちらのサイトを利用したこともなかったため、的外れな質問の仕方をしていたら申し訳ありません。どなたか回答よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/31 04:42 編集
回答2件
0
ベストアンサー
pyxel.frame_count
から経過時間を計算する
time() では、ラグ等の稀な条件下でバグの再現が困難になる場合、
時間よりも経過フレーム数から計算した方が都合が良いことも有ります。
pyxel.frame_count
は、update が呼ばれる度に増加する数値です。
sched
モジュールを使う
Python の標準ライブラリ イベントスケジューラ を
pyxel.frame_count をベースに使う方法の紹介。
概要:
例えば「10秒後に実行したい処理A」「1分後に実行したい処理B」がある場合、
後に実行する処理Bの時間を毎回確認するのは無駄が多く、
直近に実行したい処理Aの時間確認のみで良いはずです。
実行する時間でソート済みのリスト(優先度付きのキュー)で管理し、
最初に実行する処理の時間のみを確認するようにします。
ちなみに、Pythonの標準モジュールに、
優先度付きキューのアルゴリズムを実装した heapq モジュールがあり、
それを用いたイベントスケジューラの実装の sched モジュールがあります。
質問に対する直接的な回答ではありませんが、
汎用的な指定時間後に実行の方法。
python
1 2from sched import scheduler 3import pyxel 4 5class Timer: 6 def __init__(self, fps=20): 7 self.fps = fps 8 self.scheduler = scheduler(self.tick) 9 10 def tick(self): 11 return pyxel.frame_count 12 13 def update(self): 14 self.scheduler.run(blocking=False) 15 16 def call_later(self, interval, func, priority=1): 17 self.scheduler.enter( 18 interval*self.fps, 19 priority, 20 func 21 ) 22 23 def call_soon(self, func): 24 self.call_later(0, func) 25 26 def set_interval(self, interval, func): 27 def callback(): 28 if not func(): 29 self.call_later(interval, callback) 30 self.call_later(interval, callback) 31 32 def start_generator(self, gen): 33 def _next(): 34 interval = next(gen, None) 35 if interval is not None: 36 self.call_later(interval, _next) 37 self.call_soon(_next) 38 39 40class App: 41 def __init__(self, fps=20): 42 pyxel.init(200, 200, fps=fps) 43 self.timer = Timer(fps=fps) 44 45 ## 指定時間後に実行 46 # 約15秒後に終了 47 self.timer.call_later(15, pyxel.quit) 48 49 ## JavaScript の setInterval の様に 50 # 一定間隔毎に実行 51 # 毎秒カウント 1..10 52 self.num = 0 53 def count(): 54 self.num += 1 55 return self.num >= 10 56 self.timer.set_interval(1, count) 57 58 ## ジェネレーターを使い時間制御 59 # 10秒後に開始し、5秒間数値をカウント 60 def count_gen(): 61 yield 10 # 10秒sleep 62 for num in range(5): 63 self.num = 10 + num 64 yield 1 # 1秒間隔 65 self.timer.start_generator(count_gen()) 66 67 def update(self): 68 self.timer.update() 69 70 def draw(self): 71 pyxel.cls(7) 72 pyxel.text(10, 10, str(self.num), 10) 73 74 75if __name__ == "__main__": 76 app = App() 77 pyxel.run(app.update, app.draw) 78
要点
- scheduler のデフォルトの挙動では time を基準としてますが、
frame_count に差し替える事もできます。
- pyxel.run はイベントループを持ち、
scheduler.run も独自のイベントループを持ちます。
そのまま使うと競合して、片方しか実行されない状態になる為
scheduler の方をブロッキングしないようにする。
- フレーム数ではなく実時間ベースのタイマーにしたい場合は、
fps 関連の部分を省いてください。
ライブラリの提供するタイマーを使う
pyxel
については、ほぼ初見なので詳しくありませんが、
内部でSDLというライブラリを利用してるようなので、
SDLのタイマーをpyxel
経由で呼び出せないか調べてみる。
→ ソースコードを検索した限りではなさそう。
※ 但し、SDLのタイマーはOSのスレッドを用いる為、
移植性の事を考えて、敢えて採用してないかもしれません。
提供されてない場合は難しくなるので、他の方法で実装した方が良いです。
投稿2020/12/31 01:36
総合スコア8729
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/31 04:35
2020/12/31 05:49
2020/12/31 06:31
2020/12/31 06:35 編集
2020/12/31 06:38
2020/12/31 07:19
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。