2

I would like to ask your help for solving this problem of mine. I need to develop a game using only functions (NO CLASSES) in pygame.

I already manage to run the game but the animations or sprites do not update as they should. The image always stays the same when it should be changing while moving.

What am I doing wrong?

Here's the code:

import pygame               

WIDTH = 800     
HEIGHT= 600      
pygame.display.set_caption("Nico's worst adventure")    
window = pygame.display.set_mode((WIDTH, HEIGHT))        

#Color         #R       #G      #B
White =      (255,     255,    255)
Black =       (0,       0,      0)
Red =        (255,     0,      0)
Blue =        (0,       0,      255)

#Position
x = 50
y = 425

imageWidth = 64

vel = 5                 #Velocity of movement

isJumping = False   
jumpCount = 10     

left = False       
right = False         
walkCount = 0   

#Image port
walkRight = [pygame.image.load('Nico right(1).png'), pygame.image.load('Nico right(2).png'), pygame.image.load('Nico right(3).png'), pygame.image.load('Nico right(4).png')]
walkLeft = [pygame.image.load('Nico left(1).png'), pygame.image.load('Nico left(2).png'), pygame.image.load('Nico left(3).png'), pygame.image.load('Nico left(4).png')]
still = pygame.image.load('Nico still.png')
backgorund = pygame.image.load('Fondo.png')



def drawCharacter():
    global walkCount                              
    window.blit(backgorund, (0,0))                           
    if walkCount + 1 >= 12:            
        walkCount = 0                  

    if left:
        window.blit(walkLeft[walkCount//3], (x, y))
        walkCount += 1
    elif right:
        window.blit(walkRight[walkCount//3], (x, y))
        walkCount += 1
    else:
        window.blit(still, (x, y))

    pygame.display.update()


def draw():
    global imageWidth
    global WIDTH
    global x                                           
    global y                                             
    global vel                                           
    global jumpCount                               
    global isJumping                                
    clock = pygame.time.Clock()                          
    play = True                                    
    #Main loop
    while play:                                       
        clock.tick(27)                                   
        pygame.init()                                  

        for event in pygame.event.get():               
            if event.type == pygame.QUIT:               
                play = False                          

        key = pygame.key.get_pressed()                 
        if key[pygame.K_LEFT] and x > vel:               
            x -= vel
            left = True
            right = False

        elif key[pygame.K_RIGHT] and x < WIDTH - imageWidth - vel:              
            x += vel
            right = True
            left = False
        else:                                          
            right = False
            left = False
            walkCount = 0                         

        if not(isJumping):                            
            if key[pygame.K_SPACE]:
                isJumping = True
                right = False
                left = False
                walkCount = 0

        else:
            if jumpCount >= -10:                        
                neg = 1                                    
                if jumpCount < 0:
                    neg = -1
                y -= (jumpCount ** 2) * 0.5 * neg      
                jumpCount -= 1
            else:
                isJumping = False
                jumpCount = 10


        drawCharacter()
        pygame.display.flip()


    pygame.quit()

draw()

I have already checked it and compared it to other codes but I just can't find what's the real problem.

2 Answers 2

1

The simple fix has already been mentioned, but I'd rather suggest getting rid of the global variables altogether and just moving them into the function with the main loop to make them local.

Also, the drawCharacter function shouldn't be responsible to update the walkCount as well as blitting the images. I'd just remove it and update the walkCount in the if key[pygame.K_LEFT]... clauses and then use it to assign the current player image to a variable (player_image) which you can blit later in the drawing section. That allows you to get rid of the left and right variables, too.

The drawCharacter function would then only consist of these two lines,

window.blit(background, (0, 0))
window.blit(player_image, (x, y))

so you could simply call them in the main loop as well instead of calling them in the function (to which you would have to pass these arguments).

By the way, call the convert or convert_alpha methods when you load the images to improve the performance.

Here's the updated code:

import pygame


pygame.init()
WIDTH = 800
HEIGHT= 600
pygame.display.set_caption("Nico's worst adventure")
window = pygame.display.set_mode((WIDTH, HEIGHT))

White = (255, 255, 255)
Black = (0, 0, 0)
Red = (255, 0, 0)
Blue = (0, 0, 255)
# Images (I assume you're using pictures with a transparent background
# so I call the `convert_alpha` method).
walkRight = [
    pygame.image.load('Nico right(1).png').convert_alpha(),
    pygame.image.load('Nico right(2).png').convert_alpha(),
    pygame.image.load('Nico right(3).png').convert_alpha(),
    pygame.image.load('Nico right(4).png').convert_alpha(),
    ]
walkLeft = [
    pygame.image.load('Nico left(1).png').convert_alpha(),
    pygame.image.load('Nico left(2).png').convert_alpha(),
    pygame.image.load('Nico left(3).png').convert_alpha(),
    pygame.image.load('Nico left(4).png').convert_alpha(),
    ]
still = pygame.image.load('Nico still.png').convert_alpha()
background = pygame.image.load('Fondo.png').convert()



def game():
    clock = pygame.time.Clock()
    # Player related variables.
    x = 50
    y = 425
    imageWidth = 64
    vel = 5
    isJumping = False
    jumpCount = 10
    walkCount = 0
    player_image = still  # Assign the current image to a variable.

    play = True
    while play:
        clock.tick(27)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                play = False

        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT] and x > vel:
            x -= vel
            # Update the walkCount and image here.
            walkCount += 1
            player_image = walkRight[walkCount//3]
        elif key[pygame.K_RIGHT] and x < WIDTH - imageWidth - vel:
            x += vel
            walkCount += 1
            player_image = walkLeft[walkCount//3]
        else:
            player_image = still
            walkCount = 0

        if walkCount + 1 >= 12:
            walkCount = 0

        if not isJumping:
            if key[pygame.K_SPACE]:
                isJumping = True
                walkCount = 0
        else:
            if jumpCount >= -10:
                neg = 1
                if jumpCount < 0:
                    neg = -1
                y -= (jumpCount ** 2) * 0.5 * neg
                jumpCount -= 1
            else:
                isJumping = False
                jumpCount = 10

        window.blit(background, (0, 0))
        window.blit(player_image, (x, y))  # Just blit the current image.
        pygame.display.flip()  # Only one `flip()` or `update()` call per frame.


game()
pygame.quit()
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, :,) I'm really thankful with you. Basically you have saved my semester :D thks
1

It's because left and right in the draw function are local variables, not global.

A simple fix is to add

global left                                
global right

at the beginning of draw.


I need to develop a game using only functions (NO CLASSES) in pygame

That's a strange requirement given that pygame itself is full of classes and you use some of them already.

1 Comment

Thank you, :,) I'm really thankful with you. Basically you have saved my semester :,D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.