My game runs fine from text editors as a py file but when I convert it to executable using cx_Freeze and pyinstaller I cant run the exe file it outputs it gives me this error :
Traceback (most recent call last):
File "egg_rampage.py", line 12, in <module>
File "img_sound.py", line 7, in __init__
pygame.error: Unable to open file 'music/scream.wav'
[9292] Failed to execute script egg_rampage
I have tried everything I found on the Internet: -using the complete path to the files -using init.py at the end of the files -installing the exe through a setup file -putting the audio and image files on a separate module
I dont know why this happens, because I tried doing it with another game and it worked, I dont know what is wrong with this one, below I put my game code so that you can see.
import pygame
import sys
import random
import time
from game_settings import Settings
from space_ship import SpaceShip
from img_sound import ImageSound
pygame.init()
imgs = ImageSound()
red = (255,0,0)
green = (0,255,0)
white = (255,255,255)
turquoise = (175,238,238)
crash_sound = imgs.scream
imgs.music
pygame.display.set_caption('Egg Rampage')
pygame.display.set_icon(imgs.caricon)
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.scr_width,
ai_settings.scr_height))
ship = SpaceShip(screen, ai_settings)
screen_rect = screen.get_rect()
pause = False
def crash():
pygame.mixer.music.stop()
pygame.mixer.Sound.play(crash_sound)
pygame.time.delay(600)
exorcista_img = imgs.exorcista
screen.blit(exorcista_img, [0,0])
pygame.display.update()
time.sleep(2)
intro(ai_settings, screen)
def intro(ai_settings, screen):
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
intro_bg = imgs.intro_bg
screen.blit(intro_bg, (0,0))
button(screen, 170 , 200, 150, 50, ' PLAY', green, turquoise, "play")
button(screen, 170 , 270, 150, 50, ' QUIT', red, turquoise, "quit")
highscore = load_highscores()
button(screen, 170, 340, 150, 50, 'HIGHSCORE:' + str(highscore) , red, red)
pygame.display.update()
def button(screen, x, y, w, h, text, a_color, i_color, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(screen, i_color, (x, y, w, h))
if click[0] == 1 and action != None:
if action == "quit":
sys.exit()
elif action == "play":
run_game()
elif action == "continue":
unpause()
else:
pygame.draw.rect(screen, a_color, (x, y, w, h))
font = pygame.font.Font('freesansbold.ttf' , 20)
small_text2 = font.render(text, True, (255,255,255))
small_text2_rect = small_text2.get_rect()
small_text2_rect.center = (x + (w/2), y + (h/2))
screen.blit(small_text2, small_text2_rect)
def egg(egg_startx, egg_starty):
egg_img = imgs.egg_img
for egg_x in egg_startx:
screen.blit(egg_img, [egg_x, egg_starty])
def display_score(dodged):
font = pygame.font.SysFont(None, 25)
text = font.render("Your score: " + str(len(dodged)), True, white)
screen.blit(text, (0,0))
current_highscore = font.render("Highscore: " + str(load_highscores()), True , white)
screen.blit(current_highscore, (0, 25))
filename = 'highscores.txt'
highscore = load_highscores()
if len(dodged) > highscore :
highscore = len(dodged)
with open(filename, '+r') as f:
f.write(str(len(dodged)))
def load_highscores():
filename = 'highscores.txt'
with open(filename, '+r') as f:
try:
highscore = int(f.read())
except:
highscore = 0
return highscore
def paused(ai_settings, screen):
pygame.mixer.music.pause()
while pause:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
font = pygame.font.Font('freesansbold.ttf', 50)
text = font.render('PAUSED', True, (255,255,255))
text_rect = text.get_rect(center = (ai_settings.scr_width/2, 100))
screen.blit(text , text_rect)
button(screen, 170 , 200, 150, 50, ' CONTINUE', green, turquoise, "continue")
button(screen, 170 , 270, 150, 50, ' QUIT', red, turquoise, "quit")
pygame.display.update()
def unpause():
global pause
pygame.mixer.music.unpause()
pause = False
def run_game():
global pause
pygame.mixer.music.play(-1)
ship = SpaceShip(screen, ai_settings)
egg_startx = [random.randrange(0, ai_settings.scr_width)]
egg_starty = -600
egg_count = 1
ai_settings.egg_speed = 3
dodged = []
y = 0
x = 0
x1 = 0
y1 = -500
screen.blit(ai_settings.bg, ai_settings.bg.get_rect())
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
ship.pressed_left = True
elif event.key == pygame.K_RIGHT:
ship.pressed_right = True
elif event.key == pygame.K_p:
pause = True
paused(ai_settings, screen)
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
ship.pressed_left = False
elif event.key == pygame.K_RIGHT:
ship.pressed_right = False
y1 += 2
y += 2
screen.blit(ai_settings.bg, (x,y))
screen.blit(ai_settings.bg, (x1,y1))
if y > 500:
y = -500
if y1 > 500:
y1 = -500
display_score(dodged)
#crash against egg
egg(egg_startx, egg_starty)
egg_center = float(egg_starty)
egg_center += ai_settings.egg_speed
egg_starty = egg_center
if egg_starty > ai_settings.scr_height:
egg_starty = -600
egg_startx = []
for x in range(egg_count):
new_egg = random.randrange(0, ai_settings.scr_width - 75)
egg_startx.append(new_egg)
ai_settings.egg_speed += 0.1
dodged.append(egg)
if len(dodged) % 10 == 0:
if egg_count < 3:
egg_count += 1
if ship.rect.y < egg_starty + 75 and ship.rect.y + 50 > egg_starty:
for egg_x in egg_startx:
if ship.rect.x < egg_x + 75 and ship.rect.x + 50 > egg_x:
crash()
#crash against screen edges
if ship.rect.left <= screen_rect.left or ship.rect.right >= screen_rect.right:
crash()
ship.blitme()
ship.update()
pygame.display.update()
intro(ai_settings, screen)
run_game()
And here is the module containing the files:
import pygame
pygame.init()
class ImageSound():
def __init__(self):
self.scream = pygame.mixer.Sound("music/scream.wav")
self.music = pygame.mixer.music.load("music/mario_kart_music.wav")
self.caricon = pygame.image.load("images/caricon.png")
self.exorcista = pygame.image.load("images/exorcista.bmp")
self.intro_bg = pygame.image.load("images/intro_background.png")
self.egg_img = pygame.image.load("images/egg.bmp")
And this is the setup file i used:
import cx_Freeze
import os
os.environ['TCL_LIBRARY'] = r"C:\Users\User\AppData\Local\Programs\Python\Python37\tcl\tcl8.6"
os.environ['TK_LIBRARY'] = r"C:\Users\User\AppData\Local\Programs\Python\Python37\tcl\tk8.6"
executables = [cx_Freeze.Executable("egg_rampage.py")]
cx_Freeze.setup(
name = "Egg Rampage",
options = {"build_exe": {"packages":["pygame"],
"include_files":
[r"C:\Users\User\Desktop\egg_rampage\music\mario_kart_music.wav",
r"C:\Users\User\Desktop\egg_rampage\music\scream.wav",
r"C:\Users\User\Desktop\egg_rampage\images\background.png",
r"C:\Users\User\Desktop\egg_rampage\images\caricon.png",
r"C:\Users\User\Desktop\egg_rampage\images\egg.bmp",
r"C:\Users\User\Desktop\egg_rampage\images\exorcista.bmp",
r"C:\Users\User\Desktop\egg_rampage\images\intro_background.png",
r"C:\Users\User\Desktop\egg_rampage\images\rocket.bmp", "highscores.txt"]} },
executables = executables
)
I hope you can find the problem please.
from the documentation:
I suppose that the files you're passing are copied flat in the destination directory, not in sub-directory.
to include
music
andimages
folders I would just do:for files only, specify target dir
and so on with other files (tuple: original file, destination relative dir in the package)
BTW the program must still be run from the main script path else, since your code is using relative paths, this won't work. Something like:
then: