我无法修复的 Pygame2Exe 错误

Posted

技术标签:

【中文标题】我无法修复的 Pygame2Exe 错误【英文标题】:Pygame2Exe Errors that I can't fix 【发布时间】:2012-10-01 07:44:42 【问题描述】:

我做了一个“游戏”。我喜欢玩它,我想将它分发给我的朋友,而不必在他们的计算机上安装 Python 和 Pygame。

我对 Py2Exe 和 Pyinstaller 做了很多研究。我浏览了许多教程、修复程序、错误,但似乎没有一个对我有帮助。

Pyinstaller 没用,因为它不喜欢 Pygame 中的字体,而且 Py2exe 不会编译内置模块,所以我发现 Pygame2exe 只是一个预制的安装脚本,用于 py2exe,包括 pygame 和字体。据说它构建得很好,但 exe 无法使用...我收到错误:

"Microsoft Visual C++ 运行时库

运行时错误!

程序 C:...\dist\Worm Game.exe

此应用程序已请求运行时以异常方式终止 大大地。请联系应用程序的支持团队了解更多信息 信息。”

我就是不明白...为什么我不能编译这个游戏!!!

这是使用 Python 2.7 制作的游戏代码:

import pygame
import random
import os

pygame.init()

class Worm:
    def __init__(self, surface):
        self.surface = surface
        self.x = surface.get_width() / 2
        self.y = surface.get_height() / 2
        self.length = 1
        self.grow_to = 50
        self.vx = 0
        self.vy = -1
        self.body = []
        self.crashed = False
        self.color = 255, 255, 0

    def event(self, event):
        if event.key == pygame.K_UP:
            if self.vy != 1:
                self.vx = 0
                self.vy = -1
            else:
                a = 1
        elif event.key == pygame.K_DOWN:
            if self.vy != -1:
                self.vx = 0
                self.vy = 1
            else:
                a = 1
        elif event.key == pygame.K_LEFT:
            if self.vx != 1:
                self.vx = -1
                self.vy = 0
            else:
                a = 1
        elif event.key == pygame.K_RIGHT:
            if self.vx != -1:
                self.vx = 1
                self.vy = 0
            else:
                a = 1

    def move(self):
        self.x += self.vx
        self.y += self.vy
        if (self.x, self.y) in self.body:
            self.crashed = True
        self.body.insert(0, (self.x, self.y))
        if (self.grow_to > self.length):
            self.length += 1
        if len(self.body) > self.length:
            self.body.pop()

    def draw(self):
        x, y = self.body[0]
        self.surface.set_at((x, y), self.color)
        x, y = self.body[-1]
        self.surface.set_at((x, y), (0, 0, 0))

    def position(self):
        return self.x, self.y

    def eat(self):
        self.grow_to += 25

class Food:
    def __init__(self, surface):
        self.surface = surface
        self.x = random.randint(10, surface.get_width()-10)
        self.y = random.randint(10, surface.get_height()-10)
        self.color = 255, 255, 255

    def draw(self):
        pygame.draw.rect(self.surface, self.color, (self.x, self.y, 3, 3), 0)

    def erase(self):
        pygame.draw.rect(self.surface, (0, 0, 0), (self.x, self.y, 3, 3), 0)

    def check(self, x, y):
        if x < self.x or x > self.x +3:
            return False
        elif y < self.y or y > self.y +3:
            return False
        else:
            return True

    def position(self):
        return self.x, self.y

font = pygame.font.Font(None, 25)
GameName = font.render("Worm Eats Dots", True, (255, 255, 0))
GameStart = font.render("Press Any Key to Play", True, (255, 255, 0))

w = 500
h = 500
screen = pygame.display.set_mode((w, h))


GameLoop = True
while GameLoop:
    MenuLoop = True
    while MenuLoop:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
            elif event.type == pygame.KEYDOWN:
                MenuLoop = False
        screen.blit(GameName, (180, 100))
        screen.blit(GameStart, (155, 225))
        pygame.display.flip()

    screen.fill((0, 0, 0))
    clock = pygame.time.Clock()
    score = 0
    worm = Worm(screen)
    food = Food(screen)
    running = True

    while running:
        worm.move()
        worm.draw()
        food.draw()

        if worm.crashed:
            running = False
        elif worm.x <= 0 or worm.x >= w-1:
            running = False
        elif worm.y <= 0 or worm.y >= h-1:
            running = False
        elif food.check(worm.x, worm.y):
            score += 1
            worm.eat()
            print "Score %d" % score
            food.erase()
            food = Food(screen)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
            elif event.type == pygame.KEYDOWN:
                worm.event(event)

        pygame.display.flip()
        clock.tick(200)

    if not os.path.exists("High Score.txt"):
        fileObject = open("High Score.txt", "w+", 0)
        highscore = 0
    else:
        fileObject = open("High Score.txt", "r+", 0)
        fileObject.seek(0, 0)
        highscore = int(fileObject.read(2))
    if highscore > score:
        a = 1
    else:
        fileObject.seek(0, 0)
        if score < 10:
            fileObject.write("0"+str(score))
        else:
            fileObject.write(str(score))
        highscore = score
    fileObject.close()
    screen.fill((0, 0, 0))
    ScoreBoarda = font.render(("You Scored: "+str(score)), True, (255, 255, 0))
    if highscore == score:
        ScoreBoardb = font.render("NEW HIGHSCORE!", True, (255, 255, 0))
        newscore = 1
    else:
        ScoreBoardb = font.render(("High Score: "+str(highscore)), True, (255, 255, 0))
        newscore = 0
    Again = font.render("Again?", True, (255, 255, 0))
    GameOver = font.render("Game Over!", True, (255, 255, 0))
    screen.blit(GameName, (180, 100))
    screen.blit(GameOver, (200, 137))
    screen.blit(ScoreBoarda, (190, 205))
    if newscore == 0:
        screen.blit(ScoreBoardb, (190, 235))
    elif newscore == 1:
        screen.blit(ScoreBoardb, (175, 235))
    screen.blit(Again, (220, 365))
    pygame.draw.rect(screen, (0, 255, 0), (200, 400, 40, 40), 0)
    pygame.draw.rect(screen, (255, 0, 0), (260, 400, 40, 40), 0)
    LEFT = font.render("L", True, (0, 0, 0))
    RIGHT = font.render("R", True, (0, 0, 0))
    screen.blit(LEFT, (215, 415))
    screen.blit(RIGHT, (275, 415))
    pygame.display.flip()
    loop = True
    while loop:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x, y = event.pos
                if x > 200 and x < 240 and y > 400 and y < 440:
                    loop = False
                elif x > 260 and x < 300 and y > 400 and y < 440:
                    GameLoop = False
                    loop = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    loop = False
                elif event.key == pygame.K_RIGHT:
                    GameLoop = False
                    loop = False

    screen.fill((0, 0, 0))
pygame.quit()

【问题讨论】:

如果需要任何其他信息,请询问。 Someone 今年早些时候似乎也遇到了同样的问题——尽管目前还不清楚他的问题是如何解决的。 This 也可能是相关的。 谢谢,但我已经找到并尝试了这两种方法。我希望我知道 Paul 做了什么来让他工作,因为当我将所有列出的 dll 复制到 .exe 文件夹时,什么都没有修复。而且我已经浏览了分发模块和程序的指南,其中没有任何帮助......除非我错过了什么...... 问题仍未解决,仅供参考。 【参考方案1】:

我认为您的代码没有任何问题。事实上,它编译得很好,我也玩过。不错的游戏。

我建议在您的计算机中查看以下内容,

    您是否安装了所有 Microsoft 更新 查看程序(控制面板 - 程序和功能),看看您是否有最新的 Microsoft Visual C++ 库。

我认为如果上述两个都到位,它应该可以正常工作。

我在具有以下配置的机器上进行了测试: 1. 更新了所有安全补丁的 Windows 7。

【讨论】:

我已经拥有最新的 Microsoft Visual C++ Redist。包是最新的。但由于某种原因,我无法更新我的电脑。 “Windows Update 当前无法检查更新,因为该服务未运行。您可能需要重新启动计算机。”重新启动后这种情况继续存在...有关如何解决此问题的任何建议? 可能有多种可能性,我会寻找以下 1. 防火墙(和所有相关的东西) 2. 检查您的防病毒软件或任何其他相关软件是否阻止了更新。另外,我从 MS Support 团队发现了这个有趣的链接,看看是否有帮助 answers.microsoft.com/en-us/windows/forum/… "点击开始;输入:cmd;右键点击开始菜单中的cmd,选择“以管理员身份运行”;输入:net stop wuauserv;回车;输入:ren c:\windows\SoftwareDistribution softwaredistribution .old;按 Enter;类型:net start wuauserv;按 Enter;类型:exit;按 Enter” 我尝试了之前的方法,但不成功...我收到一条错误消息,提示“服务名称无效。”而且 Windows Defender 不会阻止更新。还有什么想法吗?【参考方案2】:

我也遇到了这个问题。经过排查,发现运行时错误是字体引起的。我注意到您也使用 None 作为字体名称。请记住,在 pygame2exe page 的 "Changes by arit:" 下面有一条关于字体使用 pygame2exe 的通知,我们应该使用 "fontname.ttf" 替换 None 并将 fontname.ttf 放在正确的文件夹下exe可以找到。例如,可以在创建字体时使用“freesansbold.ttf”替换None,并将freesansbold.ttf放在exe文件所在的文件夹下。希望对您有所帮助。

【讨论】:

【参考方案3】:

我的回答:

几周后(甚至之前也遇到过这个问题)我很高兴地说我解决了这个问题! :)

我的问题的第一部分 (http://i.stack.imgur.com/WpkjR.png): 我通过编辑 setup.py 脚本并在其中添加“排除”部分来解决它。这导致成功制作可执行文件!

修改 setup.py 脚本:

from distutils.core import setup
import py2exe
setup(windows=['source_static.py'], options=
          "py2exe": 
              "excludes": ["OpenGL.GL", "Numeric", "copyreg", "itertools.imap", "numpy", "pkg_resources", "queue", "winreg", "pygame.SRCALPHA", "pygame.sdlmain_osx"],
              
          
      )

所以,如果您有类似的问题,只需将那些“缺失”的模块放入此“排除”行。

第二部分:

在我成功制作可执行文件后,我遇到了下一个问题:"应用程序以异常方式请求运行时终止它。请联系..."。经过几天和几天的搜索和思考如何解决另一个问题,我找到了一种方法。我无法相信这个问题是如此荒谬。问题出在我的代码中,字体定义:

font1 = pygame.font.SysFont(None, 13)

在将“None”更改为某个系统字体名称(例如“Arial”(必须是字符串))并编译后,我不敢相信我的 .exe 文件能正常工作!

font1 = pygame.font.SysFont("Arial", 13)

当然,你可以使用自己的字体,但你必须指定它的路径并在你的程序中定义它。

因此,对于所有遇到此问题的人,请尝试以下步骤,希望您能成功。 我真的希望这会对您有所帮助,因为我已经浪费了几天和几周的时间来尝试解决这些问题。我什至尝试使用所有版本的 python 和 pygame 以及许多其他 .exe 构建器和设置脚本来制作我的 .exe 文件,但没有运气。除了这些问题,我之前也遇到过很多其他问题,但我在 ***.com 上找到了答案。

我很高兴我找到了解决这些问题的方法,并在您遇到相同问题时为您提供帮助。

小技巧(我也做过):

第一个:将您的 Microsoft Visual C++ 库更新到最新版本。

第二个:如果您有可执行程序所需的图像或字体,请将它们包含到 dist 文件夹(您的 .exe 文件已在其中创建)。

第三:当你制作你的 .exe 文件时,将所有需要的文件包含到你的 setup.py 脚本所在的文件夹中(你的主脚本使用的所有文件和目录)。

使用 Python 2.7 x64pygamepy2exe

【讨论】:

以上是关于我无法修复的 Pygame2Exe 错误的主要内容,如果未能解决你的问题,请参考以下文章

无法修复错误:此配置部分无法在此路径中使用

如何修复格式错误的 POM:无法识别的标签:'groupId'?

不要在我无法修复的循环错误中创建函数

poedit 显示似乎无法修复的错误

如何修复 xcrun 无法找到 simctl 错误?

无法修复创建名为“springSecurityFilterChain”的 bean 的错误