Я новичок в программировании с помощью pygame и самого python. Я пытался создать простую локальную многопользовательскую игру с использованием pygame. Я написал свой код во время просмотра учебника по перемещению только одного прямоугольника, потому что я не нашел ничего о том, что пытаюсь сделать. Когда я закончил, я скопировал часть скрипта с переменными и движением для прямоугольника, а затем вставил его и изменил имена переменных, чтобы он не падал или что-то в этом роде. Теперь вот моя проблема: поскольку движение простое, он напечатает новый прямоугольник, если я буду нажимать кнопки для перемещения. Из-за этого фон все время обновляет свой цвет (или что-то в этом роде), поэтому отображается только один прямоугольник, который я хочу переместить. Но если есть второй прямоугольник, цвет покрывает его, и все время виден только один. Как я могу это исправить?

Вот код:

import pygame
pygame.init()

win = pygame.display.set_mode((500, 500))

pygame.display.set_caption("local multiplayer")

#variables player 1

X = 200
Y = 200
Width = 40
Height = 60
Vel = 5

#variables player 2

x = 50
y = 50
width = 40
height = 60
vel = 5

run = True
while run:
    pygame.time.delay(100)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()

#player 1

    if keys[pygame.K_a]:
        X -= Vel
    if keys[pygame.K_d]:
        X += Vel
    if keys[pygame.K_w]:
        Y -= Vel
    if keys[pygame.K_s]:
        Y += Vel

    win.fill((0, 0, 0))
    pygame.draw.rect(win, (255, 255, 255), (X, Y, Width, Height))
    pygame.display.update()

#player 2

    if keys[pygame.K_LEFT]:
        x -= vel
    if keys[pygame.K_RIGHT]:
        x += vel
    if keys[pygame.K_UP]:
        y -= vel
    if keys[pygame.K_DOWN]:
        y += vel

    win.fill((0, 0, 0))
    pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
    pygame.display.update()

pygame.quit()
1
PhoenixAnton 9 Окт 2021 в 19:04

2 ответа

Лучший ответ

Когда вы вызываете win.fill((0, 0, 0)), весь дисплей очищается. Вы должны нарисовать прямоугольники сразу после очистки экрана.
Обновление отображения в конце цикла приложения. Множественные вызовы pygame.display.update() или pygame.display.flip() вызывают мерцание (см. Почему мерцает анимация PyGame ).

Упростите код и используйте объекты pygame.Rect для представления игроков. Используйте pygame.Rect.clamp_ip, чтобы предотвратить проигрыватель от выхода с экрана.

import pygame

pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("local multiplayer")
clock = pygame.time.Clock()

player1 = pygame.Rect(200, 200, 40, 60)
vel1 = 1
player2 = pygame.Rect(50, 40, 40, 60)
vel2 = 1

run = True
while run:
    clock.tick(50)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()
    player1.x += (keys[pygame.K_d] - keys[pygame.K_a]) * vel1
    player1.y += (keys[pygame.K_s] - keys[pygame.K_w]) * vel1
    player2.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel2
    player2.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel2
    player1.clamp_ip(win.get_rect())
    player2.clamp_ip(win.get_rect())

    win.fill((0, 0, 0))
    pygame.draw.rect(win, (255, 255, 255), player1)
    pygame.draw.rect(win, (255, 255, 255), player2)
    pygame.display.update()

pygame.quit()

Типичный цикл приложения PyGame должен:

  • ограничьте количество кадров в секунду, чтобы ограничить использование ЦП с помощью pygame.time.Clock.tick
  • обрабатывать события, вызывая pygame.event.pump() или pygame.event.get().
  • обновлять игровые состояния и позиции объектов в зависимости от входных событий и времени (соответственно фреймов)
  • очистить весь дисплей или нарисовать фон
  • нарисовать всю сцену (blit все объекты)
  • обновить отображение, вызвав либо pygame.display.update() или pygame.display.flip()
0
Rabbid76 9 Окт 2021 в 16:35

Вы выполняете win.fill((0, 0, 0)) сразу после отображения игрока 1. Удалите этот код перед отображением второго символа. Кроме того, оставьте линию заполнения в верхней части цикла приложения. Это даст:

pygame.init()

win = pygame.display.set_mode((500, 500))

pygame.display.set_caption("local multiplayer")

#variables player 1

X = 200
Y = 200
Width = 40
Height = 60
Vel = 5

#variables player 2

x = 50
y = 50
width = 40
height = 60
vel = 5

run = True
while run:
    win.fill((0, 0, 0))
    pygame.time.delay(100)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()

#player 1

    if keys[pygame.K_a]:
        X -= Vel
    if keys[pygame.K_d]:
        X += Vel
    if keys[pygame.K_w]:
        Y -= Vel
    if keys[pygame.K_s]:
        Y += Vel

    pygame.draw.rect(win, (255, 255, 255), (X, Y, Width, Height))

#player 2

    if keys[pygame.K_LEFT]:
        x -= vel
    if keys[pygame.K_RIGHT]:
        x += vel
    if keys[pygame.K_UP]:
        y -= vel
    if keys[pygame.K_DOWN]:
        y += vel

    pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
    pygame.display.update()

pygame.quit()

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

0
Paul Bekaert 9 Окт 2021 в 16:07