0

だから私は2秒ごとに変数を変更したい関数(以下)を持っています。現在、この関数は2秒ごとに変数(goblinx)を変更する機能を果たしています。問題は、time.waitによってすべての関数が2秒間一時停止することです。関数movegoblin()のみを一時停止させるにはどうすればよいですか。

def movegoblin():
    global goblinx
    global gobliny
    x = 1
    if x == 1:
        goblinx += 32
        pygame.time.wait(200)
4

4 に答える 4

4

ここに行く方法は、プログラムでのゴブリン ?(およびその他の文字) の処理を​​関数から適切なクラスに改善して、内部状態を持つことができるようにすることです。

このような各クラスは、ゲーム フレームごとに更新される変数を持つことができ、カウントが値に達したときにアクションをトリガーします。

このソリューションは、タイミング アカウンティングのためだけに並行スレッドを追加するよりもクリーンであり、適切に実行すると、開発、拡張、および保守が楽になるアプリケーション設計につながる可能性があります。

コードの機能を維持しながら採用できるスタイルの簡単な例。(pygame.sprite.Sprite クラスを使用して、オブジェクト グループごとに「更新」メソッドを自動的に呼び出すことができることに注意してください。以下で最初から行います)

frame_delay = 20

class Goblin(object):
    def __init__(self):
        self.x = 1 #or whatever
        self.y = 1 #or whatever
        self.movement_count = 0
        self.move_at_each = 10

    def move(self):
        self.movement_count += 1
        if self.movement_count < self.move_at_each:
            return
        self.movement_count = 0
        self.x += 32

メイン ループでは、ゴブリンを次のようにインスタンス化します。

goblin = Goblin()、 while ループに入る前に、 goblin.move()各フレームで呼び出します。このようにして、適切なゴブリン クラスを作成できます。これにより、ゲームに複数の「ゴブリン」を含めることができますが、例のコードでは各文字をハード コーディングする必要があります。そして、ゲームの各フレームで「goblin.move」メソッドを呼び出すだけです。上記の例は、10 フレームごとに移動するように調整されていますが、これは変更できます (インスタンス化する個々のゴブリンごとに変更できます)。

私が言ったように、pygame は既にこの種の仕組みのフレームワークとして「スプライト」と「スプライト グループ」クラスを提供していますが、いくつかの小さなゲームで独自のものを展開すると、ニーズと pygame スプライトが既に提供しているものをよりよく理解するのに役立ちます。後のプロジェクト (またはこのプロジェクトの後の段階) でそれらを使用できるようにします。

于 2012-05-26T04:43:26.647 に答える
1

最も簡単な答え:

フレームごとにゴブリンで.update()関数を呼び出します。経過時間が200ミリ秒を超える場合は、彼を動かします。それ以外は何もしません。

class Unit():
    def __init__(self):
        self.update_delay = 200
        self.last_update = pygame.time.get_ticks()

    def update(self):
        # call once per game update.
        now = pygame.time.get_ticks()
        if now - self.last_update >= self.update_delay:
            self.last_update = now

            # update AI , pathfind , etc.
            self.x += 30
于 2012-05-27T17:02:12.430 に答える
0

ほとんどの人が最初に思いつく答えは、「あなたは間違った考え方をしている!」のようなものだと思います。-- これは、従来のゲーム開発アプローチに従う場合に実際に当てはまります。jsbueno と monkey は、通常どのようにそこに行くかを示しました。

問題に到達した方法で解決策を提供しようとするpythonプロジェクトを指摘したいだけです。主張は次のとおりです。現実の世界は並行的であるため、並行してモデル化する必要があります(直感的なアプローチが並行的であったという事実がこれを裏付けています)。

問題は、問題に対して実際のマルチスレッドアプローチを使用すると、競合状態などを考慮する必要があるため、解決するよりも多くの問題が確実に発生することです(したがって、sajattack の回答のミューテックス)。また、ゲームに数百のスプライト/オブジェクトがある場合の数百のスレッドのオーバーヘッド (これは大きな数ではありません。大きく考え始めたい場合は数万を考えてください) は、それを処理する貧弱なコンピューターにとっては過剰になる可能性があります。 .

そのため、stackless pythonというプロジェクトを開始した人もいます。彼らは、マルチスレッドを使用せずに並行してプログラミングできるツールを提供したいと考えていました。これにより、提案したようにプログラムでき、1 つの関数を待機させ、他の関数を実行し続けることができます。彼らがマイクロスレッドと呼ぶ背後にある概念プログラミングにおける並行思考を紹介する非常に優れた記事もあります。そのプロジェクトを調べたいと思うかもしれませんが、それにはいくつかの問題が残る可能性があります。

  1. 別のバージョンの Python インタープリターが必要です。Stackless は標準の c-python にも pypy にもありません。
  2. 別のインタープリターを使用すると、スタックレス python で記述されたゲームを配布することがより困難になります。
  3. ゲーム プログラミングの一般的でない方法を学ぶかもしれません。これは、将来重要になるかもしれません (または重要でないかもしれません)。実際のプログラマーと話したり、既存のゲームのソースを読んだりするときに問題が発生する可能性があります。最初に、またはスタックレスに加えて、古典的なゲーム プログラミングを行うことをお勧めします。
于 2012-06-08T16:24:22.003 に答える
-1
import _thread    
_thread.start_new_thread(movegoblin, ())

またはあなたが望むなら

import threading
threading.Thread(target=movegoblin).start() 

ロック付き:

mutex = _thread.allocate_lock()
def movegoblin():
    global goblinx
    global gobliny
    x = 1
    if x == 1:
        mutex.acquire()
        goblinx += 32
        pygame.time.wait(200)
        mutex.release()
于 2012-05-26T01:25:01.937 に答える