Reputation: 681
I have read other questions posted here that are related but I can not seem to fit those answers into my state machine which can be found here: https://github.com/Aeryes/Demented
I am trying to create an animation either using a sprite sheet or just an iteration through a list or dict. I have so far managed to get the first image in a list to load as an animation but it will not cycle through the list of 4 images as long as my flag variable which is running = True is true. Instead it will load the first image from the list and hold it on that image until running = False in which case it reverts as intended back to the standstill image.
Here is my current code for my player class without my failed animation attempts:
import pygame as pg
from settings import Music_Mixer, loadCustomFont, States, screen
from time import sleep
"""This section contains entity states which are separate from game and menu states."""
class Player():
def __init__(self, x, y):
self.health = 100
self.speed = 1
self.screen = screen
self.imagex = x
self.imagey = y
self.running_right = False
self.running_left = False
self.rect = pg.draw.rect(self.screen, (255, 0, 0), [self.imagex, self.imagey, 20, 45])
self.image = pg.image.load('Images/Animations/PlayerRun/Stickman_stand_still.png').convert_alpha()
self.images = ['Images/Animations/PlayerRun/Stickman_stand_still.png', 'Images/Animations/PlayerRun/Stickman_run_1.png', 'Images/Animations/PlayerRun/Stickman_run_2.png',
'Images/Animations/PlayerRun/Stickman_run_3.png', 'Images/Animations/PlayerRun/Stickman_run_4.png']
#Moves the player and begins the animation phase.
def move_player(self, speed):
self.pressed = pg.key.get_pressed()
#Move left and start left run animation.
if self.pressed[pg.K_a]:
self.imagex -= 5
#Move right and start right run animation
if self.pressed[pg.K_d]:
self.running_right = True
self.imagex += 5
elif not self.pressed[pg.K_d]:
self.running_right = False
#Move up and start jump animation.
if self.pressed[pg.K_w]:
self.imagey -= 5
#Move down and start either crouch.
if self.pressed[pg.K_s]:
self.imagey += 5
#Animates the running movement of the player.
def runAnim(self):
if self.running_right:
pass
elif self.running_right == False:
self.image = pg.image.load('Images/Animations/PlayerRun/Stickman_stand_still.png').convert_alpha()
#draws the player to the screen.
def draw_entity(self):
screen.blit(self.image, (self.imagex, self.imagey))
I have looked here: Animation in with a list of images in Pygame
And here: Animated sprite from few images
Upvotes: 1
Views: 781
Reputation: 20488
images
(the current image list/animation) attribute to the class. images
, first pass the dt
(delta time) to the player's update
method and subsequently to the other methods that need it. Increment the timer attribute and, after the desired time interval, increment the index and use it to swap the image.That's basically all you need to do, but maybe you have to adjust a few things.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
# Load images once when the program starts. Put them into lists, so that
# you can easily swap them out when the player changes the direction.
STICKMAN_IDLE = [pg.image.load(
'Images/Animations/PlayerRun/Stickman_stand_still.png').convert_alpha()]
# You could use a list comprehension here (look it up).
STICKMAN_RUN = [
pg.image.load('Images/Animations/PlayerRun/Stickman_run_1.png').convert_alpha(),
pg.image.load('Images/Animations/PlayerRun/Stickman_run_2.png').convert_alpha(),
pg.image.load('Images/Animations/PlayerRun/Stickman_run_3.png').convert_alpha(),
pg.image.load('Images/Animations/PlayerRun/Stickman_run_4.png').convert_alpha(),
]
class Player:
def __init__(self, x, y):
self.pos_x = x
self.pos_y = y
self.images = STICKMAN_IDLE
self.image = self.images[0]
self.rect = self.image.get_rect(center=(x, y))
self.anim_index = 0
self.anim_timer = 0
def move_player(self, dt):
"""Move the player."""
self.pressed = pg.key.get_pressed()
if self.pressed[pg.K_a]:
self.pos_x -= 5 # Move left.
self.images = STICKMAN_RUN_RIGHT # Change the animation.
if self.pressed[pg.K_d]:
self.pos_x += 5 # Move right.
self.images = STICKMAN_RUN_RIGHT # Change the animation.
if not self.pressed[pg.K_d] and not self.pressed[pg.K_a]:
self.images = STICKMAN_IDLE # Change the animation.
# Update the rect because it's used to blit the image.
self.rect.center = self.pos_x, self.pos_y
def animate(self, dt):
# Add the delta time to the anim_timer and increment the
# index after 70 ms.
self.anim_timer += dt
if self.anim_timer > .07: # After 70 ms.
self.anim_timer = 0 # Reset the timer.
self.anim_index += 1 # Increment the index.
self.anim_index %= len(self.images) # Modulo to cycle the index.
self.image = self.images[self.anim_index] # And switch the image.
def update(self, dt):
self.move_player(dt)
self.animate(dt)
def draw(self, screen):
screen.blit(self.image, self.rect)
def main():
clock = pg.time.Clock()
player = Player(100, 300)
done = False
while not done:
# dt (delta time) = time in ms since previous tick.
dt = clock.tick(30) / 1000
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
player.update(dt) # Pass the delta time to the player.
screen.fill((30, 30, 30))
player.draw(screen)
pg.display.flip()
if __name__ == '__main__':
main()
pg.quit()
Upvotes: 2