Pygame球运动闪烁

Pygame ball movement flickering

我一直在尝试制作一个基本的 Pygame 代码,让球在屏幕上弹跳并离开你的球拍。桨的运动很流畅,但球闪烁不定。这是我的完整代码:

import pygame, sys
from pygame.locals import *
import random, time

pygame.init()

window = (800, 600)

background = (0, 0, 0)
back = pygame.Surface(window)
entity_color = (255, 255, 255)
x = 362.5
y = 550
ball_x = 387.5
ball_y = 50
width = 75
height = 25
clockobject = pygame.time.Clock()


screen = pygame.display.set_mode((window))

pygame.display.set_caption("Test Game")

class Ball(pygame.sprite.Sprite):
    def __init__(self):
        super(Ball, self).__init__()
        self.surf = pygame.Surface((25, 25))
        self.surf.fill((255, 255, 255))
        self.rect = self.surf.get_rect()
        self.dir_x = 1
        self.dir_y = 1
        self.speed = 2

    def update(self):
        global ball_x
        global ball_y
        if ball_x > 775:
            ball_x = 775
            ball.dir_x = -1
        elif ball_x < 0:
            ball_x = 0
            ball.dir_x = 1
        if ball_y < 0:
            ball_y = 0
            ball.dir_y = 1
        elif ball_y > 600:
            ball_y = 50
            ball_x = 387.5
        if ball_x <= x + 75 and ball_x >= x and ball_y <= y and ball_y >= y - 25:
            ball.dir_y = -1
        ball_x = ball_x + ball.speed * ball.dir_x
        ball_y = ball_y + ball.speed * ball.dir_y


class Player(pygame.sprite.Sprite):
    def __init__(self):
        super(Player, self).__init__()
        self.image_s = pygame.image.load("paddle.png")
        self.image_b = self.image_s.get_rect()
        self.surf = pygame.Surface((75, 25))

        self.surf.fill((255, 255, 255))
        self.rect = self.surf.get_rect()

    def update(self):
        global x
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            x = x - 5
        elif keys[pygame.K_RIGHT]:
            x = x + 5

    def checkboundaries(self):
        global x
        if x > 725:
            x = 725
        if x < 0:
            x = 0

ball = Ball()
player = Player()
waiting = True
while waiting:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()
            elif event.key == pygame.K_SPACE:
                running = True
                waiting = False
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False
    player.update()
    ball.update()
    player.checkboundaries()
    screen.blit(back, (0,0))
    screen.blit(player.surf, (x, y))
    screen.blit(ball.surf, (ball_x, ball_y))
    pygame.display.flip()
    clockobject.tick(360)

pygame.quit()
sys.exit()

这是因为我的代码有问题 运行 慢,还是我遗漏了什么?

如果您正在使用 pygame.sprite.Sprite, you should also use pygame.sprite.Group

pygame.sprite.Group.draw() and pygame.sprite.Group.update()pygame.sprite.Group.

提供的方法

后者委托给包含的pygame.sprite.Sprites — you have to implement the method. See pygame.sprite.Group.update()update方法:

Calls the update() method on all Sprites in the Group. [...]

前者使用包含的 pygame.sprite.Spriteimagerect 属性来绘制对象 - 你必须确保 pygame.sprite.Sprite 具有所需的属性。见 pygame.sprite.Group.draw():

Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect. [...]

例如:

import pygame, sys
from pygame.locals import *

pygame.init()
clockobject = pygame.time.Clock()
screen = pygame.display.set_mode((800, 600))
back = pygame.Surface(screen.get_size())
pygame.display.set_caption("Test Game")

class Ball(pygame.sprite.Sprite):
    def __init__(self):
        super(Ball, self).__init__()
        self.image = pygame.Surface((25, 25))
        self.image.fill((255, 255, 255))
        self.rect = self.image.get_rect(topleft = (387, 50))
        self.dir_x = 1
        self.dir_y = 1
        self.speed = 2

    def update(self):
        if self.rect.x > 775:
            self.rect.x = 775
            self.dir_x = -1
        elif self.rect.x < 0:
            self.rect.x = 0
            self.dir_x = 1
        if self.rect.y < 0:
            self.rect.y = 0
            self.dir_y = 1
        elif self.rect.y > 600:
            self.rect.topleft = (387, 50)
        if self.rect.colliderect(player.rect):
            ball.dir_y = -1
        self.rect.x += ball.speed * ball.dir_x
        self.rect.y += ball.speed * ball.dir_y

class Player(pygame.sprite.Sprite):
    def __init__(self):
        super(Player, self).__init__()
        self.image = pygame.Surface((75, 25))
        self.image.fill((255, 255, 255))
        self.rect = self.image.get_rect(topleft = (363, 550))

    def update(self):
        keys = pygame.key.get_pressed()
        self.rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 5
        self.rect.clamp_ip(screen.get_rect())

ball = Ball()
player = Player()
all_sprites = pygame.sprite.Group([ball, player])

started = False
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False
            elif event.key == pygame.K_SPACE:
                started = True
    
    
    screen.blit(back, (0,0))
    if started:
        all_sprites.update()
        all_sprites.draw(screen)
    pygame.display.flip()
    clockobject.tick(100)

pygame.quit()
sys.exit()