【问题标题】:TypeError: argument 1 must be pygame.Surface, not str, don,t know what's causing thisTypeError:参数 1 必须是 pygame.Surface,而不是 str,不知道是什么原因造成的
【发布时间】:2020-06-04 15:33:51
【问题描述】:

我回到了我在 pygame 中制作的第一个游戏,想添加精灵,所以我进入了三个不同的类并更改了代码,让它们成为精灵而不是块。现在,每当我运行代码时,我都会在all_sprites.draw(screen) 行出现错误,错误为argument 1 must be pygame.Surface, not str 我认为我在某处有不正确的语法,但其中大部分是从其他工作游戏中复制的。我已将完整代码放在这里,感谢您的帮助。谢谢。

import pygame
import os
import random
import time

big_Jump = 1
small_Jump = 1

game_folder = os.path.dirname(__file__)
img_folder = os.path.join(game_folder, "images")

class Player(pygame.sprite.Sprite):
    #How to make a player class
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join(img_folder, "ghost_sprite_right.png"))
        self.rect = pygame.Rect(50,630,50,50)
        all_sprites.add(self)

    def update(self):
        pass

    def move(self,dx,dy):
        if dx != 0:
            self.move_single_axis(dx,0)
            if dx >0:
                self.image = pygame.image.load(os.path.join(img_folder, "ghost_sprite_right.png"))
            if dx <0:
                self.image = pygame.image.load(os.path.join(img_folder, "ghost_sprite_left.png"))
        if dy != 0:
            self.move_single_axis(0,dy)

    def move_single_axis(self,dx,dy):

        self.rect.x += dx
        self.rect.y += dy
        for wall in walls:
            if self.rect.colliderect(wall.rect):
                global big_Jump
                global small_Jump
                #big_Jump = 1
                #small_Jump = 1
                #print("Big Jump :",big_Jump,"\n"+"Small Jump :",small_Jump)
                if dx>0:
                    self.rect.right = wall.rect.left
                    big_Jump = 1
                    small_Jump = 1
                if dx<0:
                    self.rect.left = wall.rect.right
                    big_Jump = 1
                    small_Jump = 1
                if dy>0:
                    self.rect.bottom = wall.rect.top
                    big_Jump = 1
                    small_Jump = 1
                if dy<0:
                    self.rect.top = wall.rect.bottom
                    #big_Jump = 1
                    #small_Jump = 1



class Wall(pygame.sprite.Sprite):
    def __init__(self,wx,wy):
        pygame.sprite.Sprite.__init__(self)
        self.image = os.path.join(img_folder,"brick_wall.png")
        self.rect = pygame.Rect(wx,wy,30,30)
        walls.append(self)
        all_sprites.add(self)
    def update(self):
        pass

class DBlock(pygame.sprite.Sprite):
    def __init__(self,wx,wy):
        pygame.sprite.Sprite.__init__(self)
        self.image = os.path.join(img_folder,"spike.jpg")
        self.rect = pygame.Rect(wx,wy,30,30)
        DBlocks.append(self)
        all_sprites.add(self)
    def update(self):
        pass

class RandomBlock(object):
    def __init__(self,wx,wy):
        RBlocks.append(self)
        self.rect = pygame.Rect(wx,wy,30,30)

class WhiteFlag(object):
    def __init__(self,wx,wy):
        WFlags.append(self)
        self.rect = pygame.Rect(wx,wy,30,30)

class BlackFlag(object):
    def __init__(self,wx,wy):
        BFlags.append(self)
        self.rect = pygame.Rect(wx,wy,30,30)

def text_objects(text,font):
    textSurface = font.render(text,True,(0,0,0))
    return textSurface, textSurface.get_rect()

def message_display(text,top,left,size):
    my_text = pygame.font.Font("freesansbold.ttf",size)
    text_surface,text_rect = text_objects(text,my_text)
    text_rect.center = ((top),(left))
    screen.blit(text_surface,text_rect)





#Start pygame
os.environ["SDL_VIDEO_CENTERED"] = "1"
pygame.init()

#Adding music
#pygame.mixer.music.load("Sounds/background_music.mp3")
#pygame.mixer.music.play(-1)
#Set up the display
WIDTH = 840
HEIGHT = 720

screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("A Sqaure on a Mission") #Title of the window
all_sprites = pygame.sprite.Group()

clock = pygame.time.Clock()

walls = []
DBlocks = []
RBlocks = []
BFlags = []
WFlags = []
playBlock = 60
player = Player() #Create a player object using the class
colour = (0,128,255)



#In this level W means wall, D mean death block, C means coin and E means exit

levels = [[
"WWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"W           D      D     BwB",
"W           D      D     wBw",
"W           D            BwB",
"WW     W    D         WWWWWW",
"W      D          WWWWRRRRRW",
"W      D          DRRRRRRRRW",
"W      D          DRRRRRRRRW",
"W     WWWWWWWWWWWWWWWWWWWWWW",
"W                          W",
"W                          W",
"W                          W",
"WWWWWWW                   WW",
"WRRRRRD                    W",
"WRRRRRD                    W",
"WWWWWWDDDDDWWWWWWWD        W",
"W                          W",
"W                          W",
"W                          W",
"W     WWWWWW            WWWW",
"W                    WWWRRRW",
"W                  WWRRRRRRW",
"W                WWRRRRRRRRW",
"WWWWWWWWWDDDDWWWWWWWWWWWWWWW"
],[
"WWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"                           W",
"                           W",
"                           W",
"WWWWW                 WWWWWW",
"WRRRRWW             WWRRRRRW",
"WRRRRRRWW         WWRRRRRRRW",
"WRRRRRRRRWW     WWRRRRRRRRRW",
"WRRRRRRRRRWW   WWRRRRRRRRRRW",
"WRRRRRRRRRRD   DRRRRRRRRRRRW",
"WRRRRRRRRRRD   DRRRRRRRRRRRW",
"WRRRRRRRRRRD   DRRRRRRRRRRRW",
"WRRRRRRRRRRD   DWWWWWWWWWWWW",
"WRRRRRRRRRRD               W",
"WRRRRRRRRRRD               W",
"WWWWWWWWWWWWWWWWWWWWW   DDDW",
"W           D              W",
"W           D              W",
"W                         DW",
"WDD    D         D       DDW",
"W      WWWWWWWWWWWWWWWWWWWWW",
"W           BwBwDRRRRRRRRRRW",
"W           wBwBDRRRRRRRRRRW",
"WWWWWWWWWWWWBwBwWWWWWWWWWWWW"
],[
"WWWWWWWWWWWWD  DWWWWWWWWWWWW",
"W          DD  DD          W",
"W                          W",
"W                          W",
"W          WWWWWW          W",
"W      DWWWRRRRRRWWWD      W",
"W     DDWRRRRRRRRRRWDD     W",
"W      DWWWWWWWWWWWWD      W",
"W            WD            W",
"W            DW            W",
"W            WD            W",
"WDDD         DW         DDDW",
"W         DDDWDDDD         W",
"W            DW            W",
"W            WD            W",
"W      DDWWWWDWWWWWDD      W",
"W            WD            W",
"W            DW            W",
"W            WD            W",
"WWWWD      DDDWDD      DWWWW",
"BwB          WD          wBw",
"wBw          DW          BwB",
"BwB          WD          wBw",
"WWWWWWWWWWWWWWWWWWWWWWWWWWWW"
],[
"WWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"                           W",
"                           W",
"                           W",
"WWWWWWWWWWWWWWWWWWWWWWWWWWWW"
],[
],[
"WWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                          W",
"W                           ",
"W                           ",
"W                           ",
"WWWWWWWWWWWWWWWWWWWWWWWWWWWW"
]]
screen.fill((0,0,0))
message_display("Hello, you're a Ghost and your on a mission,",380,300,20)
message_display("use the arrow keys and space bar for a big jump",380,330,20)
message_display("to get to the checkered flags.",400,360,20)
pygame.display.flip()
time.sleep(1)

#Start the gameplay
running = True

x=y=0
for row in levels[0]:
    for col in row:
        if col == "W":
            Wall(x,y)
        if col == "D":
            DBlock(x,y)
        if col == "R":
            RandomBlock(x,y)
        if col == "w":
            WhiteFlag(x,y)
        if col == "B":
            BlackFlag(x,y)
        x += 30
    y += 30
    x=0
Red = random.randint(0,255)
Green = random.randint(0,255)
Blue = random.randint(0,255)
levelnum = 0
velocity = 5
while running:
    #print(player.rect.x,",",player.rect.y,",",velocity)
    #print(velocity)

    clock.tick(75)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False



        if(event.type == pygame.KEYDOWN) and (event.key == pygame.K_RETURN):
            if colour == (0,128,255):
                colour = (255,100,0)
            else:
                colour = (0,128,255)



    user_input = pygame.key.get_pressed()

    if user_input[pygame.K_UP] and player.rect.y > 0 and small_Jump == 1: #Adds borders
        velocity = -10
        small_Jump = 0


    if user_input[pygame.K_SPACE] and player.rect.y > 0 and big_Jump == 1 : #Adds borders
        velocity = -15
        big_Jump = 0


    if player.rect.y < (HEIGHT-playBlock)and velocity > -21 and velocity <=5:
        player.move(0,velocity)
        if velocity != 5:
            velocity += 1
        if player.rect.y > (HEIGHT-65):
            player.move(0,660-player.rect.y) #Makes sure it cant go past the bottom of  the screen

    if user_input[pygame.K_DOWN] and player.rect.y < (HEIGHT-playBlock):
        player.move(0,2)

    if user_input[pygame.K_LEFT] and player.rect.x >0:
        player.move(-5,0)


    if user_input[pygame.K_RIGHT] and player.rect.x<WIDTH-playBlock:
        player.move(5,0)

    for a in DBlocks:
        if player.rect.colliderect(a):
            small_Jump = 1
            big_Jump = 1
            if levelnum == 0:
                player.rect.x = 50
                player.rect.y = 625
            if levelnum == 1:
                player.rect.x = 10
                player.rect.y = 45
            if levelnum ==2:
                player.rect.x = 390
                player.rect.y = 60





    if player.rect.x >WIDTH-playBlock-1 or player.rect.y >720-playBlock-1:
        del walls[:]
        del DBlocks[:]
        del RBlocks[:]
        del WFlags[:]
        del BFlags[:]
        Red = random.randint(0,255)
        Green = random.randint(0,255)
        Blue = random.randint(0,255)
        x=y=0
        levelnum += 1
        #message_display("Level :"+str(levelnum),380,30,25)
        for row in levels[levelnum]:
            for col in row:
                if col == "W":
                    Wall(x,y)
                if col == "D":
                    DBlock(x,y)
                if col == "R":
                    RandomBlock(x,y)
                if col == "w":
                    WhiteFlag(x,y)
                if col == "B":
                    BlackFlag(x,y)
                x += 30
            y += 30
            x=0

        if levelnum ==4:
            screen.fill((0,0,0))
            message_display("Well done, you completed your mission Mr.Ghost!",380,350,30)
            pygame.display.flip()
            time.sleep(5)
            running = False
        elif levelnum == 1:
            player.rect.x = 10
            player.rect.y = 45
        elif levelnum == 2:
            player.rect.x = 390
            player.rect.y = 5


    #Draw the screen
    screen.fill((70,70,70))

    for wall in walls:
        pygame.draw.rect(screen,(200,200,200),wall.rect)
    for a in DBlocks:
        pygame.draw.rect(screen,(255,0,0),a.rect)
    for b in RBlocks:
        pygame.draw.rect(screen,(Red,Blue,Green),b.rect)
    for c in WFlags:
        pygame.draw.rect(screen,(255,255,255),c.rect)
    for d in BFlags:
        pygame.draw.rect(screen,(0,0,0),d.rect)
    pygame.draw.rect(screen,colour,player.rect)

    message_display(("Level "+str(levelnum+1)+" of 4"),380,20,25)

    all_sprites.update()
    all_sprites.draw(screen)
    pygame.display.flip()



pygame.quit()

【问题讨论】:

  • 您能否解释一下,如果它与您没有精灵 .png 文件有关,那么您可以使用任何文件,或者我可以将我使用的文件发送给您。我无法将它们从代码中删除以使其适用于任何人,因为精灵是问题所在。

标签: python pygame sprite


【解决方案1】:

好的,这是一个很难注意到的错误!

Traceback (most recent call last):
  File "./square_dash.py", line 429, in <module>
    all_sprites.draw(screen)
  File "/usr/lib/python3/dist-packages/pygame/sprite.py", line 476, in draw
    self.spritedict[spr] = surface_blit(spr.image, spr.rect)
TypeError: argument 1 must be pygame.Surface, not str

该错误是由您的代码在绘制所有精灵时引起的,但直到在 PyGame 代码中才真正触发错误。

所以问题是你使用了一个字符串来表示应该是一个表面的东西。那是通过为所有精灵调用Sprite.update() 来触发的。这导致我开始查看您正在加载到所有精灵的各种 sprite.image 成员变量中的图像。

前几对没问题,但接下来是这样的:

class Wall(pygame.sprite.Sprite):
    def __init__(self,wx,wy):
        global all_sprites
        pygame.sprite.Sprite.__init__(self)
        self.image = os.path.join(img_folder,"wall.png")   # <--HERE
        self.rect = pygame.Rect(wx,wy,30,30)
        walls.append(self)
        all_sprites.add(self)

你能看到错误吗?您没有加载图像,只是将self.image 指定为字符串图像的路径。你可能想要:

self.image = pygame.image.load( os.path.join(img_folder, "wall.png" ) )

DBlock 中也存在同样的错误。

直到第一个 Sprite.draw() 被调用,self.image 才被使用,这就是为什么直到那时才出现错误的原因。如果您编写了典型的 self.rect = self.image.get_rect() 代码,那么它会在一个非常明显的地方很早就失败了。

【讨论】:

  • 是的,您完全正确,非常感谢。我现在看到了,感谢您解释这个问题,因为它现在很有意义。我刚刚做了你说的调整,游戏就可以了!感谢您的所有帮助:)
猜你喜欢
  • 1970-01-01
  • 2017-10-21
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多