简体   繁体   中英

Python pygame sprite animation

I am trying to learn python's pygame library.

I am currently learning sprite animation using spritesheets. I'm following this tutorial in "javascript": http://gamedevelopment.tutsplus.com/tutorials/an-introduction-to-spritesheet-animation--gamedev-13099 .

I tried to translate the code in python but it doesn't work; it just displays the full sprite sheet and no animation.

Here is my translated code:

import pygame,math
from pygame.locals import *
pygame.init()

screen = pygame.display.set_mode((400, 300))
done = False
img='jj.png'

class sprites:
    def sprite_sheet(self,img,frame_width,frame_height,frame_speed,end_frame):
        self.images=pygame.image.load(img)
        #calculate number of frames in a row
        self.frames_per_row=math.floor(self.images.get_rect().size[0]/frame_width)
        self.current_frame=0
        self.counter=0
        self.frame_speed=frame_speed
        self.end_frame=end_frame
    def update(self):
        if self.counter==self.frame_speed-1:
            self.current_frame=(self.current_frame+1) % self.end_frame
        self.counter=(self.counter+1) % self.frame_speed

character=sprites()
character.sprite_sheet(img,125,125,3,16)


clock=pygame.time.Clock()
while not done:
        #screen.fill((255,255,255))
        character.update()
        screen.blit(character.images,(30,100))

        for event in pygame.event.get():
                if event.type == pygame.QUIT:
                        done = True


        #screen.blit(images,(0,0))#,(current_image*32,0,32,32))
        pygame.display.flip()
        clock.tick(30)

pygame.quit()

Why it is not working? How do I animate the spritesheet from the above tutorial link?

You're blitting character.images on the screen:

screen.blit(character.images,(30,100))

Here's what this class variable contains:

self.images=pygame.image.load(img)

This variable is never updated, so naturally it won't display any animation.

Here's my implementation using this image as the sprite sheet:

import pygame, sys
from pygame.locals import *

sheet = 'sheet.png'

pygame.init()
screen = pygame.display.set_mode((500, 500))

FPS = 30
FPSCLOCK = pygame.time.Clock()

class Character(object):
    def __init__(self, sheet, width, height, end):
        self.sheet = pygame.image.load(sheet)
        self.width = width
        self.height = height
        self.end = end
        self.counterX = 0
        self.counterY = 0

        self.imageWidth = self.sheet.get_rect().size[0]
        self.imageHeight = self.sheet.get_rect().size[1]
        self.spritesPerRow = self.imageWidth / self.width
        self.spritesPerCol = self.imageHeight / self.height

        # These assertions will raise an exception if image size, sprite size
        # and sprite count don't add up as they should be. You can experiment
        # with this by changing the values when this object is instantiated.
        assert self.imageWidth % self.width == 0, 'Incorrect sprite width!'
        assert self.imageHeight % self.height == 0, 'Incorrect sprite height!'
        assert self.spritesPerRow * self.spritesPerCol == self.end, \
                                        'Incorrect number of sprites!'

    def update(self):
        # The counters keep track of which sprite to display from the
        # sprite sheet.
        self.spriteArea = (self.counterX * self.width, 
                             self.counterY * self.height,
                             self.width, self.height)
        self.counterX += 1
        if self.counterX == self.spritesPerRow:
            self.counterX = 0
            self.counterY += 1
        if self.counterY == self.spritesPerCol:
            self.counterX = 0
            self.counterY = 0

Test = Character(sheet, 125, 125, 16)

# Displays the sprite sheet for one second.
screen.blit(Test.sheet, (0, 0))
pygame.display.update()
pygame.time.wait(1000)

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

    screen.fill((255, 255, 255))
    Test.update()
    screen.blit(Test.sheet, (188, 188), Test.spriteArea)
    pygame.display.update()
    FPSCLOCK.tick(FPS)

DISCLAIMER:

I'm a Pygame/Python newbie as well, and I don't have a clue whether or not this approach is efficient... but at least it works as intended!

Another posibility is to use mulitple images and a counter.

My init-file(for my player-class in my own game) looks like this(I let some unimportant things out):

def init(self,x,y,...):
   self.x=x;self.y=y
   self.dir=0           #0==left,1==right

   self.img1_l=img1_l   #the image-files for walking left
   self.img2_l=img2_l   #

   self.img1_r=img1_r   #the image-files for walking right
   self.img2_r=img2_r   #

   self.img_r=img_r     #Idle-image right
   self.img_l=img_l     #Idle-image left

   self.image=self.img_r#the image for idle

   self.anim_counter=-1 #animations counter
   self.max_anim_counter=60 #in my chase 1 second means 60 FPS
   self.rect=self.image.get_rect()

in my update-function:

def update(self):       #this is called every frame
   self.anim_counter-=1 #I used this to track the passed time
   if self.anim_counter > 30:
      if self.dir=0:
         self.image=self.img1_l
      else:
         self.image=self.img1_r
   elif self.anim_counter >0:
      if self.dir=0:
         self.image=self.img2_l
      else:
         self.image=self.img2_r
  else:                 #this is called if you don't press any walking button
     if self.dir==0:
        self.image=self.img_l
     else:
        self.image=self.img_r
     self.rect=self.image.get_rect()

in my draw-function(used to show everything on my screen):

def draw(self):
   screen.blit(self.image,self.rect)

You need to change the coordinates if the images aren't the same size. My game is written in Python 3.6 and Pygame 1.9.3 but it works also in every other Python 3.x Version.

I hope it could help you. Although this code isn't very efficient, it works fine for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM