Surface.fill () обновляет прямоугольник в цикле while?

У меня есть две программы ниже, пытающиеся нарисовать мяч на желтом экране. Один, где мой поверхностный объект заполняется вне цикла while, и тот, который заполняется внутри цикла while.

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

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

Почему это?

Неконечный код:

import pygame
import sys

length = 1200
width = 800


screen = pygame.display.set_mode((length, width))
screen_rect = screen.get_rect()

ball = pygame.image.load('ball.bmp')
ball_rect = ball.get_rect()
ball_rect.y = ball_rect.width
ball_rect.x = screen_rect.centerx


while True: 
    screen.fill((255, 255, 103))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                ball_rect.y += 15

    screen.blit(ball, ball_rect)
    pygame.display.flip()

Конечный код изображения:

import pygame
import sys

length = 1200
width = 800


screen = pygame.display.set_mode((length, width))
screen_rect = screen.get_rect()
screen.fill((255, 255, 103))

ball = pygame.image.load('ball.bmp')
ball_rect = ball.get_rect()
ball_rect.y = ball_rect.width
ball_rect.x = screen_rect.centerx


while True: 


    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                ball_rect.y += 15

    screen.blit(ball, ball_rect)
    pygame.display.flip()

введите здесь описание изображения


person Connor    schedule 15.03.2019    source источник
comment
Добро пожаловать в Stack Overflow. Пройдите тур и прочитайте Как Спросить. Предоставьте минимальный воспроизводимый пример, чтобы мы могли помочь. Код лучше в виде текста, а не изображения, поэтому его легче запускать для других.   -  person import random    schedule 15.03.2019
comment
Пожалуйста, отредактируйте свой вопрос, включив в него текст программы.   -  person Kingsley    schedule 15.03.2019
comment
Возможный дубликат Почему PyGame отслеживает изображение?   -  person sloth    schedule 15.03.2019


Ответы (1)


Связанный код (изображение) не дает описанного вами эффекта. С левой стороны screen вообще не обновляется. С правой стороны единственное обновление — это screen.fill() желтого цвета.

Так сказать гипотетически...

Программу PyGame можно рассматривать как тип анимации. Во время основного цикла обычно есть блок для обработки пользовательского ввода, вызовы для обновления позиций объектов на экране и вызовы для обновления, то есть «перерисовки» экрана.

Каждый «кадр» этой анимации создается с фоном, а также, как правило, с некоторыми наложенными объектами. Это могут быть такие вещи, как растровые изображения игроков, растровые изображения бойцов, элементы игрового поля, текстовые очки и статусы и т. д. Обычно сначала рисуется фон, а затем накладываемые элементы. После того, как экран отрисован, движение объектов рассчитывается для следующего отображения, оно перерисовывается, и снова и снова...

Первая ситуация, описываемая вопросом, — это ситуация, когда экран обновляется таким образом, что предыдущий «кадр» анимации не был удален, и пользователь видит комбинацию предыдущего и текущего отображения.

Во второй ситуации сначала стирается весь дисплей, а screen.fill(). Таким образом удаляя любые следы предыдущего кадра. Это типичное обращение.

Есть еще один способ. Этот метод отслеживает, где экран был изменен, и перерисовывается только определенная область, которая нуждается в обновлении. Этот подход потенциально может обеспечить гораздо более эффективный цикл ввода-обновления-отрисовки, потому что он не перерисовывает элементы, которые не изменились.

person Kingsley    schedule 15.03.2019
comment
Левый код следует за моим изображением, а правый код не следует за изображением. Но, кажется, я понимаю, о чем вы говорите. По сути, я перерисовывал фон каждый раз, когда происходит движение любого из наложенных объектов? - person Connor; 16.03.2019
comment
Кроме того, какой еще способ вы описываете? - person Connor; 16.03.2019
comment
Да почти каждый кадр - закрашивайте фон, закрашивайте игровые объекты. Повторить. Третий способ использует концепцию, обычно известную как грязные прямоугольники. Часть экрана, нуждающаяся в обновлениях, считается грязной. Здесь есть краткое руководство — n0nick .github.io/blog/2012/06/03/ - person Kingsley; 17.03.2019