Модули pygame.image и pygame.transform
Загрузка и сохранение изображений в Pygame
Функция load()
модуля pygame.image
загружает изображение и создает экземпляр Surface
, на котором отображено это изображение. В load()
передается имя файла. "Родным" форматом является BMP, однако если функция pygame.image.get_extended()
возвращает истину, то можно загружать ряд других форматов: PNG, GIF, JPG и др.
import pygame as pg import sys W = 400 H = 300 sc = pg.display.set_mode((W, H)) sc.fill((100, 150, 200)) dog_surf = pg.image.load('dog.bmp') dog_rect = dog_surf.get_rect(bottomright=(W, H)) sc.blit(dog_surf, dog_rect) pg.display.update() while 1: for i in pg.event.get(): if i.type == pg.QUIT: sys.exit() pg.time.delay(20)
Если у изображения нет прозрачного слоя, но он необходим, то следует воспользоваться методом set_colorkey()
класса Surface
:
dog_surf = pg.image.load('dog.bmp') dog_surf.set_colorkey((255, 255, 255))
Все пиксели, цвет которых совпадает с переданным в set_colorkey()
значением, станут прозрачными.
У формата PNG с альфа-каналом (когда для точек можно настраивать степень прозрачности; обычно устанавливается полностью прозрачный фон) таких проблем нет:
sun_surf = pg.image.load('sun.png') sun_rect = sun_surf.get_rect() sc.blit(sun_surf, sun_rect)
Ко всем экземплярам Surface
рекомендуется применять метод convert()
, который, если не передавать аргументы, переводит формат кодирования пикселей поверхности в формат кодирования пикселей главной поверхности. При выполнении игры это ускоряет отрисовку поверхностей.
Если поверхность была создана на базе изображения с альфа-каналом, то вместо convert()
надо использовать метод convert_alpha()
, так как первый удаляет прозрачные пиксели (вместо них будет черный цвет). Таким образом, код загрузки и обработки изображений разных форматов должен выглядеть примерно так:
dog_surf = pg.image.load('dog.bmp').convert() sun_surf = pg.image.load('sun.png').convert_alpha()
Что по смыслу равносильно:
... dog_surf = pg.image.load('dog.bmp') dog_surf = dog_surf.convert() ...
Метод convert()
возвращает новую, конвертированную, поверхность. Он не изменяет ту, к которой применяется.
В модуле pygame.image
есть функция save()
, которая позволяет сохранять переданную ей поверхность (не обязательно главную) в формат BMP, TGA, PNG, JPEG. Пример:
while 1: for i in pygame.event.get(): if i.type == pygame.QUIT: sys.exit() elif i.type == pygame.KEYUP \ and i.key == pygame.K_s: pygame.image.save(sc, 'day.png') pygame.time.delay(20)
Изменение поверхностей
Модуль pygame.transform
содержит функции для изменения поверхностей. Некоторые трансформации (например, изменение размера) приводят к ухудшению изображения из-за потери части пикселей. В таких случаях надо сохранять исходную поверхность и выполнять трансформации от нее.
Функции модуля transform
, которые изменяют поверхности, возвращают новые. Первым аргументом им передается исходный Surface
. Ниже приведены примеры использования наиболее востребованных функций.
Функция flip()
переворачивает Surface
по горизонтали и вертикали, к потери качества не приводит. Указывается поверхность и булевыми значениями оси переворота.
import pygame import sys sc = pygame.display.set_mode((400, 300)) sc.fill((100, 150, 200)) dog_surf = pygame.image.load('dog.bmp').convert() dog_surf.set_colorkey((255, 255, 255)) dog_rect = dog_surf.get_rect(center=(200, 150)) sc.blit(dog_surf, dog_rect) pygame.display.update() while 1: for i in pygame.event.get(): if i.type == pygame.QUIT: sys.exit() # При отжатии (нажать и отпустить) клавиши f elif i.type == pygame.KEYUP and i.key == pygame.K_f: # собака перевернется слева направо flip = pygame.transform.flip(dog_surf, True, False) sc.fill((100, 150, 200)) sc.blit(flip, dog_rect) pygame.display.update(dog_rect) pygame.time.delay(20)
Поворот и изменение размера:
import pygame import sys sc = pygame.display.set_mode((400, 300)) sc.fill((100, 150, 200)) dog_surf = pygame.image.load('dog.bmp').convert() dog_surf.set_colorkey((255, 255, 255)) dog_rect = dog_surf.get_rect(center=(200, 150)) sc.blit(dog_surf, dog_rect) pygame.display.update() # ждем 1 секунду перед изменением pygame.time.wait(1000) sc.fill((100, 150, 200)) # уменьшаем в два раза scale = pygame.transform.scale( dog_surf, (dog_surf.get_width() // 2, dog_surf.get_height() // 2)) scale_rect = scale.get_rect(center=(200, 150)) sc.blit(scale, scale_rect) pygame.display.update(dog_rect) pygame.time.wait(1000) sc.fill((100, 150, 200)) # поворачиваем на 45 градусов rot = pygame.transform.rotate(dog_surf, 45) rot_rect = rot.get_rect(center=(200, 150)) sc.blit(rot, rot_rect) pygame.display.update() while 1: for i in pygame.event.get(): if i.type == pygame.QUIT: sys.exit() pygame.time.delay(20)
Практическая работа
Допустим, у вас есть такое изображение вида сверху машины:
Напишите программу управления ее движением с помощью стрелок клавиатуры (вверх, вниз, влево, вправо) так, чтобы объект всегда двигался головой вперед.
Курс с примерами решений практических работ:
pdf-версия