Recently, I was developing games with python+pygame. After writing, I encountered great problems when sharing with friends. Only when I built an environment can I run python scripts.
This will scare off more than 99% of people... So it is imperative to package our game (pay attention to packaging rather than compiling, python is a script program after all) into an executable file.
I searched several programs about python packaging on the Internet. After using it, I found that py2exe is more practical and convenient (py2exe is free).
1. Introduction
Py2exe can package a python program into an EXE executable file, which is convenient for using the program on computers without Python environment. To package with py2exe, you need to write a packaging script. After execution, you can get the packaging file. For the 32-bit version, py2exe can package the program into a single file; For the 64 bit version, packaging into a single file is not supported yet. However, no matter how compressed, the programs packaged by py2exe are still too large.
2. Software preparation
First, go to the official website of py2exe http://www.py2exe.org/ Download the installation package and pay attention to the corresponding python version, otherwise there will be problems.
Double click the exe file and go all the way to next. It should be noted that the 32-bit version and 64 bit version must be matched with the version used by Python.
3. Packaging process
Py2exe needs to write a script for packaging. Using the following script specially written for pygame (refer to the official py2exe) can greatly facilitate the packaging operation. Pay attention to modifying the parameters in BuildExe before use.
Thank you very much for the script provided by "xishui" God. This script is really great!!!
#!python # -*- coding: gb2312 -*- # This script is optimized for pygame. Use py2exe to package code and resources to dist directory # # If you have any questions during use, you can leave a message to: # //eyehere.net/2011/python-pygame-novice-professional-py2exe/ # # Installation requirements: # Python, pyGame and py2exe should be installed # usage method: # 1: Modify this file to specify the file to be packaged py and corresponding data # 2: python pygame2exe.py # 3: In the dist folder, enjoy it~ 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, "Sorry, you must install py2exe, pygame. %s" % message # This function is used to determine whether the DLL is provided by the system (if so, there is no need to package) origIsSystemDLL = py2exe.build_exe.isSystemDLL def isSystemDLL(pathname): # Need to hack. The DLLs of freetype and ogg are not system DLLs if os.path.basename(pathname).lower() in ("libfreetype-6.dll", "libogg-0.dll", "sdl_ttf.dll"): return 0 return origIsSystemDLL(pathname) # Rewrite Hack's function back py2exe.build_exe.isSystemDLL = isSystemDLL # This new class is also a Hack, so that the default font of pygame will be copied class pygame2exe(py2exe.build_exe.py2exe): 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 copy file list extensions.append(Module("pygame.font", pygame_default_font)) py2exe.build_exe.py2exe.copy_extensions(self, extensions) # This class is part of what we really do class BuildExe: def __init__(self): #------------------------------------------------------# ##### For a new game program, you need to modify the parameters here ##### #------------------------------------------------------# # Start py file self.script = "MyGames.py" # Game name self.project_name = "MyGames" # Game site self.project_url = "about:none" # Game version self.project_version = "0.0" # Game license self.license = "MyGames License" # Game author self.author_name = "xishui" # Contact Email self.author_email = "blog@eyehere.net" # Game copyright self.copyright = "Copyright (c) 3000 xishui." # Game Description self.project_description = "MyGames Description" # Game icon (if None, use the default icon of pygame) self.icon_file = None # Additional files and folders to be copied (pictures, audio, etc.) self.extra_datas = [] # Additional required python library name self.extra_modules = [] # python libraries that need to be excluded self.exclude_modules = [] # Additional DLLs to exclude self.exclude_dll = [''] # py file to be added self.extra_scripts = [] # Package Zip file name (if None, package into exe file) self.zipfile_name = None # Build folder self.dist_dir ='dist' def opj(self, *args): path = os.path.join(*args) return os.path.normpath(path) def find_data_files(self, srcdir, *wildcards, **kw): # Get files from source folder def walk_helper(arg, dirname, files): # Of course, you can also add other version control tools 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): # Delete last generated result shutil.rmtree(self.dist_dir) # Get default icon if self.icon_file == None: path = os.path.split(pygame.__file__)[0] self.icon_file = os.path.join(path, 'pygame.ico') # Obtain the data file to be packaged 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])) # Start packaging exe 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, # The default is to generate the window program. If you need to generate the terminal program (debug stage), use: # console = [{ 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, 'dist_dir': self.dist_dir, 'dll_excludes': self.exclude_dll, 'includes': self.extra_scripts} }, zipfile = self.zipfile_name, data_files = extra_datas, ) if os.path.isdir('build'): # Clear the build folder shutil.rmtree('build') if __name__ == '__main__': if len(sys.argv) < 2: sys.argv.append('py2exe') BuildExe().run() raw_input("Finished! Press any key to exit.")
You can start with a simple program, have a little experience, and then try to package complex games. Some tips:
- If there is an error in execution, a XXX will be generated exe. Log, refer to the log information here to see if there is less packaging.
- You can see more information in the command line of console.
- For each game, you basically need to copy the above original code and modify it into a unique packaged execution file.
- Even for a small py file, the final generated EXE file is also large (depending on the installed library, the minimum here is about 4.7M). In fact, when py2exe is packaged, it will type in countless unnecessary libraries, resulting in bloated final files, especially if you install very complicated libraries (wxPython, etc.). After using zip package, check the library files inside and add unnecessary ones to self exclude_ Modules, you can finally control the file size within an acceptable range.
Supplement: Many people have problems when packaging and using the Font module. Here we need to use sdl_ttf.dll is declared as a non system file. I have modified the script and added it by default. It is also suggested that if you are sure to package as exe in the future, do not use the system Font, that is, "pyGame Font. Sysfont (xxx) ", but use Font files, and then package the files as pictures when packaging, which will greatly reduce the probability of problems.
"dist_dir" should be a unique option of py2exe, not setup.
Reference blog: http://eyehere.net/2011/python-pygame-novice-professional-py2exe/
This concludes today's article. Thank you for reading.