You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame角色动画帧切换过快的问题求助

Pygame角色动画帧切换过快的问题求助

我的角色现在帧切换速度快得离谱,完全不知道问题出在哪。我试过调整self.animation_speed,但除了游戏启动时会卡顿一下之外,根本起不到控制帧速的作用。有没有人能帮忙看看怎么修复?

补充一下:get_frect是浮点版本的get_rect,非常实用,它来自pygame的扩展库pygame-ce。

import pygame
from random import randint
from os.path import isfile, join

pygame.init()

class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.idle_spritesheet = pygame.image.load(join('images', 'Unarmed_Idle', 'Unarmed_Idle_full.png')).convert_alpha()
        self.walk_spritesheet = pygame.image.load(join('images', 'Unarmed_Walk', 'Unarmed_Walk_full.png')).convert_alpha()
        self.run_spritesheet = pygame.image.load(join('images', 'Unarmed_Run', 'Unarmed_Run_Full.png')).convert_alpha()
        self.frame_width = 64
        self.frame_height = 64
        scale = (120,120)

        # Idle Frames List
        idle_frame_count = {
            'idledown': 12,
            'idleleft': 12,
            'idleright': 12,
            'idleup': 3
        }
        # Walk Frames List
        walk_frame_count = {
            'walkdown': 6,
            'walkleft': 6,
            'walkright': 6,
            'walkup': 6
        }
        # Run Frames List
        run_frame_count = {
            'rundown': 8,
            'runleft': 8,
            'runright': 8,
            'runup': 8
        }

        # List of Animations with properties
        self.animation_list = {
            'idle': {'down': [],'left': [], 'right': [], 'up': []},
            'walk': {'down': [],'left': [], 'right': [], 'up': []},
            'run': {'down': [], 'left': [], 'right': [], 'up': []}
        }

        x_offset = 0
        
        # Idle 
        for i in range(idle_frame_count['idledown']):
            frames = self.idle_spritesheet.subsurface((x_offset, 0, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['idle']['down'].append(frames)
            x_offset += self.frame_width
        x_offset = 0
        for i in range(idle_frame_count['idleleft']):
            frames = self.idle_spritesheet.subsurface((x_offset, 64, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['idle']['left'].append(frames)
            x_offset += self.frame_width
        x_offset = 0
        for i in range(idle_frame_count['idleright']):
            frames = self.idle_spritesheet.subsurface((x_offset, 128, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['idle']['right'].append(frames)
            x_offset += self.frame_width
        x_offset = 0
        for i in range(idle_frame_count['idleup']):
            frames = self.idle_spritesheet.subsurface((x_offset, 192, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['idle']['up'].append(frames)
            x_offset += self.frame_width

        # Walk
        x_offset = 0
        for i in range(walk_frame_count['walkdown']):
            frames = self.walk_spritesheet.subsurface((x_offset, 0, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['walk']['down'].append(frames)
            x_offset += self.frame_width
        x_offset = 0
        for i in range(walk_frame_count['walkleft']):
            frames = self.walk_spritesheet.subsurface((x_offset, 64, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['walk']['left'].append(frames)
            x_offset += self.frame_width
        x_offset = 0
        for i in range(walk_frame_count['walkright']):
            frames = self.walk_spritesheet.subsurface((x_offset, 128, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['walk']['right'].append(frames)
            x_offset += self.frame_width
        x_offset = 0
        for i in range(walk_frame_count['walkup']):
            frames = self.walk_spritesheet.subsurface((x_offset, 192, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['walk']['up'].append(frames)
            x_offset += self.frame_width

        # Run
        x_offset = 0
        for i in range(run_frame_count['rundown']):
            frames = self.run_spritesheet.subsurface((x_offset, 0, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['run']['down'].append(frames)
            x_offset += self.frame_width
        x_offset = 0
        for i in range(run_frame_count['runleft']):
            frames = self.run_spritesheet.subsurface((x_offset, 64, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['run']['left'].append(frames)
            x_offset += self.frame_width
        x_offset = 0
        for i in range(run_frame_count['runright']):
            frames = self.run_spritesheet.subsurface((x_offset, 128, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['run']['right'].append(frames)
            x_offset += self.frame_width
        x_offset = 0
        for i in range(run_frame_count['runup']):
            frames = self.run_spritesheet.subsurface((x_offset, 192, self.frame_width, self.frame_height))
            frames = pygame.transform.scale(frames, scale)
            self.animation_list['run']['up'].append(frames)
            x_offset += self.frame_width
        x_offset = 0

        self.action = 'idle'
        self.direction = 'right'
        self.current_frame = 0
        self.image = self.animation_list[self.action][self.direction][self.current_frame]
        self.rect = self.image.get_frect(center=(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2))
        self.animation_speed = 0.3
        self.last_update = pygame.time.get_ticks()
        self.speed = 0.3

    def update(self):
        now = pygame.time.get_ticks()
        keys = pygame.key.get_pressed()
        moving = False

        if keys[pygame.K_RIGHT]: 
            self.action = 'walk'; self.direction = 'right'; moving = True
            self.rect.x += self.speed
        elif keys[pygame.K_LEFT]: 
            self.action = 'walk'; self.direction = 'left'; moving = True
            self.rect.x -= self.speed
        elif keys[pygame.K_UP]: 
            self.action = 'walk'; self.direction = 'up'; moving = True
            self.rect.y -= self.speed
        elif keys[pygame.K_DOWN]: 
            self.action = 'walk'; self.direction = 'down'; moving = True
            self.rect.y += self.speed
        else: self.action = 'idle'

        if now - self.last_update > self.animation_speed * 1000:
            now = self.last_update
            frames = self.animation_list[self.action][self.direction]
            self.current_frame = (self.current_frame + 1) % len(frames)
            self.image = frames[self.current_frame]



WINDOW_WIDTH, WINDOW_HEIGHT = 900, 600
screen = pygame.display.set_mode((WINDOW_HEIGHT, WINDOW_HEIGHT))
pygame.display.set_caption('Male Top-Down SpriteSheet Test')
run = True
clock = pygame.time.Clock()

player = Player()
all_sprites = pygame.sprite.Group(player)

while run:
    dt = clock.tick() / 1000
    screen.fill('black')
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    
    all_sprites.update()
    all_sprites.draw(screen)

    pygame.display.update()

pygame.quit()
exit()

我试过调整self.animation_speed,但只会导致游戏启动时卡顿,之后帧速还是快得不正常。也试过修改帧率,但那样移动的时候角色会出现“瞬移”的情况,完全没法玩。

备注:内容来源于stack exchange,提问作者Ette

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:17:56