进行乒乓球比赛时,球动画真的很乱

时间:2019-07-19 01:03:40

标签: python pygame pong

在运行程序时,球的动画非常不稳定,我不知道为什么。 这只是程序的开始,因此请忽略游戏尚未准备就绪的事实。

这是代码:https://www.codepile.net/pile/dqKZa8OG

我希望球顺畅地移动而不会卡死。 另外我该如何做,以便程序在每次更新后删除球的最后一个位置?

1 个答案:

答案 0 :(得分:0)

这不是计时器造成的“垃圾”,您只能看到更新,因为您可能同时移动了鼠标,然后每次移动时都在更新球的位置(这是错误的,因为每当处理 any 事件时都重新更新位置。

问题是您以错误的方式使用了Clockpygame.time.Clock类创建了一个«对象,该对象可用于跟踪一定的时间» ,这意味着它不是定时器,一旦超时就可以“反应”。您正在调用的tick方法仅根据您提供的fps参数更新当前Clock,并返回自上次调用tick本身以来经过了多少毫秒。

您需要的是设置一个计时器,可能是通过使用特定的事件ID来进行更新。此外,由于您是根据事件更新球的位置,因此,如果移动鼠标(或调用任何其他事件),即使不应该移动,球也会移动得更快,这就是您要做的。 '将需要Clock对象。

# I'm using a smaller speed, otherwise it'll be too fast; it should 
# depend on the window size to ensure that bigger windows don't get 
# slower speeds
ball_velocity = .2
fps = 60
UPDATEEVENT = 24

[...]

def start_move_ball(angle):
    ticks = clock.tick()
    speed = ball_velocity * ticks
    # "global ball" is not required, as you are assigning values to an 
    # existing object, not declaring it everytime.
    # You can also use in-place operations to set the speeds, which is 
    # better for readability too.
    ball[0] += angle[0] * speed
    ball[1] += angle[1] * speed

def main_loop():
    angle = choose_angle()
    pygame.time.set_timer(UPDATEEVENT, 1000 // fps)
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return False
            # update only if necessary!
            elif event.type == UPDATEEVENT:
                window.fill((0,0,0))
                start_move_ball(angle)
                draw_mid(window)
                draw_players(window)
                draw_ball(window)
                pygame.display.flip()

该计时器设置为while周期之外,因为它在每个时间间隔自动发送事件。您还可以将其保留在while (在这种情况下,实际上不需要once=True参数,因为它会基于相同的eventid自动更新计时器),但不会没什么意义,因为set_timer总是在第一次设置事件之后触发。
我使用24(pygame.USEREVENT)作为事件ID,但是您可以根据event文档中的建议将其ID设置为pygame.NUMEVENTS - 1。如果出于任何原因要停止计时器,只需使用pygame.time.set_timer(eventid, 0),该事件ID的计时器(在这种情况下为24)将不会再次启动。

除所有建议外,还有一些建议:

  1. 删除pygame.display.update()中的draw_mid(window)行,因为它在绘画时会引起闪烁。
  2. 避免使用外部服务链接代码(这不是您的情况,但是,如果代码太长,请首先尝试将其缩减为最小的,可重现的示例,最后保留所有相关部分),因为它们有时可能无法使用未来,使面临类似问题的人难以理解您的问题,并在发布问题后不久阅读了您的答案。