Возврат из функции из класса не работает для кнопки для pygame

#python #pygame

#python #pygame

Вопрос:

По какой-то причине мой возврат не работает. Это из учебника. Когда я загружаю файл и редактирую его оттуда, он работает, но если я копирую и вставляю его из точного файла, он не работает. Извините, я новичок — открыт для любых предложений

Это учебное пособие, которое я использовал: https://www.youtube.com/watch?v=G8MYGDf_9ho

Код:

 import pygame
import sys

pygame.init()

WinHeight = 600
WinWidth = 900
Window = pygame.display.set_mode((WinWidth,WinHeight))
#button class
class Button():
    def __init__(self, x, y, image, scale):
        width = image.get_width()
        height = image.get_height()
        self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
        self.rect = self.image.get_rect()
        self.rect.topleft = (x, y)
        self.clicked = False

    def draw(self, surface):
        action = False
        #get mouse position
        pos = pygame.mouse.get_pos()

        #check mouseover and clicked conditions
        if self.rect.collidepoint(pos):
            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                self.clicked = True
                action = True

        if pygame.mouse.get_pressed()[0] == 0:
            self.clicked = False

        #draw button on screen
        surface.blit(self.image, (self.rect.x, self.rect.y))

        return action



Good_ball_img = pygame.image.load("GoodBall.png")
Bad_ball_img = pygame.image.load("BadBall.png")


#Button instances
Good_ball = Button(100,100,Good_ball_img,2)
Bad_ball = Button(200,200,Bad_ball_img,3)

def drawwin():
    Window.fill((202,241,208))
    Good_ball.draw(Window)
    Bad_ball.draw(Window)



   pygame.display.update()




def Main():
    run = True
    while run:
        if Good_ball.draw(Window):
            print("green clicked")
        if Bad_ball.draw(Window)=="t":
            print("red clicked")
        for event in pygame.event.get():
                #quit game
                if event.type == pygame.QUIT:
                        run = False
                        pygame.quit()
                        sys.exit()
        drawwin()
        checkpress()


            
    



if __name__ == "__main__":
    Main()
 

Комментарии:

1. Будьте точнее. Что не работает? Как это не работает? Что это должно произойти?

2. сначала используйте print, чтобы увидеть, что у вас есть в переменных в разные моменты, и какая часть кода выполняется. Он вызывается "print debuging" . Возможно, эта часть кода никогда не выполняется, потому что у вас неправильные значения в переменных.

3. Кстати: есть хорошее правило для использования lower_case_names для переменных — т. е. main() , good_ball , bad_ball и CamelCaseNames только для классов `. Это помогает распознавать класс в коде. Подробнее: PEP 8 — Руководство по стилю для кода Python

4. doesn't work это самая бесполезная информация. Вы должны описать проблему. Не ожидайте, что мы запустим код, чтобы увидеть проблему. Кроме того, код может корректно работать на наших компьютерах. Мы также не можем читать в ваших мыслях. Поэтому вы должны указать все детали (не в комментариях)

5. в draw вы проверяете положение мыши и изображение blit — и запускаете его два раза — сначала в if/else , а затем в drawwin — и это кажется пустой тратой времени. Вы должны иметь две функции — одну только для проверки мыши и использования с if ней, а вторую только для blit — и использовать ее в drawwin

Ответ №1:

Код работает для меня, если я меняю порядок — сначала обрабатываю все события, а затем проверяю положение мыши.

Проблема может быть в том, что PyGame обновляет значения в pygame.mouse и pygame.key только при запуске pygame.event.get() — так что это может потребоваться pygame.event.get() или, по крайней мере pygame.event.pump() , перед другими функциями.

         for event in pygame.event.get():
            #quit game
            if event.type == pygame.QUIT:
                run = False
                pygame.quit()
                sys.exit()

        if Good_ball.draw(Window):
            print("green clicked")
        if Bad_ball.draw(Window):
            print("red clicked")
 

Редактировать:

В документации для pygame.event есть

 To get the state of various input devices, you can forego the event queue and 
access the input devices directly with their appropriate modules: `pygame.mouse`, 
`pygame.key` and `pygame.joystick`. If you use this method, remember 
that pygame requires some form of communication with the system window manager 
and other parts of the platform. To keep pygame in sync with the system, 
you will need to call `pygame.event.pump()` to keep everything current. 
 

Минимальный рабочий код — с поверхностями вместо изображений, чтобы каждый мог просто скопировать и запустить его

 import pygame
import sys

# --- constants ---  # PEP8: `UPPER_CASE_NAMES`

WINDOW_WIDTH = 900
WINDOW_HEIGHT = 600

# --- classes ---  # PEP8: `CamelCaseNames`

class Button():
    
    def __init__(self, x, y, image, scale):
        width = image.get_width()
        height = image.get_height()
        self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
        self.rect = self.image.get_rect()
        self.rect.topleft = (x, y)
        self.clicked = False

    def check_click(self):
        action = False

        # get mouse
        pos = pygame.mouse.get_pos()
        left_button = pygame.mouse.get_pressed()[0]

        # check mouseover and clicked conditions

        if left_button:
            if self.rect.collidepoint(pos) and not self.clicked:
                self.clicked = True
                action = True
        else:
            self.clicked = False

        return action

    def draw(self, surface):
        # draw button on screen
        surface.blit(self.image, self.rect)

# --- functions ---  # PEP8: `lower_case_names`

def draw_window(window):
    window.fill((202, 241, 208))
    good_ball.draw(window)
    bad_ball.draw(window)

    pygame.display.update()

# --- main --- 

pygame.init()

window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))

# button class
#good_ball_img = pygame.image.load("GoodBall.png")
good_ball_img = pygame.Surface((100, 50))
good_ball_img.fill((0, 255, 0))

#bad_ball_img = pygame.image.load("BadBall.png")
bad_ball_img = pygame.Surface((100, 50))
bad_ball_img.fill((255,0,0))

# Button instances
good_ball = Button(100, 100, good_ball_img, 2)  # 
bad_ball  = Button(200, 200, bad_ball_img, 3)

run = True

while run:

    # - events -
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
            pygame.quit()
            sys.exit()

    # - checks and updates -
    
    if good_ball.check_click():
        print("green clicked")
    if bad_ball.check_click():
        print("red clicked")

    #checkpress()

    # - draws -
    
    draw_window(window)
 

PEP 8 — Руководство по стилю для кода Python