In the previous article, we used the pygame.display.set_mode() function to get a window object and the pygame.image.load() function to load an image, resulting in an image object. Both the window object and the image object are actually of the Surface type, and we collectively refer to them as Surface objects. The concept of Surface is crucial in Pygame, and this article will provide a detailed introduction.
Project code download link: https://github.com/la-vie-est-belle/pygame_codes
What is a Surface?
We can think of a Surface object in Pygame as a canvas. We can fill the canvas with colors or draw any images, text, and lines on it. Let’s briefly look at how to add images to various Surface objects. See Example Code 2-1.
import sys
import pygame
pygame.init()
surface1 = pygame.display.set_mode((800, 600)) # 1
pygame.display.set_caption('Surface Demo')
surface2 = pygame.image.load('pygame_logo.png') # 2
surface2_rect = surface2.get_rect()
surface2_rect.center = (400, 300)
surface3 = pygame.image.load('python_logo.png') # 3
surface3_rect = surface3.get_rect()
surface3_rect.topleft = (0, 0)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
surface1.fill((0, 255, 0), (0, 0, 400, 600)) # 4
surface1.blit(surface2, surface2_rect) # 5
surface2.blit(surface3, surface3_rect) # 6
pygame.display.flip()
Code Explanation:
#1 Call the pygame.display.set_mode() function to get a Surface object that represents the screen.
#2 Call the pygame.image.load() function to load the Pygame logo, resulting in a Surface object the same size as the loaded image. The Rect object's center attribute is used to set the position of the Surface object. center specifies the center of the Surface, so this actually centers the Pygame logo on the screen.
#3 Similarly, load the Python logo image to get a Surface object the same size as this image. The top-left corner of its coordinates is set to (0, 0). Since the Python logo is to be added on top of the Pygame logo, (0, 0) positions the top-left corner of the Python logo at the origin of the Pygame logo's coordinate system.
Note: The coordinate system in Pygame will be explained in the next section.
#4 Use the fill() function of the Surface object to fill the left half of the window with green. This function can take a rectangular region to specify where to fill.
#5 Use the blit() function of the Surface object to draw another Surface object. Here, the Pygame logo Surface object is added to the window Surface object.
#6 Add the Python logo Surface object onto the Pygame logo Surface object.
Note: The
Surfaceobjects that are added later will obscure those added earlier.
How to Create a Surface
In Example Code 2-1, we obtained Surface objects using the pygame.display.set_mode() and pygame.image.load() functions. Additionally, we can create a Surface object directly using pygame.Surface() by specifying its width and height.
surface = pygame.Surface((1000, 800)) # Create a Surface object with a width of 1000 and height of 800
In Pygame, when we create text, we are essentially creating a Surface object where the text is rendered.
font = pygame.font.SysFont('Arial', 50) # Set the font
text = font.render('Hello pygame!', True, (0, 0, 0)) # Render the text; 'text' is a Surface object
Common Surface Functions
Here are some commonly used Surface object functions and properties.
1.
Surface.blit(source, dest, area=None)
The blit() function is used to draw one Surface object onto another. source is the source Surface object to be drawn, and dest is the target Surface object where the source will be drawn. The area parameter specifies the drawing region and defaults to None, meaning it will draw at the top-left corner with the width and height of the source Surface.
2.
Surface.blits(((source, dest, area), ...))
The blits() function takes a sequence of tuples, each containing a source Surface, a destination Surface, and an optional area. This function allows drawing multiple Surface objects at once.
3.
Surface.convert(Surface=None)
Surface.convert_alpha(Surface=None)
When you use pygame.image.load() to load an image and then draw it onto a target Surface using blit(), if the pixel format of the image does not match the pixel format of the target Surface, the blit() function performs an internal format conversion.
Since blit() is called every frame, performing format conversion every time can be performance-intensive. Therefore, you can call convert() to convert the pixel format of the image to match the screen Surface format when loading the image. If no Surface parameter is specified, it defaults to converting to the format of the screen Surface. For example:
surface1 = pygame.image.load('demo.jpg').convert()
surface3 = pygame.image.load('demo.png').convert_alpha()
If the image has transparency, use convert_alpha() to preserve the image's transparency effects.
Note: Pixel format refers to the way pixel data is stored, including color channel arrangement and bit depth, not the file format (.jpg, .png, .gif).
4.
Surface.copy()
Creates a copy of a Surface object. The copied Surface has the same pixel format as the original.
5.
Surface.fill(color, rect=None)
Fills the target Surface object with a color. The rect parameter specifies the region to fill; if not provided, the entire Surface is filled.
6.
Surface.get_size()
Gets the width and height of the Surface object in pixels, returning a tuple (width, height).
7.
Surface.get_width()
Gets the width of the Surface object in pixels.
8.
Surface.get_height()
Gets the height of the Surface object in pixels.
9.
Surface.get_rect()
Gets the rectangle area of the Surface object, returning a Rect object.
In Example Code 2-2, we will demonstrate the use of these functions.
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Surface Demo')
pygame_logo = pygame.image.load('pygame_logo.png').convert_alpha() # 1
pygame_logo_rect = pygame_logo.get_rect()
pygame_logo_rect.center = (400, 300)
print(pygame_logo.get_size()) # 2
print(pygame_logo.get_width())
print(pygame_logo.get_height())
python_logo = pygame.image.load('python_logo.png').convert_alpha()
python_logo_rect = python_logo.get_rect()
python_logo_rect.topleft = (0, 0)
print(python_logo.get_size())
print(python_logo.get_width())
print(python_logo.get_height())
python_logo2 = python_logo.copy() # 3
python_logo_rect2 = python_logo.get_rect()
python_logo_rect2.topright = (600, 100)
print(python_logo2.get_size())
print(python_logo2.get_width())
print(python_logo2.get_height())
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill((0, 255, 0), (0, 0, 400, 600))
screen.blit(pygame_logo, pygame_logo_rect)
pygame_logo.blits(((python_logo, python_logo_rect), (python_logo2, python_logo_rect2))) # 4
pygame.display.flip()
Code Explanation:
#1 Call the convert_alpha() function to convert the image's pixel format and retain its transparency.
#2 Use get_size(), get_width(), and get_height() functions to obtain the dimensions of the Surface object.
#3 Use the copy() function to create a copy of a Surface object and set its top-right corner to (600, 100).
#4 Use the blits() function to draw two Python logo images onto the Pygame logo. As observed, part of the Python logo on the right is not displayed because it is outside the rectangle area of the Pygame logo, so it is not rendered.
Summary
In this article, we introduced the Surface, including its concept, creation methods, and common functions, and demonstrated their usage with examples. The Surface is a key concept in Pygame, and understanding it will enhance your familiarity with Pygame.
Buy author a cup of coffee if you enjoyed this tutorial. :)




Top comments (0)