Using Images in Pygame

Draw an image

Drawing an image file (jpeg or png) is really easy! Only two lines of code needed. The following assumes your image files are located in your PyCharms project folder.

Load the image to a variable. Do this only once, typically where you declare your colours, fonts etc. It is important that your pygame.image.load is not in your game loop. Every time you run it you are reloading the file into memory, slowing your system down!

IMAGE = pygame.image.load("image.jpg").convert_alpha()

To draw the full image onto the screen, use the blit() command. The coordinates are the top-left corner of the image on your screen. Do this where you would have used pygame.draaw.rect or similar.

window.blit(IMAGE, (x, y))

Resize an image

To resize an image before drawing it onto the screen.

picture = pygame.image.load(filename)
picture = pygame.transform.scale(picture, (newWidth, newHeight))

Rotate an image

originalPicture = pygame.image.load(filename)
rotatedPicture = pygame.transform.rotate(originalPicture, 90)

Get a colour at a given pixel

pixel_colour = window.get_at(( x , y ))

Draw part of an image

To only render part of an image onto the screen, you can supply the coordinates of the rectangle within the image you want to use.

window.blit(IMAGE, (window-x, window-y), (image-x, image-y, image-width, image-height))

Where

Use a sprite-map

A sprite map is where one image has several icons drawn on it. The idea is you rotate through the icons to give the appearance of animation.

Sprite maps are easy to find online, or create your own using a site such as piskelapp.com/

The following exercise creates a simple Mario walking scene where his “walk” is animated through a series of cells for the left and right walking as shown

You will need to download the following files:

The sprite animation runs from functionality in the pygamemadeeasy library. Ensure you have it installed and import as follows

from pygamemadeeasy import *

Creating an animation then involves creating an animation object such as below. In this case, the 90, 133 indicates the height and width of the individual frames within the image file. The SpriteAnimation() object has been designed to work on PNG files exported from Piskelapp where columns has been set to 1.

mario_left_animation    = SpriteAnimation("media/mario-left-animation.png", 90, 133)

To then obtain the image data to blit onto screen, use the .next_frame() function which will automatically iterate through the set of sprite frames each time it is called.

window.blit(mario_right_animation.next_frame(), (player_x, player_y))

THe full code for the demo is:

import pygame, time, random
from pygame.locals import *
from pygamemadeeasy import *
from spritemap import load_sprite_map

### FUNCTIONS ####

def jump(frame_number):
    """
    Calculate gravity effect for jumping
    Returns change in y-axis for x-frames. Jumps to a height of 200 pixels and lands again over a total of 100 frames
    (~20 frames/sec = 5 second process)
    Who ever said quadratics and physics weren't useful!?
    """
    frame_number = float(frame_number)              # convert integer to float for calculation purposes
    delta_y = -(2.0/25.0)*(frame_number**2) + 8.0*frame_number
    return int(delta_y)                             # turn the decimal float back to an integer to represent change of pixels

### START GAME CODE ###

pygame.init()
window = pygame.display.set_mode((1000,760))
fps = pygame.time.Clock()

# Declare colors, fonts, images
background_image        = pygame.image.load("media/mario-background-768p.png").convert_alpha()
mario_left_animation    = SpriteAnimation("media/mario-left-animation.png", 90, 133)
mario_right_animation   = SpriteAnimation("media/mario-right-animation.png", 90, 133)
mario_stationary_image  = pygame.image.load("media/mario-stationary.png").convert_alpha()
arial_60                = pygame.font.SysFont("Arial", 60)

# Variables
player_x = 30                                       # x-value of player
player_y = 400                                      # y-value of player
quit = False                                        # game still playing while this is True
score = 0                                           # starting score
floor = 555                                         # y-value of the floor
gravity = 25                                         # Gravity speed
falling = True                                      # are we falling??
jumping = False                                     # are we jumping?
jumping_frames = 0                                  # number of frames we have been jumping
delta_x = 0
sprite_num = 0
sprite_scene =0
# Main game loop
while not quit:
    # Process events
    for event in pygame.event.get():
        if event.type == QUIT:
            quit = True
        elif event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                quit = True
            if event.key == K_SPACE:
                if not falling and not jumping:     # We can't jump if we are already in the air
                    jumping = True                  # we are jumping!
                    jumping_frames = 0              # start of a new jump
            if event.key == K_LEFT:
                delta_x = -20
            if event.key == K_RIGHT:
                delta_x = 20
        elif event.type == KEYUP:
            if event.key == K_LEFT or event.key == K_RIGHT:
                delta_x = 0
        elif event.type == MOUSEMOTION:             ## The mouse has moved
            paddle_x = event.pos[0]                 ## We only need the x coordinate of the mouse position

    if jumping:
        player_y -= gravity
        jumping_frames += 1
        if jumping_frames > 10:                     # We've reached our jump limit, time to fall down again
            jumping = False
            falling = True
    elif player_y < floor:
        falling = True
        player_y += gravity
    else:
        falling = False
    player_x += delta_x
    # Draw graphics
    window.fill(colors.black)
    window.blit(background_image, (0, 0))
    if delta_x > 0: # moving right
        window.blit(mario_right_animation.next_frame(), (player_x, player_y))
    elif delta_x < 0:
        window.blit(mario_left_animation.next_frame(), (player_x, player_y))
    else:
        window.blit(mario_stationary_image, (player_x, player_y))
    window.blit(arial_60.render( str(score), 1, colors.white ), (20, 20))
    pygame.display.update()
    fps.tick(10)
pygame.quit()