2017-06-11 2 views
1

Ich mache ein Box-Programm für die Schule, wo Sie den Feind knock-out schlagen müssen, aber der Feind auch angreifen alle paar Sekunden. Es zeigt ein Ausrufezeichen an, wenn er angreift und Sie müssen schnell reagieren, um es zu blockieren.Reaktion Timer Fehler

Grundsätzlich, was ich will, ist es, eine zufällige Zeit zu erzeugen, nach der es einen Befehl ausführt (ein Angriff in meinem Fall), wenn ich einen Knopf nicht schnell genug drücke. Ein Reaktionszeitgeber kurz.

Ich benutzte Multithreading, um die blockierende Funktion und die feindliche Angriffsfunktion gleichzeitig ausführen zu können. In der Zukunft möchte ich einen Thread hinzufügen, damit Sie angreifen können.

Dies ist meine Reaktion Timer:

from random import * 
from turtle import * 
from time import * 
from threading import * 

def Reaction(): 
    vTime = 0 
    while vTime < 3: #The time in which you have to react 
     vNow = time() 
     vStep = vNow + 0.25 
     while time() < vStep: 
      vJack = True #Useless arguments to fill up the time between each step 
      vJack = False 
     vTime += 0.25 
     print(vTime) 
     if vReaction == True: #Checking if you have pressed the key 
      print("Oke") 
      break 
    print("af") 

def key(): 
    global vReaction 
    vReaction = True 

def Block(): 
    global vTimer 
    while vTimer < 5: 
     onkey(key, "space") 
     listen() 

def AttackEnemy(): 
    global vTimer 
    while vTimer < 5: 
     vHitTime = randrange(4, 12)/4 * 1000 # Generating the random time after which the enemy is going to hit 
     ontimer(Reactie, vHitTime) 
     vTimer += 1 


vTimer = 0 
vBlock = Thread(target = Block, args =()) 
vAttack = Thread(target = AttackEnemy, args =()) 

vBlock.start() 
vAttack.start() 

vBlock.join() 
vAttack.join() 

print("End") 

Wenn das Programm, das ich diese Fehler zum Laufen bringen:

Exception in thread Thread-2: 
Traceback (most recent call last): 
    File "D:\Programma's\Python\lib\threading.py", line 916, in _bootstrap_inner 
    self.run() 
    File "D:\Programma's\Python\lib\threading.py", line 864, in run 
    self._target(*self._args, **self._kwargs) 
    File "G:\test getal.py", line 35, in AanvalVijand 
    ontimer(Reactie, vSlagtijd) 
    File "<string>", line 6, in ontimer 
    File "D:\Programma's\Python\lib\turtle.py", line 3662, in Screen 
    Turtle._screen = _Screen() 
    File "D:\Programma's\Python\lib\turtle.py", line 3690, in __init__ 
    TurtleScreen.__init__(self, _Screen._canvas) 
    File "D:\Programma's\Python\lib\turtle.py", line 985, in __init__ 
    "blank" : Shape("image", self._blankimage()) 
    File "D:\Programma's\Python\lib\turtle.py", line 470, in _blankimage 
    img = TK.PhotoImage(width=1, height=1) 
    File "D:\Programma's\Python\lib\tkinter\__init__.py", line 3539, in __init__ 
    Image.__init__(self, 'photo', name, cnf, master, **kw) 
    File "D:\Programma's\Python\lib\tkinter\__init__.py", line 3495, in __init__ 
    self.tk.call(('image', 'create', imgtype, name,) + options) 
RuntimeError: main thread is not in main loop 

ich all dies bin neu und nur gerade Code für ein paar Wochen Ich möchte wirklich wissen, was ich falsch mache und wie ich es beheben kann.

PS: für das Projekt kann ich keine erweiterten Bibliotheken verwenden.

Antwort

0

Ich denke, Sie sollten vermeiden, Threading mit Schildkröte zu mischen, wenn Sie nur mit turtle eigenen ontimer() Ereignis durchkommen können. Hier ist meine Nacharbeiten des Codes mit nur ontimer() die Aktion zu steuern:

from random import randrange 
from turtle import Turtle, Screen 

vStep = 0.25 # in seconds 
FONT = ('Arial', 18, 'normal') 
ROUNDS = 3 
TIME_PER_ROUND = 5 # in seconds 
TIME_BETWEEN_ROUNDS = 2 # in seconds 

def StartAttack(): 
    global vTimer, vReaction 

    magicMarker.undo() 
    magicMarker.write("!", align='center', font=FONT) 

    vTimer = 3 # you now have 3 seconds to react 
    vReaction = False 
    Reaction() 

def Reaction(): 
    global vTimer 

    if vTimer > 0: # The time in which you have to react 

     if vReaction: # Check if you have pressed the key 
      magicMarker.undo() 
      magicMarker.write("Reacted in time!", align='center', font=FONT) 
     else: 
      vTimer -= vStep 
      screen.ontimer(Reaction, int(vStep * 1000)) # recheck in vStep seconds 
    else: 
     magicMarker.undo() 
     magicMarker.write("Didn't react in time!", align='center', font=FONT) 

def key(): 
    global vReaction 
    vReaction = True 

def Block(): 
    screen.onkey(key, 'space') 
    # disable above event handler in after round ends 
    screen.ontimer(lambda: screen.onkey(None, 'space'), int(TIME_PER_ROUND * 1000)) 

def AttackEnemy(): 
    global vTimer 

    vTimer = -1 
    # Generate random time after which the enemy is going to hit 
    vHitTime = randrange(4, 12)/4 * 1000 
    screen.ontimer(StartAttack, int(vHitTime)) 

def NextRound(): 
    global vRounds 

    if vRounds > 0: 

     magicMarker.undo() 
     magicMarker.write(" ", align='center', font=FONT) 

     Block() 

     AttackEnemy() 

     vRounds -= 1 

     screen.ontimer(NextRound, int((TIME_PER_ROUND + TIME_BETWEEN_ROUNDS) * 1000)) 
    else: 
     magicMarker.undo() 
     magicMarker.write("Match Over!", align='center', font=FONT) 

screen = Screen() 
screen.listen() 

magicMarker = Turtle(visible=False) 
magicMarker.write(" ", align='center', font=FONT) 

vTimer = -1 # just to make these exist 
vReaction = None 
vRounds = ROUNDS 

NextRound() 

screen.mainloop() 

Klicken Sie auf das Fenster, das zu machen, erscheint aktiv, so kann es Tastaturereignisse empfangen.

Ich glaube, das Problem, das Sie in lief ist Tkinter (Untermauerung der Schildkröte) mit den Fäden in Wechselwirkung - wenn Sie diesen Weg gehen wollen, können Sie Tkinter and Threads Besuche

+0

Die screen.listen() funktioniert nicht Stoppen Sie das Programm, bis Sie eine Taste gedrückt haben? – Rek3beef21

+0

@ Rek3beef21, nein. Es aktiviert einfach das Fenster, um Schlüsselereignisse zu empfangen, die es standardmäßig nicht aktiviert ist. Laut der Dokumentation "Fokus auf TurtleScreen setzen (um Schlüsselereignisse zu sammeln)." Sie rufen es nur einmal in einem Programm auf, wenn überhaupt. – cdlane

+0

Ich hätte fast vergessen, Ihnen für Ihre Ratschläge und Korrekturen zu danken. Danke vielmals!! – Rek3beef21