Sign in to follow this  
skin

Animating Sprites in Pygame

Recommended Posts

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.

[code]#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()[/code]

Share this post


Link to post
Share on other sites
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:"
[code]clock = pygame.time.Clock()[/code]
& inside of the loop:
[code]clock.tick(FPS)[/code]

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:

[code]
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
[/code]

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 ...

Share this post


Link to post
Share on other sites
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.

[code]
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)[/code]

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this