воскресенье, 20 февраля 2011 г.

Pygame:учим Python рисовать

    Так уж получилось, что  у меня в универе начался предмет компьютерная геометрия, а на нем,естественно, нужно представлять программы, которые генерируют нужные изображения. У нас выбрали как инструмент представления результатов  Qbasiс. 
Мне это понравилось неслишком по той простой причине, что в Ubuntu он не идет да и в Windows он запускается с бубном.
Память подсказала мне  кроссплатформенную   библиотеку Pygame. Она базируется на С-библиотеке SDL. Гарантировано работает на Windows,Linux,FreeBSD,Mac.
Собственно, чтобы в Ubuntu установить данную библиотеку, можно воспользоваться либо Центром приложений, либо в консоли: 
sudo apt-get install python-pygame. Установится все должно быстро и без вашего участия. 
Проверить,  действительно ли, установилась pygame можно при помощи: 
import pygame  
Если команда отработала без сообщений, то все в порядке. 
   Нарисуем с вами круг, закрашенный и наоборот, а на этом примере увидим, как работать с Pygame.
Начать нужно с инициализации библиотеки: 
import pygame
pygame.init()
Это обязательный шаг: во время этой команды Pygame настраивает себя на работу с вашей системой. Дальше нам надо получить область рисования на экране. Для этого напишем следующее: 

resolution=(420,320)#ширина и высота области 
flag=0#никаких дополнительных условий и настроек 
depth=32#глубина
screen=pygame.display.set_mode(resolution, flag,depth)

Здесь мы обращаемся к той части pygame,которая отвечает за работу с вашим экраном. Мы производим начальную настройку области рисования. Стандартная область 420,320. В переменной flag мы например можем потребовать у pygame использовать полноэкранный режим (pygame.FULLSCREEN) , однако во время отладки вашего приложения лучше его не использовать, так как прибить ошибочно работающий скрипт будет много легче не в полноэкранном режиме. 
Дальше задаем глубину цвета. 
После всех подготовительных действий передаем это все в функцию настройки экрана set_mode()
Дальше закрасим нашу область белым цветом. Для этого вызовем у объекта screen метод fill, а перед этим занесем в переменную color тот цвет, который нам нужен.
 
color=(255, 255, 255)# задаем белый цвет модели RGB цветов   
screen.fill(color) #закрашиваем всю область, цветом color    

цвета в pygame определяются кортежем из трех элементов. Как уже написано  в комментариях цвет должен передаваться в модели RGB. Давайте определим набор цветовых констант: 
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)                 
Я думаю так будет удобней:) 
А меж тем мы изменили изображение на экране, поэтому надо бы картинку на экране обновить, сделаем же это: 
pygame.display.update()      
После того как вы что-либо закрасили, нарисовали фигуру и т.д. обязательно вставляйте строку с вызовом функции обновления изображения экрана. 
Теперь нарисуем закрашенную  окружность черного цвета, а для этого нам понадобится функция circle. 
circolor=BLACK #цвет круга
center=(420/2,320/2)#центр окружности 
radius=100#радиус круга 
pygame.draw.circle(screen, circolor, center, radius)     
Итак с цветом понятно,а центр это кортеж из x-координаты и y-координаты 
радиус число больше нуля. 
На самом деле есть еще параметр width, однако сейчас мы его оставили со значением по умолчанию 0. Так как границы у нового изображения нет, то оно все закрашивается черным цветом. 
Но если в вызов функции после radius мы добавим через запятую 3, то увидим совсем иное. В чем дело? А лаарчик открывается просто: мы дали указание pygame начертить линию с толщиной 3 и цветом BLACK, вот ровно это она и сделала. Собственно говоря именно так можно получить незакрашенные фигуры во многих случаях.      
добавим pygame.display.update() 
В принципе все, за исключением того,что скрипт, не управляем пользователем. Единственный метод сейчас из него выйти это набрать в консоли python pygame.quit()
Это неправильно тем более что pygame нам предоставляет возможность обрабатывать различные события. Напишем код останавливающий  наш скрипт, либо по нажатию крестика в окне, либо по нажатию клавиши Esc:    
while True:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if  event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()            
Что мы сделали? Мы организовали бесконечный цикл обработки событий. Как только  событие  попадает в очередь обработки оно будет извлечено при первой возможности и pygame передаст его в наш цикл. А в нем мы проверим следующее: 
1) Это событие сигнал к выходу? (генерируется при нажатии крестика)Если да,то завершаем  приложение и закрываем сам интерпретатор.      
2) Это нажатие клавиши ? Если да, то проверяем, что нажата клавиша Escape (самая верхняя слева) . Да? закрываем приложение и интерпретатор.   
Мы рассмотрели лишь очень малую часть возможностей этой замечательной библиотеки, зайдите на сайт www.pygame.org 
Там вы найдете документацию, ссылки на руководства и сможете загрузить различные версии библиотеки.Кстати она является OpenSource разработкой и распространяется на условиях LGPL . 
А в завершении заметки полный исходный текст нашего приложения(закрашенный круг): 
# -*- coding: utf-8 -*-
import pygame
import sys 
pygame.init()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
resolution=(420,320)#ширина и высота области 
flag=0#никаких дополнительных условий и настроек 
depth=32#глубина
screen=pygame.display.set_mode(resolution, flag,depth)
color=(255, 255, 255)# задаем белый цвет модели RGB цветов   
screen.fill(color) #закрашиваем всю область, цветом color
pygame.display.update()
circolor=BLACK #цвет круга
center=(420/2,320/2)#центр окружности 
radius=100#радиус круга 
pygame.draw.circle(screen, circolor, center, radius)
pygame.display.update()
while True:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if  event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()      
А вот и незакрашенная окружность:
# -*- coding: utf-8 -*-
import pygame
import sys 
pygame.init()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
resolution=(420,320)#ширина и высота области 
flag=0#никаких дополнительных условий и настроек 
depth=32#глубина
screen=pygame.display.set_mode(resolution, flag,depth)
color=(255, 255, 255)# задаем белый цвет модели RGB цветов   
screen.fill(color) #закрашиваем всю область, цветом color
pygame.display.update()
circolor=BLACK #цвет круга
center=(420/2,320/2)#центр окружности 
radius=100#радиус круга 
pygame.draw.circle(screen, circolor, center, radius,3)
pygame.display.update()
while True:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if  event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()