A relaxing, colorful pong game controlled by your webcam's view of your hand. The paddle moves up and down as your hand does in the image frame!
Running the game just requires having the correct libraries and a supported python version installed. I recommend using a venv to keep your development environments isolated, but you can also install these dependencies globally.
Python 3.10.* and 3.11.* should all work on all platforms. There is currently no working mediapipe version for apple silicon Macs that supports python 3.12.*, but on windows and linux I expect (but have not been able to verify) that 3.12.2 should work fine. I highly reccommend using python 3.10 or 3.11.
Enter a shell in the project root folder. If you do not have pip installed as a standalone command, replace pip with
python -m pip in these instructions.
If this is the first time you are running cz-pong, create a venv and install the dependencies (ignore this if you have already done it):
python -m venv .venv # Using the builtin python module "venv", create a virtual environment at ~/.venv.
source .venv/bin/activate # Configure this shell instance to use the new venv
pip install -r requirements.txt # Install the game's dependencies, which are listed in the file `requirements.txt`
python main.py # Run the gameIf you have already created a venv and installed the dependencies, and just want to run the game, just run
source .venv/bin/activate # Enter the venv so that python can find the game's dependencies
python main.py # Run the gameEnter a shell in the project root folder. If you do not have pip installed as a standalone command, replace pip with
python -m pip in these instructions.
If this is the first time you are running cz-pong, install the needed dependencies:
pip install -r requirements.txtThen, run the game:
python main.pyIf you are using the Nix package manager, you can get a development environment set up by entering a shell in the project root and running
nix develop # enter a development shell using Nix
python main.py # run the gameUsing Nix is not necessary, but it ensures that you will not have any issues due to an incorrect python version or conflicting library installations. This approach will also automatically manage the venv for you.
- Why is my paddle not moving?
- Make sure you only have one hand in frame - the wrong hand may be getting chosen as an input. In a more robust game, there would be an option to choose a dominant hand, but this is just a demo.
A rough architectural overview is given here, but the code is the primary source of truth.
The entry point of the program is main.py - this is used to get the path of the root folder and spawn a game instance.
src/game.py contains the core gameloop and manages state. The different game states (i.e. the setup menu and the pong
game) are concrete implementations of the abstract State type, which exposes a draw, update, and handle_event method.
When a state is active, Game will call those methods on it in the game loop. This allows the different levels and the core
game engine to all be strongly decoupled.
States that require access to hand tracking data can request a reference to the global TrackingContext in their constructor.
Event passing to the game loop is done using pygame's event system (custom events are registered in src/events.py).
- Code by Seth Hinz (sethhinz@me.com)
- Music by FASSounds from Pixabay
flap.wavby ani_music on freesound.orgknock.mp3by AUDACITIER on freesound.org
Some (probably <100loc) of the code in this repo is generated by ChatGPT. I only rely on ChatGPT when I know exactly what I
would write, but it is tedious to do so (i.e. the aspect-ratio preserving camera feed resizing code in src/states/setup.py).
