【问题标题】:TypeError: 'pygame.Surface' object is not callable [Pygame module]TypeError: 'pygame.Surface' 对象不可调用 [Pygame 模块]
【发布时间】:2017-08-27 07:05:19
【问题描述】:

我最近在设计一款游戏,因为我要在学校开设一门课程 并认为这会有所帮助。

我遇到了错误

Traceback (most recent call last):
  File "C:\Users\Jake\Documents\Dungeon Crawler 2.1\Main.py", line 100, in <module>
    town()    
  File "C:\Users\Jake\Documents\Dungeon Crawler 2.1\Main.py", line 85, in town
    houseSpr1(0,250)
TypeError: 'pygame.Surface' object is not callable

在执行此代码时。

def town ():
    global outTown
    while not outTown:
            for event in pygame.event.get():
                    if event.type == pygame.MOUSEBUTTONDOWN:
                            print (event)
                            mx, my = pygame.mouse.get_pos()
                            mx = mx + my
                            if 375 <= mx <= 448:
                                    outTown = True
                                    print ("OK!")
                    if event.type == pygame.QUIT:
                            pygame.quit()
                            quit()

            houseSpr1 = pygame.image.load ('houseD.png') # default house img
            houseSpr1(0,250)
            gameDisplay.fill(green) # background
            pygame.draw.rect(gameDisplay,grey,(0,400,1280,50)) # main path
            pygame.draw.rect(gameDisplay,grey,(200,125,50,280)) # branch path
            player(x,y)
            pygame.display.update()
            clock.tick(60)

def houseSpr1(a,b):
    gameDisplay.blit(houseSpr1, (0,250))

def house1():
    global outHouse
    while not outHouse:
            gameDisplay.fill(black)
town()
houseSpr1()
gameIntro()
house1()
pygame.quit()
quit()

我了解此代码在某些方面可能效率低下,如果您希望就此提供见解,我很乐意知道如何改进它。


任何有关此错误的帮助将不胜感激。是的,我已经阅读了我之前的其余问题,我发现这主要是由于印刷错误,但我在这里看不到任何问题。

【问题讨论】:

  • 请包含异常的完整回溯,而不仅仅是异常行本身。
  • 为什么要分配本地名称houseSpr1?你屏蔽了你定义的全局函数houseSpr1。函数不存在于单独的命名空间中,您不能为多个事物使用相同的名称。
  • 我不知道蒙面是什么意思。我已更新条目以显示完整错误。 @MartijnPieters
  • 你重用了同名作为局部变量;函数town() 中对houseSpr1 的所有引用均指该本地名称。全局名称houseSpr1,即您定义的函数,在town() 函数内不再可访问。
  • 因此,当您编写houseSpr1(..) 时,您将(..) 调用表达式添加到您在其前一行创建的houseSpr1 对象中。为您加载的函数或图像使用不同的名称。

标签: python python-3.x pygame


【解决方案1】:

你用houseSpr1这个名字做了两件事:

  • 一个全局函数,def houseSpr1(a,b): ...
  • 您加载的图像的局部变量:houseSpr1 = pygame.image.load ('houseD.png')

这两个名称不独立。函数只是 Python 中的另一种类型的对象,它们就像任何其他变量一样存储。

在您使用表达式houseSpr1(0,250) 的那一刻,Python 将其视为:

  1. 加载名为houseSpr1的对象
  2. 0250(两个整数对象)获取结果
  3. 调用第 1 步中加载的对象,传入第 2 步的结果。

因为您在 town() 函数中为名称 houseSpr1 分配了一些东西,所以 Python 尝试调用的是 那个对象,即加载的图像。 PyGame 使用名为Surface 的对象类型来加载图像,错误告诉您您尝试调用该对象,但该对象不支持被调用。

解决办法是不要使用同名:

houseSpr1Image = pygame.image.load('houseD.png')
houseSpr1(0, 250)

您还必须调整您的 houseSpr1 函数:

def houseSpr1(a,b):
    gameDisplay.blit(houseSpr1Image, (0,250))

这里还有其他问题; houseSpr1Image 不是全局的,所以 houseSpr1() 函数找不到它,给你一个 NameError 异常。您还忽略了函数的ab 参数,在那里硬编码0,250。您必须解决这些问题才能使代码正常工作。也许您可以使用第三个参数image

def houseSpr1(image, a, b):
    gameDisplay.blit(image, (a, b))

并传入图像表面:

houseSpr1Image = pygame.image.load('houseD.png')
houseSpr1(houseSpr1Image, 0, 250)

【讨论】:

  • 好吧,我可能应该先提到这一点,但我忘了提到我试图将坐标分配给变量 a 和 b,然后放弃并输入的事实他们直接。由于您在此答案中包含 a 和 b 并且它们不容易被替换,我将如何去做呢?您能否相应地编辑您的答案,然后我将能够将其标记为已接受的答案。
  • 我正在寻求一种方法来更改您在代码中的大部分参数中输入的 a 和 b,并将它们替换为整数,这些整数将用作屏幕上对象的坐标。
  • @Jake:然后删除 ab 参数。
  • 不。它声称它是无效的语法。
  • @Jake:我看不出你是如何删除它们的。如果你对 Python 还这么陌生,我建议你work through the Python tutorial
【解决方案2】:

Martijn Pieters 已经彻底解释了为什么您的代码不起作用。这是您的程序的工作简化版本,向您展示它的外观。

实际上,blit_houseSpr1 函数不是必需的,因为您也可以在主循环中调用 gameDisplay.blit(houseSpr1, (80, 250)),但我只是想演示如何使用函数并向其传递一些参数。

import pygame

pygame.init()
gameDisplay = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()

green = pygame.Color('green4')
grey = pygame.Color('grey50')
# Load the images once, because loading them from the hard disk is slow.
# And use the convert or convert_alpha methods to improve the performance.
houseSpr1 = pygame.image.load('houseD.png').convert()


def town():
    outTown = False
    while not outTown:
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                mx, my = pygame.mouse.get_pos()
                mx = mx + my
                if 375 <= mx <= 448:
                    outTown = True
            elif event.type == pygame.QUIT:
                outTown = True

        gameDisplay.fill(green) # background
        pygame.draw.rect(gameDisplay,grey,(0,400,1280,50)) # main path
        pygame.draw.rect(gameDisplay,grey,(200,125,50,280)) # branch path
        # Pass the image and the coordinates to the function.
        blit_houseSpr1(houseSpr1, 80, 250)

        pygame.display.update()
        clock.tick(60)


def blit_houseSpr1(image, a, b):
    # Now use the passed image and coordinates.
    gameDisplay.blit(image, (a, b))


town()
pygame.quit()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 2018-05-18
    • 2017-06-17
    • 2014-09-21
    • 2011-05-30
    相关资源
    最近更新 更多