Pygame
lastmod 2026-03-27created 2020-05-0784 edits
Pygame is a cross-platform set of Python modules designed for writing video games. It includes computer graphics and sound libraries designed to be used with the Python programming language. It is built over the Simple DirectMedia Layer (SDL) library, with the intention of allowing real-time computer game development without the low-level mechanics of the C programming language and its derivatives. This is based on the assumption that the most expensive functions inside games (mainly the graphics part) can be abstracted from the game logic, making it possible to use a high-level programming language, such as Python, to structure the game.
Categories
Modules
- pygame._sdl2.controller - pygame module to work with controllers
- pygame._sdl2.touch - pygame module to work with touch input
- pygame._sdl2.video - Experimental pygame module for porting new SDL video systems
- pygame.camera - pygame module for camera use
- pygame.cursors - pygame module for cursor resources
- pygame.display - pygame module to control the display window and screen
- pygame.draw - pygame module for drawing shapes
- pygame.event - pygame module for interacting with events and queues
- pygame.examples - module of example programs
- pygame.font - pygame module for loading and rendering fonts
- pygame.freetype - Enhanced pygame module for loading and rendering computer fonts
- pygame.geometry - pygame geometry module
- pygame.gfxdraw - pygame module for drawing shapes
- pygame.image - pygame module for loading and saving images
- pygame.joystick - Pygame module for interacting with joysticks, gamepads, and trackballs.
- pygame.key - pygame module to work with the keyboard
- pygame.locals - pygame constants
- pygame.mask - pygame module for image masks.
- pygame.math - pygame module for vector classes
- pygame.midi - pygame module for interacting with midi input and output.
- pygame.mixer - pygame module for loading and playing sounds
- pygame.mixer.music - pygame module for controlling streamed audio
- pygame.mouse - pygame module to work with the mouse
- pygame.pixelcopy - pygame module for general pixel array copying
- pygame.scrap - pygame module for clipboard support.
- pygame.sndarray - pygame module for accessing sound sample data
- pygame.sprite - pygame module with basic game object classes
- pygame.surfarray - pygame module for accessing surface pixel data using array interfaces
- pygame.system - pygame module to provide additional context about the system
- pygame.tests - Pygame unit test suite package
- pygame.time - pygame module for monitoring time
- pygame.transform - pygame module to transform surfaces
- pygame.version - small module containing version information
Libraries
- pygame tags libraries
- pyscroll - Scrolling maps. Fast scrolling images easy - https://github.com/bitcraft/pyscroll
- pyTMX - Reads Tiled Map Editors TMX maps. Can use a Map editor easily - https://github.com/bitcraft/pytmx
- pymunk - 2d physics library. Lots of examples, very well maintained - http://www.pymunk.org/en/latest/
- animation.py - animation helper for pygame projects - https://github.com/bitcraft/animation
- pygame-text - Greatly simplifies drawing text with the pygame.font module - https://github.com/cosmologicon/pygame-text
GUI Libraries
- GUIs with pygame - pygame wiki
- Pygame GUI
- pgu
- OcempGUI (unmaintained)
- PyGVisuals
- pyimgui
- thorpy - GUI library. Extensive documentation, and lots of GUI controls. I especially like this tutorial on how to integrate thorpy GUI elements with a pygame game. - https://www.thorpy.org/
- pygame-menu - Seems decent?
WebAssembly
- Pygbag - https://github.com/pygame-web/pygbag - python and pygame wasm for everyone ( packager + test server + simulator )
- https://pygame-web.github.io/
- https://github.com/pygame-web/pygbag
Packaging
- Pynsist - Tool for building Windows installers for Python applications. Example for packaging pygame using the 'aliens' example game - https://github.com/takluyver/pynsist
- pyinstaller
- buildozer
Examples
- Pygame:WebTetris - Demo of playing Tetris in a web page with pygame+pygbag.
- Pygame:HangulInputText - Notes on Korean (Hangul) text input.
- NetHack#pygame-ce clone coding - Clone coding NetHack with pygame-ce.
- Terraria#pygame-ce clone coding - Clone coding Terraria with pygame-ce.
- Auralux#pygame-ce clone coding - Clone coding Terraria with pygame-ce.
Terms
- VFX - Short for Visual effects.
- SFX - Short for Sound effects.
pygame-ce
Seems it was forked off because the pygame maintainer was overbearing? -> Pygame CE - Better & Faster - YouTube (someone's opinion)
Free Game Tools
- Free Gamedev Tools I Use - YouTube
- Beepbox - https://beepbox.co/
- Bosca Ceoil - https://boscaceoil.net/
- LMMS - https://lmms.io/
- Krita - https://krita.org/
- Px Editor - https://cmlsc.itch.io/px-editor
- MS Paint - You know where to find it...
- SFXR - http://www.drpetter.se/project_sfxr.html
- BFXR - https://www.bfxr.net/
- Audacity - https://www.audacityteam.org/
- Hitfilm Express - https://fxhome.com/hitfilm-express
- OBS - https://obsproject.com/
- Gifcam - http://blog.bahraniapps.com/gifcam/
- Chronolapse - https://www.chronolapse.com/
- aseprite - If you can build it yourself ...
OpenGL support
The rendering pipeline seems to change... the existing pygame drawing APIs didn't work... (not confirmed exactly) See pyimgui for related examples.
Drawing images with PyOpenGL
Drawing fonts with PyOpenGL
Generator
- https://itch.io/games/tag-generator
- Planet Generator - https://itch.io/search?q=Planet+Generator
Show OpenCV Image
- python - OpenCV cv2 image to PyGame image? - Stack Overflow
- python - How to load and play a video in pygame - Stack Overflow
Key code:
Minimal example:
import pygame
import cv2
video = cv2.VideoCapture("video.mp4")
success, video_image = video.read()
fps = video.get(cv2.CAP_PROP_FPS)
window = pygame.display.set_mode(video_image.shape[1::-1])
clock = pygame.time.Clock()
run = success
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
success, video_image = video.read()
if success:
video_surf = pygame.image.frombuffer(
video_image.tobytes(), video_image.shape[1::-1], "BGR")
else:
run = False
window.blit(video_surf, (0, 0))
pygame.display.flip()
pygame.quit()
exit()
Sample program
import sys, pygame
pygame.init()
size = width, height = 320, 240
speed = [2, 2]
black = 0, 0, 0
screen = pygame.display.set_mode(size)
ball = pygame.image.load("ball.gif")
ballrect = ball.get_rect()
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
ballrect = ballrect.move(speed)
if ballrect.left < 0 or ballrect.right > width:
speed[0] = -speed[0]
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[1]
screen.fill(black)
screen.blit(ball, ballrect)
pygame.display.flip()
Adding fonts
- .: Pygame (4) Loading fonts, writing text on the screen
- How to load custom fonts and text effects in Pygame – All Things N
- Pygame fullscreen issue : r/pygame
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((400,300))
pygame.display.set_caption('Hello World!')
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
BLUE = (0, 0, 128)
BLACK = (0, 0, 0)
fontObj = pygame.font.Font('font/nanum.ttf', 32)
textSurfaceObj = fontObj.render('Hello world!', True, BLACK, WHITE)
textRectObj = textSurfaceObj.get_rect()
textRectObj.center = (100, 16)
while True: # main game loop
DISPLAYSURF.fill(WHITE)
DISPLAYSURF.blit(textSurfaceObj, textRectObj)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
Fullscreen issues (pixelation, hardware errors, etc.)
- Fullscreen & Resizing - Pygame Tutorial - YouTube
- [Recommended] Pygame Fullscreen Tutorial - Complete Guide - GameDev Academy
- In pygame pygame 2.0.0 the fullscreen mode flashes at the start and then it is entirely black · Issue #1529 · pygame/pygame
- python - The fullscreen mode in pygame is entirely black - Stack Overflow
- [Recommended] python - How to avoid automatic resolution adjustment by pygame.FULLSCREEN? - Stack Overflow
Note that fonts have an Anti-aliasing flag. If you want to keep a pixel-art look, choose carefully whether to turn it on.
Handling Fullscreen Toggle
...
# Game loop
run = True
fullscreen = False
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# Toggle fullscreen when F11 is pressed
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_F11:
fullscreen = not fullscreen
if fullscreen:
win = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
else:
win = pygame.display.set_mode((800, 600))
pygame.quit()
Exiting From Fullscreen
# Game loop
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_F11):
run = False
# Switch back to windowed mode before exiting
pygame.display.set_mode((800, 600))
Adjusting Screen Resolution
# Get screen size
screen = pygame.display.get_surface()
width, height = screen.get_size()
# Game loop
run = True
while run:
# Switch fullscreen/resolution when F11 is pressed
if fullscreen:
win = pygame.display.set_mode((width, height), pygame.FULLSCREEN)
else:
win = pygame.display.set_mode((800, 600))
Handling Multiple Sizable Game Elements
from pygame import transform
def load_image(filename, width, height):
# Load image
img= pygame.image.load(filename)
# Scale image
scaled_img = transform.scale(img, (width, height))
return scaled_img
# Load and scale images
background = load_image('background.png', width, height)
player = load_image('player.png', 100, 100)
# Game loop
run = True
while run:
...
# Draw images
win.blit(background, (0, 0))
win.blit(player, (width//2, height//2))
Disabling antialiasing on fullscreen mode
game_resolution = (800, 600)
display_resolution = (8000, 6000) # Or use a function to get the real screen res
stretch_to_fit_resolution = (display_resultion[0]^2/game_resolution[0], display_resultion[1]^2/game_resolution[1])
# ...
screen = pygame.display.set_mode(display_resolution, pygame.FULLSCREEN)
Then, inside the game-loop:
Well-known screen resolutions suitable for games
See Display resolution#Well-known screen resolutions suitable for games.
How to use the pygame.sprite.Sprite class
- Microsoft PowerPoint - 6-PythonGUI-sprite - 6-PythonGUI-sprite.pdf - Introduction to sprites in Pygame
Generating cloud images with Python (Cloud images using the diamond-square algorithm)
See the relevant page for details.
How to blend images or colors
- python - How to make transparent pygame.draw.circle - Stack Overflow
- [Recommended] PyGameExamplesAndAnswers/documentation/pygame/pygame_blending_and_transaprency.md at master · Rabbid76/PyGameExamplesAndAnswers
Image rotation issues
import pygame
pygame.init()
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
def blitRotate(surf, image, pos, originPos, angle):
# offset from pivot to center
image_rect = image.get_rect(topleft = (pos[0] - originPos[0], pos[1]-originPos[1]))
offset_center_to_pivot = pygame.math.Vector2(pos) - image_rect.center
# roatated offset from pivot to center
rotated_offset = offset_center_to_pivot.rotate(-angle)
# roatetd image center
rotated_image_center = (pos[0] - rotated_offset.x, pos[1] - rotated_offset.y)
# get a rotated image
rotated_image = pygame.transform.rotate(image, angle)
rotated_image_rect = rotated_image.get_rect(center = rotated_image_center)
# rotate and blit the image
surf.blit(rotated_image, rotated_image_rect)
# draw rectangle around the image
pygame.draw.rect(surf, (255, 0, 0), (*rotated_image_rect.topleft, *rotated_image.get_size()),2)
def blitRotate2(surf, image, topleft, angle):
rotated_image = pygame.transform.rotate(image, angle)
new_rect = rotated_image.get_rect(center = image.get_rect(topleft = topleft).center)
surf.blit(rotated_image, new_rect.topleft)
pygame.draw.rect(surf, (255, 0, 0), new_rect, 2)
try:
image = pygame.image.load('AirPlaneFront.png')
except:
text = pygame.font.SysFont('Times New Roman', 50).render('image', False, (255, 255, 0))
image = pygame.Surface((text.get_width()+1, text.get_height()+1))
pygame.draw.rect(image, (0, 0, 255), (1, 1, *text.get_size()))
image.blit(text, (1, 1))
w, h = image.get_size()
angle = 0
done = False
while not done:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pos = (screen.get_width()/2, screen.get_height()/2)
screen.fill(0)
blitRotate(screen, image, pos, (w/2, h/2), angle)
#blitRotate2(screen, image, pos, angle)
angle += 1
pygame.draw.line(screen, (0, 255, 0), (pos[0]-20, pos[1]), (pos[0]+20, pos[1]), 3)
pygame.draw.line(screen, (0, 255, 0), (pos[0], pos[1]-20), (pos[0], pos[1]+20), 3)
pygame.draw.circle(screen, (0, 255, 0), pos, 7, 0)
pygame.display.flip()
pygame.quit()
exit()
Particles
Screen Shake
Lighting effects and light source effects
Water/wind/grass (Water, Wind, Grass) sway effects
- Water, Wind, and Grass - Python/Pygame Devlog #2 - YouTube
- Program a Cool Water effect using #pygame in #python - YouTube
3,000+ Particles with Physics
Shaders in Pygame
- How I Added Shaders to Pygame - YouTube
- Easy Way to Use Shaders in Pygame - YouTube
- Github - MarkelZ/pygame-render - Python package for rendering textures with shaders using pygame.
Smoke effects
Fire effects
Fluttering cloth VFX
Spark VFX
Drawing outlines
Sprite Stacking
- Sprite Stacking in Python and Pygame - YouTube
- StanislavPetrovV/SpriteStacking: Sprite Stacking Graphics Engine with Python and Pygame
A technique that stacks 2D sprites to make them look 3D.
Dust trail effect (dust kicked up when running)
Dust floating in the air (particles)
- Adding Special Effects to Pygame Games: Particle Systems and Visual Enhancements
- How to Create PARTICLE EFFECTS in Python - Pygame Tutorial - YouTube
dust particles floating in the air ...
Celeste's wind particles (Celeste Wind Particle)
Background Parallax Scrolling
Scene Transitions
- demaisj/Pygame-Transitions: Beautiful & easy transitions for pygame programs
- Pygame ARPG Tutorial Series | 9. Scene Transitions - YouTube
- Pygame Scene Transitions - and help from the Norwich Python Community - YouTube
Loading SVG
Loading from a string (short):
svg_string = '<svg height="100" width="500">...</svg>'
pygame_surface = pygame.image.load(io.BytesIO(svg_string.encode()))
Loading from a string (long version):
import pygame
import io
pygame.init()
window = pygame.display.set_mode((500, 200))
clock = pygame.time.Clock()
svg_string = '<svg height="100" width="500"><ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" /><ellipse cx="220" cy="50" rx="190" ry="20" style="fill:white" /></svg>'
pygame_surface = pygame.image.load(io.BytesIO(svg_string.encode()))
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill((255, 255, 255))
window.blit(pygame_surface, pygame_surface.get_rect(center = window.get_rect().center))
pygame.display.flip()
pygame.quit()
exit()
Using svglib
from svglib.svglib import svg2rlg
import io
def load_svg(svg_string):
svg_io = io.StringIO(svg_string)
drawing = svg2rlg(svg_io)
str = drawing.asString("png")
byte_io = io.BytesIO(str)
return pygame.image.load(byte_io)
Long version example:
from svglib.svglib import svg2rlg
import pygame
import io
def load_svg_svglib(svg_string):
svg_io = io.StringIO(svg_string)
drawing = svg2rlg(svg_io)
str = drawing.asString("png")
byte_io = io.BytesIO(str)
svg_surf = pygame.image.load(byte_io)
return svg_surf
def display_svg_figure(screen, svg_string):
surf = load_svg_svglib(svg_string)
screen.blit(surf, (0, 0))
background_colour = (255, 255, 255)
(width, height) = (900, 900)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Display SVG')
screen.fill(background_colour)
svg_string='<svg height="100" width="500"><ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" /><ellipse cx="220" cy="50" rx="190" ry="20" style="fill:white" /></svg>'
display_svg_figure(screen, svg_string)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()
Using CairoSVG
import cairosvg
import io
def load_svg(filename):
new_bites = cairosvg.svg2png(url = filename)
byte_io = io.BytesIO(new_bites)
return pygame.image.load(byte_io)
Using pynanosvg
- Load svg into Pygame image using pynanosvg (https://github.com/ethanhs/pynanosvg) - pynanosvg seems to be unmaintained
Pygame Subset for Android
The Pygame Subset for Android is a port of a subset of Pygame functionality to the Android platform. The goal of the project is to allow the creation of Android-specific games, and to ease the porting of games from PC-like platforms to Android.
Headless mode
Setting the SDL_VIDEODRIVER environment variable to dummy or fbcon seems to do it?
Real-time rendering with FFmpeg
See ffmpeg-python#Real-time rendering with pygame.
Auto-detecting and setting SDL environment variables
See Simple DirectMedia Layer#Auto-detecting and setting SDL environment variables for details.
Troubleshooting
OpenGL.error.Error: Attempt to retrieve context when no valid context
When running under Wayland on Ubuntu 20.04 or later, the following error may be printed:
pygame-ce 2.4.1 (SDL 2.28.5, Python 3.11.4)
/home/your/Project/ddrm/test.py:13: Warning: PyGame seems to be running through X11 on top of wayland, instead of wayland directly
...
OpenGL.error.Error: Attempt to retrieve context when no valid context
This indicates that PyGame is running in a Wayland session through an X11 compatibility layer instead of interfacing with Wayland directly. This can affect performance and compatibility.
Set the SDL_VIDEO_X11_FORCE_EGL=1 environment variable as follows:
Or reportedly you can use the wayland driver directly <- look into this solution later
Running OpenGL-related code with pygame shows no window and the terminal freezes
See also
- Python
- Python:RenderingEngines
- pygame
- pyglet
- panda3d
- Python Arcade
- kivy
- bevy (rust)
- PyOpenGL
- Pyxel
- Dungeon Generation
Favorite site
- PyGame website
- PyGame documetns
- Wikipedia (en) description of PyGame
- [Recommended] The New Pygame Trinket - View PyGame demos in the browser.
- Making an action game: 1. Introducing the Street Pyghter game 1
- Invent with python (PyGame)
- Pygame - python GUI module page | GUI Python programming, Pyside2 practice, Visual python
- An In-Depth Analysis of LibGDX vs Pygame | Aircada Pro (LibGDX vs Pygame)
- Pygame - python GUI module page | GUI Python programming, Pyside2 practice, Visual python - Korean tutorial
- [Highly recommended] Rabbid76/PyGameExamplesAndAnswers: Summary of answers to pygame questions posted on stack overflow - Sample code, with images, that solves various issues encountered in pygame.
References
- Auralux
- Bevy
- CEF Python
- Ffmpeg-python
- Game Engine
- Game Programming
- Hexagon
- IntelliJ IDEA
- Kivy
- LibGDX
- Manus
- Mini Motorways
- Minit
- NetHack
- Programming
- Pygame GUI
- Pygame.event
- Pygame.sprite
- Pygame:HangulInputText
- Pygame:WebTetris
- Pygbag
- Pyimgui
- PyOpenGL
- Python Arcade
- Python-mpv
- Python:Libraries
- Pyxel
- Read–eval–print loop
- Ren'Py
- Simple DirectMedia Layer
- Sprite Stacking
- Terraria
- Tetris
- Tweener