Pygame не отвечает на обновления переменных

#python #python-3.x #pygame

#python #python-3.x #pygame

Вопрос:

Я пытаюсь создать программу, которая изменит каждый отдельный пиксель на поверхности Pygame на случайный цвет.

Для фиксированного и постоянного размера поверхности (например, 1300 x 700) это работает, и вся поверхность заполняется случайными цветами, однако я пытаюсь изменить размер поверхности с помощью pygame.Возможность ИЗМЕНЕНИЯ размера Pygame «на лету» (путем обновления вычисленных значений X и Y, с которыми работает программа), однако при каждом изменении размера поверхности Pygame surface выводит только случайно окрашенные пиксели для пикселей в пределах начальной ширины и высоты поверхности программы (в данном случае 1300 x 700) иостальная часть поверхности остается черной (заданный по умолчанию цвет фона), хотя, когда я печатаю переменные, которые соответствуют высоте и ширине экрана (и используются для итерации по всему пикселю) в журнале программы, они обновляются, как и ожидалось.

Я не понимаю, как surface не реагирует на обновленные переменные, и я не знаю, как исправить эту проблему.

Любая помощь приветствуется, и любые вопросы о моем коде приветствуются, спасибо!

 import pygame
import random
pygame.init() #initiates pygame

Comp_X = 1300
Comp_Y = 700

Window = pygame.display.set_mode((Comp_X, Comp_Y), pygame.RESIZABLE) #defines the window size (the varible doesnt have to be called window)
pygame.display.set_caption("Random Colours") #sets the title of the window
clock = pygame.time.Clock() #sets the refresh rate of the program



def GameLoop():    
    global Comp_X #computed pixles for the X axis
    global Comp_Y #computed pixles for the Y axis
    Comp_Tot = Comp_X * Comp_Y #total pixles on the screen
    print("initial computed total pixles = "   str(Comp_Tot))

    #setting x and y position
    x = 0
    y = 0


    GameExit = False #sets the defult value of this varible to true

    while not GameExit: #this is effectivly a "while true" loop, unless the varible "crashed" is set to false

        for event in pygame.event.get(): #this for loop will listen for events
            print(event.type)
            print("X = "   str(Comp_X))
            print("Y = "   str(Comp_Y))

            if event.type == pygame.QUIT: # this if statement checks to see if the X in the top right of the window was pressed
                GameExit = True # this will break the while loop if the condition is met
                print("X = "   str(Comp_X))
                print("Y = "   str(Comp_Y))

            if event.type == 16: #event type 16 is the window resizing event
                Comp_X = event.dict['size'][0]
                Comp_Y = event.dict['size'][1]
                Comp_Tot = Comp_X * Comp_Y
                print("current computed total pixles = "   str(Comp_Tot))

            #Creating the colours
            if event.type == pygame.KEYDOWN:

                if event.key == pygame.K_RETURN:

                    for pixle in range (0, Comp_Tot):
                        if x == Comp_X:
                            print("Computed X = "   str(Comp_X))
                            print("Computed Y = "   str(Comp_Y))
                            x = 0
                            y  = 1
                        pygame.draw.rect(Window, (random.randint(0,255), random.randint(0,255), random.randint(0,255)), [x, y, 2, 2])# draws a red square
                        x  = 1


        #Drawing the frame
        pygame.display.update() #This updates the frame
        clock.tick(60) # this defines the FPS



GameLoop()
pygame.quit() # this will close the window if the "while GameLoop" loop stops running
quit()
 

Использование высоты и ширины по умолчанию 1300 x 700

Изменение размера поверхности до 1457 x 992 — не вся поверхность заполнена!

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

1. Не связано с вашим первоначальным вопросом, а является комментарием как человека, который делал именно это раньше (для эффекта статического экрана телевизора), вы получите лучшую производительность, если создадите одноразовый глобальный список цветов Comp_Tot, а затем просто вызовите random.shuffle один раз в списке. Я еще больше улучшил производительность, применив этот метод только к временной поверхности размером 200×200, а затем выложил это изображение плиткой на свой большой экран.

2. Классное спасибо! Для вывода эффекта этой программе требуется некоторое время, поэтому я попробую 🙂

Ответ №1:

На самом деле есть две проблемы с кодом, которые вызывают ошибку. Первый — отсутствие

Window = pygame.display.set_mode((Comp_X, Comp_Y), pygame.RESIZABLE)

строка внутри if event.type == 16: , как уже упоминалось.

Другая проблема очень незначительна, но приводит к тому, что она не работает должным образом, если ее изменить после заполнения экрана уже один раз, и заключается в том, что вы никогда не сбрасываете значения x или y обратно на 0 после заполнения экрана.

Исправлена часть кода:

             if event.type == pygame.VIDEORESIZE: 
                Comp_X = event.w
                Comp_Y = event.h
                Comp_Tot = Comp_X * Comp_Y
                print("current computed total pixles = "   str(Comp_Tot))
                Window = pygame.display.set_mode((Comp_X, Comp_Y), pygame.RESIZABLE)

            #Creating the colours
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    for pixle in range (0, Comp_Tot):
                        if x == Comp_X:
                            #print("Computed X = "   str(Comp_X))
                            #print("Computed Y = "   str(Comp_Y))
                            x = 0
                            y  = 1
                        pygame.draw.rect(Window, (random.randint(0,255), random.randint(0,255), random.randint(0,255)), [x, y, 2, 2])# draws a red square
                        x  = 1
                    x = 0
                    y = 0
 

Я также изменил event.type == 16 event.type == pygame.VIDEORESIZE его на более читаемый.

Ответ №2:

Когда срабатывает событие изменения размера окна, вам нужно снова вызвать pygame.display.set_mode((w, h)) , чтобы выделить новую поверхность такого размера. В противном случае вы все еще записываете в исходный экземпляр поверхности 1300×700.

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

1. Это работает для первого запуска игры, но когда я нажимаю клавишу возврата, чтобы запустить ее снова, для вычисления требуется столько же времени, однако он просто отображает черную поверхность. это также происходит, если я изменяю размер поверхности после вычисления цветов. Есть идеи?

2. если event.type == 16: #тип события 16 — это событие изменения размера окна Comp_X = event.dict[‘size’][0] Comp_Y = event.dict[‘size’][1] pygame.display.set_mode((Comp_X, Comp_Y), pygame. ИЗМЕНЯЕМЫЙ РАЗМЕР) Comp_Tot = Comp_X * Comp_Y print(«текущее вычисленное общее количество пикселей = » str(Comp_Tot))