I am faced with the following problem: in Pygame when controlling the direction of movement of the object manually an error appears due to the conversion of the values of the calculated coordinates into integers. How can I fix this error ? With small offsets, the error is significant, this can be seen when displaying the actual direction of movement and the calculated angle. My code:
import pygame as pg
import math
py.init()
clock = pg.time.Clock()
SCREEN_WEIGHT = 1400
SCREEN_HEIGHT = 1000
screen = pg.display.set_mode((SCREEN_WEIGHT, SCREEN_HEIGHT))
FPS = 50
RED = (255, 0, 0)
BLUE = (0, 0, 255)
velocity = 20
def get_angle(p1, p2):
dx = p1[0] - p2[0]
dy = p1[1] - p2[1]
if dx < 0:
angle = 2*math.pi - math.atan(-dy/dx) if dy >= 0 else math.atan(dy/dx)
elif dx > 0:
angle = math.atan(dy/dx) + math.pi if dy >= 0 else math.atan(-dx/dy) + math.pi/2
else:
angle = math.pi/2 if dy < 0 else 3*math.pi/2
if angle == 2*math.pi:
angle = 0
return angle
class Car(pg.sprite.Sprite):
def __init__(self, im_name):
pg.sprite.Sprite.__init__(self)
self.image = pg.image.load(im_name).convert_alpha()
self.rect = self.image.get_rect(center=(SCREEN_WEIGHT/2, SCREEN_HEIGHT/2))
self.angle = 0
def move(self):
sin_a = math.sin(self.angle)
cos_a = math.cos(self.angle)
keys = pg.key.get_pressed()
prev_coords = [self.rect.centerx, self.rect.centery]
self.rect.centerx = round(self.rect.centerx + velocity * cos_a)
self.rect.centery = round(self.rect.centery + velocity * sin_a)
if keys[pg.K_RIGHT]:
self.angle += 0.1
if keys[pg.K_LEFT]:
self.angle -= 0.1
mistake = get_angle(prev_coords, (self.rect.centerx, self.rect.centery))
# индикация фактического направления движения
pg.draw.line(screen, BLUE, (car.rect.centerx - 300*math.cos(mistake), car.rect.centery - 300*math.sin(mistake)),
(car.rect.centerx + 300*math.cos(mistake), car.rect.centery + 300*math.sin(mistake)))
def blitRotate(self):
rotate_image = pg.transform.rotate(self.image, -math.degrees(self.angle))
new_rect = rotate_image.get_rect(center=self.image.get_rect(topleft=self.rect.topleft).center)
screen.blit(rotate_image, new_rect)
car = Car("car.png")
pg.display.update()
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
exit()
screen.fill((255, 255, 255))
car.blitRotate()
car.move()
# actual direction of movement
pg.draw.line(screen, RED, (car.rect.centerx, car.rect.centery), (car.rect.centerx + 80*math.cos(car.angle),
(car.rect.centery + 80*math.sin(car.angle))))
pg.display.update()
clock.tick(FPS)