keystate = pg.key.get_pressed()
if keystate[pg.K_LEFT]:
self.counter = (self.counter + 1) % len(player_images)
self.acc.x = -PLAYER_A
You need to keep track of the time, so you can either use pygame.time.get_ticks
or the time that clock.tick()
returns (it's usually called dt
for delta time) and then update the image after some time has passed.
The pygame.time.get_ticks
variant:
class Player(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.frame = 0 # Index of the current animation frame.
self.image = IMAGES[self.frame] # Set image to the first image.
self.rect = self.image.get_rect(center=pos)
# Start time of the last animation frame.
self.start_time = pg.time.get_ticks()
# If the time limit is reached, increment the index
# and change self.image.
self.time_limit = 300 # Milliseconds.
def update(self):
now = pg.time.get_ticks()
if now - self.start_time > self.time_limit:
self.frame += 1 # Increment the frame index.
self.frame %= len(IMAGES) # Keep the index in the range.
self.image = IMAGES[self.frame] # Switch the image.
self.start_time = now
And a complete example with the delta time variant. (You'll need the dt
in your class anyway for the movement speed, if you eventually want to make the game frame rate independent).
import pygame as pg
# Some images with dots for the animation.
IMAGE1 = pg.Surface((90, 90))
IMAGE1.fill((30, 90, 200))
pg.draw.circle(IMAGE1, (50, 170, 220), (45, 45), 15)
IMAGE2 = pg.Surface((90, 90))
IMAGE2.fill((30, 90, 200))
pg.draw.circle(IMAGE2, (50, 170, 220), (30, 30), 15)
pg.draw.circle(IMAGE2, (50, 170, 220), (60, 60), 15)
IMAGE3 = pg.Surface((90, 90))
IMAGE3.fill((30, 90, 200))
pg.draw.circle(IMAGE3, (50, 170, 220), (20, 20), 15)
pg.draw.circle(IMAGE3, (50, 170, 220), (45, 45), 15)
pg.draw.circle(IMAGE3, (50, 170, 220), (70, 70), 15)
IMAGES = [IMAGE1, IMAGE2, IMAGE3]
class Entity(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.frame = 0 # Index of the current animation frame.
self.image = IMAGES[self.frame] # Set image to the first image.
self.rect = self.image.get_rect(center=pos)
self.timer = 0 # Time in seconds.
def update(self, dt):
self.timer += dt # Increment the timer.
# If the timer is above the desired time limit ...
if self.timer >= .5:
self.timer = 0 # Reset the timer.
self.frame += 1 # Increment the frame index.
self.frame %= len(IMAGES) # Keep the index in the range.
self.image = IMAGES[self.frame] # Switch the image.
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group(Entity((200, 200)))
dt = 0
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
# Pass dt to the update methods of all sprites.
all_sprites.update(dt)
screen.fill((30, 30, 30))
all_sprites.draw(screen)
pg.display.flip()
# dt is the time that has passed since the last clock.tick call.
# Divide by 1000 to convert milliseconds to seconds.
dt = clock.tick(30) / 1000
if __name__ == '__main__':
pg.init()
main()
pg.quit()