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.