首页 > 解决方案 > 我的 pygame 屏幕的左上角没有正确更新,但其他一切正常

问题描述

这是我开始乒乓球比赛的代码:

import pygame
from random import (uniform, choice) 

pygame.init()

from pygame.locals import (
K_UP, 
K_DOWN, 
K_s, 
K_w, 
QUIT
)

class Ball(pygame.sprite.Sprite): 
    def __init__(self, color, left, top): 
        pygame.sprite.Sprite.__init__(self) 
        radius = 20
        self.surface = pygame.Surface((radius * 2, radius * 2))
        self.surface.set_colorkey([255, 0, 255])
        self.surface.fill([255, 0, 255]) 
        self.rect = pygame.draw.circle(self.surface, color, (radius, radius), radius)
        self.old_rect = None 
        self.rect.x = left - radius
        self.rect.y = top - radius
        self.x_vel = None
        self.y_vel = None 
        self.x_pos = self.rect.left
        self.y_pos = self.rect.top 

    def start(self):
        signs = [-1, 1] 
        self.x_vel = .1 * choice(signs) 
        self.y_vel = uniform(-.1, .1) 
    

    def move(self, screen): 
        screen.blit(self.surface, self.rect, self.rect)
        self.x_pos += self.x_vel 
        self.y_pos += self.y_vel
        self.old_rect = self.rect.copy() 
        self.rect.topleft = self.x_pos, self.y_pos 
        screen.blit(self.surface, self.rect)  



class Paddle(pygame.sprite.Sprite):
    def __init__(self, color, left, top): 
        pygame.sprite.Sprite.__init__(self) 
        width, height = 40, 120
        self.surface = pygame.Surface((width, height))
        self.surface.fill(color)
        self.rect = self.surface.get_rect()
        self.old_rect = None 
        self.rect.update(left, top, width, height)
        self.y_pos = self.rect.top

    def move(self, pressed_keys, keys, screen):
        dy = 0 
        screen.blit(self.surface, self.rect, self.rect)
        l_bound, u_bound = 5, 750 - self.rect.height - 5 
        if pressed_keys[keys[0]] and self.rect.top > l_bound: 
            dy = -.2  
            
        if pressed_keys[keys[1]] and self.rect.top < u_bound: 
            dy = .2

        self.y_pos += dy
        self.old_rect = self.rect.copy()
        self.rect.top = self.y_pos  
        screen.blit(self.surface, self.rect)

class Main: 
    def __init__(self):
        self.height, self.width = 750, 1000
        self.screen = pygame.display.set_mode((self.width, self.height)) 
        pygame.display.set_caption("pong") 
        self.loop()

    def loop(self): 
        blue = [0, 0, 255]
        red = [255, 0, 0]
        paddle1 = Paddle(blue, 30, self.height // 2) 
        paddle2 = Paddle(blue, 930, self.height // 2) 
        ball = Ball(red, self.width // 2, self.height // 2)

        running = True
        start = True  
        while running:
            self.screen.fill([0, 0, 0]) 
            for event in pygame.event.get():
                if event.type == QUIT: 
                    running = False 
        
            pressed_keys = pygame.key.get_pressed()
            if start: 
                ball.start() 
                start = False 
            paddle1.move(pressed_keys, [K_w, K_s], self.screen)
            paddle2.move(pressed_keys, [K_UP, K_DOWN], self.screen)
            ball.move(self.screen)
            pygame.display.update([paddle1.rect, 
                               paddle1.old_rect,
                               paddle2.rect,
                               paddle2.old_rect, 
                               ball.rect, 
                               ball.old_rect])

        pygame.quit()


Main()

如果你测试一下,你应该明白我的意思 - 基本上任何与屏幕左上角(左桨和可能的球)交互的精灵在离开屏幕左上角并留下后都不会完全更新其表面的一些残留部分。

我认为这与我使用左上角更新矩形的位置这一事实有关,将此行视为一个示例:

self.rect.topleft = self.x_pos, self.y_pos

但我想不出为什么这会是一个问题。

编辑:我也知道,从技术上讲,不带任何参数调用 update 就可以解决问题,但我想保持我的代码优化,只更新需要更新的内容。

编辑 2:有人好心地在他们的 Windows 机器上测试我的代码,它对他们有用,没有问题。所以我认为问题可能与操作系统有关(我在 linux 上)。如果有 linux 机器的人想看看他们是否可以复制我的问题,我将不胜感激!

标签: pythonpygame

解决方案


推荐阅读