I've been trying all day to make an executable from python file using pygame too. I was doing okay until it got to the mixer module which is where it failed quite epically. I then searched the web a bit and came up with this as it was on the pygame website The Pygame website code. I would be really grateful if anyone could help me with this or tell me how to import the mixer module (I've commented it to help you if you can't find it. Its under the Build_exe Class)
By the way, i got rid of the " < 2:" on this version as it didn't seem to want to work with my python and compiles everything fine without it. (It should be on line 143) I just thought it might help you if your stuck. Cheers in advance

try:
    from distutils.core import setup
    import py2exe, pygame
    from modulefinder import Module
    import glob, fnmatch
    import sys, os, shutil
except ImportError, message:
    raise SystemExit,  "Unable to load module. %s" % message
 
class pygame2exe(py2exe.build_exe.py2exe): #This hack make sure that pygame default font is copied: no need to modify code for specifying default font
    def copy_extensions(self, extensions):
        #Get pygame default font
        pygamedir = os.path.split(pygame.base.__file__)[0]
        pygame_default_font = os.path.join(pygamedir, pygame.font.get_default_font())
 
        #Add font to list of extension to be copied
        extensions.append(Module("pygame.font", pygame_default_font))
        py2exe.build_exe.py2exe.copy_extensions(self, extensions)
 
class BuildExe:
    def __init__(self):
        #Name of starting .py
        self.script = "MyApp.py"
 
        #Name of program
        self.project_name = "MyApp"
 
        #Project url
        self.project_url = "about:none"
 
        #Version of program
        self.project_version = "0.0"
 
        #License of the program
        self.license = "MyApps License"
 
        #Auhor of program
        self.author_name = "Me"
        self.author_email = "example@example.com"
        self.copyright = "Copyright (c) 2009 Me."
 
        #Description
        self.project_description = "MyApps Description"
 
        #Icon file (None will use pygame default icon)
        self.icon_file = "MyIcon.ico"
 
        #Extra files/dirs copied to game
        self.extra_datas = ["#Extra Files"]
 
        #Extra/excludes python modules (This is the module I'm having errors using.
        self.extra_modules = ["pygame.mixer.module"]
        self.exclude_modules = []
        
        #DLL Excludes
        self.exclude_dll = ['']
 
        #Zip file name (None will bundle files in exe instead of zip file)
        self.zipfile_name = None
 
        #Dist directory
        self.dist_dir ='dist'
 
    ## Code from DistUtils tutorial at http://wiki.python.org/moin/Distutils/Tutorial
    ## Originally borrowed from wxPython's setup and config files
    def opj(self, *args):
        path = os.path.join(*args)
        return os.path.normpath(path)
 
    def find_data_files(self, srcdir, *wildcards, **kw):
        # get a list of all files under the srcdir matching wildcards,
        # returned in a format to be used for install_data
        def walk_helper(arg, dirname, files):
            if '.svn' in dirname:
                return
            names = []
            lst, wildcards = arg
            for wc in wildcards:
                wc_name = self.opj(dirname, wc)
                for f in files:
                    filename = self.opj(dirname, f)
 
                    if fnmatch.fnmatch(filename, wc_name) and not os.path.isdir(filename):
                        names.append(filename)
            if names:
                lst.append( (dirname, names ) )
 
        file_list = []
        recursive = kw.get('recursive', True)
        if recursive:
            os.path.walk(srcdir, walk_helper, (file_list, wildcards))
        else:
            walk_helper((file_list, wildcards),
                        srcdir,
                        [os.path.basename(f) for f in glob.glob(self.opj(srcdir, '*'))])
        return file_list
 
    def run(self):
        if os.path.isdir(self.dist_dir): #Erase previous destination dir
            shutil.rmtree(self.dist_dir)
        
        #Use the default pygame icon, if none given
        if self.icon_file == None:
            path = os.path.split(pygame.__file__)[0]
            self.icon_file = os.path.join(path, 'pygame.ico')
 
        #List all data files to add
        extra_datas = []
        for data in self.extra_datas:
            if os.path.isdir(data):
                extra_datas.extend(self.find_data_files(data, '*'))
            else:
                extra_datas.append(('.', [data]))
        
        setup(
            cmdclass = {'py2exe': pygame2exe},
            version = self.project_version,
            description = self.project_description,
            name = self.project_name,
            url = self.project_url,
            author = self.author_name,
            author_email = self.author_email,
            license = self.license,
 
            # targets to build
            windows = [{
                'script': self.script,
                'icon_resources': [(0, self.icon_file)],
                'copyright': self.copyright
            }],
            options = {'py2exe': {'optimize': 2, 'bundle_files': 1, 'compressed': True, \
                                  'excludes': self.exclude_modules, 'packages': self.extra_modules, \
                                  'dll_excludes': self.exclude_dll} },
            zipfile = self.zipfile_name,
            data_files = extra_datas,
            dist_dir = self.dist_dir
            )
        
        if os.path.isdir('build'): #Clean up build dir
            shutil.rmtree('build')
 
if __name__ == '__main__':
    if len(sys.argv):  
        sys.argv.append('py2exe')
    BuildExe().run() #Run generation
    raw_input("Press any key to continue") #Pause to let user see that things ends

Recommended Answers

All 7 Replies

How about your actual game code? Can't really debug what the problem is without it...

My gut feeling is that you don't need to specify pygame.mixer.module; try searching this forum for vegaseat's excellent and simple py2exe script that should pull in your basic modules.

thats the code i was using before but it didn't seem work with the mixer module so i tried the current one as it's got a space on it to import modules. Just can't work out how to import on the pygame2exe script. My code for the game is below:

import random

wormcolor = 255, 255, 0
w = 500
h = 500
bgcolor = 0, 0, 0
score = 0
foodcolor = 255, 255, 255
screen = pygame.display.set_mode((w, h))
clock = pygame.time.Clock()

pygame.mixer.init()
chomp = pygame.mixer.Sound("Content\\pop.wav")

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


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

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

    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), wormcolor)
        x, y = self.body[-1]
        self.surface.set_at((x, y), bgcolor)

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

class Food:
    def __init__(self, surface):
        self.surface = surface
        self.x = random.randint(0, surface.get_width())
        self.y = random.randint(0, surface.get_height())

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

    def position(self):
        return self.x, self.y
    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 erase(self):
        pygame.draw.rect(self.surface, bgcolor, (self.x, self.y, 3, 3), 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()
        chomp.play()
        print "Score: %d" % score
        food.erase()
        food = Food(screen)

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

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

The Errors for Vegaseats one is:
--------------------------------------------------------------------------------------
C:\Documents and Settings\User\My Documents\Python\dist\Snake.exe:13: RuntimeWarning: use mixer: MemoryLoadLibrary failed loading pygame\mixer.pyd
Traceback (most recent call last):
File "snake.py", line 13, in <module>
File "pygame\__init___.pyo", line 70, in __getattr__
NotImplementedError: mixer module not available
--------------------------------------------------------------------------------------

And the error for the pygame one is sent to a text file (log file) which says:
--------------------------------------------------------------------------------------
C:\Documents and Settings\User\My Documents\Python\dist\Snake.exe:13: RuntimeWarning: use mixer: MemoryLoadLibrary failed loading pygame\mixer.pyd
Traceback (most recent call last):
File "Snake.py", line 13, in <module>
File "pygame\__init__.pyo", line 70, in __getattr__
NotImplementedError: mixer module not available
--------------------------------------------------------------------------------------

Firstly, I want to ask - Do you know how to make a Python Exe? Have you done it before or is this your first try? If it`s your first attempt I`ll try and send you a step by step way of doing this.

However, assuming you`ve done it before there are a few points I`d like to make.
Firstly, you must have import pygame at the top of your code,Secondly, I would prefer ( though its not essential ) to change the line that has your wav file to this: chomp = pygame.mixer.Sound("pop.wav") (and put your wav file in the same folder that your Python is in)

and thirdly, the code on the Pygame website seems incredibly complicated to me.Below is a simple setup.py that will work ( I`ve just done it and it does )

from distutils.core import setup
import py2exe
setup(
    windows = [{"script":"worm.py"}],
    data_files = [ (".", ["pop.wav"]) ]
    )

Anyway, like I say, if this is your first Exe - most of this (like it did with me )will probably go over your head the first time. Let me know if you still have difficulties.

That code still doesn't work... I get a log file made that says that the mixer module is not available :(

I`ve decided to give you a general step by step approach to the way I make a Python Exe and hopefully this will help you:
( I am assuming you`re using Python 25 and you already have Pygame installed)

1) You must add Python 25 to your Path variable ( I won`t go into that here but if you can find the Path on the Environment variable part of your system - double left click the word Path
and type ( ;C:\Python25;C:\Python25\Scripts ) at the end of the blue line that is highlighted ( don`t type the brackets).
Exit all the windows. Type cmd in the Run box , press Return
and type the word python in the console window
and press return.If you don`t get something saying python isnt a recognised file - but you get the python console instead - congratulations you`ve got Python on your path.!
Now CLOSE THIS CONSOLE.

2) Install Py2Exe ( in this case Py2Exe for Python25 )

3)create a folder on your C drive called mycode

4)open IDLE then go to FILE - NEW WINDOW - OPEN

5)Type the following in the new window

print "Hello py2exe"
raw_input("Close Window to Finish")

6)save this file as hello.py in the mycode folder

7)Open another file ( go to FILE - NEW WINDOW - OPEN )

8)In this window type the following

from distutils.core import setup
import py2exe
setup(
    console = [{"script":"hello.py"}]
    )

9)Save this file as setup.py in the mycode folder

10) go to Run and type CMD ( Return ) to bring up a new console and type this:
CD C:\mycode ( Return )
now on the new line type

start setup.py py2exe ( Return )

(as an alternative to the above you can also type:

python setup.py py2exe (Return))

11) Now if you look in your mycode folder there will be 2 files created called BUILD and DIST.
Ignore the first but DIST is the folder where your exe is created. Look in there
and double left click the hello.exe. It should run.

12)Take a break

13) If (instead of a console program) you want to run a windows program with some graphics, music, fonts etc,
it`s the same principle as above however:
a) put all your graphics,fonts, music etc in the mycode folder and
b) change your setup.py to look something like below

from distutils.core import setup
import py2exe
setup(
    windows = [{"script":"graphicprogram.py"}],
    data_files = [ (".", ["ball.png", "freesansbold.ttf", "pop.wav"]) ]
    )

14)Two final points-= about Fonts and Sound: If you are using a font please DONT use a line like the following: font = pygame.font.Font(None, 24) Instead, delete this and specify the font in your code with a line like this: font = pygame.font.Font("freesansbold.ttf", 24) (also make sure that you have the 'freesansbold.ttf' file in the mycode folder, your Python 25 folder
AND, if necessary the DIST folder ( put it in before you run the exe )).

If you are using the Pygame module I find that Pygame.mixer.Sound is much better at turning into exe`s than Pygame.mixer.Music.

Hope you understand all of this. Any problems let me know.

cheers, it must have been because i was using python 2.6 or something crazy like that :) thank you soo much

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.