Python中的Turtle(Ball)是否保持一致的速度? (傍)

时间:2019-06-26 20:48:38

标签: python python-3.x

我在 Python 3 中使用 Turtle模块对Pong进行了编程,但球的速度并不一致。它会随机减速,然后加速,然后减速。它不可能是我的笔记本电脑,因为如果我可以完美运行《孤岛惊魂5》而没有问题,那么我就看不到一个笨拙的Pong游戏如何无法顺利运行。当我的笔记本电脑在充电器上运行时,它运行起来会更流畅一些,但是仍然存在一些加速,减速,加速问题。

import turtle 

# Window Set Up
wn = turtle.Screen()
wn.title("Pong")
wn.bgcolor("black")
wn.setup(width=800, height=600)
wn.tracer(0)

# Paddle A 
paddle_a = turtle.Turtle()
paddle_a.speed(0)
paddle_a.shape("square")
paddle_a.shapesize(stretch_len=1, stretch_wid=5)
paddle_a.color("white")
paddle_a.penup()
paddle_a.goto(-350, 0)

# Paddle B
paddle_b = turtle.Turtle()
paddle_b.speed(0)
paddle_b.shape("square")
paddle_b.shapesize(stretch_len=1, stretch_wid=5)
paddle_b.color("white")
paddle_b.penup()
paddle_b.goto(350, 0)

# Ball
ball = turtle.Turtle()
ball.speed(0)
ball.shape("circle")
ball.color("white")
ball.penup()
ball.goto(0, 0)
ball_dx = .2
ball_dy = .2

# Paddle A Up
def paddle_a_up():
    y = paddle_a.ycor()
    y += 35
    paddle_a.sety(y)

# Paddle A Down
def paddle_a_down():
    y = paddle_a.ycor()
    y -= 35
    paddle_a.sety(y)

# Paddle B Up
def paddle_b_up():
    y = paddle_b.ycor()
    y += 35
    paddle_b.sety(y)

# Paddle B Down
def paddle_b_down():
    y = paddle_b.ycor()
    y -= 35
    paddle_b.sety(y)

# Keyboard Bindings
wn.listen()
wn.onkeypress(paddle_a_up, "w")
wn.onkeypress(paddle_a_down, "s")
wn.onkeypress(paddle_b_up, "Up")
wn.onkeypress(paddle_b_down, "Down")





# Main Loop
while True:
    wn.update()

    # Make The Ball Move
    ball.setx(ball.xcor() + ball_dx)
    ball.sety(ball.ycor() + ball_dy)

    # Border Collisions 
    if ball.ycor() > 290:
        ball_dy *= -1
    if ball.ycor() < -290:
        ball_dy *= -1
    if ball.xcor() > 390:
        ball.goto(0, 0)
        ball_dx *= -1
    if ball.xcor() < -390:
        ball.goto(0, 0)
        ball_dx *= -1

    # Paddle Collisions 
    if (ball.xcor() < 350 and ball.xcor() > 340) and (ball.ycor() < paddle_b.ycor() + 50 and ball.ycor() > paddle_b.ycor() - 50):
        ball.setx(340)
        ball_dx *= -1
    if (ball.xcor() > -350 and ball.xcor() < -340) and (ball.ycor() < paddle_a.ycor() + 50 and ball.ycor() > paddle_a.ycor() - 50):
        ball.setx(-340)
        ball_dx *= -1

Pastebin Link

1 个答案:

答案 0 :(得分:1)

据我观察,问题在于,当您调用窗口更新函数时,它不会等到显示下一帧,因此,在更新窗口之后,将立即执行while循环中的下一步在显示最后一个屏幕之前。这意味着对于屏幕的每一帧,不仅绘制单个屏幕,而且实际上,您的程序将绘制尽可能多的屏幕。由于您的逻辑与框架相关联,并且由于while循环中计算机可以处理的步骤数量将取决于外部因素(即其他程序的CPU使用率),因此不会为显示的每个框架处理步骤数量一致并导致您观察到的行为。而且这效率很低,因为您正在绘制许多甚至都不会显示的帧!

要获得更一致的行为,您可以在循环中添加足够长的暂停时间,以抵消计算时间的可变性并避免绘制无用的帧。您可以使用time

import time

# Initialization
...

while True:
   time.sleep(1 / 60)

   # The rest of your game logic
   ...

您还可以将自己的逻辑与经过的时间联系起来,而不是将球每步移动恒定量

last_time = time.perf_counter()
ball_xspeed = 10

while True:
   current_time = time.perf_counter()
   elapsed_time = current_time - last_time
   last_time = current_time

   ball.setx(ball.xcor() + ball_xspeed * elapsed_time)
   ... # Update the rest of the variables