while循环中的time.sleep函数会不断崩溃程序,解决方案或替代方法?

时间:2017-12-09 18:02:05

标签: python time crash sleep turtle-graphics

我正在尝试使用乌龟制作太空入侵者游戏,并且为了将子弹移动到屏幕上,我试图每0.5秒更新一次子弹的y坐标。我尝试使用while循环和time.sleep()函数执行此操作,但每次尝试触发子弹时,程序都会崩溃。有什么方法可以阻止它这样做吗?或者为什么它不起作用?是否有一个同样有效的方法不会崩溃我的程序?

import turtle
import time

userx = 0

x = 0
y = -300

enemies = [(300,50, "left"), (400,50, "left"), (350, -50, "right")]

bullets = []

gameover = False

def frame():
    pass
    ship = turtle.Turtle()
    ship.pu()
    ship.ht()
    ship.setpos(userx, -300)
    ship.pd()
    ship.circle(5)

    bullet = turtle.Turtle()
    bullet.pu()
    bullet.ht()
    bullet.setpos(x, y)
    bullet.pd()
    bullet.circle(2)

def key_left():
    global userx
    pass
    userx += -10
    print(userx)

def key_right():
    global userx
    pass
    userx += 10
    print(userx)

def key_space():
    pass # your code here
    global x
    global y
    global bullets
    x = userx
    while y <= 300:
        time.sleep(0.5)
        y += 4
    else: y = 0
    bullets += (x,y)

def physics():
    global bullets
    global enemies
    pass

def ai():
    global enemies
    global gameover
    pass

def reset():
    global enemies
    global bullets
    global userx
    global gameover
    pass

def main():
    turtle.tracer(0,0)
    turtle.hideturtle()
    turtle.onkey(key_left, "Left")
    turtle.onkey(key_right, "Right")
    turtle.onkey(key_space, "space")
    turtle.listen()
    reset()
    while not gameover:
        turtle.clear()
        physics()
        ai()
        frame()
        turtle.update()
        time.sleep(0.05)

main()

2 个答案:

答案 0 :(得分:1)

我会:

def key_space():
    # simply spawn a new bullet and put it into your bullets list 

def advance_bullet(): # call this after paintnig all bullets in frame 
    # iterate over all bullets inside bullets, advance the Y position by 3

def frame(): 
    # add code to paint all bullets inside bullets - and call advance_bullets()

在检查与敌人发生碰撞的代码中:

# remove a bullet from bullets when its outside your screen (or passed all enemies max y coord) - no need to track that bullet anymore

如果你需要推进子弹的速度较慢,那么你的主循环就会进行干涉,制作一个&#34; framespassed&#34;反击并查看是否framespassed % something == 0然后才推进你的子弹。

适应您已有的

您需要更改这些部分:

def frame():
    global bullets
    pass
    ship = turtle.Turtle()
    ship.pu()
    ship.ht()
    ship.setpos(userx, -300)
    ship.pd()
    ship.circle(5)

    # debugging all bullets: 
    # print(bullets) # remove this

    for idx in range(0,len(bullets)): # paint ALL bullets in the bullets list
        bulletTurtle = turtle.Turtle()
        b = bullets[idx] # current bullet we are painting
        bulletTurtle.pu()
        bulletTurtle.ht()
        bulletTurtle.setpos(b[0], b[1])
        bulletTurtle.pd()
        bulletTurtle.circle(2)
        b[1] += 13 # quick and dirty approach, move bulltet after painting
                   # to save another complete bullets-foreach-loop 

    # quick n dirty bullet removal for out of screen bullets
    # normally I would do this probably in your "check if enemy hit" 
    # method as you are going over bullets there as well and can remove
    # them as soon as they passed all enemies 
    bullets = [x for x in bullets if x[1] < 500] 


def key_space():
    global x
    global y
    global bullets
    bullets.append([userx,-300]) # start a new bullet at current player position

编辑:

您可能需要查看turtle.shape,turtle.size和turtle.stamp - 使用&#34;圈&#34;形状和尺寸适合,你可能会&#34;盖章&#34;这个形状下来。优点:您可以简单地删除标记的形状 - 通过其integer-id。我还没有和乌龟一起工作 - 如果这样可以轻松重绘你的球员位置和/或子弹,那就考虑一下自己

答案 1 :(得分:1)

这不理想,但它开始工作。

key_space中,您只需将新子弹添加到列表中 在while not gameover你运行的功能将移动所有子弹 在frame中,您可以绘制所有项目符号。

import turtle
import time

userx = 0

x = 0
y = -300

enemies = [(300,50, "left"), (400,50, "left"), (350, -50, "right")]

bullets = []

gameover = False

def frame():
    pass
    ship = turtle.Turtle()
    ship.pu()
    ship.ht()
    ship.setpos(userx, -300)
    ship.pd()
    ship.circle(5)

    # redraw bullets
    for x, y in bullets:
        bullet = turtle.Turtle()
        bullet.pu()
        bullet.ht()
        bullet.setpos(x, y)
        bullet.pd()
        bullet.circle(2)

def key_left():
    global userx
    pass
    userx += -10
    print(userx)

def key_right():
    global userx
    pass
    userx += 10
    print(userx)

def key_space():
    pass # your code here
    global x
    global y
    global bullets
    x = userx

    # add bullet to list
    bullets.append([x, -300])

def move_bullets():
    global bullets

    live_bullets = []

    # move every bullet and check if should still live
    for x, y in bullets:
        y += 4

        # keep only some bullets and other forget (kill/remove)
        if y <= 300:
            live_bullets.append([x, y])

    bullets = live_bullets

def physics():
    global bullets
    global enemies
    pass

def ai():
    global enemies
    global gameover
    pass

def reset():
    global enemies
    global bullets
    global userx
    global gameover
    pass

def main():
    turtle.tracer(0,0)
    turtle.hideturtle()
    turtle.onkey(key_left, "Left")
    turtle.onkey(key_right, "Right")
    turtle.onkey(key_space, "space")
    turtle.listen()
    reset()
    while not gameover:
        turtle.clear()
        physics()
        ai()
        move_bullets() # <--  move bullets (or maybe before physics)
        frame()
        turtle.update()
        time.sleep(0.05)

main()