如何让我的代码等待点击?

时间:2017-06-18 12:56:24

标签: python loops pygame logic

我正在尝试为pvp战舰游戏编写代码而且我有点卡住了。

我先向您展示代码然后解释它们是如何工作的。

这是第一个代码。此功能用于在网格上定位每艘船:

def ship_builder(name):
# client ship value = 6, server ship value = 7
    v_or_h = randrange(2)
    if v_or_h == 0:
        vertical = True
    else:
        vertical = False

    if name == 'destroyer':
        print('Click a cell to build a destroyer.')
        if vertical == True:
            print('Vertical')
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    break
                if event.type == pygame.MOUSEBUTTONDOWN:
                    pos = pygame.mouse.get_pos()
                    col = (pos[0] // (cell_side + margin)) + 1
                    row = (pos[1] // (cell_side + margin)) + 1
                    grid[row][col] = 7
                    for i in range(3):
                        row += 1
                        grid[row][col] = 7

        elif vertical == False:
            print('Horizontal')
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    break
                if event.type == pygame.MOUSEBUTTONDOWN:
                    pos = pygame.mouse.get_pos()
                    col = (pos[0] // (cell_side + margin)) + 1
                    row = (pos[1] // (cell_side + margin)) + 1
                    grid[row][col] = 7
                    for i in range(3):
                        col += 1
                        grid[row][col] = 7

    elif name == 'frigate':
        print('Click a cell to build a frigate')
        if vertical == True:
            print('Vertical')
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    break
                if event.type == pygame.MOUSEBUTTONDOWN:
                    pos = pygame.mouse.get_pos()
                    col = (pos[0] // (cell_side + margin)) + 1
                    row = (pos[1] // (cell_side + margin)) + 1
                    grid[row][col] = 7
                    for i in range(2):
                        row += 1
                        grid[row][col] = 7
        elif vertical == False:
            print('Horizontal')
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    break
                if event.type == pygame.MOUSEBUTTONDOWN:
                    pos = pygame.mouse.get_pos()
                    col = (pos[0] // (cell_side + margin)) + 1
                    row = (pos[1] // (cell_side + margin)) + 1
                    grid[row][col] = 7
                    for i in range(2):
                        col += 1
                        grid[row][col] = 7

第二个是上述函数的for循环:

for ship in ['destroyer','frigate']:
    ship_builder(ship)
    color_change()

    #color_change() is a function that colors the responding cells for the ships.

这就是它们的工作方式。首先,ship_builder被称为船舶名称(例如,“战舰”)。代码所做的第一件事就是检查船是垂直放置还是水平放置。根据其值,用户可以单击一个单元格来确定位置。这是我遇到问题的地方;代码只是跳过那个部分而没有做任何事情。

我的问题是:为什么它跳过鼠标点击部分? pygame.event.get()不应该让Python'等待'动作吗?

我不确定我是否大幅解释过。如果我需要提供更多信息,请给我发表评论。我真的需要一些帮助!

谢谢!

1 个答案:

答案 0 :(得分:3)

答案简短: 不,pygame.event.get() -> EventList不应该'等待'采取行动。请改用pygame.event.wait() -> EventType

答案越长: Pygame使用一个事件队列来存储已发生的事件。我们来看看pygame.event.get()文档。

pygame.event.get()  
  get events from the queue 
  get() -> Eventlist  
  get(type) -> Eventlist
  get(typelist) -> Eventlist
     

这将获取所有消息并将其从队列中删除。如果给出类型或类型序列,则只从队列中删除这些消息。如果您只是从队列中获取特定事件,请注意队列最终可能会填满您不感兴​​趣的事件。

基本上,pygame.event.get()返回自上次调用以来发生的每个事件。如果我们的活动尚未发生,则不会在返回的EventList

但是还有另一个名为pygame.event.wait()的函数,它的行为与请求的方式相同(尽管它只返回一个事件)。

pygame.event.wait()
  wait for a single event from the queue
  wait() -> EventType instance
     

从队列中返回单个事件。如果队列为空,则此函数将等待,直到创建一个。返回后,事件将从队列中删除。

因此可以等待像

这样的mousedown事件
event_happened = False
while not event_happened:
    event = pygame.event.wait()
    if event.type == pygame.MOUSEBUTTONDOWN:
        do_something()
        event_happened = True

但是,我们需要仔细,因为正如文档中所述,事件已从队列中删除,这意味着所有不属于pygame.MOUSEBUTTONDOWN类型的事件都将迷路了。如果我们需要的话,我们必须处理它们或手动传递它们/安全它们。

这是更长的答案,但我有一个补充/警告。在这样的代码中的不同点处获取事件可能非常快速地导致混淆(例如,由于如上所述的丢失事件等)。在这种情况下的决定可能与程序中缺少主游戏循环有关(我无法确定,因为我不知道周围的代码,但当前的实现似乎暗示类似的东西)。

通常,在连续的主游戏循环中访问事件,这可能看起来像这样

while True:
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:
            build_ship_on_event(event)

        elif event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

build_ship_on_event(event)函数可能会尝试执行类似

的操作
def build_ship_on_event(event):
    if event_is_mouse_click(event):
        ship_builder(selected_ship_type, event.pos)

并在给定位置为之前选择的类型构建船舶(当然,检查船舶是否已经建造过,依此类推)。