'pygame inconsistent behaviour with delta time despite adjusting for rect truncating

I am trying to create a spaceship style game that uses delta time.

The code I have is this:

import pygame, sys, time
from math import sin,cos, pi

class Main:
    def __init__(self):
        
        # window setup
        pygame.init()
        self.display_surface = pygame.display.set_mode((1280, 720))
        pygame.display.set_caption('Asteroids')
        self.clock = pygame.time.Clock()

        # groups
        self.all_sprites = pygame.sprite.Group()

        # sprites
        self.player = Player((640,360),self.all_sprites) 

    def run(self):
        while True:
            
            # delta time
            dt = self.clock.tick(60) / 1000 # remove 60 to get unlimited frames 

            # event loop
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()

            self.display_surface.fill((10,10,10))
            self.all_sprites.update(dt)
            self.all_sprites.draw(self.display_surface)
            
            pygame.display.update()

class Player(pygame.sprite.Sprite):
    def __init__(self,pos,groups):
        super().__init__(groups)
        self.original = pygame.Surface((40,80))
        self.original.fill('red')
        self.image = self.original
        self.rect = self.image.get_rect(center = pos)

        # rotation
        self.angle = 0
        self.rotation_speed = 300

        # movement
        self.pos = pygame.math.Vector2(self.rect.topleft)
        self.direction = pygame.math.Vector2((0,-1))
        self.speed = 0

        self.max_speed = 1000
        self.velocity = 0
        self.acceleration = 0.5
        self.deceleration = 0.2

    def input(self,dt):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_RIGHT]:
            self.angle += self.rotation_speed * dt      
        if keys[pygame.K_LEFT]:
            self.angle -= self.rotation_speed * dt
        
        if keys[pygame.K_SPACE]: self.velocity += self.acceleration
        else: self.velocity -= self.deceleration
        self.velocity = max(0, min(self.velocity, self.max_speed))

    def rotate(self):
        self.image = pygame.transform.rotozoom(self.original,-self.angle,1)
        self.rect = self.image.get_rect(center = self.rect.center)
        self.pos = pygame.math.Vector2(self.rect.topleft)

    def move(self,dt):
        
        direction = pygame.math.Vector2(cos((self.angle - 90) * pi / 180), sin((self.angle - 90) * pi / 180))
        self.pos += direction * self.velocity # add '* dt' to account for delta time
        self.rect.topleft = (round(self.pos.x), round(self.pos.y))

    def update(self,dt):
        self.input(dt)
        self.rotate()
        self.move(dt)


if __name__ == '__main__':
    main = Main()
    main.run()

It is a spaceship that can rotate and is moved by a direction. If I lock the framerate to 60 and ignore delta time, all of this is working really well. However, if I remove the framerate limited from self.clock in run method of the Main class and add delta time to the player's move method (I added comments in the code), the movement becomes choppy and inconsistent.

I am aware there is a similar question here: pygame delta time causes inconsistent movement but the issue here is different: I am storing the position information in a separate vector (self.pos) for the player and the rect position gets the information from that, so no data should be lost from truncated values.

So, my question would be why the movement is choppy when delta time is used even though the movement position is stored inside of a vector that can store floating point numbers.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source