Pygame TypeError:join()参数必须是str,bytes或os.PathLike对象,而不是'Surface'

时间:2020-03-29 06:23:25

标签: python python-3.x pygame

我只学习Python几周了,这个问题让我很困惑。我正在尝试使用Pygame创建一个简单的塔防风格游戏。经过谷歌搜索和研究超过4个小时(在发布时,pygame docs网站已关闭,具体取决于缓存版本)。我相信它最终将变得很容易修复,但是我没有想法。

我在一个文件中有Tower类,在另一个文件中有主游戏循环。图像文件存储在名为“ assets”的文件夹中,该文件夹与塔类和主游戏循环在同一目录中。当我尝试创建新塔楼时,特别是加载塔楼图像时,出现标题中列出的错误。

我知道我以某种方式传递了“ Surface”作为参数,但是我一生无法弄清楚它在哪里。我让玩家使用1或2键选择他们要建造的塔的类型,然后为该按键查找相应的图像,然后将塔放置在屏幕上单击的位置。 pygame事件之后,用于正确单击鼠标的紧接着的print语句将“ elf_tower.png”列为文件名,但是该类的 init 中的print语句显示为“”。如果我为图像硬编码文件名,则该类将正常运行,但是我怀疑这是最好的解决方案。我还尝试仅将变量设置为“ assets /” + tower_type,但是类似地它说不能将Surface连接到str。

主文件:

"""Homebrew tower defense game using pygame and object oriented programming.
This is a learning project"""
import pygame
from tower import Tower
from scaling import get_scaling_info

get_scaling_info()

def run_game():
    """Runs the game"""
    pygame.init()
    get_scaling_info()
    width, height = get_scaling_info()[1:]
    screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN, 32)
    pygame.display.set_caption("Tower Defense")
    game_surface = screen.copy()

    def toggle_fullscreen():
        """Toggles between fullscreen and windowed mode"""
        if screen.get_flags() & pygame.FULLSCREEN:
            return pygame.display.set_mode((800, 600), pygame.RESIZABLE)
        return pygame.display.set_mode((width, height), pygame.FULLSCREEN)

    def update_display():
        """Update the game display"""
        scaling_info = get_scaling_info()[0]
        screen.fill((0, 0, 0))
        for tower in Tower.towers:
            tower.draw()
        screen.blit(pygame.transform.scale(
            game_surface, (scaling_info.current_w, scaling_info.current_h)), (0, 0))
        pygame.display.update()

    run = True
    tower_type = 0
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    run = False
                if event.key == pygame.K_F11:
                    toggle_fullscreen()
                if event.key == pygame.K_1 or event.key == pygame.K_2:
                    tower_type = Tower.selection_dict[event.key]
            if event.type == pygame.MOUSEBUTTONDOWN and tower_type != 0: #to prevent game from breaking if no tower selected.
                print(tower_type) #returns elf_tower.png which is the expected result
                mouse_x, mouse_y = pygame.mouse.get_pos()
                Tower(tower_type, mouse_x, mouse_y).create_tower()

        update_display()

    pygame.quit()

run_game()

塔楼类文件:

"""Contains the class used to generate towers"""
import os
import pygame
from scaling import get_scaling_info

get_scaling_info()

class Tower:
    """Tower information"""
    selection_dict = {49:"elf_tower.png", 50:"dwarf_tower.png"} #pygame keypress of 1 corresponds to value 49, 2 to 50.
    towers = []
    def __init__(self, img, x, y, display_surface="game_surface"):
        x_scale, y_scale = get_scaling_info()[1:]
        self.img = pygame.image.load(os.path.join('assets', img))
        print(self.img) # returns <Surface(40x40x32 SW)>
        self.x_coord = x * x_scale
        self.y_coord = y * y_scale
        self.display_surface = display_surface

    def create_tower(self):
        """Creates a tower of the selected type and scales to the correct size"""
        Tower.towers.append(Tower(self.img, self.x_coord, self.y_coord))
        print(Tower.towers)

    def draw(self):
        """Draws the tower on the screen using the specified image at coordinates x and y"""
        pygame.transform.scale(self.img, (32, 32))
        self.display_surface.blit(self.img, (self.x_coord, self.y_coord))
        print(self.img)

 #   def attack(self):
 #       """Causes the tower to attack enemies in range
 #       Not yet written"""

图像缩放文件

"""Gets the scaling info used in the other modules of the game"""
import pygame

def get_scaling_info():
    """Gathers display info for scaling elements of the game"""
    pygame.init()
    display_info = pygame.display.Info()
    scaling_info = pygame.display.Info()
    x_ratio = display_info.current_w/scaling_info.current_w
    y_ratio = display_info.current_h/scaling_info.current_h
    return scaling_info, x_ratio, y_ratio

1 个答案:

答案 0 :(得分:1)

您正在查看错误的Tower构造(即在run_game中);问题实际上是在线出现的

Tower.towers.append(Tower(self.img, self.x_coord, self.y_coord))

create_tower方法中,您可以使用Tower作为第一个参数来构造新的self.img。在__init__中,self.img被初始化为pygame.image.load(os.path.join('assets', img)),它返回一个Surface

同样,您要将存储img的{​​{1}}参数存储为另一个实例属性,然后在Tower方法中使用它,例如:

create_tower