2012-06-08 6 views
6

私は基本的にテキストベースの戦闘ゲームであるシングルプレイヤーMUDを構築しています。ネットワーク化されていません。ユーザ入力を非同期で取得し、Pythonのイベントループに渡す

私はユーザーコマンドを収集し、それらをイベントループに非同期で渡す方法を理解していません。プレイヤーは、ゲームイベントが発生するといつでもコマンドを入力できる必要があります。 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() 

の場合は、次のようなイベントループを持っていますか?

さらに簡単に言えば、誰かが別のループが同時に実行されている間にユーザー入力を格納する例を表示できますか?私達がそれを遠くに得ることができるなら、私は残りを理解することができます。

+0

は[ツイスト](http://twistedmatrix.com/)オプションですか? – sarnold

+2

あなた自身を動かすのではなく、PyGameやcursesを使って入力を処理してみてください。 –

+0

MUDはマルチユーザダンジョンを表していませんか?とにかく@AndrewGorcesterに同意すれば、おそらくホイールの再発明を避ける方が簡単でしょう。 –

答えて

2

本当に2つのスレッドが必要です。 1つはメインゲームループに関係し、もう1つはユーザー入力を処理するためのものです。 2人はQueueで通信しています。

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

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

ゲームループスレッドは、単にキューからテキスト行を取得し、それを実行します。

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

また、この種のプロジェクトにも役立つ簡単なコマンドラインインターペアモジュール(実用的な概要はcmd modulehere)があります。

1

私は重要なラインである非同期here

入力を読み取りpygameのハノイ・ビジュアライザ製:

#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() 
関連する問題