2012-06-08 5 views
6

Sto costruendo un singolo giocatore MUD, che è fondamentalmente un gioco di combattimento basato su testo. Non è in rete.input dell'utente Grab in modo asincrono e passare ad un ciclo evento in python

Non capisco come raccogliere i comandi dell'utente e li passa nel mio ciclo di eventi in modo asincrono. Il giocatore deve essere in grado di inserire i comandi in qualsiasi momento mentre gli eventi di gioco stanno sparando. Quindi sospendere il processo usando raw_input non funzionerà. Penso di aver bisogno di fare qualcosa come select.select e usare i thread.

Nell'esempio seguente, ho una funzione di mockup di userInputListener(), che è dove mi piacerebbe ricevere i comandi, e aggiungerli al comando Que se c'è un input.

Se avere un ciclo di eventi quali:

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() 

Come faccio ad avere il mio input dell'utente in là?

O più semplicemente, qualcuno mi può mostrare alcun esempio di memorizzare l'input dell'utente, mentre un altro ciclo è in esecuzione allo stesso tempo? Posso capire il resto se possiamo arrivare così lontano.

+0

Is [ritorto] (http://twistedmatrix.com/) un'opzione? – sarnold

+2

Piuttosto che rotolare il tuo, potresti provare a usare PyGame o curses per gestire i tuoi input. –

+0

non Vuol MUD riposare per Multi-User Dungeon? Sono d'accordo con @AndrewGorcester comunque, sarebbe probabilmente più facile evitare di reinventare la ruota. –

risposta

2

Avrete infatti bisogno di due thread. Uno per occuparsi del ciclo di gioco principale e uno per gestire l'input dell'utente. I due sarebbero comunicanti attraverso una Queue.

È possibile impostare il processo principale per avviare il thread del ciclo di gioco e quindi ottenere una riga di testo dall'utente e "metterla in coda" (ad esempio, runGame.start()). Questo può essere semplice come:

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

Il gioco filo ciclo sarà semplicemente "geting" una linea di testo dalla coda, interpert ed eseguirlo.

Python dispone di un thread-safe queue implementation che è possibile utilizzare (incluso un esempio di base per l'utilizzo multi-thread che è possibile utilizzare come guida).

C'è anche un semplice modulo di interpolazione a linea di comando (il cmd module e here per una buona panoramica pratica) che potrebbe essere utile anche per questo tipo di progetto.

1

ho fatto un Pygame Hanoi-visualizzatore che legge l'input in modo asincrono here

Le linee importanti sono:

#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() 
Problemi correlati