Pygame 初学者,播放器动画尽管按照教程做了但还是不工作

Pygame beginner, player animation not working despite doing it by the tutorial

第一次与 Pygame 一起完成学校作业,我正在与我的项目成员一起学习教程(教程 link https://youtu.be/AY9MnQ4x3zk)。 问题是,尽管遵循了“为玩家设置动画”的教程,但我的角色(在游戏和代码中名为“Marko”)没有播放他的动画。当我开始游戏时,角色停留在它的第一帧动画上。我创建了一个 3 帧动画并将帧作为单独的 png 文件。到目前为止,游戏本身是可行的(它处于非常初级的水平,到目前为止只生成了几个生成的敌人、碰撞和介绍屏幕),但是动画让我和我的项目组绞尽脑汁好几天了。到目前为止还没有通过谷歌搜索或在这里搜索找到解决方案。

同样在“# Marko's animations”部分,“marko”变暗,当将鼠标悬停在其上时,它显示“”(可变)marko:Surface - “marko”未访问 Pylance”“

完整代码如下:

import sys
from pygame.locals import *
from random import randint
from pygame import mixer

pygame.init()

width = 1920
height = 1080
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("Putkimies Marko")
start_time = 0
score = 0
nopeus = [3,3]
clock = pygame.time.Clock()
game_active = False
marko_gravity = 0

# Score
def display_score():
    current_time = int(pygame.time.get_ticks() / 1000) - start_time
    score_surf = test_font.render(f'Score: {current_time}',False,(black))
    score_rect = score_surf.get_rect(center = (900,50))
    screen.blit(score_surf,score_rect)
    return current_time


def obstacle_movement(obstacle_list):
    if obstacle_list:
        for obstacle_rect in obstacle_list:
            obstacle_rect.x -= 5 
            if obstacle_rect.bottom == 955:
                screen.blit(rat,obstacle_rect)
            else: 
                screen.blit(fly,obstacle_rect)
            
        return obstacle_list
    else: return[]    


def collisions(marko,obstacles):
    if obstacles:
        for obstacle_rect in obstacles:
            if marko.colliderect(obstacle_rect): return False
    return True


# Surfaces
background = pygame.image.load("marko_background.png").convert_alpha()
sewer = pygame.image.load("background_sewer.png").convert_alpha()
ground = pygame.image.load("ground.png").convert_alpha()
rat = pygame.image.load("rat.png").convert_alpha()
game_over = pygame.image.load("game_over.png").convert_alpha()
fly = pygame.image.load("fly.png").convert_alpha()

# Marko Surfaces
marko_run_1 = pygame.image.load("marko_run_1.png").convert_alpha()
marko_run_2 = pygame.image.load("marko_run_2.png").convert_alpha()
marko_run_3 = pygame.image.load("marko_run_3.png").convert_alpha()
marko_run = [marko_run_1,marko_run_2,marko_run_3]
marko_index = 0
marko_jump = pygame.image.load("marko_jump.png").convert_alpha()
marko = marko_run[marko_index]

# Fonts
test_font = pygame.font.Font("supermario.ttf", 50)

# Colors
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
light_blue = (94,129,162)
purple = (36,5,83)

# Rects
game_overSurface = game_over.get_rect(midtop = (970,-200))
platform = pygame.Surface((300,50))
groundSurface = ground.get_rect(midtop = (960,480))
markoSurface = marko.get_rect()
text_surface = test_font.render('Putkimies Marko', False, red)

markoSurface.left = 50
markoSurface.bottom = 714

# Obstacles
obstacle_rect_list = []

# Intro screen
player_stand = pygame.image.load("putkimies_marko_idle.png")
player_stand = pygame.transform.rotozoom(player_stand,0,2)
player_stand_rect = player_stand.get_rect(center = (950,500))

game_name = test_font.render("PUTKIMIES MARKO", False,"Black")
game_name_rect = game_name.get_rect(center = (950,350))

game_message = test_font.render('PRESS SPACE TO PLAY',False,"Black")
game_message_rect = game_message.get_rect(center = (950,650))
game_message_start_again = test_font.render('PRESS SPACE TO PLAY AGAIN',False,"Black")
game_message_start_again_rect = game_message.get_rect(center = (850,720))

# Marko's animations
def marko_animation():
    global markoSurface, marko_index
    if markoSurface.bottom < 955:
        marko = marko_jump
    else:
        marko_index += 0.1
        if marko_index >= len(marko_run):marko_index = 0
        marko = marko_run[int(marko_index)]

# Timer
obstacle_timer = pygame.USEREVENT + 1
pygame.time.set_timer(obstacle_timer,1500)

# Background music
mixer.music.load('smb_stage_clear.wav')
mixer.music.play(0)
# -1 Makes the music loop

while True:
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()
        if game_active:
            if event.type == KEYDOWN:
                if event.key == K_SPACE and markoSurface.bottom >= 955:
                    marko_gravity = -18
        else:
            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                game_active = True
                start_time = int(pygame.time.get_ticks() / 1000)
        
        if event.type == obstacle_timer and game_active:
            if randint (0,2):
                 obstacle_rect_list.append(rat.get_rect(midbottom = (randint(2000,2200),955)))
            else:
                 obstacle_rect_list.append(fly.get_rect(midbottom = (randint(2000,2200),855)))




    if game_active:
        # Draw 
        screen.blit(sewer, (0,0))
        screen.blit(ground, (0,955))
        marko_animation()
        screen.blit(marko,markoSurface)
        score = display_score()

        # Key uses
        key_use = pygame.key.get_pressed()
        if key_use[K_LEFT]:
            markoSurface.move_ip((-7,0))
        if key_use[K_RIGHT]:
            markoSurface.move_ip((7,0))

        # Marko
        marko_gravity += 1
        markoSurface.y += marko_gravity
        if markoSurface.bottom >= 955: markoSurface.bottom = 955
        if markoSurface.left <= 0: markoSurface.left = 0
        if markoSurface.right >= 1920: markoSurface.right = 1920
    
        # Obstacle movement
        obstacle_rect_list = obstacle_movement(obstacle_rect_list)

        # Collision
        game_active = collisions(markoSurface,obstacle_rect_list)

    else: # Intro screen
        screen.fill ("Light blue")
        screen.blit(player_stand,player_stand_rect)
        obstacle_rect_list.clear()
        markoSurface.left = 80 # returns marko to 80 

        # Draws score message if score > 0 
        score_message = test_font.render(f'Your score: {score}',False,(red))
        score_message_rect = score_message.get_rect(center = (950,650))
        screen.blit(game_name,game_name_rect)
        

        if score == 0: screen.blit(game_message,game_message_rect)
        else:
            screen.blit(score_message,score_message_rect)
            screen.blit(game_over,game_overSurface)
            screen.blit(game_message_start_again,game_message_start_again_rect)

    pygame.display.update()
    clock.tick(60)```

marko 是全局命名空间中的一个变量。您必须使用 global statement 来更改函数内全局命名空间中的变量:

def marko_animation():
    
    global marko          # <---
    
    global marko_index
    
    if markoSurface.bottom < 955:
        marko = marko_jump
    else:
        marko_index += 0.1
        if marko_index >= len(marko_run):
            marko_index = 0
        marko = marko_run[int(marko_index)]