2

我起草了一些代码来测试我制作的 pygame 程序上的动画。解释器干净利落地通过它,但是当我尝试运行它时,它保持冻结状态。X按钮不起作用,玩家角色被冻结在角落里,根本不会移动。

终端窗口根本没有输出任何错误,我坚持认为它没有移动。任何帮助或见解将不胜感激。

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

2 回答 2

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结束任何循环,需要改变面部方向,并且需要抬起键。但是,这不可能发生,因为更改其中任何一个的代码都在主循环内。

此外,两次更改图像是多余的。如果您尝试制作动画,则需要记住pygame.display.flip()在每次图像更改之间调用。


相反,我会将您的代码编写为如下所示。(警告!我没有测试过这段代码,因为我没有图像文件,所以这里和那里可能存在一些错误。我假设 gif 不是动画)

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函数获取图像。基本上,属性允许函数看起来像属性。

使用属性,我可以使播放器自动为自己设置动画,以便在移动时每秒更改一次图像。

于 2013-10-07T17:51:04.577 回答
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()
于 2013-10-08T17:24:51.527 回答