Порядок отрисовки спрайтов в pygame

Простая игра на pygame, порядок отрисовки вроде правильный(сначала фон, затем остальные спрайты), но почему-то вместо игры рисуется только фон. введите сюда описание изображения

import pygame, sys
class MyBallClass(pygame.sprite.Sprite):
    def __init__(self,image_file,speed,location):
        pygame.sprite.Sprite.__init__(self)
        self.image=pygame.image.load('football.png')
        self.image=pygame.transform.scale(self.image,(30,30))
        self.rect=self.image.get_rect()
        self.rect.left, self.rect.top=location
        self.speed=speed
    def move(self):
        global score, score_surf, score_font
        self.rect=self.rect.move(self.speed)
        if self.rect.left<0 or self.rect.right>screen.get_width():
            self.speed[0]=-self.speed[0]
        if self.rect.top<=0:
            self.speed[1]=-self.speed[1]
            score=score+1
            score_surf=score_font.render(str(score),1,(0,0,0))
            
class MyPaddleClass(pygame.sprite.Sprite):
     def __init__(self,location=[0,0]):
         pygame.sprite.Sprite.__init__(self)
         self.image=pygame.image.load('footballer.png')
         self.image=pygame.transform.scale(self.image,(150,220))
         self.rect=self.image.get_rect()
         self.rect.left,self.rect.top=location
         
pygame.init()
screen=pygame.display.set_mode([460,320])
pygame.display.set_caption('Проект "Футболист"')
clock=pygame.time.Clock()
myBall=MyBallClass('footballer.png',[10,20],[20,20])
ballGroup=pygame.sprite.Group(myBall)
paddle=MyPaddleClass([270,150])
lives=3;score=0
score_font=pygame.font.Font(None,50)
score_surf=score_font.render(str(score),1,(0,0,0))
score_pos=[10,10];done=False;
running=True


while running:
    clock.tick(30)
    pole_surf=pygame.image.load('pole.png')
    pole_surf=pygame.transform.scale(pole_surf,(460,320))
    pole_rect=pole_surf.get_rect(center=(230,160))
    screen.blit(pole_surf,pole_rect)
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            running=False
        elif event.type==pygame.MOUSEMOTION:
            paddle.rect.centerx=event.pos[0]

            
if pygame.sprite.spritecollide(paddle, ballGroup, False):
    myBall.speed[1]=-myBall.speed[1]
    pygame.display.flip()
myBall.move()


if not done:
    screen.blit(myBall.image, myBall.rect)
    screen.blit(paddle.image, paddle.rect)
    screen.blit(score_surf, score_pos)
    pygame.display.flip()
    for i in range (lives):
        width=screen.get_width()
        screen.blit(myBall.image, [width - 40*i, 20])
        pygame.display.flip()

        
if myBall.rect.top>=screen.get_rect().bottom:
    lives=lives-1
    if lives==0:
        final_text1="Конец игры"
        final_text2="Количество очков:" + str(score)
        ft1_font=pygame.font.Font(None,70)
        ft1_surf=ft1_font.render(final_text1,1,(255,0,0))
        ft2_font=pygame.font.Font(None,50)
        ft2_surf=ft2_font.render(final_text2,1,(255,0,0))
        screen.blit(ft1_surf,[screen.get.width()/2 - \
                              ft1_surf.get_width()/2,100])
        screen.blit(ft2_surf,[screen.get.width()/2 - \
                              ft2_surf.get_width()/2,200])
        pygame.display.flip()
        done=True
    else:
        pygame.time.delay(5)
        myBall.rect.topleft=[50,50]

        
if event.type==pygame.QUIT:
    running=False
pygame.quit()

Ответы (1 шт):

Автор решения: Agressive Programmer
  1. Ваш код отображения мяча и футболиста выполняется после цикла.
  2. Вы использовали метод pygame.display.flip() после отображения каждого объекта, из-за этого при успешном запуске ваши картинки "мигали"

Вот исправленный код:

import pygame

class MyBallClass(pygame.sprite.Sprite):
    def __init__(self,image_file,speed,location):
        pygame.sprite.Sprite.__init__(self)
        self.image=pygame.image.load('football.png')
        self.image=pygame.transform.scale(self.image,(30,30))
        self.rect=self.image.get_rect()
        self.rect.left, self.rect.top=location
        self.speed=speed
    def move(self):
        global score, score_surf, score_font
        self.rect=self.rect.move(self.speed)
        if self.rect.left<0 or self.rect.right>screen.get_width():
            self.speed[0]=-self.speed[0]
        if self.rect.top<=0:
            self.speed[1]=-self.speed[1]
            score=score+1
            score_surf=score_font.render(str(score),1,(0,0,0))
            
class MyPaddleClass(pygame.sprite.Sprite):
     def __init__(self,location=[0,0]):
         pygame.sprite.Sprite.__init__(self)
         self.image=pygame.image.load('footballer.png')
         self.image=pygame.transform.scale(self.image,(150,220))
         self.rect=self.image.get_rect()
         self.rect.left,self.rect.top=location
         
pygame.init()

screen=pygame.display.set_mode([460,320])
pygame.display.set_caption('Проект "Футболист"')

clock=pygame.time.Clock()

myBall=MyBallClass('footballer.png',[10,20],[20,20])
ballGroup=pygame.sprite.Group(myBall)
paddle=MyPaddleClass([270,150])

lives=3;score=0
score_font=pygame.font.Font(None,50)
score_surf=score_font.render(str(score),1,(0,0,0))
score_pos=[10,10];done=False;
running=True

while running:
    pole_surf=pygame.image.load('pole.png')
    pole_surf=pygame.transform.scale(pole_surf,(460,320))
    pole_rect=pole_surf.get_rect(center=(230,160))
    screen.blit(pole_surf,pole_rect)
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            running=False
        elif event.type==pygame.MOUSEMOTION:
            paddle.rect.centerx=event.pos[0]

    if pygame.sprite.spritecollide(paddle, ballGroup, False):
        myBall.speed[1]=-myBall.speed[1]
        myBall.move()


    if not done:
        screen.blit(myBall.image, myBall.rect)
        screen.blit(paddle.image, paddle.rect)
        screen.blit(score_surf, score_pos)
        for i in range (lives):
            width=screen.get_width()
            screen.blit(myBall.image, [width - 40*i, 20])

    if myBall.rect.top>=screen.get_rect().bottom:
        lives=lives-1
        if lives==0:
            final_text1="Конец игры"
            final_text2="Количество очков:" + str(score)
            ft1_font=pygame.font.Font(None,70)
            ft1_surf=ft1_font.render(final_text1,1,(255,0,0))
            ft2_font=pygame.font.Font(None,50)
            ft2_surf=ft2_font.render(final_text2,1,(255,0,0))
            screen.blit(ft1_surf,[screen.get.width()/2 - \
                                ft1_surf.get_width()/2,100])
            screen.blit(ft2_surf,[screen.get.width()/2 - \
                                ft2_surf.get_width()/2,200])
            done=True
        else:
            pygame.time.delay(5)
            myBall.rect.topleft=[50,50]
    
    pygame.display.flip() # Нужно выполнять только ОДИН раз в цикле, иначе спрайты, которые вы отобразите, будут мигать
    clock.tick(30) # Советую при возможности перемещать те части кода, с которыми вы не будете часто работать, в конец.
→ Ссылка