【问题标题】:Pygame: Alien Invasion Ship ImagePygame:外星入侵船图片
【发布时间】:2020-10-22 08:45:47
【问题描述】:

您好,我目前正在尝试从 Python Crash Course 的第 12 章创建太空入侵。但是,当我尝试将船舶图像添加到游戏中时,我被卡住了。这是外星人入侵的代码:

import sys
import pygame
from settings import Settings
from ship import Ship
class AlienInvasion:
#Overall class to manage game assests and behavior

    def __init__(self):
        #Initialize the game and create game resources
        pygame.init()
        self.settings=Settings()
    
        self.screen=pygame.display.set_mode((self.settings.screen_width,self.settings.screen_height))
        pygame.display.set_caption('Alien Invasion')

       self.Ship=Ship(self)



    def run_game(self):
        # Start the main loop for the game
        while True:
           #Watch for keyboard and mouse events
            for event in pygame.event.get():
                 if event.type==pygame.QUIT  :
                     sys.exit()
            #Redraw the screen during each pass through the loop.
             self.screen.fill(self.settings.bg_color)

            self.Ship.blitme()
            #Make the most recently drawn screen visible.
            pygame.display.flip()

if __name__=='__main__':
#Make a game instance, and run the game.
ai=AlienInvasion()
ai.run_game()

船号:

import pygame


 class Ship:
     #A class to manage the ship
     def __init__(self, ai_game):
       #Initialize the ship and set its starting position
       self.screen=ai_game.screen
       self.screen_rect=ai_game.screen.get_rect()

        #Load the ship image and get its rect.
        self.image=pygame.image.load('images/ship.bmp')
        self.rect=self.image.get_rect()

        #start each new ship at the bottom center of the screen.
        self.rect.midbottom=self.screen_rect.midbottom

    def blitme(self):
        #Draw the ship at its current location
        self.scren.bilt(self.image, self.rect)
    

尝试运行时出现此错误:

Traceback (most recent call last):
File "c:/Users/rico3/OneDrive/Desktop/Python Scripts/Alien Invasion/Alien_Invaders.py", line 39, in <module>
 ai=AlienInvasion()
 File "c:/Users/rico3/OneDrive/Desktop/Python Scripts/Alien Invasion/Alien_Invaders.py", line 19, in __init__
self.Ship=Ship(self)
File "c:\Users\rico3\OneDrive\Desktop\Python Scripts\Alien Invasion\ship.py", line 12, in __init__
self.image=pygame.image.load('images/ship.bmp')
pygame.error: Couldn't open images/ship.bmp

images 文件夹与 Alien Invasion 文件位于同一文件夹中,但它似乎仍然无法找到 ship 文件。

【问题讨论】:

  • 如何启动游戏?图像文件夹与 Alien Invasion 文件位于同一文件夹中是不够的。您还需要将进程的当前目录设置为与 Alien Invasion 文件相同。要检查当前目录是什么,请在调用 pygame.image.load('images/ship.bmp') 之前添加:import os; print(os.getcwd()) 并查看打印的值是否符合您的期望。
  • 您的目录分隔符可能有问题。您可以使用import osprint(os.sep) 检查您的操作系统分隔符。如果您的分隔符是反斜杠,那么您必须相应地编辑您的文件路径,同时转义反斜杠。
  • 我在 VS 代码终端中启动游戏并使用 Alien Invasion 文件。飞船和外星人入侵的目录匹配,但我仍然收到无法打开的错误。

标签: python image pygame load traceback


【解决方案1】:

顺便说一句,您是否创建了一个包含 ship.bmp 的目录“images”并将其包含在主项目文件夹中,如屏幕截图所示。

vscode:

终端:

【讨论】:

    【解决方案2】:

    这个问题经常出现,所以我会以一个规范的答案为目标。

    基本上,代码正在尝试加载文件,但它假设它运行在与所需文件相同的目录中。这个问题不仅限于 Python 或 PyGame,它是一个通用的编程问题。当 PyGame 程序被打包到可执行文件中时,问题就变得更大了,这些可执行文件在运行时被解压到 who-knows-where

    那么,你能做什么?首先,不要假设任何事情。在启动时,“感受”环境 - 找出代码从哪里运行。

    您的当前目录可从os 模块获得:

    import os
    print( "Running in directory: " + os.getcwd() ) 
    

    如果我从不同位置运行此脚本,请注意不同的结果:

    tmp> python3 ~/Code/Python/PyGame/working_dir.py
    Running in directory: /tmp
    

    并且来自同一个目录:

    PyGame> python3 ./working_dir.py 
    Running in directory: /home/kingsley/Code/Python/PyGame
    

    在您的情况下,它就像第一个输出 - 当前目录与您的 images/ 所在的目录不同。所以在这种情况下,您可以使用os.path 模块diranme()realpath() 函数来确定脚本的完整路径。这很好用,因为无论从哪个目录启动脚本都是一样的。

    import os
    import os.path
    
    exe_location = os.path.dirname( os.path.realpath( __file__ ) )
    
    print( "Running in directory: " + os.getcwd() ) 
    print( "Running script from:  " + exe_location )
    

    给予:

    tmp> python3 ~/Code/Python/PyGame/working_dir.py
    Running in directory: /tmp
    Running script from:  /home/kingsley/Code/Python/PyGame
    

    现在此路径可以用作您的图像目录的偏移量。这让我想到了下一点。 不要做这样的事情:

    path = exe_location + "\\" + images_dir + "\\" + subdir1  # <-- WRONG!
    

    您的代码在任何不使用与您相同的目录分隔符的系统上都会失败。使用os.path 模块函数join()。它知道本地系统的正确路径分隔符,并正确处理双分隔符等的任何清理。

    path = os.path.join( exe_location, images_dir, subdir1 )  # <-- PERFECT!
    

    所以在你的代码中:

    import os.path
    
    # [...]
    
    if __name__=='__main__':
        exe_location = os.path.dirname( os.path.realpath( __file__ ) )
    

    然后将exe_location 用作全局变量,或者将其作为参数传递给您的类构造函数。加载图像(或声音,或字体等)时,使用os.path.join() 计算正确的绝对路径:

    class Ship:
        #A class to manage the ship
        def __init__( self, ai_game, install_path ):
            #Initialize the ship and set its starting position
            [ ... ]
    
            #Load the ship image and get its rect.
            filename = os.path.join( install_path, "images", "ship.bmp" )
            self.image=pygame.image.load( filename )
            self.rect=self.image.get_rect()
    

    您可能还需要注意目录和文件名的字母大小写。在某些文件系统上,“Images/”与“images/”不同。使用你想要的任何情况,但要保持准确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-02
      • 2021-02-04
      相关资源
      最近更新 更多