Учим Python, делая крутые игры 2018. Invent your owncomputer gameswith python
Скачать 6.56 Mb.
|
htmlcolorcodes. com вы найдете дополнительную информацию о RGB-цветах. Таблица 17.1. Цвета и соответствующие значения RGB Цвет Значение RGB Черный (0, 0, 0) Синий (0, 0, 255) Серый (128, 128, 128) Зеленый (0, 128, 0) Лаймовый (0, 255, 0) Пурпурный (128, 0, 128) Красный (255, 0, 0) Бирюзовый (0, 128, 128) Белый (255, 255, 255) Желтый (255, 255, 0) Мы будем использовать только пять определенных нами цветов. Но в своих программах вы можете использовать любой из этих цветов или даже составлять собственные оттенки. Вывод текста в окне pygame Вывод текста в окне немного отличается от использования функции print() в текстовых играх. Чтобы вывести текст в окне, сначала нужно произ- вести кое-какие настройки. Использование шрифтов для оформления текста Шрифт — это полный набор букв, цифр и специальных символов, вы- полненных в одном стиле. Каждый раз, как нам нужно будет вывести текст 328 Глава 17 в окне pygame, мы будем использовать шрифты. На рис. 17.2 показано одно и то же предложение с использованием разных шрифтов. Рис. 17.2. Примеры различных шрифтов В наших предыдущих играх мы инструктировали Python просто выво- дить текст. Цвет, размер и шрифт для отображения этого текста полностью определялись настройками операционной системы. Программа Python не влияла на шрифт. Однако модуль pygame может вывести текст любым шриф- том. Код в строке 19 создает объект pygame.font.Font (для краткости будем на- зывать его объектом Font), вызывая функцию pygame.font.SysFont() с двумя параметрами. 18. # Назначение шрифтов. 19. basicFont = pygame.font.SysFont(None, 48) Первый параметр — это название шрифта, но мы передадим значение None , чтобы использовался системный шрифт по умолчанию. Второй пара- метр — размер шрифта (который измеряется в единицах, называемых пун- ктами). Мы выведем в окне надпись 'Привет, мир!', используя шрифт по умолчанию размером 48 пунктов. Создание изображения из букв для текста «Привет, мир!» называется рендерингом. Рендеринг объекта Font Объект Font, который вы сохранили в переменной basicFont, имеет ме- тод под названием render(). Этот метод вернет объект Surface с текстом, ото- Создание графики 329 браженном на нем. Первым параметром метода render() является строка с текстом для отображения. Второй параметр — логическое значение, указы- вающее, следует ли производить сглаживание шрифта. Сглаживание слегка размывает текст, чтобы придать ему более гладкий вид. Рисунок 17.3 показы- вает, как выглядит линия со сглаживанием и без него. Aliased Anti-aliased Без сглаживания Со сглаживанием Рис. 17.3. Увеличенное изображение линии до и после сглаживания Чтобы использовать сглаживание, мы передадим значение True в стро- ке 22. 21. # Настройка текста. 22. text = basicFont.render('Привет, мир!', True, WHITE, BLUE) Третий и четвертый параметры в строке 22 являются кортежами RGB. Третий параметр — это цвет шрифта текста (в данном случае это белый), а четвертый — фоновый цвет позади текста (синий). Мы присваиваем объ- ект Font переменной text. После настройки объекта Font нам нужно поместить его в определенную позицию в окне. Настройка местоположения текста с помощью атрибутов Rect Тип данных pygame.Rect (сокращенно Rect) представляет прямоугольные области, у которых заданы размер и положение на экране. Чтобы создать новый объект Rect, вызовите функцию pygame.Rect(). Обра- тите внимание, что функция pygame.Rect() имеет то же имя, что и тип данных pygame.Rect . Функции, которые имеют то же имя, что и их тип данных, и соз- дают объекты или значения своего типа данных, называются функциями- конструкторами. Параметрами для функции pygame.Rect() выступают целые числа, обозначающие координаты x и y верхнего левого угла, а также ширина и высота, и указываемые в пикселях. Синтаксис функции с параметрами вы- глядит следующим образом: pygame.Rect( лево, верх, ширина, высота). 330 Глава 17 Когда мы создали объект Font, объект Rect для него уже был создан, поэто- му нам нужно лишь запросить его. Для этого мы используем метод get_rect() в переменной text и присваиваем Rect переменной textRect. 23. textRect = text.get_rect() 24. textRect.centerx = windowSurface.get_rect().centerx 25. textRect.centery = windowSurface.get_rect().centery Подобно тому, как методы являются функциями, связанными с объек- том, атрибуты — это переменные, связанные с объектом. Тип данных Rect имеет много атрибутов, которые описывают прямоугольник, который они представляют. Чтобы установить местоположение textRect в окне, нам нужно присвоить значения x и y его центра координатам в пикселях в этом окне. По- скольку у каждого объекта Rect уже есть атрибуты, которые хранят коорди- наты x и y центра Rect, называемые centerx и centery , соответственно, все, что нам нужно сделать, — это назначить значения этих координат. Мы хотим поместить textRect в центр окна, поэтому нужно получить объ- ект windowSurface Rect, его атрибуты centerx и centery, а затем присвоить их со- ответствующим атрибутам объекта в textRect. Я сделал это в строках 24 и 25. Мы можем использовать множество других атрибутов Rect . Таблица 17.2 перечисляет атрибуты объекта Rect с именем myRect. Таблица 17.2. Атрибуты объекта Rect Атрибут pygame.Rect Описание myRect.left Целочисленное значение координаты x левой стороны прямоугольника myRect.right Целочисленное значение координаты x правой стороны прямоугольника myRect.top Целочисленное значение координаты y верхней стороны прямоугольника myRect.bottom Целочисленное значение координаты y нижней стороны прямоугольника myRect.centerx Целочисленное значение координаты x центра прямоугольника myRect.centery Целочисленное значение координаты y центра прямоугольника myRect.width Целочисленное значение ширины прямоугольника myRect.height Целочисленное значение высоты прямоугольника myRect.size Кортеж из двух целых чисел: (width, height) myRect.topleft Кортеж из двух целых чисел: (left, top) myRect.topright Кортеж из двух целых чисел: (right, top) myRect.bottomleft Кортеж из двух целых чисел: (left, bottom) myRect.bottomright Кортеж из двух целых чисел: (right, bottom) myRect.midleft Кортеж из двух целых чисел: (left, centery) myRect.midright Кортеж из двух целых чисел: (right, centery) myRect.midtop Кортеж из двух целых чисел: (centerx, top) myRect.midbottom Кортеж из двух целых чисел: (centerx, bottom) Создание графики 331 Самое замечательное при работе с объектами Rect заключается в том, что если вы измените какой-либо из этих атрибутов, все остальные атрибуты ав- томатически изменятся сами. Например, если вы создадите объект Rect ши- риной и высотой по 20 пикселей с верхним левым углом в координатах (30, 40 ), тогда координата x правой стороны автоматически будет установлена равной 50 (поскольку 20 + 30 = 50). Или, если вы вместо этого замените атрибут left строкой кода myRect.left = 100 , тогда pygame автоматически изменит атрибут right на 120 (поскольку 20 + 100 = 120). Все остальные атрибуты для этого объекта Rect также обновятся. БОЛЬШЕ О МЕТОДАХ, МОДУЛЯХ И ТИПАХ ДАННЫХ Внутри модуля pygame есть модули font и surface, а внутри этих модулей — типы данных Font и Surface. Разработчики модуля pygame сделали так, чтобы имена модулей начинались со строчной буквы, а типов данных — с про- писной, чтобы было проще различать типы данных и модули. Обратите внимание, что и объект Font (хранящийся в переменной text в строке 23), и объект Surface (хранящийся в переменной windowSurface в строке 24) имеют метод get_rect(). Технически это два разных метода, но разработчики pygame дали им одно и то же имя, так как они делают одно и то же: возвращают объекты Rect, которые представляют размер и поло- жение объекта Font или Surface. Заливка цветом объекта Surface В нашей программе мы заполним белым цветом всю поверхность, храня- щуюся в переменной windowSurface. Функция fill() полностью зальет поверх- ность цветом , который вы передадите в качестве параметра. Помните, что мы присвоили переменной WHITE значение (255, 255, 255) в строке 13. 27. # Нанесение на поверхность белого фона. 28. windowSurface.fill(WHITE) Обратите внимание, что в pygame окно на экране не изменится при вызове метода fill() или любой другой функции рисования. Вместо этого они из- менят объект Surface. Для того чтобы увидеть изменения, вы должны будете вывести на экран новый объект Surface с помощью функции pygame.display. update() 332 Глава 17 Это связано с тем, что изменение объекта Surface осуществляется в па- мяти компьютера намного быстрее, чем изменение изображения на экране. Гораздо эффективнее производить вывод на экран один раз после того, как все функции рисования были применены к объекту Surface. Функции рисования pygame Мы уже научились заполнять окно цветом и добавлять текст, но в pygame также есть функции, позволяющие рисовать фигуры и линии. Вы можете комбинировать эти фигуры в своей графической игре, получая различные изображения. Рисование многоугольника Функция pygame.draw.polygon() позволяет нарисовать любую многоуголь- ную фигуру, которую вы ей передадите. Многоугольник представляет собой многогранную фигуру со сторонами, образованными прямыми. Круги и эл- липсы не являются многоугольниками, поэтому для этих фигур мы будем ис- пользовать другие функции. Аргументы функции указываются в следующем порядке: 1. Объект Surface , на который будет наноситься многоугольник. 2. Цвет многоугольника. 3. Кортеж из кортежей, представляющий координаты x и y рисуемых то- чек по порядку. Последний кортеж автоматически соединяется с пер- вым для завершения фигуры. 4. Опционально, целое число для толщины контура многоугольника. Без этого многоугольник будет залит целиком. В строке 31 мы рисуем зеленый многоугольник на белом объекте Surface. 30. # Нанесение на поверхность зеленого многоугольника. 31. pygame.draw.polygon(windowSurface, GREEN, ((146, 0), (291, 106), (236, 277), (56, 277), (0, 106))) Рис. 17.4. Примеры многоугольников Создание графики 333 Так как нам нужно залить многоугольник целиком, мы не передаем нео- бязательный параметр толщины контура. На рис. 17.4 показаны некоторые примеры многоугольников. Рисование линии Функция pygame.draw.line() проводит линию от одной точки на экране до другой. Параметры для pygame.draw.line() указываются в следующем по рядке: 1. Объект Surface , на котором будет проведена линия. 2. Цвет линии. 3. Кортеж из двух целых чисел для координат x и y одного конца линии. 4. Кортеж из двух целых чисел для координат x и y другого конца линии. 5. Опционально целое число для толщины линии в пикселях. В строках с 34 по 36 мы трижды вызываем функцию pygame.draw.line(). 33. # Нанесение на поверхность синих линий. 34. pygame.draw.line(windowSurface, BLUE, (60, 60), (120, 60), 4) 35. pygame.draw.line(windowSurface, BLUE, (120, 60), (60, 120)) 36. pygame.draw.line(windowSurface, BLUE, (60, 120), (120, 120), 4) Если вы не укажете параметр width, он примет значение по умолчанию, равное 1. В строках 34 и 36 для width мы передаем значение 4, так что линии будут иметь толщину в 4 пикселя. Три вызова pygame.draw.line() в строках 34, 35 и 36 позволяют отобразить синюю букву Z на объекте Surface. Рисование круга Функция pygame.draw.circle() рисует на объектах Surface круги. Ее пара- метры указываются в следующем порядке: 1. Объект Surface , на котором нужно нарисовать круг. 2. Цвет круга. 3. Кортеж из двух целых чисел для координат x и y центра круга. 4. Целое число радиуса (то есть размера) круга. 5. Опционально целое число толщины контура. Толщина 0 означает, что круг будет залит цветом без контура. Код в строке 39 рисует синий круг на объекте Surface. 38. # Нанесение на поверхность синего круга. 39. pygame.draw.circle(windowSurface, BLUE, (300, 50), 20, 0) Центр этого круга имеет координату x, равную 300 и координату y, рав- ную 50. Радиус круга составляет 20 пикселей, круг заполнен синим цветом. 334 Глава 17 Рисование эллипса Функция pygame.draw.ellipse() напоминает функцию pygame.draw.circle(), но вместо этого она рисует эллипс — фигуру, которая выглядит как сплющен- ный круг. Параметры функции pygame.draw.ellipse() указываются в следую- щем порядке: 1. Объект Surface , на который наносится эллипс. 2. Цвет эллипса. 3. Кортеж из четырех целых чисел для левого верхнего угла объекта Rect эллипса, а также ширины и высоты эллипса. 4. Опционально целое число толщины контура. Толщина 0 означает, что эллипс будет залит цветом без контура. Код в строке 42 рисует красный эллипс на объекте Surface. 41. # Нанесение на поверхность красного эллипса. 42. pygame.draw.ellipse(windowSurface, RED, (300, 250, 40, 80), 1) Координата х верхнего левого угла эллипса равна 300, а координата y — 250. Ширина фигуры 40 пикселей, высота — 80 пикселей. Контур эллипса имеет толщину в 1 пиксель. Рисование прямоугольника Функция pygame.draw.rect() создает прямоугольники . Параметры функ- ции pygame.draw.rect() указываются в следующем порядке: 1. Объект Surface , на котором нужно нарисовать прямоугольник. 2. Цвет прямоугольника. 3. Кортеж из четырех целых чисел для координат x и y верхнего левого угла, ширины и высоты прямоугольника. Вместо кортежа из четырех целых чисел вы также можете передать в качестве третьего параметра объект Rect. В программе «Привет, мир!» отображаемый прямоугольник на 20 пик- селей будет выступать за пределы всех границ текста. Помните, что в стро- ке 23 мы создали переменную textRect, содержащую наш текст. В строке 45 мы присваиваем левой и верхней точкам прямоугольника соответствующие значения textRect минус 20 (вычитаем, поскольку координаты уменьшаются по мере продвижения влево и вверх). 44. # Нанесение на поверхность фонового прямоугольника для текста. 45. pygame.draw.rect(windowSurface, RED, (textRect.left - 20, textRect.top - 20, textRect.width + 40, textRect.height + 40)) Создание графики 335 Ширина и высота прямоугольника равны ширине и высоте textRect плюс 40. Мы используем 40, а не 20, поскольку лево и верх были перемещены к на- чалу координат на 20 пикселей, поэтому вам нужно компенсировать это про- странство. Окрашивание пикселей Код в строке 48 создает объект pygame.PixelArray (для краткости, объ- ект PixelArray). Объект PixelArray — это список списков цветовых кортежей, представляющий объект Surface, который вы ему передали. Объект PixelArray позволяет управлять каждым пикселем, поэтому пре- красно подойдет, если вам нужно вывести на экран глубоко детализирован- ные или специфические изображения вместо простых больших форм. Мы будем использовать PixelArray для окраски одного пикселя на объекте windowSurface в черный цвет. Этот пиксель можно заметить в правом нижнем углу окна при запуске pygame-программы «Привет, мир!». Код в строке 48 передает объект windowSurface вызову pygame.PixelArray(), поэтому присвоение значения константы BLACK переменной pixArray[480][380] в строке 49 окрасит пиксель с координатами (480, 380) в черный цвет. 47. # Получение массива пикселов поверхности. 48. pixArray = pygame.PixelArray(windowSurface) 49. pixArray[480][380] = BLACK Модуль pygame автоматически внесет в объект windowSurface это измене- ние. Первый индекс в объекте PixelArray соответствует координате x. Второй индекс — координате y. Объекты PixelArray упрощают процесс окрашивания отдельных пикселей на объекте Surface в определенный цвет. Каждый раз, когда вы создаете объект PixelArray из объекта Surface, этот объект Surface блокируется. Это означает, что на этом объекте Surface не могут быть осуществлены вызовы метода blit() (описано ниже). Чтобы разблокировать объект Surface, нужно удалить объект PixelArray с помощью инструкции del. 50. del pixArray Если вы забудете это сделать, то получите сообщение об ошибке: pygame. error: Surfaces must not be locked during blit 336 Глава 17 Метод blit() для объектов Surface Метод blit() будет рисовать содержимое одного объекта Surface на дру- гом объекте Surface. Все текстовые объекты, созданные методом render(), су- ществуют на их собственном объекте Surface. Все методы рисования pygame могут указывать конкретный объект Surface, на котором нужно рисовать фи- гуры или линии, но наш текст был сохранен в переменной text, а не нарисо- ван на объекте windowSurface. Чтобы нанести text на тот объект Surface, где мы хотим его видеть, нужно использовать метод blit(). 52. # Нанесение текста на поверхность. 53. windowSurface.blit(text, textRect) Код в строке 53 рисует объект Surface 'Привет, мир!' из переменной text (определенной в строке 22) на объекте Surface, хранящемся в переменной windowSurface Второй параметр метода blit() указывает позицию на windowSurface, в ко- тором должна быть нарисована поверхность text. Объект Rect, который вы получили из вызова метода text.get_rect() в строке 23, передается в качестве этого параметра. Вывод объекта Surface на экран Поскольку в pygame на экран ничего не выводится до тех пор, пока не вы- зывается функция pygame.display.update(), мы вызываем ее в строке 56 для отображения нашего обновленного объекта Surface. 55. # Отображение окна на экране. 56. pygame.display.update() Для экономии памяти не стоит обновлять экран после вызова каждой от- дельной функции рисования; вместо этого лучше обновить его лишь раз, по- сле того, как были вызваны все функции рисования. |