Pygame не обновляет экран - PullRequest
       7

Pygame не обновляет экран

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

Я на самом деле создаю программу, которая распознает два контроллера PS3 и выводит их изображения на экран вместе с именами их контроллеров и другими «фоновыми спрайтами».Я хочу, чтобы пользователи нажимали на контроллер, и над ИХ контроллером появляется круг или что-то подобное - чтобы они знали, что они подобрали, затем, когда их кнопки отпущены, круг исчезнет (или будет затянут со всеми моимифоновый рисунок для эффективного удаления кругов с экрана).Я думаю, что этот фоновый список и то, как он не обновляет экран, как мне хотелось бы, является фундаментальным здесь ...

Чтобы упростить эту проблему, я привожу более короткий пример: я хочучтобы показать контроллеры как подключенные устройства, представленные изображением контроллера, или в этом укороченном фрагменте кода в виде белых вертикальных линий.Я создал фоновое изображение, используя список, bgd [].Когда я нажимаю кнопку на любом из джойстиков, я хочу видеть временную серую линию, связанную с соответствующим контроллером (белая линия), которая должна исчезнуть, когда клавиша нажата.Моя проблема в том, что я не могу заставить серые линии исчезнуть.Я подумал, что мне просто нужно проклясть все содержимое неизменных фоновых изображений bgd [].

import pygame
from pygame.locals import *
import os

# Place the display 'screen' at top. 
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0,10) 
# Iterate over all graphics which make up the 'unalterable background'
# This should put graphics into memory ready for blitting later...
# 
def reDraw(background):
    for r in (range (len(background))):
        background[r]

pygame.init()    
size = display_width, display_height = 100,100
screen = pygame.display.set_mode(size)
# List of 'unalterable background graphics/sprites
bgd = []
# Bottom of the virtual z-stack of screen graphics - a black background
bgd.append(screen.fill((0,0,0)))
# Count the number of Joysticks
joystick_count = pygame.joystick.get_count()
# One joystick is represented by a grey line on the left of the screen
if joystick_count == 1:
        bgd.append(pygame.draw.rect(screen, (255,255,255), (10,20,10,60)))
        reDraw(bgd) #Ready to display.update later
# A second joystick is represented by a grey line on the right of the screen
if joystick_count == 2:
        bgd.append(pygame.draw.rect(screen, (255,255,255), (10,20,10,60)))
        bgd.append(pygame.draw.rect(screen, (255,255,255), (80,20,10,60)))
        reDraw(bgd) #Ready to display.update later

# Now to create TEMPORARY SCREEN FEATURES, which should only be present 
# Whilst the buttons are pressed on each PS3 controller joystick :
run = True
while run == True:
    for j in range(joystick_count):
        joystick = pygame.joystick.Joystick(j)
        joystick.init()
        buttons = joystick.get_numbuttons()
        reDraw(bgd) #Ready to display.update later

        #Now to put all the queued draw statements onto the screen
        pygame.display.update() 


        for i in range( buttons ):
            button = joystick.get_button( i )
            if button != 0 and j == 0 :        
                pygame.draw.rect(screen, (150,150,150), (20,20,30,10))
            if button != 0 and j == 1 :        
                pygame.draw.rect(screen, (150,150,150), (50,70,30,10))

    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
            pygame.quit()
            quit()  

Я включил пояснительное изображение:

The code in action

1 Ответ

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

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

Кстати, функция reDraw в вашем примере ничего не рисует.Вы должны были бы вызвать pygame.draw.rect в цикле for, но тогда он просто нарисовал бы несколько белых ректов.Вы можете поместить списки [color, rect] в список bgd вместо просто rects, а затем использовать цикл for для их отрисовки.

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

import pygame
from pygame.locals import *


pygame.init()
screen = pygame.display.set_mode((100,100))
clock = pygame.time.Clock()
# A list of [color, rect] lists.
bgd = []
# Count the number of Joysticks.
joystick_count = pygame.joystick.get_count()
# Instantiate a joystick and initialize it.
if joystick_count == 1:
    joystick0 = pygame.joystick.Joystick(0)
    joystick0.init()
    # Append the color and the rect.
    bgd.append([(255,255,255), (10,20,10,60)])

run = True
while run:
    for event in pygame.event.get():
        if (event.type == pygame.QUIT
                or event.type == KEYDOWN and event.key == K_ESCAPE):
            run = False

    screen.fill((0,0,30))  # Clear the screen each frame.
    # Iterate over the [color, rect] lists and pass them to draw.rect.
    for color, rect in bgd:
        pygame.draw.rect(screen, color, rect)
    # Check if button 0 is pressed, if True, draw the rect.
    if joystick0.get_button(0):
        pygame.draw.rect(screen, (150,150,150), (20,20,30,10))

    pygame.display.update()
    clock.tick(60)  # Limit the frame rate to 60 FPS.

pygame.quit()

Проблема с функцией reDraw заключается в том, что она практически выполняетничего, потому что список bgd содержит только те ректы, которые возвращает pygame.draw.rect, а не сами вызовы функции pygame.draw.rect.Чтобы обновить экран, вам необходимо очистить его каждый кадр, затем снова нарисовать каждый видимый объект и, наконец, вызвать pygame.display.flip() или pygame.display.update().

list.append просто добавит объект, который вы передаете ему.В этом случае вы добавляете значение, которое возвращает pygame.draw.rect (прямоугольник).Если бы pygame.draw.rect просто что-то нарисовал и ничего не возвратил, он бы добавил None, потому что функции, которые ничего не возвращают, возвращают None неявно.

Вот еще один пример, который ближе к вашему исходному:

import pygame
from pygame.locals import *


def reDraw(background, screen):
    for color, rect in background:
        pygame.draw.rect(screen, color, rect)


pygame.init()
size = display_width, display_height = 100,100
screen = pygame.display.set_mode(size)
# List of 'unalterable background graphics/sprites
bgd = []
# Count the number of Joysticks
joystick_count = pygame.joystick.get_count()
if joystick_count == 1:
    bgd.append([(255,255,255), (10,20,10,60)])
if joystick_count == 2:
    bgd.append([(255,255,255), (10,20,10,60)])
    bgd.append([(255,255,255), (80,20,10,60)])

# Create the joystick instances.
joysticks = [pygame.joystick.Joystick(x)
             for x in range(pygame.joystick.get_count())]
# Initialize them.
for joystick in joysticks:
    joystick.init()

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT or (
                event.type == KEYDOWN and event.key == K_ESCAPE):
            run = False

    screen.fill((0, 0, 0))  # Clear the screen.
    reDraw(bgd, screen)  # Draw the joystick rects.

    for joystick in joysticks:
        for i in range(joystick.get_numbuttons()):
            button = joystick.get_button(i)
            # Draw the gray rects.
            if button and joystick.get_id() == 0:
                pygame.draw.rect(screen, (150,150,150), (20,20,30,10))
            if button and joystick.get_id() == 1:
                pygame.draw.rect(screen, (150,150,150), (50,70,30,10))

    pygame.display.update()  # Show everything we've drawn this frame.

pygame.quit()

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

# Create or load the symbol images/surfaces.
CIRCLE_IMG = pygame.Surface((30, 30), pygame.SRCALPHA)
pygame.draw.circle(CIRCLE_IMG, (150, 0, 80), (15, 15), 14, 2)
# Add the images to a dictionary. The keys are the associated
# button numbers.
# You could also use a list if you have images for all buttons.
BUTTON_SYMBOLS = {1: CIRCLE_IMG, 2: SQUARE_IMG}  # etc.

# In the while loop use the button numbers to get the images in the dict and blit them.
for joystick in joysticks:
    for x in range(joystick.get_numbuttons()):
        if x in BUTTON_SYMBOLS and joystick.get_button(x):
            screen.blit(BUTTON_SYMBOLS[x], (20, 20))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...