Проблема вызвана тем, что pygame.Rect
хранит интегральные координаты. Дробная составляющая delta_x
и delta_y
теряется при elf.rect.move(delta_x, delta_y)
.
. Для вычисления необходимо использовать числа с плавающей запятой. Добавьте атрибут self.pos
, который представляет собой форму с двумя компонентами и хранит центральную точку шара:
self.pos = self.rect.center
Вычислить позицию с максимальной точностью с плавающей точкой:
delta_x = self.speed * math.cos(self.angle)
delta_y = self.speed * math.sin(self.angle)
self.pos = (self.pos[0] + delta_x, self.pos[1] + delta_y)
Обновите self.rect.center
на позицию round()
ed .
self.rect.center = round(self.pos[0]), round(self.pos[1])
self.pos
является "внутренней" позицией и отвечает за точное вычисление позиции. self.rect.center
является неотъемлемой позицией и отвечает за рисование мяча. self.pos
слегка меняется в каждом кадре. self.rect.center
изменяется только в том случае, если компонент координаты изменился на 1.
Класс Ball
:
class Ball():
def __init__(self,
screen,
color,
radius,
startX,
startY,
speed,
angle=45):
super().__init__()
self.screen = screen
self.color = color
rectSize = radius * 2
self.rect = pygame.Rect(startX, startY, rectSize, rectSize)
self.speed = speed
self.angle = math.radians(angle)
self.pos = self.rect.center
def update(self):
delta_x = self.speed * math.cos(self.angle)
delta_y = self.speed * math.sin(self.angle)
self.pos = (self.pos[0] + delta_x, self.pos[1] + delta_y)
self.rect.center = round(self.pos[0]), round(self.pos[1])
if self.rect.right >= self.screen.get_width() or self.rect.left <= 0:
self.angle = math.pi - self.angle
if self.rect.top <= 0 or self.rect.bottom >= self.screen.get_height():
self.angle = -self.angle
def draw(self):
'''
Draw our ball to the screen with position information.
'''
pygame.draw.circle(self.screen, self.color, self.rect.center, int(self.rect.width / 2))
С помощью этого решения вы можете увеличить флопы за секунду (clock.tick()
) и уменьшите скорость на ту же шкалу. Это приводит к плавному движению без мигания.