If you have read my previous post regarding the PyInstaller then this one will further shows you how to create a installer for your pygame program for windows os so the windows users can download and install your program on their windows os’s pc.
Before we go further lets us revisit the part on how to create a distribution folder which includes a clickable application file that our application user can click on it to start the pygame application on windows os. In our previous tutorial regarding the PyInstaller we have only created a distribution folder for one file but in this one we will create the distribution folder for many files include the image files.
Make sure you have copied the freesansbold.ttf file to the main file folder if you are using it in your game before you create the spec file because PyInstaller is unable to locate it in the pygame package. We do not need to specify the pygame’s library because PyInstaller is smart enough to import all the pygame modules that the game requires for us.
As usual in the windows command prompt we will browse to the directory which contains all the files that we wish to turn into a single pygame application.
Create distribution folder :
1) Type in below command in the windows command prompt then press enter.
pyinstaller --noconsole main.py
where main.py is the main file of the pygame application (the one which starts the application) and the ‘—noconsole’ option is used to hide the console window which will open in the background of python application program.
You will see errors such as the PyInstaller is unable to find the api-ms-win-crt-runtime-l1-1-0.dll file during the compilation stage but that is not a big issue as these files are in the windows os itself so we do not need to include it in our game package anymore. Also for the users to play the game they must have Python installed in their machine.
2) After PyInstaller has generated a spec file for your application open it up with any code editor which you prefer. Below is the spec file for my python game.
Besides the spec file you will also find a dist folder which contains of your application file in it but at the moment you cannot start the application because the application’s helper files are not there yet. There are also two other folders the pyinstaller has created for you : build and __pycache__ folder but we do not need to worry about those two as our main focus is on the dist folder.
3) Now I will edit or add in the following lines of code in that spec file.
# -*- mode: python -*- block_cipher = None a = Analysis(['rocksweeper.py'], pathex=['E:\\Pygame\\project0\\src'], binaries=None, datas=None, hiddenimports=, hookspath=, runtime_hooks=, excludes=, win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher) game_files = [('world.py', 'E:\\Pygame\\project0\\src\\world.py', 'DATA')] game_files += [('win.png', 'E:\\Pygame\\project0\\src\\win.png', 'DATA')] game_files += [('vector2d.py', 'E:\\Pygame\\project0\\src\\vector2d.py', 'DATA')] game_files += [('title.png', 'E:\\Pygame\\project0\\src\\title.png', 'DATA')] game_files += [('thick.png', 'E:\\Pygame\\project0\\src\\thick.png', 'DATA')] game_files += [('state_winning.py', 'E:\\Pygame\\project0\\src\\state_winning.py', 'DATA')] game_files += [('state_playing.py', 'E:\\Pygame\\project0\\src\\state_playing.py', 'DATA')] game_files += [('state_over.py', 'E:\\Pygame\\project0\\src\\state_over.py', 'DATA')] game_files += [('state_losing.py', 'E:\\Pygame\\project0\\src\\state_losing.py', 'DATA')] game_files += [('state_loading.py', 'E:\\Pygame\\project0\\src\\state_loading.py', 'DATA')] game_files += [('state_engine.py', 'E:\\Pygame\\project0\\src\\state_engine.py', 'DATA')] game_files += [('state.py', 'E:\\Pygame\\project0\\src\\state.py', 'DATA')] game_files += [('ship_sprite.py', 'E:\\Pygame\\project0\\src\\ship_sprite.py', 'DATA')] game_files += [('screen_win.py', 'E:\\Pygame\\project0\\src\\screen_win.py', 'DATA')] game_files += [('screen_over.py', 'E:\\Pygame\\project0\\src\\screen_over.py', 'DATA')] game_files += [('screen_lose.py', 'E:\\Pygame\\project0\\src\\screen_lose.py', 'DATA')] game_files += [('screen_load.py', 'E:\\Pygame\\project0\\src\\screen_load.py', 'DATA')] game_files += [('screen.py', 'E:\\Pygame\\project0\\src\\screen.py', 'DATA')] game_files += [('rock_sprite.py', 'E:\\Pygame\\project0\\src\\rock_sprite.py', 'DATA')] game_files += [('play_on.png', 'E:\\Pygame\\project0\\src\\play_on.png', 'DATA')] game_files += [('next.png', 'E:\\Pygame\\project0\\src\\next.png', 'DATA')] game_files += [('menu.png', 'E:\\Pygame\\project0\\src\\menu.png', 'DATA')] game_files += [('maintile.png', 'E:\\Pygame\\project0\\src\\maintile.png', 'DATA')] game_files += [('icon.png', 'E:\\Pygame\\project0\\src\\icon.png', 'DATA')] game_files += [('game_state_engine.py', 'E:\\Pygame\\project0\\src\\game_state_engine.py', 'DATA')] game_files += [('game_sprite.py', 'E:\\Pygame\\project0\\src\\game_sprite.py', 'DATA')] game_files += [('gameover.png', 'E:\\Pygame\\project0\\src\\gameover.png', 'DATA')] game_files += [('freesansbold.ttf', 'E:\\Pygame\\project0\\src\\freesansbold.ttf', 'DATA')] pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, exclude_binaries=True, name='Rocksweeper', debug=False, strip=False, upx=True, console=False , icon='iconfile.ico' ) coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas + game_files, strip=False, upx=True, name='Rocksweeper')
Basically I have added in all those files that the game needs under the game_files list and then added that list to the a.datas list
a.datas + game_files
The game_files list takes in three element 1) The name of the file 2) The full path to the file (remember to use double backslash in your file path) 3) The string ‘DATA’ which is required by the spec file.
[('freesansbold.ttf', 'E:\\Pygame\\project0\\src\\freesansbold.ttf', 'DATA')]
Besides that if we do not want a console to appear on the background when we start the game (although we have already used the ‘—noconsole’ option when we create the spec but the console will still start for a short time) then we will simply set the console value to false
We can also include an icon for our application by specifying the path to the icon file.
After we have added and changed a few lines in the spec file we are now ready to recreate it with below command in the command prompt.
After we have ran the above command the contents of the dist folder will be rewritten and now you are ready to distribute the entire folder for the user to download. Although we can stop here if we want to because the dist folder has already contained everything we need to start the application (the main application file and it’s helper files such as image and the module files) but it will be very hard for the users to start the program if they are not familiar with the files inside the folder therefore we need to create an installer for our program which will lead us to the second part of this tutorial.
Create installer :
There are so many softwares for python developers to choose from when it comes to create an installer for their application but in this post I will only show you how to use Inno Setup to create the application’s installer for windows os.
Inno Setup is a free installer for Windows programs. First introduced in 1997, Inno Setup today rivals and even surpasses many commercial installers in feature set and stability.
As compared to other installers Inno Setup is easy to use thus you can create a workable windows’ installer with just a few clicks.
1) Download Inno Setup and install it.
2) Start Inno Setup, select ‘Create a new script file using the Script Wizard’ then press OK.
13) If you like you can save the new script for future use before compile it, that is it, once you have compiled the script Inno Setup will create the installer for you which you can then upload to your website for user to download and install your program.
Creating application with python and then pack it up is a long and painful process which takes lots of your time to do so, so make sure you stay cool and always look for help on forum or blog!