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

Time:02-03

First time ever working with Pygame for a school assignment and I'm following a tutorial for it with my project members (tutorial link https://youtu.be/AY9MnQ4x3zk). Problem is that despite following the tutorial to the dot at the "animating the player", my character (named "Marko" in the game and code) doesn't have his animation playing. When I start the game the character is stuck on it's first frame of animation. I've created a 3-frame animation and have the frames as separate png-files. The game so far itself works (it's on very beginner level, just a couple spawning enemies, collision and intro screens done so far), but the animation has had me and my project group scratching our heads for days. So far haven't found a solution by Googling nor searching here.

Also at the "# Marko's animations" -part "marko" is darkened and when hovering mouse on it, it says ""(variable) marko: Surface - "marko" is not accessed Pylance""

Here's the entire code:

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

CodePudding user response:

marko is a variable in global namespace. You must use the global statement to change a variable in the global namespace within a function:

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)]
  •  Tags:  
  • Related