Animating Sprites in Pygame

Started by
1 comment, last by AdamShultz 12 years, 7 months ago
I'm very new to pygame and I want to create character movement from a sprite sheet. I'm able to get the character to move across the screens with the arrow keys, but the walking animation is very jittery and blinks very quickly. If anyone can offer me advice on how to properly animate the character, that'd be great.

#Load Images#
bif="panorama.png"
mif="nikkis.png"

import pygame, sys
import pygame.movie
import pygame.mixer
from pygame.locals import *

pygame.init()

screen = pygame.display.set_mode((640,480),0,32)
background = pygame.image.load(bif).convert()
mouse_c = pygame.image.load(mif).convert_alpha()

x,y = 290,200
movex, movey = 0,0
leftFrame = range(3)
topFrame = range(4)
frame = [1,2]

#Load Sounds#
footstep1 = pygame.mixer.Sound("footstep1.wav")

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

if event.type == KEYDOWN:
if event.key == K_LEFT:
movex -= 3
elif event.key==K_RIGHT:
movex += 3
elif event.key==K_UP:
movey -= 3
elif event.key==K_DOWN:
movey += 3

if event.type == KEYUP:
if event.key == K_LEFT:
movex = 0
frame = leftFrame[1], topFrame[3]
elif event.key==K_RIGHT:
movex = 0
frame = leftFrame[1], topFrame[1]
elif event.key==K_UP:
movey = 0
frame = leftFrame[1], topFrame[0]
elif event.key==K_DOWN:
movey = 0
frame = leftFrame[1], topFrame[2]

#Play Sound#
if event.type == pygame.KEYDOWN:
if (event.key == pygame.K_UP or
event.key == pygame.K_DOWN or
event.key == pygame.K_LEFT or
event.key == pygame.K_RIGHT):
footstep1.play()

if event.type == pygame.KEYUP:
if (event.key == pygame.K_UP or
event.key == pygame.K_DOWN or
event.key == pygame.K_LEFT or
event.key == pygame.K_RIGHT):
footstep1.stop()

#Draw Sprites
if event.type == KEYDOWN:
if event.key == K_LEFT:
if frame == (leftFrame[2], topFrame[3]):
frame = leftFrame[0], topFrame[3]
else:
frame = leftFrame[2], topFrame[3]
elif event.key == K_RIGHT:
if frame == (leftFrame[2], topFrame[1]):
frame = leftFrame[0], topFrame[1]
else:
frame = leftFrame[2], topFrame[1]
elif event.key == K_UP:
if frame == (leftFrame[2], topFrame[0]):
frame = leftFrame[0], topFrame[0]
else:
frame = leftFrame[2], topFrame[0]

elif event.key == K_DOWN:
if frame == (leftFrame[2], topFrame[2]):
frame = leftFrame[0], topFrame[2]
else:
frame = leftFrame[2], topFrame[2]

x += movex
y += movey

#Screen Boundary#
if x > 640:
x = 0
if x < 0:
x = 640
if y > 480:
y = 0
if y < 0:
y = 480

screen.blit(background,(0,0))
area = pygame.Rect(frame[0] * 40, frame[1] * 60, 40, 60)
screen.blit(mouse_c,(x,y), area)

pygame.display.update()
Advertisement
Hello! I am also new with pygame and sprite handling but it's what I have for now.
The main problem, as I can see, is that you don't use timing! So your fps depends on CPU speed and it is bad ( on fast machines it will move faster and vice versa ).
pygame have solution for this: pygame.time .

before "while True:"
clock = pygame.time.Clock()
& inside of the loop:
clock.tick(FPS)

where FPS is your desirable frame per second value. It assumes your loop will run ~60 times per second ( to be exactly not more than 60 )
And to solve fast changing images you need implement something like this:


import pygame
...
time = pygame.time.get_ticks()
timeStep = 1000 # one second
...
def Func(time)
if state == "running": # it's running
if flag == 0:
startTime = time # when left leg was moved
image = img[0] # move left leg
flag = 1 # change leg
if flag == 1:
if time - startTime > timeStep: # passed one second
image = img[1] # now move right leg
if time - startTime > timeStep*2: # passed two seconds
flag = 0 # now move left leg


I don't think it is a good example, it looks ugly to me and if someone have better solution I would like to see it.
Or if I find it later I will post it here.

p.s: and of course it is better to use pygame.sprite for all sprite thing ...
OP, do you know how to use class objects yet? If not, I'd highly suggest enriching yourself with that knowledge before you delve into game dev.

Otherwise, my suggestion would be to create an Actor or Player class and an Animation class.


image = pygame.image.load(os.path.join(path, filename)).convert_alpha()

class Animation(object):
def __init__(self, spritesheet, frames, directions):
self.spritesheet = spritesheet # full sprite sheet
self.frames = frames # number of frames (either across or down) that your sprite sheet utilizes
self.directions = directions # number of character directions your sprite sheet supports

self.image = self.get_spritesheet_image()

def get_spritesheet_image(self):
frame_width = self.spritesheet.get_width() / self.frames
frame_height = self.spritesheet.get_height() / self.directions
""" these could be reversed for you. """
...
# do some stuff
...
return image

class Actor(obect):
def __init__(self):
self.position = 290, 200
self.current_animation = Animation(image, frames, directions)


My code is all messed up cuz GDN doesn't like tabs, but hopefully you see where I'm going with this.

This topic is closed to new replies.

Advertisement