Pygame Cheat Sheet
Last updated
Setup and the game loop
Every pygame program opens a window, then repeats one loop until the player quits.
| Operation | Code |
|---|---|
| Install pygame-ce | python3 -m pip install pygame-ce |
| Import and start pygame | import pygame
pygame.init() |
| Open a window | screen = pygame.display.set_mode((640, 480)) |
| Set the window title | pygame.display.set_caption("My Game") |
| Make a clock | clock = pygame.time.Clock() |
| The game loop | running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill("black")
pygame.display.flip()
clock.tick(60) |
| Shut down after the loop | pygame.quit() |
Display
The screen is a Surface; nothing shows until you flip it.
| Operation | Code |
|---|---|
| Show the finished frame | pygame.display.flip() |
| Show only some areas | pygame.display.update([rect1, rect2]) |
| Clear the screen | screen.fill((30, 30, 46)) |
| Window size | screen.get_size(), screen.get_width() |
| The screen as a Rect | screen.get_rect() |
| Resizable window | pygame.display.set_mode((640, 480), pygame.RESIZABLE) |
| Fullscreen at the desktop size | pygame.display.set_mode((0, 0), pygame.FULLSCREEN) |
Colors and drawing
pygame.draw functions take a surface, a color and a position. width=0 fills.
| Operation | Code |
|---|---|
| Color as RGB | (255, 140, 0) |
| Color by name or hex | "tomato", "#ff8c00", pygame.Color("gold") |
| Rectangle | pygame.draw.rect(screen, "red", (x, y, w, h)) |
| Outline and rounded corners | pygame.draw.rect(screen, "red", rect, width=2, border_radius=8) |
| Circle (by its center) | pygame.draw.circle(screen, "blue", (cx, cy), radius) |
| Line | pygame.draw.line(screen, "white", (x1, y1), (x2, y2), 3) |
| Polygon | pygame.draw.polygon(screen, "green", [(0, 0), (40, 0), (20, 30)]) |
| Ellipse in a box | pygame.draw.ellipse(screen, "purple", (x, y, w, h)) |
Rect
A Rect stores a position and a size as whole numbers.
| Operation | Code |
|---|---|
| Make a Rect | player = pygame.Rect(x, y, width, height) |
| Position by any point | player.center = (320, 240), player.bottom = 400 |
| Edges and corners | left, right, top, bottom, topleft, midbottom |
| Move in place | player.move_ip(dx, dy) |
| Moved copy | moved = player.move(dx, dy) |
| Keep inside the screen | player.clamp_ip(screen.get_rect()) |
| Grow around the center | bigger = player.inflate(20, 20) |
| Float positions (pygame-ce) | pygame.FRect(10.5, 20.25, 40, 40) |
Images, Surfaces and blit
Load images once, before the loop, then blit them every frame.
| Operation | Code |
|---|---|
| Load an image with transparency | img = pygame.image.load("player.png").convert_alpha() |
| Load a solid image | bg = pygame.image.load("sky.png").convert() |
| Draw an image | screen.blit(img, (x, y)) |
| Draw centered | screen.blit(img, img.get_rect(center=(320, 240))) |
| New blank Surface | panel = pygame.Surface((200, 100)) |
| Transparent Surface | layer = pygame.Surface((200, 100), pygame.SRCALPHA) |
| Fade a whole Surface | img.set_alpha(128) |
| Cut a frame from a sheet | frame = sheet.subsurface((0, 0, 32, 32)) |
| Save a screenshot | pygame.image.save(screen, "shot.png") |
Transform
Each function returns a new Surface; transform the original, not the last result.
| Operation | Code |
|---|---|
| Resize | pygame.transform.scale(img, (64, 64)) |
| Scale by a factor | pygame.transform.scale_by(img, 2) |
| Smooth resize | pygame.transform.smoothscale(img, (64, 64)) |
| Rotate (counterclockwise, degrees) | pygame.transform.rotate(img, 45) |
| Rotate around the center | rotated = pygame.transform.rotate(original, angle)
rect = rotated.get_rect(center=rect.center) |
| Mirror horizontally | pygame.transform.flip(img, True, False) |
Events and keyboard
Use events for single presses and get_pressed() for keys held down.
| Operation | Code |
|---|---|
| Read this frame's events | for event in pygame.event.get(): |
| Window closed | event.type == pygame.QUIT |
| A key was pressed | event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE |
| A key was released | event.type == pygame.KEYUP |
| Character typed | event.unicode |
| Keys held now | keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= 5 |
| Direction from two keys | dx = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT] |
| Keys pressed this frame (pygame-ce) | pygame.key.get_just_pressed()[pygame.K_SPACE] |
| Key constants | K_a...K_z, K_0...K_9, K_UP, K_RETURN, K_ESCAPE, K_LSHIFT |
| Name of a key | pygame.key.name(event.key) |
| Custom event | HIT = pygame.event.custom_type()
pygame.event.post(pygame.event.Event(HIT)) |
Mouse
Buttons: 1 left, 2 middle, 3 right.
| Operation | Code |
|---|---|
| A button was pressed | event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 |
| Where it was pressed | event.pos |
| Pointer position now | x, y = pygame.mouse.get_pos() |
| Buttons held now | left, middle, right = pygame.mouse.get_pressed() |
| Mouse moved | event.type == pygame.MOUSEMOTION, event.rel |
| Wheel turned | event.type == pygame.MOUSEWHEEL, event.y |
| Clicked inside a button | button_rect.collidepoint(event.pos) |
| Hide the pointer | pygame.mouse.set_visible(False) |
Sprites and groups
A sprite keeps an image and a rect; a group updates and draws many.
| Operation | Code |
|---|---|
| Sprite class | class Coin(pygame.sprite.Sprite):
def __init__(self, pos):
super().__init__()
self.image = coin_img
self.rect = self.image.get_rect(center=pos) |
| Make a group | coins = pygame.sprite.Group() |
| Add to a group | coins.add(Coin((100, 50))) |
| Update every sprite | coins.update() |
| Draw every sprite | coins.draw(screen) |
| Remove a sprite from all groups | coin.kill() |
| Group holding one sprite | player = pygame.sprite.GroupSingle(Player()) |
Collisions
Rects collide when they overlap; touching edges do not count.
| Operation | Code |
|---|---|
| Two rectangles | a.colliderect(b) |
| Point inside | rect.collidepoint(x, y) |
| First of many | rect.collidelist(walls) # index or -1 |
| Sprite against a group | hits = pygame.sprite.spritecollide(player, coins, True) |
| Any hit at all | pygame.sprite.spritecollideany(player, enemies) |
| Group against group | pygame.sprite.groupcollide(bullets, enemies, True, True) |
| Pixel-perfect | pygame.sprite.spritecollide(a, group, False, pygame.sprite.collide_mask) |
| Circles | pygame.Vector2(a).distance_to(b) < r1 + r2 |
Text and fonts
Render text to a Surface, then blit it.
| Operation | Code |
|---|---|
| Default font | font = pygame.font.Font(None, 36) |
| System font | font = pygame.font.SysFont("arial", 24) |
| Font file | font = pygame.font.Font("pixel.ttf", 32) |
| Render text | text = font.render("Score: 10", True, "white") |
| Draw it centered | screen.blit(text, text.get_rect(center=(320, 40))) |
| Wrap long text (pygame-ce) | font.render(story, True, "white", None, 400) |
| Size without rendering | font.size("Hello") |
| Installed fonts | pygame.font.get_fonts() |
Sound and music
Load sounds once. Music streams one track from its file.
| Operation | Code |
|---|---|
| Load a sound | jump = pygame.mixer.Sound("jump.ogg") |
| Play it | jump.play() |
| Sound volume | jump.set_volume(0.5) |
| Load music | pygame.mixer.music.load("theme.ogg") |
| Loop music forever | pygame.mixer.music.play(-1) |
| Pause and resume | pygame.mixer.music.pause(), pygame.mixer.music.unpause() |
| Stop the music | pygame.mixer.music.stop() |
Time and timers
Ticks are in milliseconds.
| Operation | Code |
|---|---|
| Cap the frame rate | clock.tick(60) |
| Delta time in seconds | dt = clock.tick(60) / 1000 |
| Current frame rate | clock.get_fps() |
| Milliseconds since init | pygame.time.get_ticks() |
| Repeating timer event | SPAWN = pygame.event.custom_type()
pygame.time.set_timer(SPAWN, 1000) |
| One-shot timer | pygame.time.set_timer(SPAWN, 2000, loops=1) |
| Stop a timer | pygame.time.set_timer(SPAWN, 0) |
Vector2
Floats for positions and velocities.
| Operation | Code |
|---|---|
| Make a vector | pos = pygame.Vector2(100, 200) |
| Move by a velocity | pos += velocity * dt |
| Length | velocity.length() |
| Same speed on diagonals | if direction.length() > 0:
direction = direction.normalize() |
| Distance between points | pos.distance_to(target) |
| Rotate | velocity.rotate(90) |
| Step toward a point (pygame-ce) | pos.move_towards_ip(target, 5) |
The pygame code you reach for while making a 2D game in Python, grouped by task: the game loop, the display, colors and drawing, Rect, images and blit, scaling and rotating, keyboard and mouse input, sprites and groups, collisions, text, sound, timers and Vector2. Each row is a short snippet to paste, next to what it does.
Everything here is written for pygame-ce 2.5, the community edition of pygame, which you still import with import pygame. Rows marked pygame-ce use its additions; every other row also works in the original pygame. Try any snippet in the pygame playground, which runs pygame in your browser with nothing to install. New to Python itself? Start with the Python cheat sheet.
Pygame cheat sheet FAQ
Is this pygame cheat sheet free?
Yes. It is free with no sign-up. Bookmark it, or print it to PDF from your browser, and come back whenever you need the exact call for a sprite group, a sound or a collision check.
Does this cheat sheet work with pygame and pygame-ce?
import pygame and share almost the whole API. The rows marked pygame-ce (FRect, scale_by, get_just_pressed, text wrapping and move_towards_ip) need pygame-ce, and everything else runs on either.Why does my pygame window not respond?
pygame.event.get() once every frame, even if you ignore the events, and end each frame with pygame.display.flip() and clock.tick(60).Should I use events or key.get_pressed() for input?
KEYDOWN event for actions that happen once per press, such as jumping or opening a menu. Use pygame.key.get_pressed() for actions that last while a key is held, such as walking.