Animation for a platform game… or other casual games
In this new version of the code to animate a sprite, with also the displaying of the frame rate, now add a way to slow down the speed of the animation without having to slow down the frame rest of the rest of the game.
Where is the trick?
The code to make this is in this 3 lines of code (plus the self.count += 1 at the start and the initialization of the self.count in the __init__ method):
if self.count > 2: #self.image = self.images[self.index] self.index += 1 self.count = 0
Very simple: the self.count attribute increases at each frame, but the image changes only when the self.count goes to 2 (0, 1, 2), so after 3 frames. In this way the animation goes slower than the frame rate, making the passage among the different pictures of the animation less compulsive. Another way could be to increase the number of images for that ‘pose’, so that the result is slower and also smoother in the passage, but this is just an idea, I don’t know what could the the actual result. I will try to do this in a future post, adding 30 frames for each pose, instead of 15.
Where I get the images for the sprite? Are they free?
You can download the images here for free and then unpack them in a folder called png into the same folder where you save the following code:
import pygame import glob def fps(): fr = "V.3 Fps: " + str(int(clock.get_fps())) frt = font.render(fr, 1, pygame.Color("coral")) return frt class MySprite(pygame.sprite.Sprite): def __init__(self, action): super(MySprite, self).__init__() self.action = action # This is to slow down animation # takes the frame now and... self.elapsed = 0 self.images = [] self.temp_imgs = [] self.load_images() self.count = 0 def load_images(self): l_imgs = glob.glob(f"png\\{self.action}*.png") for img in l_imgs: if len(img) == len(l_imgs[0]): self.images.append(pygame.image.load(img)) else: self.temp_imgs.append(pygame.image.load(img)) self.images.extend(self.temp_imgs) self.index = 0 self.rect = pygame.Rect(5, 5, 150, 198) def update(self): self.count += 1 if self.index == len(self.images): self.index = 0 self.image = self.images[self.index] if self.count > 2: #self.image = self.images[self.index] self.index += 1 self.count = 0 def group_sprites(self): return pygame.sprite.Group(self) def group(): "Dictionary of group of sprites" dici = {} actions = "idle walk run jump dead" actions = actions.split() for action in actions: dici[action] = MySprite(action).group_sprites() return dici def main(): global clock global font SIZE = 600, 600 FPS = 60 pygame.init() action = group() my_group = action["idle"] screen = pygame.display.set_mode(SIZE) pygame.display.set_caption("Game v.3") font = pygame.font.SysFont("Arial", 60) clock = pygame.time.Clock() keyactions = ( (pygame.K_LEFT, "walk"), (pygame.K_UP, "jump"), (pygame.K_SPACE, "idle"), (pygame.K_RIGHT, "run"), (pygame.K_DOWN, "dead")) loop = 1 while loop: for event in pygame.event.get(): if event.type == pygame.QUIT: loop = 0 if event.type == pygame.KEYDOWN: for k, a in keyactions: if event.key == k: my_group = action[a] my_group.update() screen.fill((0, 0, 0)) my_group.draw(screen) screen.blit(fps(), (10, 0)) pygame.display.update() clock.tick(FPS) pygame.quit() if __name__ == '__main__': main()