Вопрос-Ответ

How can I move the ball instead of leaving a trail all over the screen in pygame?

Как я могу перемещать мяч вместо того, чтобы оставлять след по всему экрану в pygame?

Я создаю игру в понг, пытаясь стать лучше в программировании, но у меня возникают проблемы с перемещением мяча. При вызове метода move_right эллипс растягивается вправо вместо того, чтобы двигаться вправо. Я пытался поместить переменную ball в метод init, но из-за этого она вообще не перемещается, хотя переменные должны меняться из-за метода move_right . Я также пытался установить позиции x и y в качестве параметров в классе Ball, но это также просто растягивает его. Я не понимаю, почему при запуске следующего кода мяч, который я пытаюсь переместить, растягивается вправо, а не перемещается вправо. Кто-нибудь может объяснить, почему это происходит? Я перепробовал все, что только мог придумать, но не могу заставить его делать то, что я хочу.

import pygame,sys
import random


class Ball:
def __init__(self):
self.size = 30
self.color = light_grey
self.x_pos = width/2 -15
self.y_pos = height/2 -15
self.speed = 1
#self.ball = pygame.Rect(self.x_pos, self.y_pos,self.size,self.size)


def draw_ball(self):
ball = pygame.Rect(self.x_pos, self.y_pos,self.size,self.size)
pygame.draw.ellipse(screen,self.color,ball)

def move_right(self):
self.x_pos += self.speed

class Player:
def __init__(self,x_pos,y_pos,width,height):
self.x_pos = x_pos
self.y_pos = y_pos
self.width = width
self.height = height
self.color = light_grey

def draw_player(self):
player = pygame.Rect(self.x_pos,self.y_pos,self.width,self.height)
pygame.draw.rect(screen,self.color,player)



class Main:
def __init__(self):
self.ball=Ball()
self.player=Player(width-20,height/2 -70,10,140)
self.opponent= Player(10,height/2-70,10,140)

def draw_elements(self):
self.ball.draw_ball()
self.player.draw_player()
self.opponent.draw_player()

def move_ball(self):
self.ball.move_right()





pygame.init()
size = 30
clock = pygame.time.Clock()
pygame.display.set_caption("Pong")
width = 1000
height = 600
screen = pygame.display.set_mode((width,height))
bg_color = pygame.Color('grey12')
light_grey = (200,200,200)

main = Main()
#ball = pygame.Rect(main.ball.x_pos, main.ball.y_pos,main.ball.size,main.ball.size)
#player = pygame.Rect(width-20,height/2 -70,10,140)
#opponent = pygame.Rect(10,height/2-70,10,140)


while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#ball = pygame.Rect(main.ball.x_pos, main.ball.y_pos,main.ball.size,main.ball.size)
#pygame.draw.rect(screen,light_grey,player)
#pygame.draw.rect(screen,light_grey,opponent)
#pygame.draw.ellipse(screen,light_grey,ball)
main.draw_elements()
main.move_ball()
main.ball.x_pos += main.ball.speed
pygame.display.flip()
clock.tick(60)
Переведено автоматически
Ответ 1

Вы должны очищать отображение в каждом кадре с помощью pygame.Surface.fill:

while True:
# [...]

screen.fill(0) # <---

main.draw_elements()
main.move_ball()
main.ball.x_pos += main.ball.speed
pygame.display.flip()

# [...]

Все, что рисуется, рисуется на целевой поверхности. Вся сцена перерисовывается в каждом кадре. Поэтому отображение необходимо очищать в начале каждого кадра в цикле приложения. Типичный цикл приложения PyGame должен:


  • обрабатывайте события с помощью pygame.event.pump() или pygame.event.get().

  • обновляйте состояния игры и положения объектов в зависимости от входных событий и времени (соответственно кадров)

  • очистить весь экран или нарисовать фон

  • нарисовать всю сцену (blit все объекты)

  • обновите отображение, выполнив либоpygame.display.update(), либо pygame.display.flip()

python pygame