Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a Runtime Error in Executable made with pyinstaller

So I have made a game using Pygame, and now I want to make a executable out of it(standalone executable is preferred). So I used this to make the executable:

pyinstaller --onefile main.py

The compiling goes well but I get a error while running it. This is the error:

Traceback (most recent call last):
  File "main.py", line 15, in <module>
TypeError: expected str, bytes or os.PathLike object, not BytesIO
[5604] Failed to execute script 'main' due to unhandled exception!

I have a few image and sound files that I use with pygame and I suppose they are creating the issue. This is my main.py file.:

import pygame as pg
import random
import time
import pygame.time
from pygame import mixer

pg.init()

pg.display.set_caption('Space Invaders')
icon = pg.image.load('001-ufo.png')
pg.display.set_icon(icon)
mixer.music.load('Tetris.mp3')
mixer.music.play(-1)
kills = 0
font = pg.font.Font('freesansbold.ttf', 34)


def Score():
    global kills
    score = font.render(f'Score: {kills}', True, (255, 000, 000))
    screen.blit(score, (10, 10))


class Vector:
    def __init__(self):
        self.x = None
        self.y = None


class Bullet(pg.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pg.image.load('bullet.png')
        self.rect = self.image.get_rect()
        self.position = Vector()
        self.velocity = Vector()
        self.position.x = x
        self.position.y = y
        self.velocity.x = 0
        self.velocity.y = 5
        self.rect.center = [self.position.x, self.position.y]
        self.fire_sound = mixer.Sound('rocket_sound.wav')
        self.explosion_sound = mixer.Sound('explosion.wav')

    def update(self):
        self.position.y = self.position.y - self.velocity.y
        if self.position.y < -16:
            self.kill()
        self.rect.center = [self.position.x, self.position.y]
        new = pg.sprite.groupcollide(bullet_group, enemy_group, True, True)
        if new != {}:
            enemy = Enemy()
            enemy_group.add(enemy)
            self.explosion_sound.play()


class Player(pg.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pg.image.load('player.png')
        self.rect = self.image.get_rect()
        self.position = Vector()
        self.velocity = Vector()
        self.position.x = 650
        self.position.y = 600
        self.velocity.x = 0
        self.velocity.y = 0
        self.rect.center = [self.position.x, self.position.y]

    def update(self):
        self.position.x = self.position.x + self.velocity.x
        if self.position.x+32 > 1300:
            self.velocity.x = 0
            self.position.x = 1300-32
        if self.position.x-32 < 0:
            self.velocity.x = 0
            self.position.x = 0+32
        self.rect.center = [self.position.x, self.position.y]

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


class Enemy(pg.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.position = Vector()
        self.velocity = Vector()
        self.image = pg.image.load('001-ufo.png')
        self.rect = self.image.get_rect()
        self.position.y = random.randint(32, 368)
        self.position.x = random.randint(32, 1284)
        self.velocity.x = 5
        self.velocity.y = 0
        self.rect.center = [self.position.x, self.position.y]

    def update(self):
        self.position.x = self.position.x + self.velocity.x
        if self.position.x > 1284:
            self.position.x = 1284
            self.velocity.x = -5
            self.position.y += 32
        if self.position.x < 16:
            self.position.x = 16
            self.velocity.x = 5
            self.position.y += 32
        if self.position.y > 600-16:
            quit(0)
        self.rect.center = [self.position.x, self.position.y]


p1 = Player()
p_g = pg.sprite.Group()
p_g.add(p1)

bullet_group = pg.sprite.Group()

enemy_group = pg.sprite.Group()
for i in range(20):
    enemy = Enemy()
    enemy_group.add(enemy)

img = pg.image.load('player.png')
screen = pg.display.set_mode((1300, 700))
clock = pygame.time.Clock()
prev_time = time.time()
running = True
while running:
    screen.fill((0, 255, 0))
    for event in pg.event.get():
        if event.type == pg.QUIT:
            quit(0)
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_LEFT:
                p1.velocity.x = -10
            if event.key == pg.K_RIGHT:
                p1.velocity.x = 10
            if event.key == pg.K_SPACE:
                now_time = time.time()
                if now_time - prev_time > 0.5:
                    bullet = p1.create_bullet()
                    bullet_group.add(bullet)
                    bullet.fire_sound.play()
                    prev_time = now_time
        if event.type == pg.KEYUP:
            if event.key == pg.K_LEFT or event.key == pg.K_RIGHT:
                p1.velocity.x = 0

    p_g.update()
    p_g.draw(screen)

    bullet_group.update()
    bullet_group.draw(screen)
    enemy_group.update()
    enemy_group.draw(screen)
    pg.display.update()
    clock.tick(60)

These are my image and sound files. (ignore mainbak.py its just a backup file) enter image description here

P.S. My game runs fine in python. The problem is only with the executable.

like image 703
Kshitij Joshi Avatar asked Jan 20 '26 17:01

Kshitij Joshi


1 Answers

This is a bug in pygame.

Reported in https://github.com/pygame/pygame/issues/2603, fixed in https://github.com/pygame/pygame/pull/2604

This will be fixed in pygame 2.0.2, whenever it comes out.

Edit: It was still broken for onefile executables, should be fixed by https://github.com/pygame/pygame/pull/2911, available in pygame 2.1.3.dev2. However, it broke again for a completely different reason (https://github.com/pygame/pygame/issues/3070) in the same release. So no current version works with this, at time of writing.

To mitigate this, you have to include a font file in your project, and not rely on the pygame default font. Many ttf files are available for download from Google Fonts.

like image 170
Starbuck5 Avatar answered Jan 23 '26 06:01

Starbuck5



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!