10

基本的にテキストベースの戦闘ゲームであるシングルプレイヤー MUD を構築しています。ネットワーク化されていません。

ユーザー コマンドを収集してイベント ループに非同期で渡す方法がわかりません。ゲーム イベントが発生している間、プレイヤーはいつでもコマンドを入力できる必要があります。そのため、raw_input を使用してプロセスを一時停止しても機能しません。select.select のようなことをしてスレッドを使用する必要があると思います。

以下の例では、userInputListener() のモックアップ関数を使用しています。ここでコマンドを受け取り、入力がある場合はそれらをコマンド Que に追加します。

次のようなイベント ループがある場合:

from threading import Timer
import time

#Main game loop, runs and outputs continuously
def gameLoop(tickrate):

    #Asynchronously get some user input and add it to a command que 
    commandQue.append(userInputListener())
    curCommand = commandQue(0)
    commandQue.pop(0)

    #Evaluate input of current command with regular expressions
    if re.match('move *', curCommand):
        movePlayer(curCommand)
    elif re.match('attack *', curCommand):
        attackMonster(curCommand)
    elif re.match('quit', curCommand):
        runGame.stop()
    #... etc    

    #Run various game functions...
    doStuff()

    #All Done with loop, sleep
    time.sleep(tickrate)

#Thread that runs the game loop
runGame = Timer(0.1, gameLoop(1))
runGame.start()

そこにユーザー入力を取得するにはどうすればよいですか?

もっと簡単に言えば、別のループが同時に実行されている間にユーザー入力を保存する例を誰か教えてもらえますか? そこまで行けば残りはわかる。

4

2 に答える 2

3

実際には 2 つのスレッドが必要になります。1 つはメインのゲーム ループに関係し、もう 1 つはユーザー入力を処理します。この 2 つはQueueを介して通信します。

メイン プロセスでゲーム ループ スレッドを開始し、ユーザーからテキスト行を取得して、それをキューに「配置」することができます (つまり、runGame.start() に従ってください)。これは次のように簡単です。

while not gameFinished:
    myQueue.put(raw_input()). 

ゲーム ループ スレッドは、単純にキューからテキスト行を「取得」し、解釈して実行します。

Python には、使用できるスレッドセーフなキューの実装があります (ガイドとして使用できるマルチスレッド使用の非常に基本的な例を含む)。

また、この種のプロジェクトに役立つかもしれない単純なコマンド ライン インターパーター モジュール ( cmd モジュールと、実用的な概要についてはこちら) もあります。

于 2012-06-08T01:56:24.243 に答える
2

ここで入力を非同期に読み取る pygame hanoi-visualiser を作成しました

重要な行は次のとおりです。

#creates an input buffer for stdin 
bufferLock=threading.Lock()
inputBuffer=[]

class StdinParser(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        global inputBuffer
        running = True
        while running:
            try:
                instruction=raw_input()
                bufferLock.acquire()
                if inputBuffer == False:
                    running = False
                else:
                    inputBuffer.insert(0,instruction)
                bufferLock.release()
            except EOFError:
                running = False
        pyglet.app.exit()

def check_for_input(dt):
    bufferLock.acquire()
    if len(inputBuffer)>0:
        instruction = inputBuffer.pop()
        parseLine(instruction,board)
    bufferLock.release()
于 2015-07-02T15:19:31.383 に答える