A pygame.Rect is a rectangle: a position (x, y, its top-left corner) and a size (width, height). In a pygame game nearly every object has one. It says where the object is, where to draw it and what it touches.
Press Play, click the game and steer with the arrow keys. The square turns red when it touches the wall, and clamp_ip keeps it inside the window.
Making a Rect
a = pygame.Rect(10, 20, 100, 50) # x, y, width, height
b = pygame.Rect((10, 20), (100, 50)) # position, size
c = image.get_rect() # the size of an image, at (0, 0)
d = image.get_rect(center=(240, 180)) # ...placed by its center
Surface.get_rect() is the most common way: it gives a Rect the size of an image, and keyword arguments place it.
Attributes
A Rect has many names for its position. Set any of them and the Rect moves; its size stays the same.
| Attribute | Meaning |
|---|---|
x, y, left, top | The top-left corner |
right, bottom | The right and bottom edges (x + width, y + height) |
width, height, w, h, size | The size |
center, centerx, centery | The middle |
topleft, topright, bottomleft, bottomright | The corners, as (x, y) |
midtop, midbottom, midleft, midright | The middle of each edge |
So player.bottom = 300 puts the player on a floor at 300, and bullet.midbottom = ship.midtop puts a bullet on the ship's nose.
Moving and resizing
| Method | Does |
|---|---|
r.move(dx, dy) | Returns a moved copy |
r.move_ip(dx, dy) | Moves r itself |
r.inflate(dw, dh) | Returns a copy grown (or shrunk) around its center |
r.clamp_ip(area) | Pushes r inside area, for example the screen |
r.union(other) | Returns the smallest Rect covering both |
r.clip(other) | Returns the overlap of the two |
r.copy() | Returns an independent copy |
Methods ending in _ip ("in place") change the Rect and return None. The others return a new Rect, so r.move(5, 0) on its own line does nothing visible: write r = r.move(5, 0) or r.move_ip(5, 0).
Collisions
| Method | True when |
|---|---|
r.colliderect(other) | The two rectangles overlap |
r.collidepoint(x, y) | The point is inside, for example the mouse |
r.contains(other) | other is completely inside r |
r.collidelist(rects) | Returns the index of the first Rect it overlaps, or -1 |
Rectangles that only share an edge do not collide: Rect(0, 0, 10, 10) and Rect(10, 0, 10, 10) touch but do not overlap. Collision detection builds on these.
Rects hold whole numbers
A pygame.Rect stores integers. Assigning 10.7 stores 10, and rect.x += 0.5 adds nothing, so slow movement freezes:
The red box never moves; the green one glides. Keep exact positions in float variables (or a Vector2) and copy them into the Rect, or, in pygame-ce, use pygame.FRect, which has the same attributes and methods but stores floats.
Frequently Asked Questions
What is a Rect in pygame?
A pygame.Rect stores a rectangle as x, y, width and height. Games use one per object to remember where it is, move it, draw it and check whether it touches something else.
How do I center something with a Rect?
Set its center: rect.center = (240, 180). To center an image, get a Rect from it already placed: image.get_rect(center=(240, 180)), then blit the image at that Rect.
Why does my Rect not move when I add 0.5?
A pygame.Rect stores whole numbers, so rect.x += 0.5 rounds back to the same value every frame. Keep the position in a float variable and copy it into the Rect, or use pygame-ce's pygame.FRect, which stores floats.
What is the difference between move() and move_ip()?
move() returns a new, moved Rect and leaves the original alone. move_ip() (in place) moves the Rect itself and returns None. The same _ip pattern applies to inflate_ip, clamp_ip and others.