Проблема с анимацией персонажа при использовании Pygame с функциями - PullRequest
0 голосов
/ 12 ноября 2018

Я хотел бы попросить вашей помощи для решения этой моей проблемы. Мне нужно разработать игру, используя только функции (без классов) в Pygame.

Мне уже удается запустить игру, но анимации или спрайты не обновляются должным образом. Изображение всегда остается неизменным, когда оно должно изменяться во время движения.

Что я делаю не так?

Вот код:

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

Я уже проверил это и сравнил его с другими кодами, но я просто не могу найти, в чем реальная проблема.

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Простое исправление уже упоминалось, но я бы скорее предложил полностью избавиться от глобальных переменных и просто переместить их в функцию с помощью основного цикла, чтобы сделать их локальными.

Кроме того, функция drawCharacter не должна нести ответственность за обновление walkCount, а также за стирание изображений.Я бы просто удалил его и обновил walkCount в предложениях if key[pygame.K_LEFT]..., а затем использовал его, чтобы присвоить текущему изображению игрока переменную (player_image), которую вы можете пометить позже в разделе рисования.Это позволяет вам избавиться и от переменных left и right.

Функция drawCharacter будет состоять только из этих двух строк,

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

, так что выможно просто вызвать их в главном цикле, вместо того, чтобы вызывать их в функции (которой вы должны передать эти аргументы).

Кстати, вызывать методы convert или convert_alpha, когдаВы загружаете изображения для повышения производительности.

Вот обновленный код:

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()
0 голосов
/ 12 ноября 2018

Это потому, что left и right в функции draw являются локальными переменными, а не глобальными.

Простым решением является добавление

global left                                
global right

в началеdraw.


Мне нужно разработать игру с использованием только функций (БЕЗ КЛАССОВ) в Pygame

Это странное требование, учитывая, что сама Pygame полнаклассов, и вы уже используете некоторые из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...