python - 改变 Sprite 动画速度(pygame)

标签 python animation pygame sprite-sheet

我设法使用我创建的“动画”功能为我的播放器设置动画 - 在角色移动时循环浏览每帧的角色图像列表。然而,我还发现这种情况发生的速度与游戏运行的速度相同;并希望有一种简单的方法来改变它,以便 Sprite 的动画速度比游戏 FPS 慢。

这是我的 Sprite 类代码:

class Civilian(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.all_sprites, game.player1group, game.bothplayers
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self._layer = PLAYER1_LAYER
        self.image = pg.Surface((61, 67))
        self.rect = self.image.get_rect()
        self.hit_rect = PLAYER_HIT_RECT
        self.hit_rect.center = self.rect.center
        self.playerspeed = 90
        self.vel = vec(0, 0)
        self.pos = vec(x , y)
        self.move = 0
        self.speedboost = False
        self.last_dir = 'down'#
        self.anim_speed = 0

    def animate(self, direction):
        if direction == 'right':
            self.spritesheet = pg.image.load('walk right civ.png') # Loading the right directional movement spritesheet into the variable
        if direction == 'left':
            self.spritesheet = pg.image.load('walk left civ.png')
        if direction == 'up':
            self.spritesheet = pg.image.load('walk up civ.png')
        if direction == 'down':
            self.spritesheet = pg.image.load('walk down civ.png')
        self.frames = [] # List which will contain each cell of the spritesheet
        # Adding the cells to the list #
        self.frames.append(self.spritesheet.subsurface(pg.Rect(0, 0, 61, 67)).convert_alpha())
        self.frames.append(self.spritesheet.subsurface(pg.Rect(61, 0, 61, 67)).convert_alpha())
        self.frames.append(self.spritesheet.subsurface(pg.Rect(122, 0, 61, 67)).convert_alpha())
        self.frames.append(self.spritesheet.subsurface(pg.Rect(183, 0, 61, 67)).convert_alpha())
        self.frames.append(self.spritesheet.subsurface(pg.Rect(244, 0, 61, 67)).convert_alpha())
        self.frames.append(self.spritesheet.subsurface(pg.Rect(305, 0, 61, 67)).convert_alpha())
        self.frames.append(self.spritesheet.subsurface(pg.Rect(366, 0, 61, 67)).convert_alpha())
        self.frames.append(self.spritesheet.subsurface(pg.Rect(427, 0, 61, 67)).convert_alpha())
        self.frames.append(self.spritesheet.subsurface(pg.Rect(488, 0, 61, 67)).convert_alpha())
        # Number of frames/cells
        self.frames_number = len(self.frames)
        # Current animation frame
        self.current_frame = 0
        # Frame rectangle
        self.frame_rect = self.frames[0].get_rect()
        self.last_dir = direction

    def get_keys(self):
        self.vel= vec(0, 0)
        keys = pg.key.get_pressed()

        if keys[pg.K_a]:    # Const. subtracts player speed from velocity (E.g. Moves sprite to the left)
            self.vel.x= -self.playerspeed
            self.move += 1
            self.moving = 'left' # Uses different spritesheet depending on direction
        elif keys[pg.K_d]:    # Const. adds player speed value to velocity (E.g. Moves sprite to the right)
            self.vel.x= self.playerspeed
            self.move += 1
            self.moving = 'right'
        elif keys[pg.K_w]:    # Const. subtracts player speed value from y velocity (Moves player upwards; opposite)
            self.vel.y= -self.playerspeed
            self.move += 1
            self.moving = 'up'
        elif keys[pg.K_s]: # Const. adds player speed value to y velocity (Moves player downwards; opposite)
            self.vel.y= self.playerspeed
            self.move += 1
            self.moving = 'down'

    def add_speed(self):
        pass

    def collide_with_player2(self, dir, ifColliding):
        if dir == 'x':
            collides = pg.sprite.spritecollide(self, self.game.player2group, False, collide_player_hit_rect)
            if collides:
                if self.vel.x > 0:
                    self.pos.x = collides[0].hit_rect.left - self.hit_rect.width / 2
                if self.vel.x < 0:
                    self.pos.x = collides[0].hit_rect.right + self.hit_rect.width / 2
                self.vel.x = 0
                self.hit_rect.centerx = self.pos.x
                print("collide x")
                if random.randint(0, 100) <= 4:
                    random.choice(self.game.thief_hit_sounds).play()
                self.ifColliding = True

        if dir == 'y':
            collides = pg.sprite.spritecollide(self, self.game.player2group, False, collide_player_hit_rect)
            if collides:
                if self.vel.y > 0:
                    self.pos.y = collides[0].hit_rect.top - self.hit_rect.height / 2
                if self.vel.y < 0:
                    self.pos.y = collides[0].hit_rect.bottom + self.hit_rect.height / 2
                self.vel.y = 0
                self.hit_rect.centery = self.pos.y
                print("collide y")
                if random.randint(0, 100) <= 4:
                    random.choice(self.game.thief_hit_sounds).play()
                self.ifColliding = True

    def collide_with_walls(self, dir):
        if dir == 'x':
            collides = pg.sprite.spritecollide(self, self.game.walls, False, collide_hit_rect)
            if collides:
                if self.vel.x > 0:
                    self.pos.x = collides[0].rect.left - self.hit_rect.width / 2
                if self.vel.x < 0:
                    self.pos.x = collides[0].rect.right + self.hit_rect.width / 2
                self.vel.x = 0
                self.hit_rect.centerx = self.pos.x
        if dir == 'y':
            collides = pg.sprite.spritecollide(self, self.game.walls, False, collide_hit_rect)
            if collides:
                if self.vel.y > 0:
                    self.pos.y = collides[0].rect.top - self.hit_rect.height / 2
                if self.vel.y < 0:
                    self.pos.y = collides[0].rect.bottom + self.hit_rect.height / 2
                self.vel.y = 0
                self.hit_rect.centery = self.pos.y

    def update(self):
        # frame updates
        self.anim_speed += 1
        self.moving = 'idle'
        self.animate(self.last_dir) # Sets the down spritesheet as default
        self.get_keys()
        if self.moving == 'up':
            self.animate(self.moving) # Uses the up-movement spritesheet if char moving upwards
        if self.moving == 'down':
            self.animate(self.moving) # Same as above, different direction
        if self.moving == 'left':
            self.animate(self.moving)
        if self.moving == 'right':
            self.animate(self.moving)
        self.ifColliding = False




        self.rect.center = self.pos
        self.pos += self.vel * self.game.dt
        self.hit_rect.centerx = self.pos.x
        self.collide_with_walls('x'), self.collide_with_player2('x', self.ifColliding)
        self.hit_rect.centery = self.pos.y
        self.collide_with_walls('y'), self.collide_with_player2('y', self.ifColliding)
        self.rect.center = self.hit_rect.midtop




        if self.ifColliding == True:
            Thief.health -= COL_DAMAGE
            print(Thief.health)
        self.current_frame = (self.current_frame + self.move) % self.frames_number
        if self.moving == 'idle':
            self.current_frame = 0
        self.image = self.frames[self.current_frame] # Image of sprite changes as program cycles through the sheet

最佳答案

您可以通过以某种方式将动画速率与帧速率绑定(bind)到时间来将动画速率与帧速率解耦。

一种方法是使用pygame.time.get_ticks()返回自调用 pygame.init() 以来的毫秒数。如果您存储此值,您可以测量已经过去了多少时间并适本地设置动画。

def update(self):
    self.elapsed = pygame.time.get_ticks() - self.elapsed
    if self.elapsed > 500: # animate every half second
        self.animate()

注意:您还需要在构造函数中初始化 self.elapsed

关于python - 改变 Sprite 动画速度(pygame),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49237363/

相关文章:

python - 最常见单词或短语的 FreqDist

javascript - 如何设置一个随着窗口大小变化而变化的位置

java - 如何在 Swing 中淡化图像?

android - Lottie 动画填充

python - 在 Pygame 中,当移动到游戏窗口上的另一个位置时,图像不会被删除

python - 如何安装pygame字体

python - Django CSRF 检查因 Ajax POST 请求而失败

python - 从 Python 编写真正的原始二进制文件

python - Django:ValueError:当前限制超过最大限制

python - 无法使 Sprite 在pygame中不可见