当前位置: 代码迷 >> python >> pygame不会刷新屏幕
  详细解决方案

pygame不会刷新屏幕

热度:95   发布时间:2023-07-14 09:49:51.0

我实际上正在制作一个识别两个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()  

我包括一个解释图像:

我将检查主循环中是否按下了特定按钮,然后只绘制相应的矩形。

顺便说一下,示例中的reDraw函数不会绘制任何内容。 你必须在for循环中调用pygame.draw.rect ,但是它只会绘制几个白色的rects。 您可以将[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返回的rects而不是pygame.draw.rect函数调用它们自己。 要更新屏幕,您需要每帧清除它,然后再次绘制每个可见对象,最后调用pygame.display.flip()pygame.display.update()

list.append将只附加您传递给它的对象。 在这种情况下,您追加pygame.draw.rect返回的值(rect)。 如果pygame.draw.rect只是绘制一些东西并且什么都不返回,那么它会附加None因为没有返回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循环中将它们blit:

# 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))