Невозможно вызвать событие «Мышь вниз» на цвет для запуска - PullRequest
2 голосов
/ 01 декабря 2019

Я создаю игру Avoider для школьного проекта, и я столкнулся со странной ошибкой, когда событие MOUSEBUTTONDOWN не сработает, когда курсор нажимает на зеленый цвет («цвет выигрыша»), даже если почти идентична версиятот же код работает , но с другим цветом.

Мой текущий код для цветовых событий:

        pos = pygame.mouse.get_pos()
    color_at_cursor = screen.get_at(pos)

    if event.type == pygame.MOUSEBUTTONDOWN and color_at_cursor == (0, 0, 255, 255):
        print("Game Start")
        start_clicked = True
    if start_clicked and color_at_cursor == (0, 228, 255, 255):
        died = True
    if died:
        screen.blit(ded, ded_rect)
        if event.type == pygame.MOUSEBUTTONDOWN:
            is_alive = False

  if start_clicked and event.type == pygame.MOUSEBUTTONDOWN and color_at_cursor == (0, 255, 0, 255):
      screen.blit(win_screen, win_rect)
      if event.type == pygame.MOUSEBUTTONDOWN:
          is_alive = False

, где проверяются первые 3 оператора ifесли была нажата синяя кнопка запуска, и если курсор касается голубого / светло-синего цвета смерти. Эти утверждения работают так, как они должны, но последнее утверждение, которое использует почти точно такую ​​же концепцию, не работает. При нажатии на зеленый ничего не происходит. Я пришел к выводу, что причина, по которой он не работает, заключается в том, что рассматриваемый зеленый цвет расположен на отдельном объекте, чем фон. Но это было все еще странно, потому что второе приведенное выше утверждение IF не привело к немедленной смерти, когда курсор завис над платформой (который окрашен не так, как голубой фоновый цвет смерти)

В любом случае, я попытался написатькод, который может обнаружить событие щелчка мыши определенного цвета поверх объекта. Как видно ниже:

if event.type == pygame.MOUSEBUTTONDOWN and start_clicked:
    x, y = event.pos
    if platform1.get_rect().collidepoint(x,y) and platform1.get_at((x, y)) == (0, 255, 0, 255):
        print("win button clicked")
        screen.blit(win_screen, win_rect)
        if event.type == pygame.MOUSEBUTTONDOWN:
            is_alive = False

И это все равно не привело к тому, что ничего не произошло. Кто-нибудь знает, почему я сталкиваюсь с этой проблемой, и как я могу это исправить?

1 Ответ

2 голосов
/ 02 декабря 2019

Во втором вашем фрагменте я не уверен на 100%, что такое platform1, но позвольте мне догадаться, что это поверхность, заполненная зеленым цветом.

Если это так, то, скорее всего, ошибкасмещение координат. Позвольте мне проиллюстрировать это следующим MCVE , который является упрощенной версией вашего второго фрагмента:

pygame.init()
screen = pygame.display.set_mode((800, 800))

platform1 = pygame.Surface((200, 200))
platform1.fill((0, 255, 0))
screen.blit(platform1, (300, 300))
pygame.display.update()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            x, y = event.pos
            if platform1.get_rect().collidepoint(x,y) and platform1.get_at((x, y)) == (0, 255, 0):
                print("win button clicked")

Теперь это создает зеленый квадрат в середине экрана, но когда выщелкните по нему, "win button clicked" не печатается (воспроизводит описанную вами ошибку).

Причина в том, что event.pos возвращает координаты мыши в экранной системе координат: то есть позиция (0, 0) равнаверхний левый угол окна экрана.
Однако прямоугольник, полученный из platform1.get_rect(), не знает, где на самом деле нарисован прямоугольник, поэтому его происхождение предполагается равным (0, 0) вместо того, чем оно является ((300, 300) в таком случае). Таким образом, у вас есть ошибка при обнаружении столкновения точек.

Если вы заменили последний if блок на:

    if event.type == pygame.MOUSEBUTTONDOWN:
        x, y = event.pos
        x -= 300
        y -= 300
        if platform1.get_rect().collidepoint(x,y) and platform1.get_at((x, y)) == (0, 255, 0):
            print("win button clicked")

Он работает, как ожидалось, потому что мы учли смещение (300, 300).

Это иллюстрирует проблему, но, конечно, не является хорошим способом ее решения, поскольку смещение жестко закодировано и не будет одинаковым для всех объектов. Лучший способ справиться с подобной ситуацией - использовать Sprite вместо просто Surfaces, которые можно использовать для последовательного отслеживания и положения объекта на экране.

...