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

问题描述 投票:0回答:2

我正在尝试使用海龟制作一款太空入侵者游戏,为了将子弹向上移动到屏幕上,我尝试每 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()
python time turtle-graphics sleep
2个回答
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()

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

如果您需要比主循环间隔更慢地推进子弹,请制作一个“帧通过”计数器,看看是否

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 - 通过使用“圆形”形状和合适的尺寸,您可以“盖印”这个形状。优点:您可以简单地删除标记形状 - 通过其整数 ID。我从未与乌龟合作过 - 考虑一下这是否是一种轻松重绘玩家位置和/或子弹的方法

© www.soinside.com 2019 - 2024. All rights reserved.