简体   繁体   English

TypeError:“ pygame.Surface”对象不可调用[Pygame模块]

[英]TypeError: 'pygame.Surface' object is not callable [Pygame module]

I have been designing a game recently as I'm starting a course at school and thought it would be helpful to get ahead. 我最近在学校学习课程时就一直在设计游戏,并认为这对取得成功很有帮助。

I encountered the error 我遇到了错误

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

While executing this code. 在执行此代码时。

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

I understand this code may be inefficient in some ways, and I would be happy to know how I can improve it as well if you wish to provide insight in that light. 我了解这段代码在某些方面可能是低效的,如果您希望以此来提供见解,我也很高兴知道我也可以对其进行改进。


Any help with this error would be appreciated. 任何与此错误的帮助将不胜感激。 And yes, I have read the rest of the questions before mine and I saw it was mostly down to typographical errors, but I can not see any of those here. 是的,我阅读了我之前的其余问题,我发现这主要归因于印刷错误,但我看不到这里的任何问题。

You used the name houseSpr1 for two things: 您将名称houseSpr1用于两件事:

  • A global function, def houseSpr1(a,b): ... 全局函数def houseSpr1(a,b): ...
  • A local variable for an image you load: houseSpr1 = pygame.image.load ('houseD.png') . 您加载的图像的局部变量: houseSpr1 = pygame.image.load ('houseD.png')

The two names are not independent . 这两个名字不是独立的 Functions are just another type of object in Python, and they are just stored like any other variable. 函数只是Python中对象的另一种类型,它们就像其他任何变量一样被存储。

The moment you use the expression houseSpr1(0,250) , Python sees this as: 当您使用表达式houseSpr1(0,250) ,Python houseSpr1(0,250)其视为:

  1. Load the object named houseSpr1 加载名为houseSpr1的对象
  2. Take the results from 0 and 250 (two integer objects) 0250 (两个整数对象)中的结果
  3. Call the object loaded in step 1, passing in the results of step 2. 调用在步骤1中加载的对象,并传递步骤2的结果。

Because you assigned something to the name houseSpr1 in your town() function, it is that object , the image loaded, that Python tries to call. 因为您在town()函数中给名称houseSpr1分配了一些东西,所以Python尝试调用的是该对象 (即加载的图像)。 PyGame uses an object type named Surface to load images, and the error tells you you tried to call that object, but that object doesn't support being called. PyGame使用名为Surface的对象类型加载图像,该错误告诉您您尝试调用该对象,但该对象不支持被调用。

The solution is to not use the same name: 解决方案是不要使用相同的名称:

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

You'll have to adjust your houseSpr1 function too: 您还必须调整houseSpr1函数:

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

You still have other problems here; 您在这里还有其他问题; houseSpr1Image is not a global, so the houseSpr1() function won't find it, giving you a NameError exception. houseSpr1Image不是全局的,因此houseSpr1()函数找不到它,给您一个NameError异常。 You are also ignoring the a and b arguments to the function, hardcoding the 0,250 there. 您也将忽略该函数的ab参数,在那里将0,250硬编码。 You'll have to solve those issues to for the code to work. 您必须解决这些问题才能使代码正常工作。 Perhaps you can take a 3rd parameter, image : 也许您可以采用第三个参数image

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

and pass in the image surface: 并传递到图像表面:

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

Martijn Pieters has already explained thoroughly why your code doesn't work. Martijn Pieters已经彻底解释了为什么您的代码不起作用。 Here's a working, simplified version of your program to show you how it should look like. 这是程序的工作简化版,向您展示程序的外观。

Actually, the blit_houseSpr1 function is not necessary, since you could as well call gameDisplay.blit(houseSpr1, (80, 250)) in the main loop, but I just wanted to demonstrate how you can use a function and pass some arguments to it. 实际上, 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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM