Как сделать кнопку переключения типа в Pygame? - PullRequest
0 голосов
/ 23 сентября 2018

Я делаю игру с pygame, но у меня проблема в том, что кнопка не работает как переключатель.

while True:
mousepos = pygame.mouse.get_pos()
mouseclk = pygame.mouse.get_pressed()
game.fill((0,0,0))
game.blit(cic, (0,0))

if mouseclk[0] and 1227 > mousepos[0] > 1120 and 485 > mousepos[1] > 413:
    while True:
        game.blit(pbut_rgm84, (1120,413))
        pygame.mixer.music.load("sounds\se_beep.mp3")
        pygame.mixer.music.play(0)
        current_weaponinf = font.render(current_weapon[1], True, (255, 0, 0))
        game.blit(current_weaponinf, (930,45))
else:
    game.blit(but_rgm84, (1120,413))

Это мой код кнопки.Как вы знаете, если я нажму на эту кнопку, изображение кнопки будет изменено, и будет воспроизводиться звук.Но это произойдет, пока я нажимаю на кнопку.Итак, я хочу, чтобы кнопка была переключать тип.У вас есть идеи по этому поводу?

1 Ответ

0 голосов
/ 24 сентября 2018

РЕДАКТИРОВАТЬ 1 : Извините за случай. Ответ в первой части .Остальное - лишь некоторые заметки о более стандартном способе сделать то, что вы просили в PyGame.В конце концов, ответ не только для ОП, но и для всех, кто посещает эту страницу.

РЕДАКТИРОВАТЬ 2 : Обратите внимание, что мне пришлось изменить код, чтобы понизить FPS до 5 дляэто работать нормально.То, как вы проверяли наличие клика, означало, что кнопка мыши была нажата примерно на 30-40 кадров каждый клик на моей машине, что привело к переключению 30-40 кнопок, когда нужен был только один, поэтому мне пришлось снизить FPS до 5в коде.Это еще одна причина, по которой вы можете использовать другой метод, описанный мной для обработки событий.


Ответ:

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

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

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

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

toggle = False
pygame.mixer.music.load("sounds\se_beep.mp3")
pygame.mixer.music.play(-1)
pygame.mixer.music.pause()
clock = pygame.time.Clock()

while True:
    mousepos = pygame.mouse.get_pos()
    mouseclk = pygame.mouse.get_pressed()

    game.fill((0, 0, 0))
    game.blit(cic, (0, 0))

    if mouseclk[0] and 1227 > mousepos[0] > 1120 and 485 > mousepos[1] > 413:
        if toggle:
            toggle = False
            pygame.mixer.music.pause()
        else:
            toggle = True
            pygame.mixer.music.unpause()

    if toggle:
        game.blit(pbut_rgm84, (1120, 413))
        current_weaponinf = font.render(current_weapon[1], True, (255, 0, 0))
        game.blit(current_weaponinf, (930,45))
    else:
        game.blit(but_rgm84, (1120,413))

    clock.tick(5)

Лучший способ: обработка событий

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

У вас уже есть один в вашем коде!- В каждом цикле в цикле while вы проверяете, была ли нажата мышь, используя mouseclk = pygame.mouse.get_pressed()

Однако это неполно и не является стандартным способом реализации циклов событий с использованием модуля Pygame.Вот как вы это делаете ( прочитайте комментарий над каждой строкой, чтобы понять, что он делает ):

import pygame
from pygame.locals import *

...

# Main game loop - this is the while loop you have in your code. This is where frames are rendered on every new loop
while True: 
    #Get all event that have been triggered from the last frame
    events = pygame.event.get()

    # Now we go through each event separately
    for event in events:
        #Use an if statement to check what the event is. For example...
        if event.type == MOUSEBUTTONDOWN:  #If this event was a mouse button click
            print("Clicked")  #Do whatever function
        elif event.type == QUIT: #If this event was quitting the game, i.e: pressing the X button on the game window
            pygame.quit() #Close the game
        #and so on. You can have as many elifs to check all the events you need


   game.fill((0,0,0)) #... The rest of your code goes after the for loop (event loop)

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


A Better Way: Rect Objects

Вы обнаружите, что, чтобы увидеть, находится ли позиция щелчка мыши (x, y) в пределах диапазона кнопки мыши, вы должны были проверить, было ли значение x щелчка мыши в пределах диапазонаот X1 до X2 объекта, на который вы щелкаете (верхний правый и верхний левый углы), и в то же время он также должен находиться в диапазоне от Y1 до Y2 объекта (верхний правый и нижний правый углы), что эффективноозначает, что мышь находилась где-то на объекте, когда было вызвано событие щелчка мыши

. Для этого Pygame реализует Rect объекты.Прямоугольник можно объяснить как воображаемый прямоугольник с шириной и высотой, которые вы определяете при его создании (я покажу вам, как это делается в приведенном ниже коде).Чтобы быть более реалистичным, это объект-пигмейм для хранения прямоугольных координат (диапазон всех точек в этом прямоугольнике).

Теперь дело в том, что у этого прямоугольного объекта есть методы, подобные Rect.collidepoint, которые будут возвращать True, если позиция щелчка мыши находится внутри прямоугольника.Это более простой и понятный способ определения, находится ли позиция щелчка мыши внутри прямоугольника или вне его.

Итак.

# Constructing a rect at position (0, 0) with width 100 and height 500
r = pygame.Rect(0, 0, 100, 50)

# Now lets assume that above there is code where a mouse click is detect and the position is stored in `mousepos`, where `mousepos[0]` is the X and `mousepos[1]` is the Y
# All we have to do now is tell pygame to check if this position is inside our Rect object *r* or not
if r.collidepoint(mousepos):
    print("You clicked inside an imaginary box")
else:
    print("You clicked outside my imaginary box")

# Simple!!!

Намного проще и удобочитаемее!(особенно после того, как вы удалите комментарии, вы будете ошеломлены простотой этого (точка столкновения означает внутри прямоугольника).

В действительности это не то, как вы обычно используете rects , хотя этодает базовое представление о том, что они из себя представляют. Rects используются в более объектно-ориентированном методе, где кнопка является дочерним классом класса Pygame.sprite.Sprite. Затем вы можете назначить объект rect как его self.image.rectсвойство и использовать его оттуда. ПРИМЕЧАНИЕ: это не очень подробно: D.

Кроме того, это не единственное использование rects. Вы можете проверить, находится ли один прямоугольник внутри другого. Вы можете проверить, если группаобъектов внутри прямоугольника. Вы можете даже с помощью только одной строки кода проверить, находится ли один объект группы внутри определенного прямоугольника, и если это так, удалить его!


Чтобы понять, каккодировать Pygame от начала до конца (так как дополнительная часть этого ответа, говорящая о событиях и ритах, очень неполна и только там как отправная точка), я бы предложилэто превосходная, но очень простая и понятная книга .И все, что вам нужно, это базовое понимание синтаксиса Python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...