2013-10-07 2 views
2

Я подготовил код, который тестирует анимацию в программе pygame, которую я сделал. Интерпретатор проходит через это чисто, но когда я пытаюсь запустить его, он остается замороженным. Кнопка X не работает, и символ игрока остается замороженным в углу и не будет двигаться вообще.Персонаж замораживается на игре Pygame

Окно терминала не выводит никаких ошибок, и я придерживаюсь того, как он не движется или нет. Любая помощь или понимание будут оценены.

import pygame 

# Define some colors 
black = ( 0, 0, 0) 
white = (255, 255, 255) 
red  = (255, 0, 0) 

faceWhatDirection = 4 
keyDown = False 

class Player(pygame.sprite.Sprite): 

    #constructor function 
    def __init__(self): #what this is doing is declaring a self variable and an x and y varible 

     #call up the parent's constructor 
     pygame.sprite.Sprite.__init__(self) 

     #List of images for different types of movement 
     self.imagesLeft = [] 

     self.imagesRight = [] 

     self.imagesUp = [] 

     self.imagesDown = [] 

     #load the up images 
     img = pygame.image.load("man1_bk1.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesUp.append(img) #adds the image to the list 

     img = pygame.image.load("man1_bk2.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesUp.append(img) #adds the image to the list 

     #load the down images 

     img = pygame.image.load("man1_fr1.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesDown.append(img) #adds the image to the list 

     img = pygame.image.load("man1_fr2.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesDown.append(img) #adds the image to the list 

     #load the left images 
     img = pygame.image.load("man1_lf1.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesLeft.append(img) #adds the image to the list 

     img = pygame.image.load("man1_lf2.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesLeft.append(img) #adds the image to the list 

     #load the right images 
     img = pygame.image.load("man1_rt1.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesRight.append(img) #adds the image to the list 

     img = pygame.image.load("man1_rt2.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesRight.append(img) #adds the image to the list 

     #the best image to use by default is the one that has the player facing the screen. 
     self.image=self.imagesDown[0] 

     #This line of code, as the Programming website showed me, gets the dimensions of the image 
     #Rect.x and rect.y are the coordinates of the rectangle object, measured at the upper right 
     #hand corner 

     self.rect = self.image.get_rect() 

    def changeImage(self): 

     ## 
     ## FUNCTION THAT UPDATES THE IMAGES AND CYCLES THROUGH THEM 
     ## 

     #if player is going left 
     while faceWhatDirection == 1 and keyDown == True: 
      self.image =self.imagesLeft[0] 
      self.image =self.imagesLeft[1] 

     #if player is going right 
     while faceWhatDirection == 2 and keyDown == True: 
      self.image =self.imagesRight[0] 
      self.image =self.imagesRight[1] 

     #if player is going up 
     while faceWhatDirection == 3 and keyDown == True: 
      self.image =self.imagesUp[0] 
      self.image =self.imagesUp[1] 

     #if player is going down 
     while faceWhatDirection == 4 and keyDown == True: 
      self.image =self.imagesDown[0] 
      self.image =self.imagesDown[1] 






#initialize pygame 
pygame.init() 

#set the height and width of the screen 
width = 800 
height = 480 

mainScreen = pygame.display.set_mode([width,height]) 

#A list off all of the sprites in the game 
all_sprites_list = pygame.sprite.Group() 

#creates a player object 
player = Player() 
all_sprites_list.add(player) 

#a conditional for the loop that keeps the game running until the user Xes out 
done = False 

#clock for the screen updates 
clock = pygame.time.Clock() 

while done==False: 
    for event in pygame.event.get(): #user did something 
     if event.type == pygame.QUIT: #if the user hit the close button 
       done=True 

     if event.type == pygame.KEYDOWN: # if the user pushes down a key 
      if event.key == pygame.K_LEFT: #if the left arrow key is pressed 
       player.rect.x -=1 
       faceWhatDirection = 1 
       keyDown = True 
      if event.key == pygame.K_RIGHT: #if the left arrow key is pressed 
       player.rect.x +=1 
       faceWhatDirection = 2 
       keyDown = True 
      if event.key == pygame.K_UP: #if the left arrow key is pressed 
       player.rect.y -=1 
       faceWhatDirection = 3 
       keyDown = True 
      if event.key == pygame.K_DOWN: #if the left arrow key is pressed 
       player.rect.y +=1 
       faceWhatDirection = 4 
       keyDown = True 

     if event.type == pygame.KEYUP: # if the user pushes down a key 
      if event.key == pygame.K_LEFT: #if the left arrow key is pressed 
       keyDown = False 
      if event.key == pygame.K_RIGHT: #if the left arrow key is pressed 
       keyDown = False 
      if event.key == pygame.K_UP: #if the left arrow key is pressed 
       keyDown = False 
      if event.key == pygame.K_DOWN: #if the left arrow key is pressed 
       keyDown = False 


    mainScreen.fill(white)#makes the background white, and thus, the white part of the images will be invisible 
    player.changeImage() 

    #draw the sprites 
    all_sprites_list.draw(mainScreen) 

    #limit the game to 20 fps 
    clock.tick(20) 

    #update the screen on the regular 
    pygame.display.flip() 

pygame.quit() 

if __name__ == '__main__': 
    main() 
+0

Ваш 'changeImage()' функция выглядит странно. Я думаю, что когда вы нажмете клавишу со стрелкой, ваш глобальный «keydown» изменится на «True», и программа застрянет внутри 'changeImage()' в одном из циклов while. – Milo

ответ

3

Проблема заключается в этот бит:

def changeImage(self): 

    ## 
    ## FUNCTION THAT UPDATES THE IMAGES AND CYCLES THROUGH THEM 
    ## 

    #if player is going left 
    while faceWhatDirection == 1 and keyDown == True: 
     self.image =self.imagesLeft[0] 
     self.image =self.imagesLeft[1] 

    #if player is going right 
    while faceWhatDirection == 2 and keyDown == True: 
     self.image =self.imagesRight[0] 
     self.image =self.imagesRight[1] 

    #if player is going up 
    while faceWhatDirection == 3 and keyDown == True: 
     self.image =self.imagesUp[0] 
     self.image =self.imagesUp[1] 

    #if player is going down 
    while faceWhatDirection == 4 and keyDown == True: 
     self.image =self.imagesDown[0] 
     self.image =self.imagesDown[1] 

Для того, чтобы любой из while петель до конца, направление лицо должно измениться, и ключ должен быть отменен. Тем не менее, для этого не существует возможного способа, так как код для изменения любого из них находится внутри mainloop.

Кроме того, изменение изображения в два раза является избыточным. Если вы пытаетесь сделать анимацию, вам нужно не забудьте позвонить pygame.display.flip() между каждым изменением изображения.

Вместо этого я напишу ваш код, чтобы посмотреть что-то вроде ниже. (Внимание! Я не проверял этот код, так как у меня нет файлов изображений, так что может быть несколько ошибок здесь и там. Я предполагаю, что ГИФС не анимированный)

import pygame 
import sys 

# Define some colors 
black = ( 0, 0, 0) 
white = (255, 255, 255) 
red  = (255, 0, 0) 

class Player(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 

     self.images = { 
      'left': self.load_animation('man1_lf1.gif', 'man1_lf2.gif'), 
      'right': self.load_animation('man1_rt1.gif', 'man1_rt2.gif') 
      'up': self.load_animation('man1_bk1.gif', 'man1_bk2.gif') 
      'down': self.load_animation('man1_fr1.gif', 'man1_fr2.gif') 
     } 

     self.direction = 'down' 
     self.moving = False 

     # Arbitrary starting coordinates 
     self.x = 5 
     self.y = 5 

    def load_animation(self, *names): 
     output = [] 
     for name in names: 
      img = pygame.image.load(name).convert() 
      img.set_colorkey(white) 
     return output 

    @property 
    def image(self): 
     seconds = pygame.time.get_ticks()/1000 
     # Returns the time in milliseconds since the game started 
     image_index = seconds % 2: 

     # Returns a new image every second 
     if self.moving: 
      return self.images[self.direction][image_index] 
     else: 
      return self.images[self.direction][0] 

    @property 
    def rect(self): 
     image_rect = self.get_image().get_rect() 
     return pygame.Rect((self.x, self.y), image_rect.size) 


def main(): 
    pygame.init() 

    width = 800 
    height = 480 
    mainScreen = pygame.display.set_mode([width,height]) 

    player = Player() 

    all_sprites_list = pygame.sprite.Group() 
    all_sprites_list.add(player) 

    clock = pygame.time.Clock() 

    while True: 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       pygame.quit() 
       sys.exit() 

      if event.type == pygame.KEYUP: 
       if event.key in (pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN): 
        player.moving = False 

      if event.type == pygame.KEYDOWN: 
       player.moving = True 
       if event.key == pygame.K_LEFT: 
        player.x -= 1 
        player.direction = 'left' 
       if event.key == pygame.K_RIGHT: 
        player.x += 1 
        player.direction = 'right' 
       if event.key == pygame.K_UP: 
        player.y -=1 
        player.direction = 'up' 
       if event.key == pygame.K_DOWN: 
        player.y +=1 
        player.direction = 'down' 


     clock.tick(20) 

     mainScreen.fill(white) 
     all_sprites_list.draw(mainScreen) 
     pygame.display.flip() 

    pygame.quit() 

if __name__ == '__main__': 
    main() 

Обратите внимание, как внутри класса Player я использовал свойства. Это позволяет мне делать что-то вроде my_player.image (обратите внимание, что это не функция!) И получить изображение от вызова функции image. В принципе, свойства позволяют функциям выглядеть как атрибуты.

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

1

Благодарим вас за помощь Michael0x2a.

Я все еще новичок в этом, поэтому я взял более длинный и менее эффективный маршрут для обработки программы.

Вот мой код для тех, кто смотрит на этот вопрос:

#help from ProgramArcadeGames.com 
import pygame 

# Define some colors 
black = ( 0, 0, 0) 
white = (255, 255, 255) 
red  = (255, 0, 0) 

faceWhatDirection = 4 
keyDown = False 

class Player(pygame.sprite.Sprite): 

    #constructor function 
    def __init__(self): #what this is doing is declaring a self variable and an x and y varible 

     #call up the parent's constructor 
     pygame.sprite.Sprite.__init__(self) 

     #List of images for different types of movement 
     self.imagesLeft = [] 

     self.imagesRight = [] 

     self.imagesUp = [] 

     self.imagesDown = [] 

     #load the up images 
     img = pygame.image.load("man1_bk1.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesUp.append(img) #adds the image to the list 

     img = pygame.image.load("man1_bk2.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesUp.append(img) #adds the image to the list 

     #load the down images 

     img = pygame.image.load("man1_fr1.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesDown.append(img) #adds the image to the list 

     img = pygame.image.load("man1_fr2.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesDown.append(img) #adds the image to the list 

     #load the left images 
     img = pygame.image.load("man1_lf1.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesLeft.append(img) #adds the image to the list 

     img = pygame.image.load("man1_lf2.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesLeft.append(img) #adds the image to the list 

     #load the right images 
     img = pygame.image.load("man1_rt1.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesRight.append(img) #adds the image to the list 

     img = pygame.image.load("man1_rt2.gif").convert() 
     img.set_colorkey(white) #sets the color key. any pixel with the same color as the colorkey will be transparent 
     self.imagesRight.append(img) #adds the image to the list 

     #the best image to use by default is the one that has the player facing the screen. 
     self.image=self.imagesDown[0] 

     #This line of code, as the Programming website showed me, gets the dimensions of the image 
     #Rect.x and rect.y are the coordinates of the rectangle object, measured at the upper right 
     #hand corner 

     self.rect = self.image.get_rect() 

     #getter for the image 

    def updateLeft(self): 

      #code block for handling the left movement animations 
      if self.image == self.imagesLeft[0]: 
       self.image = self.imagesLeft[1] 
      else: 
       self.image = self.imagesLeft[0] 

    def updateRight(self): 

      #code block for handling the right movement animations 
      if self.image == self.imagesRight[0]: 
       self.image = self.imagesRight[1] 
      else: 
       self.image = self.imagesRight[0] 


    def updateUp(self): 

      #code block for handling the right movement animations 
      if self.image == self.imagesUp[0]: 
       self.image = self.imagesUp[1] 
      else: 
       self.image = self.imagesUp[0] 

    def updateDown(self): 

      #code block for handling the right movement animations 
      if self.image == self.imagesDown[0]: 
       self.image = self.imagesDown[1] 
      else: 
       self.image = self.imagesDown[0] 








#initialize pygame 
pygame.init() 

#set the height and width of the screen 
width = 800 
height = 480 

mainScreen = pygame.display.set_mode([width,height]) 

#A list off all of the sprites in the game 
all_sprites_list = pygame.sprite.Group() 

#creates a player object 
player = Player() 
all_sprites_list.add(player) 

#a conditional for the loop that keeps the game running until the user Xes out 
done = False 

#clock for the screen updates 
clock = pygame.time.Clock() 

while done==False: 
    for event in pygame.event.get(): #user did something 
     if event.type == pygame.QUIT: #if the user hit the close button 
       done=True 

     if event.type == pygame.KEYDOWN: # if the user pushes down a key 
      if event.key == pygame.K_LEFT: #if the left arrow key is pressed 
       player.rect.x -=15 
       faceWhatDirection = 1 
       player.updateLeft()  

      if event.key == pygame.K_RIGHT: #if the left arrow key is pressed 
       player.rect.x +=15 
       faceWhatDirection = 2 
       player.updateRight() 

      if event.key == pygame.K_UP: #if the left arrow key is pressed 
       player.rect.y -=15 
       faceWhatDirection = 3 
       player.updateUp() 

      if event.key == pygame.K_DOWN: #if the left arrow key is pressed 
       player.rect.y +=15 
       faceWhatDirection = 4 
       player.updateDown() 


    mainScreen.fill(white)#makes the background white, and thus, the white part of the images will be invisible 
    #player.changeImage() 

    #draw the sprites 
    all_sprites_list.draw(mainScreen) 

    #limit the game to 20 fps 
    clock.tick(20) 

    #update the screen on the regular 
    pygame.display.flip() 

pygame.quit() 
Смежные вопросы