7

我做了一个“游戏”。我喜欢玩它,我想将它分发给我的朋友,而无需在他们的计算机上安装 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()
4

3 回答 3

5

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

于 2012-12-29T10:19:08.430 回答
1

我的答案:

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

我的问题的第一部分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 文件,但没有运气。除了这些问题,我之前也遇到过很多其他问题,但我在 stackoverflow.com 上找到了答案。

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

小技巧(我也做过):

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

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

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

使用Python 2.7 x64pygamepy2exe

于 2013-03-05T04:31:20.133 回答
1

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

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

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

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

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

于 2012-10-30T20:42:06.173 回答