Рисование и анимация в TkInter
Испольуем Canvas
В процессе работы над вторым проектом мы успели познакомится с библиотекой tkInter. В этом разделе мы научимся рисовать и передвигать объекты, а затем - создадим несложную компьютерную игру. Начнем же! 🏎
Для рисования в окне tkInter, в него нужно добавить Canvas - холст.
from tkinter import *
tk = Tk()
# создаем холст размером 640 на 640 пикселей с белым фоном внутри основного окна
c = Canvas(tk, width=640, height=640, bg='white')
c.pack()
# тут будет код для рисования
mainloop()
На холсте мы сможем рисовать прямоугольники, произвольные многоугольники, линии и овалы.
Полная документация - http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html (Раздел 8).
Рисуем дом
Начнем с простых геометрических фигур. Вот как устроено рисование прямоугольника:
А вот так - треугольника:
Если совместить вместе, то получится... дом! 🏠
from tkinter import *
tk = Tk()
c = Canvas(tk, width=640, height=640, bg='white')
c.pack()
# рисуем прямоугольник зеленого цвета
c.create_rectangle(30, 60, 130, 120, fill='green')
# рисуем треугольник (полигон с тремя вершинами) синего цвета
c.create_polygon(30, 60, 80, 10, 130, 60, fill='blue')
mainloop()
Как сделать его лучше? Напиши программу, которая рисует домик с заданными размером, цветом крыши и первого этажа по нажатию кнопки. Для ввода размеров и цветов используйте Entry. Для очистки canvas
можно использовать команду c.delete("all")
.
Деревня
А теперь супер-задание - используй циклы, чтобы нарисовать целую деревню!
Анимация
Теперь мы можем комбинировать геометрические фигуры, но вот только для игры этого недостаточно - объекты должны двигаться! Для начала научимся рисовать овалы:
Для того, чтобы оживить наш рисунок, нам нужно научится перемещать объекты. Для этого используется функция move
.
from tkinter import *
tk = Tk()
c = Canvas(tk, width=640, height=640, bg='white')
c.pack()
# сохраняем номер соданной фигуры в переменную
my_favorite_oval = c.create_oval(0, 0, 50, 50, fill='blue')
def moveBall():
# передвигаем наш овал на 10 пикселей по обеим осям
c.move(my_favorite_oval, 10, 10)
# повторяем через 100 мс (1 секунда)
c.after(100, moveBall)
# спустя 1 секунду (100 мс) после запуска выполнить moveBall
c.after(100, moveBall)
mainloop()
Отталкиваемся от стен
Теперь шарик движется, но недолго - очень скоро он вылетает за границу и мы его уже больше не видим. Нужно как то заставить его отталкиваться от стен. Самый простой вариант - просто разворачивать его скорость, как только он касается одной из границ. Коснулись вертикальной границы - умножаем горизонтальную скорость на -1, вертикальной - умножаем вертикальную.
Что дальше?
Отлично, теперь у нас двигается и отталкивается от стен один шарик. Какую игру мы можем из этого сделать? Например, подобие астероидов: космический корабль должен как можно дольше уворачиваться от метеоритов, летающих во всех стороны.
Но вот только для этой игры метеоритов нам понадобится много, а заводить отдельную четверку переменных для каждого из десятка метеоритов - неудобно. Хорошо бы как-то хранить их в одном месте. И так правда можно, для этого используются списки.