Python pygame精灵动画

时间:2015-04-19 13:37:16

标签: python animation pygame sprite

我正在尝试学习python的pygame库。

我目前正在使用spritesheets学习精灵动画。我在“javascript”中关注本教程:http://gamedevelopment.tutsplus.com/tutorials/an-introduction-to-spritesheet-animation--gamedev-13099

我试图在python中翻译代码,但它不起作用;它只显示完整的精灵表,没有动画。

这是我的翻译代码:

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()

为什么它不起作用?如何从上面的教程链接中为spritesheet设置动画?

2 个答案:

答案 0 :(得分:0)

你在屏幕上显示了character.images:

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

这是这个类变量包含的内容:

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

此变量永远不会更新,因此它自然不会显示任何动画。

我的实现是使用this image作为精灵表:

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)

声明:

我也是Pygame / Python的新手,我不知道这种方法是否有效......但至少它是按预期工作的!

答案 1 :(得分:0)

另一个可能性是使用多个图像和计数器。

我的初始文件(对于我自己游戏中的玩家类)看起来像这样(我让一些不重要的东西出来):

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()

在我的更新功能中:

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()

在我的绘图功能中(用于显示屏幕上的所有内容):

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

如果图像尺寸不同,则需要更改坐标。 我的游戏是用Python 3.6和Pygame 1.9.3编写的,但它也适用于其他所有Python 3.x版本。

我希望它可以帮到你。虽然这段代码效率不高,但对我来说效果很好。

相关问题