Как переместить объект Pygame и стереть его в предыдущей позиции? - PullRequest
2 голосов
/ 19 мая 2019

Я пытаюсь создать игру, в которой маленький красный игрок (прямоугольник) управляется клавишами со стрелками. Есть белая сетка поверх черного фона, 2 разноцветные цели (прямоугольники) и несколько случайных красных прямоугольников (прямоугольники).

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

Согласно некоторым другим сообщениям, я слышал, что единственный способ сделать это - заполнить экран фоновым цветом (в данном случае черным) и перерисовать поверх него игроков; однако, в моем случае это действительно сложно, так как красные поля и цели расположены случайным образом, поэтому каждый раз, когда я рисую их снова, они рисуют в новой случайной позиции, а не в своих старых. Я хочу, чтобы красные поля и цели оставались в одной и той же позиции, но чтобы прямоугольники игроков перемещались (в основном удаляя старые версии самих себя).

Вот код, который у меня сейчас есть (я исключил основы, такие как определение цветов, импорт и настройка высоты / ширины экрана):

p1_velocity_x = 0
p1_velocity_y = 0
p2_velocity_x = 0
p2_velocity_y = 0


def grid():
    for col in range(0, screen_width - 100, 10):
        for row in range(0, screen_height, 10):
            screen.set_at((row, col), white)


def red_boxes():
    for i in range(100):
        pygame.draw.rect(screen, red, (randrange(1, 1200), randrange(1, 470), 25, 25))


def blue_score_box():
    pygame.draw.rect(screen, blue, (randrange(1, 1200), randrange(1, 470), 25, 25))


def yellow_score_box():
    pygame.draw.rect(screen, yellow, (randrange(1, 1200), randrange(1, 470), 25, 25))


class Player:
    color = (0, 0, 0)

    def __init__(self, color):
        self.x = 0
        self.y = 0
        self.color = color


p1 = Player(red)
p1.x = randrange(1, 1200, 10)
p1.y = randrange(1, 470, 10)

p2 = Player(yellow)
p2.x = randrange(1, 1200, 10)
p2.y = randrange(1, 470, 10)


while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                p1.x += 10

    screen.fill(black)
    grid()
    red_boxes()
    yellow_score_box()
    blue_score_box()

    pygame.draw.rect(screen, p1.color, (p1.x, p1.y, 10, 10))
    pygame.draw.rect(screen, p2.color, (p2.x, p2.y, 10, 10))

    pygame.display.update()

Результатом приведенного выше кода является то, что я могу перемещать красный прямоугольник, как я хочу, но так как я вызываю методы red_boxes (), yellow_score_box () и blue_score_box () в цикле while, они продолжают вызывать неопределенно, рисуя случайные красные, синие и желтые прямоугольники по всему экрану почти каждую секунду. Я хочу, чтобы они оставались в одном месте, имея возможность перемещать плеер, как я делаю сейчас.

1 Ответ

0 голосов
/ 19 мая 2019

Создайте pygame.Surface того же размера, что и красный прямоугольник игрока:

bkP1 = pygame.Surface((10, 10))

Сделайте резервную копию фона (pygame.Surface.blit) и сохранитепозиция игрока, перед тем как игрок будет нарисован:

prevPos = (p1.x, p1.y)
bkP1.blit(screen, (0, 0), (*prevPos, 10, 10))

Нарисуйте фон поверх игрока, когда игрок должен быть стерт:

screen.blit(bkP1, prevPos)

Процесс может работать какследует:

prevPos = None
bkP1 = pygame.Surface((10, 10))

while True:

    # [...]

    if prevPos:
        screen.blit(bkP1, prevPos)
    prevPos = (p1.x, p1.y)
    bkP1.blit(screen, (0, 0), (*prevPos, 10, 10))
    pygame.draw.rect(screen, p1.color, (p1.x, p1.y, 10, 10))

Конечно, можно добавить механизм в класс Player:

class Player:

    def __init__(self, color):
        self.x = 0
        self.y = 0
        self.color = color
        self. prevPos = None
        self.bk = pygame.Surface((10, 10))

    def draw(self, screen):
        if self.prevPos:
            screen.blit(self.bk, self.prevPos)
        self.prevPos = (self.x, self.y)
        self.bk.blit(screen, (0, 0), (*self.prevPos, 10, 10))
        pygame.draw.rect(screen, self.color, (self.x, self.y, 10, 10))

while True:

    # [...]

    p1.draw(screen) 
...