Viktor Stefanov
Viktor Stefanov

Reputation: 80

PyInstaller's .exe file closes immediately after opening

I created a basic reaction game with python's pygame library. There is a link to my github so you can view the code. As the title states whenever I click on the .exe file it simply creates the window and then closes it. From my inspection there is nothing that stops the flow of the program in the code and the problem must be in pygame. I reinstalled pygame but the result is the same. No error message pops up on the console screen when launching the .exe file. I looked for similar questions, but couldn't find the answer. I create the .exe file with the following command: pyinstaller game.py --onefile

repository link - https://github.com/Viktor-stefanov/Reaction-Game

Upvotes: 0

Views: 5293

Answers (1)

tgikal
tgikal

Reputation: 1680

So I went through and tracked down the error with print statements.

The error is occurring on line 103: font = pygame.font.SysFont('comicsans', 38, True)

This is due to the 'comicsans' font not being a typical font.

Changing the three instances of 'comicsans' to 'comicsansms' fixed it on my computer, I built it with pyinstaller.exe --onefile "path/to/script.py"

You may want to look into packing the font with pyinstaller, or explicitly including pygame's font files for greater compatibility.

As you can see in this package's open issue referencing pyinstaller not including the pygame's font files "PyInstaller does not pull in data files with imports that it finds": https://github.com/lordmauve/pgzero/issues/59

NOT THE SOLUTION:

If you're interested in what I did, build this in an .exe and run it through command prompt:

(You will see it stop at "here13")

import pygame
from random import choice, randint

pygame.init()

s_width, s_height = 600, 700
win = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption('Reaction Speed Game')

print("here")

class square():
    def __init__(self, x, y, width, height, color):
        print("here2")
        super().__init__()
        self.x = x
        self.y = y
        self.color = color
        self.width = width
        self.height = height

        self.image = pygame.Surface([width, height])
        self.image.fill((0, 0, 0))

        self.rect = pygame.Rect(x, y, width, height)

    def clicked(self):
        print("here3")
        self.width = randint(50, 80)
        self.height = self.width
        self.x, self.y = randint(1, s_width-self.width), randint(1, s_height - self.height)
        self.color = choice(square_colors)
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)

    def draw(self, surface):
        print("here4")
        pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height))



def renderText(time):
    print("here5")
    global dest
    font = pygame.font.SysFont('comicsans', 32)
    if time < 325:
        text = font.render('Legendary!', 0, (255, 255, 255))
    elif time < 450:
        text = font.render('Epic!', 0, (255, 255, 255))
    elif time < 600:
        text = font.render('Great!', 0, (255, 255 ,255))
    else:
        text = font.render('Good!', 0, (255, 255, 255))
    dest = s.x, s.y + s.height // 2
    return text


def redrawWindow(surface, clickMessage=False):
    print("here6")
    surface.fill((0, 0, 0))
    s.draw(surface)
    if clickMessage:
        surface.blit(text, dest)
    pygame.display.update()


def main():
    print("here7")
    global s, square_colors, text
    square_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]
    sx, sy = s_width // 2 - 32, s_height // 2 - 32
    sw, sh = 50, 50
    s = square(sx, sy, sw, sh, choice(square_colors))
    start_time = pygame.time.get_ticks()
    time = 0
    message = False
    flag = True
    while flag:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                flag = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                pos = pygame.mouse.get_pos()
                if s.rect.collidepoint(pos):
                    time = pygame.time.get_ticks() - start_time
                    text = renderText(time)
                    start_time = pygame.time.get_ticks()
                    s.clicked()
                    message = True

        if pygame.time.get_ticks() - start_time > 800:
            message = False
        redrawWindow(win, message)


    pygame.display.quit()


def menu():
    print("here8")
    flag = True
    while flag:
        win.fill((0, 0, 0))

        for event in pygame.event.get():
            print("here10")
            if event.type == pygame.QUIT:
                print("here11")
                flag = False

        print("here12")
        start_time = pygame.time.get_ticks()
        if start_time <= 5000:
            print("here13")
            font = pygame.font.SysFont('comicsans', 38, True)
            print("here17")
            text = font.render('Click on the squares as fast as you can!', 0, (255, 255, 255))
            print("here18")
            win.blit(text, (12, 250))
            print("here19")
        else:
            print("here14")
            font = pygame.font.SysFont('comicsans', 46, True)
            if start_time <= 6000:
                text = font.render('3', 0, (255, 255, 255))
            elif start_time <= 7000:
                text = font.render('2', 0, (255, 255, 255))
            elif start_time <= 8000:
                text = font.render('1', 0, (255, 255, 255))
            else:
                flag = False
                main()

            print("here15")
            win.blit(text, (s_width // 2 - 10, 250))
            print("here16")

        pygame.display.update()

    pygame.display.quit()



if __name__ == '__main__':
    print("here9")
    menu()

Upvotes: 3

Related Questions