2016-10-15 2 views
0

У меня проблема с pygame. Я установил окно, которое случайно размещает круги по экрану очень быстро, только для целей тестирования. Существуют также три кнопки: воспроизведение/пауза (переключатели вперед и назад, прекращение появления кругов) и кнопка увеличения скорости и уменьшения скорости. Я не очень опытный с питоном или Pygame, но я придумал эту функцию для создания интерактивных кнопок на экране:Pygame отвечает неправильно на нажатия кнопок

def makeButton(rect, color, hovercolor, text, textsize, textcolor): 
    clicked = False 
    for event in pygame.event.get(): 
     if event.type == pygame.MOUSEBUTTONDOWN: 
      clicked = True 

    mouse = pygame.mouse.get_pos() 
    rect = pygame.Rect(rect) 
    displaycolor = color 
    if rect.collidepoint(mouse): 
     displaycolor = hovercolor 

    buttonSurface = pygame.draw.rect(gameDisplay, displaycolor, rect, 0) 
    font = pygame.font.Font('freesansbold.ttf',textsize) 
    TextSurf = font.render(text, True, textcolor) 
    TextRect = TextSurf.get_rect() 
    TextRect.center = rect.center 
    gameDisplay.blit(TextSurf, TextRect) 
    if clicked: 
     return True   
    else: 
     return False 

Эта функция может определенно быть сокращен и упрощен, но он работал меня, до сих пор. Я вынул большой кусок кода, который, как я понял, был бесполезным (имея совершенно другой блок кода для визуализации кнопки при наведении курсора, а не только изменение цвета дисплея). Теперь, всякий раз, когда я нажимаю любую из трех ранее упомянутых кнопок, кажется, что выбрал случайный вариант и вернул True, испортил остальную часть программы. Например, кнопка воспроизведения будет увеличивать скорость один раз, нажатие уменьшает скорость паузы и т. Д. Иногда это делает то, что предполагается, но это кажется случайным.

Некоторой дополнительная информация, если это полезно:

-Эты функция вызывается три раза каждый тик. Он находится внутри цикла, и если он возвращает true, его соответствующие действия должны выполняться (пауза или игра в игру, увеличение/уменьшение скорости).

-Кнопка воспроизведения/паузы - это одна кнопка, которая переключается между зеленым цветом с помощью кнопки «играть» стрелку, а красный - с символом паузы. Это две отдельные кнопки и функции, и только один из них выполняется одновременно.

-У меня почти нет опыта работы с классами, поэтому они могут быть лучше справляться с этой ситуацией.

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

+0

запускайте его только один раз в каждом тике. Изучайте классы. Теперь вы создаете время действия кнопок на кнопках, но вы можете сделать две поверхности - нормальные и зависающие - только один раз перед циклом. А затем в цикле вы можете разбрызгать различную поверхность, зависящую от 'clicked' – furas

ответ

1

«pygame.event.get()» принимает по одному событию за раз и * очищает его ** из списка событий, которые необходимо обработать.

Таким образом, pygame.event.get() возвращает каждое событие только раз.

Взгляните на следующий код:

clicked = False 
for event in pygame.event.get(): 
    if event.type == pygame.MOUSEBUTTONDOWN: 
     clicked = True 

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

  1. Первое событие, event.KEYDOWN, помещается в переменную "событие".
  2. Программа проверяет, равно ли событие «событие» (в настоящее время равно event.KEYDOWN) event.MOUSEBUTTONDOWN. Очевидно, это не одно и то же, поэтому следующая строка пропускается.
  3. Второе событие event.MOUSEBUTTONDOWN, помещается в переменную «event». Это удаляет то, что было ранее в переменной «событие», удаляя первое событие из существования.
  4. Программа проверяет, «событие» (в настоящее время равно событию.MOUSEBUTTONDOWN) равно событию.MOUSEBUTTONDOWN. Это так, поэтому он переходит к следующей строке ...
  5. «clicked» имеет значение True, и цикл for завершается, потому что события не осталось.

Теперь вы должны лучше понять, как Pygame обрабатывает события.

Есть также много проблем с функцией, которую вы дали (makeButton). Вы должны найти учебник python, чтобы узнать все остальное. Я предлагаю книгу под названием «Hello World», Картер и Уоррен Санд. Книга немного устарела (учит Python 2.5), но ее код по-прежнему работает с Python 2.7, и это одна из немногих достойных книг Python, которые я смог найти.

Я включил код, чтобы сделать то, что вы пытаетесь сделать. Я не использую объекты Rect, но если вы хотите их, вы можете изменить код, чтобы включить их. Я также не включал текст, потому что я не успел. Вместо того, чтобы помещать случайные круги, это печатает текст (в оболочку) при нажатии кнопок.

import pygame, sys 
pygame.init() 
screen = pygame.display.set_mode([640,480]) 
clock = pygame.time.Clock() 

buttons = [] 
#buttons = [[rect, color, hovercolor, hovering, clicked, msg]] 

def makeButton(rect, color, hovercolor, text): 
    global buttons 
    buttons.append([rect, color, hovercolor, False, False, text]) 

makeButton([0,0,50,50], [0,127,0], [0,255,0], "Clicked Green") 
makeButton([50,0,50,50], [190,190,0], [255,255,0], "Clicked Yellow") 
makeButton([100,0,50,50], [0,0,127], [0,0,255], "Clicked Blue") 

while 1: 
    clock.tick(60) 
    for event in pygame.event.get(): 
     if event.type == pygame.MOUSEMOTION: 
      mousepos = event.pos 
      for a in range(len(buttons)): 
       if mousepos[0] >= buttons[a][0][0] and mousepos[0] <= buttons[a][0][0]+buttons[a][0][2] and mousepos[1] >= buttons[a][0][1] and mousepos[1] <= buttons[a][0][1]+buttons[a][0][3]: 
        buttons[3] = True 
       else: 
        buttons[3] = False 
     if event.type == pygame.MOUSEBUTTONDOWN: 
      mousepos = event.pos 
      for a in range(len(buttons)): 
       if mousepos[0] >= buttons[a][0][0] and mousepos[0] <= buttons[a][0][0]+buttons[a][0][2] and mousepos[1] >= buttons[a][0][1] and mousepos[1] <= buttons[a][0][1]+buttons[a][0][3]: 
        buttons[4] = True 
       else: 
        buttons[4] = False 
    for a in range(len(buttons)): 
     if buttons[3] == 0: 
      pygame.draw.rect(screen, buttons[1], buttons[0]) 
     else: 
      pygame.draw.rect(screen, buttons[2], buttons[0]) 
     if buttons[4] == 1: 
      buttons[4] = 0 
      print buttons[5] 
    pygame.display.flip() 

Я не имел возможности проверить код я просто набранный (используя школьный компьютер), но он должен работать. Если есть какие-либо проблемы с кодом, просто оставьте комментарий, и я исправлю его.

Также оставляйте комментарий, если вы что-то не понимаете. Не сдавайтесь, вы можете это сделать!

+0

Это отличное объяснение, спасибо. Я действительно прочитал эту книгу, мне нужно ее найти. – NoRt9001

+0

Это фантастическая книга, но не позволяйте ей портить вас. В конце концов вам придется начать читать скучные книги, если вы серьезно относитесь к Python. Однако это отличная книга. – Douglas

Смежные вопросы