PyGame Drawing Shapes

Adding some flair!

Introduction

In this section we will begin to look at how you create visuals in Pygame. You will find out how to add shapes to your game. In the subsequent two sections you will learn how to include images and text as well. After we have done this we will then start animating and adding interactivity to these game elements.

Getting Set Up

Pygame template windowBefore we begin, let's create a new file (call it rendering.py) and copy in the template code from the previous section.

Once you've saved your file with the template code in it, run the file to make sure you've copied it in ok.

Working through the rest of this section you will progressively add code to this file to demonstrate some of the ways in which you can draw shapes in PyGame.

As you copy the code in, tinker and experiment with the values to get a feel for what they do.

Colours

When creating text and shapes (and a few other things) we need to define their colour. There are a few ways in which we can do this. We will stick to the easiest method for this tutorial but be aware that there are others.

Creating an RGB triplet

You've already seen this format in the basic template. It's how we set the background colour for the window. We set three values (each between 0 and 255) which represent the amount of RED, GREEN and BLUE in the colour. Here are some example colours :

  • FULLRED = (255, 0, 0)
  •  
  • FULLGREEN = (0, 255, 0)
  •  
  • FULLBLUE = (0, 0, 255)
  •  
  • # What do you think this colour might be?
  • MYSTERY = (247, 184, 37)
  •  

variableName = (red, green, blue)

It is possible to create about 16.5 million colours which should be plenty for anyone.

In the sample code above we have saved the colour into a variable but it is possible to use the colour directly within a function call for a shape or text if you want.

Even though we can use the colour directly it is best practice to save all your colours into variables at the top of the script and then just to use the variables. This makes it easier to tinker with colours later on (which is very common when you're polishing your game and trying to get things just right).

Drawing Shapes

Shapes are pretty easy so let's start with those. The shapes we can draw in PyGame are :

  • Rectangles
  • Circles
  • Ellipses (squashed circles)
  • Lines
  • Polygons

There is a library called gfxdraw which gives you more control over your drawing but it's a bit more involved so we won't cover it here in this introductory tutorial.

The methods we will look at here we will only cover in an introductory manner. There is a lot more that can be done with all of these so if you get the urge to delve deeper I would recommend investigating PyGame Draw.

Rectangles

When creating rectangles we will take a two step approach. It is possible to combine both steps into one single step but breaking it up into two steps will make things easier later on when we want to animate and add interactivity to our games so we may as well start in the way which is going to be the most useful to us.

variableName = pygame.Rect(Xcoordinate, Ycoordinate, width, height)

To begin with we will create a rectangle object (also known as a Rect) which will hold the coordinates of our rectangle. Add the following code to your file :

  •     # Processing
  •  
  •     rectangle1 = pygame.Rect(10, 30, 50, 70)

In the code snippets, any greyed out code refers to existing code which should be in your file to help you figure out where to place the new code. When pasting, or typing in the code, make sure you have the right indenting too.

What we have done here is define a rectangle which is :

  • 10 pixels from the left edge of the window
  • 30 pixels from the top edge of the window
  • 50 pixels wide
  • 70 pixels high

Although in most areas when we define an X, Y coordinate it is from the bottom left, in PyGame it is relative to the top left instead.

Next we need to define a colour for our rectangle. We'll do this at the top of the file :

  • # Colours
  •  
  • RED = (255, 30, 70)

When naming your colours there are two ways you can do it. Either you can name the variable as the colour you are defining (as we have done above). Or you can name your variable as the item it is going to be used for. eg. if this was going to be the colour for our enemy bullets we could have named the variable ENEMYBULLETS instead.

And now we can render the rectangle to the screen :

  •     WINDOW.fill(BACKGROUND)
  •     pygame.draw.rect(WINDOW, RED, rectangle1)

pygame.draw.rect(surface, colour, rectangleObject)

Pygame rectangleIf you save the file and run it now you should get a red rectangle in the top left of the screen.

We had to place the command to draw the rectangle after the command to fill the screen with the BACKGROUND colour as items are drawn in the order that they appear in the file. If we had it the other way the rectangle would be drawn and then the screen filled with white, covering over the rectangle and we wouldn't see it.

Often when things aren't displaying on the screen properly it is the order of drawing objects that is the problem. Keep this in mind later on when you are drawing many items to the window.

Can you move the rectangle to be in each of the four corners of the window?
Try changing the dimensions of the rectangle as well.

Drawing several rectangles to the screen is as simple as creating multiple Rectangle objects and calling multiple draw commands :

  • # Colours
  •  
  • RED = (255, 30, 70)
  • BLUE = (10, 20, 200)
  • GREEN = (50, 230, 40)
  •     # Processing
  •  
  •     rectangle1 = pygame.Rect(10, 30, 50, 70)
  •     rectangle2 = pygame.Rect(30, 40, 70, 50)
  •     rectangle3 = pygame.Rect(20, 50, 50, 70)
  •     WINDOW.fill(BACKGROUND)
  •     pygame.draw.rect(WINDOW, RED, rectangle1)
  •     pygame.draw.rect(WINDOW, GREEN, rectangle2)
  •     pygame.draw.rect(WINDOW, BLUE, rectangle3)
Pygame rectangles

Change the order of the draw commands and see what happens to the rectangles in your window.

When drawing the rectangle, we may also add another agrument to the draw command to define the line thickness of the rectangle (as opposed to being filled in as it is now).

  •     WINDOW.fill(BACKGROUND)
  •     pygame.draw.rect(WINDOW, RED, rectangle1)
  •     pygame.draw.rect(WINDOW, GREEN, rectangle2)
  •     pygame.draw.rect(WINDOW, BLUE, rectangle3, 2)
Pygame rectangles

If you increase the line thickness does the line increase in thickness outward, inward or evenly both outward and inward? Tinker with the line thickness and find out.

Circles

Circles (and a few of the following shapes) are similar in several ways to the drawing rectangles but differ in that we don't create an object with the coordinates first.

To define a circle we need to know it's center and it's radius (and optionally, it's line thickness).

pygame.draw.circle(surface, colour, center, radius, width) # width is optional

The following command will draw a filled in circle with a radius of 30 pixels :

  •     pygame.draw.rect(WINDOW, BLUE, rectangle3)
  •  
  •     pygame.draw.circle(WINDOW, GREEN, (160, 70), 30)
Pygame circles

If we add another argument to the command call then we can define the line thickness of the circle instead of having a filled in circle :

  •     pygame.draw.rect(WINDOW, BLUE, rectangle3)
  •  
  •     pygame.draw.circle(WINDOW, GREEN, (160, 70), 30)
  •     pygame.draw.circle(WINDOW, BLUE, (200, 90), 40, 2)
Pygame circles

It is also possible to split the circle into 4 quadrants and choose which quadrants to display.

This is a new feature that has been included in PyGame 2.0.

pygame.draw.circle(surface, colour, center, radius, width, topRight, topLeft, bottomLeft, bottomRight)

In this version of the command the width is mandatory to specify, if you want it to be filled in then give a value of 0. The four values for topRight, topLeft, bottomLeft and bottomRight are also either True to display or False to not display.

  •     pygame.draw.circle(WINDOW, GREEN, (160, 70), 30)
  •     pygame.draw.circle(WINDOW, BLUE, (200, 90), 40, 2)
  •     pygame.draw.circle(WINDOW, RED, (200, 220), 50, 2, True, False, True, False)
Pygame quadrants

If you want to draw a section of the circle which is not one of these quadrants then you want to look into the arc command.

Ellipses

An ellipse is like a squashed circle. We define an ellipse by creating a Rectangle object which the ellipse will be drawn within (touching each edge of the rectangle).

pygame.draw.ellipse (surface, colour, rect, width) # width is optional

We'll start by creating a Rectangle object :

  • # Processing
  •  
  •     rectangle1 = pygame.Rect(10, 30, 50, 70)
  •     rectangle2 = pygame.Rect(10, 30, 50, 70)
  •     rectangle3 = pygame.Rect(10, 30, 50, 70)
  •     ellipse1 = pygame.Rect(70, 200, 40, 100)

And then draw it to the screen :

  •     pygame.draw.rect(WINDOW, BLUE, rectangle3)
  •  
  •     pygame.draw.circle(WINDOW, GREEN, (160, 70), 30)
  •     pygame.draw.circle(WINDOW, BLUE, (200, 90), 40, 2)
  •     pygame.draw.ellipse(WINDOW, RED, ellipse1)
Pygame ellipse

And similar to the other shapes we may include an optional last argument to indicate the line thickness :

  •     pygame.draw.rect(WINDOW, BLUE, rectangle3)
  •  
  •     pygame.draw.circle(WINDOW, GREEN, (160, 70), 30)
  •     pygame.draw.circle(WINDOW, BLUE, (200, 90), 40, 2)
  •     pygame.draw.ellipse(WINDOW, RED, ellipse1, 4)
Pygame ellipse hollow

Unlike circles, you cannot draw just part of the ellipse. If you want to do this you should investigate the arc command.

Lines

Drawing a line is fairly straight forward. All we need to do is specify the starting position, ending position and line width.

pygame.draw.line(surface, colour, (startX, startY), (endX, endY), width)

  •     pygame.draw.circle(WINDOW, BLUE (200, 90), 40, 2)
  •     pygame.draw.ellipse(WINDOW, RED, ellipse1, 4)
  •     pygame.draw.line(WINDOW, BLUE, (300, 20), (330, 200), 3)
Pygame line

If you have several lines to draw then you should investigate the lines command.

Polygons

Polygons aren't used terribly often but they are very useful when you have an interesting, non-uniform shape you wish to create. A polygon is similar to a line in how we define it but instead of two points we provide a list of points.

pygame.draw.polygon(surface, colour, points, width) # width is optional

In the above outline, points is a list of points. You may have as many points in the list as you like.

Here is an example to illustrate :

  •     pygame.draw.ellipse(WINDOW, RED, ellipse1, 4)
  •     pygame.draw.line(WINDOW, BLUE, (300, 20), (330, 200), 3)
  •     pygame.draw.polygon(WINDOW, GREEN, ((100, 140), (120, 120), (130, 160), (120, 200), (110, 180)))
Pygame polygon

And if we want it to just be an outline :

  •     pygame.draw.ellipse(WINDOW, RED, ellipse1, 4)
  •     pygame.draw.line(WINDOW, BLUE, (300, 20), (330, 200), 3)
  •     pygame.draw.polygon(WINDOW, GREEN, ((100, 140), (120, 120), (130, 160), (120, 200), (110, 180)), 3)
Pygame polygon hollow

Another way we can do this is to include the points as a separate list :

  •     rectangle3 = pygame.Rect(10, 30, 50, 70)
  •     ellipse1 = pygame.Rect(70, 200, 40, 100)
  •     polygonPoints = ((100, 140), (120, 120), (130, 160), (120, 200), (110, 180))
  •     pygame.draw.ellipse(WINDOW, RED, ellipse1, 4)
  •     pygame.draw.line(WINDOW, BLUE, (300, 20), (330, 200), 3)
  •     pygame.draw.polygon(WINDOW, GREEN, polygonPoints, 3)

This can make your code a little easier to read and manage.

And that wraps up our overview of shapes in PyGame. There is a lot more you can do with shapes so once you start getting a feel for things and you want to increase your abilities, I would highly recommend looking up what else is possible.

Ancilliary Data

Whenever you create a Rect object in PyGame you also get access to a whole lot of other details about that rectangle that PyGame works out for you automatically. Here is a list of the details available to you :

(We will assume a Rect variable called rectangle1 has been created.)

Attribute name Attribute value
rectangle1.left The X coordinate of the left side of the rectangle.
rectangle1.right The x coordinate of the right side fo the rectangle.
rectangle1.top The Y coordinate of the top side of the rectangle.
rectangle1.bottom The Y coordinate of the bottom side of the rectangle.
rectangle1.width The width of the rectangle.
rectangle1.height The height of the rectangle
rectangle1.size A tuple of two values, the width and height of the rectangle.
rectangle1.topleft A tuple of the X, Y coordinates of the top left of the rectangle.
rectangle1.topright A tuple of the X, Y coordinates of the top right of the rectangle.
rectangle1.bottomleft A tuple of the X, Y coordinates of the bottom left of the rectangle.
rectangle1.bottomright A tuple of the X, Y coordinates of the bottom right of the rectangle.
rectangle1.midleft A tuple of the X, Y coordinates of the middle of the left side of the rectangle.
rectangle1.midright A tuple of the X, Y coordinates of the middle of the right side of the rectangle.
rectangle1.midtop A tuple of the X, Y coordinates of the middle of the top side of the rectangle.
rectangle1.midbottom A tuple of the X, Y coordinates of the middle of the bottom side of the rectangle.
rectangle1.centerx The X coordinate of the center of the rectangle.
rectangle1.centery The Y coordinate of the center of the rectangle.
rectangle1.center A tuple of the X, Y coordinates of the center of the rectangle.

(All values returned are as integers, or tuples of integers.)

These won't be of much use to you right now but later on when we want to manipulate our game objects they will come in handy to make certain tasks easier so keep them in mind.

Rect objects also have a series of methods (built in functions) for doing things like moving and checking if the rectangle is colliding with other objects but we will introduct these later on.

And here is an example of how you access this data :

Rect-object.py

  1. import pygame, sys, random
  2. from pygame.locals import *
  3. pygame.init()
  4.  
  5. WINDOW_WIDTH = 400
  6. WINDOW_HEIGHT = 300
  7.  
  8. WINDOW = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
  9. pygame.display.set_caption('My Game!')
  10.  
  11. # The main function that controls the game
  12. def main () :
  13.   rectangle1 = pygame.Rect(10, 30, 50, 70)
  14.   
  15.   print (rectangle1.left)
  16.   
  17.   print (rectangle1.topright)
  18.   
  19.   print (rectangle1.center)
  20.  
  21. main()

Activities

Even though our program doesn't do too much just yet we can still tinker with a few elements to make sure we understand them.

Have a go at the following :

1. Can you write your name using the basic shapes. Try and use as many of them as possible.

2. Can you make a space invaders alien out of the basic shapes?

3. Try making some fancy sci-fi targetting cross hairs.

4. Can you make a static (non moving or functional) interface for the game Pong? Include the two paddles, the ball, the middle dividing line.

5. Try making a static (non moving or functional) interface for another game. Include a health bar and indication of lives at the top and the character inside some environment. The game could be a platform game, or a top down map based game etc.