按键上的精灵动画

时间:2012-11-03 13:21:42

标签: python animation sprite pygame

当您按下键盘上的按钮时,我正在尝试为spritesheet设置动画。我最初的想法是只按下按键上的图像。我将动画代码从主循环移动到用户输入循环。这不起作用,因为游戏循环处理整个游戏的个别状态。什么技术用于触发用户输入的动画?我想要一个动画系统,它可以通过用户输入处理动画,也可以在后台自己处理动画。

 if __name__ == "__main__":
    print "the game"
    pygame.init()
    screen = pygame.display.set_mode((800,600))

    images = load_sliced_sprites(100, 71, "spinning_roundhouse_kick.png")
    spritesheet = AnimatedSprite(images, 20)
    #while pygame.event.poll().type != KEYDOWN:
    while True:
        screen.fill((255,255,255))
        event = pygame.event.poll()

        if event.type == KEYDOWN:
            #print "keydown"
            for image in images:
                screen.blit(image, (0,0))

        #time = pygame.time.get_ticks()
        #spritesheet.update(time)
        #screen.blit(spritesheet.image, (0,0))

        pygame.display.update()

2 个答案:

答案 0 :(得分:2)

看起来你应该做这样的事情..

sprite = AnimatedSprite(images, 20)
if event.type == KEYDOWN:
        sprite.update(pygame.time.get_ticks())
        screen.blit(sprite.getimage())

应该发生什么,是你的精灵类应该获得时间增量的更新,并在更改为新帧之前计算时间。键关闭时绘制动画。

答案 1 :(得分:0)

我通过跟踪动画帧并使用另一个真正循环来解决问题。

import os
import pygame
from pygame.locals import *

def load_sliced_sprites(w, h, filename):
    '''
    Specs :
        Master can be any height.
        Sprites frames width must be the same width
        Master width must be len(frames)*frame.width
    Assuming you ressources directory is named "resources"
    '''
    images = []
    master_image = pygame.image.load(os.path.join('resources', filename)).convert_alpha()

    master_width, master_height = master_image.get_size()
    for i in xrange(int(master_width/w)):
        images.append(master_image.subsurface((i*w,0,w,h)))
    return images



class AnimatedSprite(pygame.sprite.Sprite):
    def __init__(self, images, fps = 10):
        pygame.sprite.Sprite.__init__(self)
        self._images = images

        # Track the time we started, and the time between updates.
        # Then we can figure out when we have to switch the image.
        self._start = pygame.time.get_ticks()
        self._delay = 1000 / fps
        self._last_update = 0
        self._frame = 0

        # Call update to set our first image.
        self.update(pygame.time.get_ticks())

    def update(self, t):
        # Note that this doesn't work if it's been more that self._delay
        # time between calls to update(); we only update the image once
        # then, but it really should be updated twice.

        if t - self._last_update > self._delay:
            self._frame += 1
            #if self._frame >= len(self._images): self._frame = 0
            if self._frame < len(self._images):
                self.image = self._images[self._frame]
                self._last_update = t

    def getimage(self):
        return self.image

    def isfinished(self):
        if self._frame == len(self._images):
            return True
        else:
            return False

    def reset(self):
        if self._frame >= len(self._images): self._frame = 0

if __name__ == "__main__":
    print "the game"
    pygame.init()
    screen = pygame.display.set_mode((800,600))

    images = load_sliced_sprites(100, 71, "spinning_roundhouse_kick.png")
    sprite = AnimatedSprite(images, 20)
    #while pygame.event.poll().type != KEYDOWN:
    while True:
        screen.fill((255,255,255))
        event = pygame.event.poll()
        if event.type == KEYDOWN and event.key == K_a:
            #print "keydown"
            #for image in images:
            while True:
                #print "frame"
                #print sprite._frame
                #print sprite.isfinished()
                time = pygame.time.get_ticks()
                sprite.update(time)
                screen.blit(sprite.getimage(), (0,0))
                pygame.display.update()
                #sprite.reset()
                if sprite.isfinished() == True:
                    sprite.reset()
                    break

        #time = pygame.time.get_ticks()
        #sprite.update(time)
        #screen.blit(sprite.image, (0,0))

        pygame.display.update()