2012-06-08 9 views
6

में एक ईवेंट लूप को पास करें मैं एक एकल खिलाड़ी एमयूडी का निर्माण कर रहा हूं, जो मूल रूप से एक टेक्स्ट-आधारित मुकाबला गेम है। यह नेटवर्क नहीं है।उपयोगकर्ता इनपुट को अतुल्यकालिक रूप से पकड़ें और पाइथन

मुझे समझ में नहीं आता कि उपयोगकर्ता कमांड कैसे इकट्ठा करें और उन्हें मेरे ईवेंट लूप को असीमित रूप से पास करें। गेम इवेंट फायरिंग के रूप में किसी भी समय आदेश दर्ज करने में सक्षम होना चाहिए। तो raw_input का उपयोग करके प्रक्रिया को रोकना काम नहीं करेगा। मुझे लगता है कि मुझे कुछ चुनने की ज़रूरत है। चयन करें और थ्रेड का उपयोग करें।

नीचे दिए गए उदाहरण में, मेरे पास userInputListener() का एक मॉकअप फ़ंक्शन है, जहां मैं आदेश प्राप्त करना चाहता हूं, और यदि इनपुट है तो उन्हें क्यू कमांड में जोड़ दें।

अगर इस तरह के रूप में एक घटना पाश है:

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

क्या एमयूडी बहु-उपयोगकर्ता डंगऑन के लिए खड़ा नहीं है? मैं वैसे भी @AndrewGorcester से सहमत हूं, शायद पहिया को पुनर्निर्मित करने से बचना आसान होगा। –

उत्तर

2

आपको वास्तव में दो धागे की आवश्यकता होगी। मुख्य गेम लूप और उपयोगकर्ता इनपुट को संभालने के लिए एक से चिंतित होना चाहिए। दोनों Queue के माध्यम से संचार करेंगे।

आप अपनी मुख्य प्रक्रिया गेम लूप थ्रेड शुरू कर सकते हैं और उसके बाद इसे उपयोगकर्ता से टेक्स्ट की एक पंक्ति प्राप्त हो रही है और इसे कतार में "डाल" है (यानी runGame.start() के बाद)। यह रूप में सरल रूप में हो सकता है:

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

खेल पाश धागा बस हो जाएगा "geting" कतार, interpert से टेक्स्ट की पंक्ति में है और इसे निष्पादित।

पायथन के पास थ्रेड-सुरक्षित queue implementation है जिसका आप उपयोग कर सकते हैं (बहु-थ्रेडेड उपयोग के लिए एक बहुत ही बुनियादी उदाहरण सहित जिसे आप एक गाइड के रूप में उपयोग कर सकते हैं)।

एक अच्छा व्यावहारिक अवलोकन के लिए एक साधारण कमांड लाइन इंटरपरेटर मॉड्यूल (cmd module और here) भी है जो इस तरह के प्रोजेक्ट के लिए भी उपयोगी हो सकता है।

1

मैं एक pygame हनोई-visualiser कि इनपुट एसिंक्रोनस रूप here

पढ़ता बनाया महत्वपूर्ण पंक्तियां हैं:

#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() 
संबंधित मुद्दे