反应时间

2024-09-27 21:28:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为学校做一个拳击项目,在那里你必须把敌人击倒,但敌人也每隔几秒钟攻击一次。当他要攻击时,它会显示一个感叹号,你必须快速反应才能阻止它。你知道吗

基本上我想要它做的是生成一个随机时间,在这个时间之后,当我没有足够快地按下按钮时,它执行一个命令(在我的情况下是一个攻击)。简而言之就是反应计时器。你知道吗

我使用多线程可以同时运行阻塞功能和敌人攻击功能。在未来我想添加一个线程,这样你就可以攻击。你知道吗

这是我的反应计时器:

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

运行程序时,我会遇到以下错误:

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

我对这一切都是新手,只编写了几个星期的代码,所以我真的很想知道我做错了什么,以及如何修复它。你知道吗

PS:对于这个项目,我不能使用扩展库。你知道吗


Tags: infrompyimportselftimeinitlib
1条回答
网友
1楼 · 发布于 2024-09-27 21:28:43

我觉得你应该避免把线程和turtle混合在一起,如果你可以不用使用turtle自己的ontimer()事件。下面是我对您的代码的重做,仅使用ontimer()来控制操作:

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

单击弹出的窗口使其处于活动状态,以便接收键盘事件。你知道吗

我相信您遇到的问题是Tkinter(turtle的基础)与线程交互如果您想走这条路,您可以查看Tkinter and Threads

相关问题 更多 >

    热门问题