Как люди эффективно обрабатывают повторяющиеся проверки событий (python / pygame)? - PullRequest
0 голосов
/ 16 мая 2018

Это скорее вопрос любопытства, потому что я вернулся и сумел сделать то, что хотел. Первоначально заголовок должен был быть чем-то вроде «Проверка, находится ли упорядоченный кортеж в кортеже диапазонов?»

До сих пор я проверял щелчки мышью, используя этот код -

pos = pygame.mouse.get_pos()

if pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2:
    #Do this

#Separate function with same XY's
if pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2:
    #Do something else - could be used for mouse hover rather than click.  

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

for event in pygame.event.get():
    if event.type == pygame.MOUSEBUTTONDOWN:
        gp = game.pos
        #Initial gbh declaration
        gbh = game.button_health = range(391, 527), range(179, 253)

        if gp[0] in gbh[0] and gp[1] in gbh[1]:
        player.skillpoints -= 1
        player.health += 10
        player.healthmax += 10

#Separate func.
gp = game.pos
gbh = game.button_health

if gp[0] in gbh[0] and gp[1] in gbh[1]:
    blit(font.render(str(Z), True, BLACK), (X, Y))

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Поскольку ваш вопрос помечен performance, лучше всего начать с известной цитаты:

"Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всего зла . Однако мы не должны упускать наши возможности в эти критические 3% "(Д. Кнут," Структурированное программирование с переходом к утверждениям ", выделите мое)

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

Прежде всего, обратите внимание, что в Python вы можете написать:

if X < pos[0] < X2 and Y < pos[1] < Y2:
     ....

Но есть более важное: сделать то, что вы тестируетеясно .Как ты это объяснишь?Просто назвав его:

if pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2: 
    # Do this

становится:

if area_contains(X, X2, Y, Y2, pos):
    # Do this

или с пользовательским классом:

area = Area(X, X2, Y, Y2)
if area.contains(pos):
    # Do this

Вы должны сделать это, даже если у вас есть только одинтест, для ясности.Функции предназначены не только для уменьшения дублирующегося кода (СУХОЙ: не повторяйтесь), но и для улучшения читабельности.Посмотрите на это:

player.skillpoints -= 1
player.health += 10
player.healthmax += 10

Почему бы и нет:

player.increase_health()

?

Не используйте объекты только как структуры: они предоставляют вам удобный способ выразить то, что вы делаете, не раскрывая детали реализации.Теперь вы можете изменить значение increase_health, не просматривая все события, которые к нему ведут.

0 голосов
/ 17 мая 2018

Если у вас есть повторяющийся код, вы можете поместить его в функцию и вызвать там, где был код.Это облегчает изменение кода позже, поскольку вам просто нужно изменить его в одном месте.Тестирование кода также проще.

Вот пример (я также добавил строку в стиле Google ):

def collided(pos, X, X2, Y, Y2):
    """Check if a point `pos` collides with an area.

    Args:
        pos (tuple): The point.
        X (int, float): The left coordinate of the area.
        etc.

    Returns:
        bool: True if it collides, otherwise False.
    """
    return pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2


# Call the function and pass the needed arguments.
if collided(pg.mouse.get_pos(), X, X2, Y, Y2):
    print('collision')
...