如果我将整个代码作为一个函数放在 pygame 中,为什么某些功能不起作用?

why doesnt some features not work if i put my whole code as a function in pygame?

所以,我一直在开发这个简单的游戏,其中有这个弹弓和球,球图像就隐藏在它的正下方。然后我有一只鸟。我的游戏目标是将鸟击落。一切正常,鸟被击落,我的球在开火。当我把它全部放入一个函数时,我正处于这个游戏的最后阶段,这样在鸟被击落后我可以再次调用它并重复它。所以当我将我的代码放入函数中并对其进行测试时,精灵绘制正确但是当我单击 space 条来发射我的球时它不起作用。我正在为这个项目使用 pygame。您可以在下面查看我的代码:

提前致谢

import random
onlystarting = True
def main():
    global onlystarting
    onlystarting = False

    pygame.init()
    screen = pygame.display.set_mode((800, 600))


    postImg = pygame.image.load('post.png')
    postX = 0
    postY = 150

    lineImg = pygame.image.load('line.png')
    lineImg = pygame.transform.scale(lineImg, (610, lineImg.get_height()))

    slingshotImg = pygame.image.load('slingshot.png')
    slingshotX = 340
    slingshotY = 500
    slingshotX_change =  0


    ballImg = pygame.image.load('ball.png')
    ballX = slingshotX
    ballY = 533
    ballYchange = 2
    ballImg = pygame.transform.scale(ballImg, (20, 20))
    ballState = "ready"

    birdImg = pygame.image.load('bird.png')
    birdX = random.randint(300, 600)
    birdY = 240
    birdState = "alive"

    def post(x, y) :
        screen.blit(postImg, (x, y))

    def line(x, y) :
        screen.blit(lineImg, (x, y))

    def slingshot(x, y) :
        screen.blit(slingshotImg, (x, y))

    def fire_ball(x,y):
        global ballState
        ballState = "fire"
        screen.blit(ballImg, (x + 16, y))
    def bird(x,y):
        screen.blit(birdImg, (x, y))

    running = True
    #Game loop
    while running:
        screen.fill((225, 225, 225))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
        
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    slingshotX_change = -0.5

                if event.key == pygame.K_RIGHT:
                    slingshotX_change = 0.5
                
                if event.key == pygame.K_SPACE:
                    if ballState == "ready":
                        ballX = slingshotX
                        fire_ball(ballX, ballY)
            
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT:
                    slingshotX_change = 0

            slingshotX += slingshotX_change

        slingshotX += slingshotX_change


        if ballState == "fire":
            fire_ball(ballX, ballY)
            ballY -= ballYchange

        if slingshotX <= 100:
            slingshotX = 100.1

        if slingshotX >= 640:
            slingshotX = 639.9



        distanceX = ballX - birdX
        distanceY = ballY - birdY
        
        if distanceX > -32:
            if distanceX < 32 :
                if distanceY > -32:
                    if distanceY < 32:
                        birdX = 1000
                        birdY = 1000
                        main()


        post(postX, postY)
        post(650, 150)
        line(95, 270)
        line(95, 370)
        slingshot(slingshotX, slingshotY)
        bird(birdX, birdY)
        
        pygame.display.update()
if onlystarting:
    main()```

您在函数中有函数使用全局变量ballStatescreenpostImglineImgslingshotImgballImgbirdImg。但是,这些变量从未在全局范围内定义。这些变量是 main 函数中的局部变量。

要么使用 global statement 使这个变量成为全局变量:

def main():
    global ballState, screen, onlystarting, postImg, lineImg, slingshotImg, ballImg, birdImg
    # [...]

或者将变量传递给函数:

def draw(screen, surf, x, y) :
    screen.blit(postImg, (x, y))

def fire(screen, surf, x, y):
    global ballState
    ballState = "fire"
    screen.blit(surf, (x + 16, y))
def main():
    global onlystarting, ballState
    # [...]

    for event in pygame.event.get():
            # [...]
        
            if event.type == pygame.KEYDOWN:
                # [...]
           
                if event.key == pygame.K_SPACE:
                    if ballState == "ready":
                        ballX = slingshotX
                        fire(screen, ballImg, ballX, ballY)
            
        # [...]   

        if ballState == "fire":
            fire(screen, ballImg, ballX, ballY)
            ballY -= ballYchange

        # [...]
        
        draw(screen, postImg, postX, postY)
        draw(screen, postImg, 650, 150)
        draw(screen, lineImg, 95, 270)
        draw(screen, lineImg, 95, 370)
        draw(screen, slingshotImg, slingshotX, slingshotY)
        draw(screen, birdImg, birdX, birdY)
        
        pygame.display.update()