Програмування руху об'єктів
Анімація — це ілюзія руху об’єктів, яка досягається за рахунок зміни зображень на екрані з великою швидкістю.
Методи, призначені для переміщення об’єкта полотном:
- canvas.move() переміщає графічний об’єкт, змінюючи значення його координат на задані величини:
canvas.move(item, x, y),
де canvas — назва об’єкта класу Сanvas, item — ідентифікатор графічного об’єкта ; x, y — значення зміщення по горизонталі та вертикалі (у пікселях). - tk.update() примусово оновлює зображення; tk — назва об'єкта класу Тк (вікна програми).
- time.sleep() затримує виконання програми:
time.sleep(t),
де t — величина затримки (в секундах).
Приклад:
Організуємо горизонтальний рух круга по полотну. Перший створений об’єкт (круг) автоматично отримує ідентифікатор 1:
import time
from tkinter import*
tk = Tk()
canvas = Canvas(tk, width = 400, height = 400)
canvas.pack()
canvas.create_oval(10, 10, 30, 30, fill = 'red')
for x in range(0, 60):
import time
from tkinter import*
tk = Tk()
canvas = Canvas(tk, width = 400, height = 400)
canvas.pack()
canvas.create_oval(10, 10, 30, 30, fill = 'red')
for x in range(0, 60):
canvas.move(1, 5, 0) # Переміщення об’єкта із ідентифікатором 1
tk.update()
time.sleep(0.05)
Блок коду в циклі for призначено для пересування круга по полотну. Зокрема, команда canvas.move(1, 5, 0) пересуне об’єкт із ідентифікатором 1 (це і є круг) на 5 пікселів праворуч і 0 пікселів по вертикалі.
tk.update()
time.sleep(0.05)
Блок коду в циклі for призначено для пересування круга по полотну. Зокрема, команда canvas.move(1, 5, 0) пересуне об’єкт із ідентифікатором 1 (це і є круг) на 5 пікселів праворуч і 0 пікселів по вертикалі.
Для пересування ліворуч знадобилася б команда canvas.move(1, –5, 0).
Для руху по діагоналі слід змінювати одночасно координати х і у:
canvas.move(1, 5, 5).
Приклад:
Запрограмуємо рух кульки по полотну. Координати кульки задаються випадковим чином. Кулька рухається по полотну, відбиваючись від меж полотна.
from tkinter import*
from random import*
import time
from random import*
import time
tk = Tk()
canvas = Canvas(tk, width=200, height=200)
canvas.pack()
x=randint(10,150)
y=randint(10,150)
id = canvas.create_oval(x, y, x+50, y+50, fill='red') # Ідентифікатор круга зберігається в змінній id
dx=dy=5
canvas = Canvas(tk, width=200, height=200)
canvas.pack()
x=randint(10,150)
y=randint(10,150)
id = canvas.create_oval(x, y, x+50, y+50, fill='red') # Ідентифікатор круга зберігається в змінній id
dx=dy=5
while True:
if x>150 or x<10: dx=-dx # Коли кулька досягає меж полотна,
if y>150 or y<10: dy=-dy # змінюється напрямок руху
x=x+dx
y=y+dy
canvas.move(id, dx, dy)
tk.update()
time.sleep(0.05)
if x>150 or x<10: dx=-dx # Коли кулька досягає меж полотна,
if y>150 or y<10: dy=-dy # змінюється напрямок руху
x=x+dx
y=y+dy
canvas.move(id, dx, dy)
tk.update()
time.sleep(0.05)
Програмування реакції об’єктів на події
Для встановлення зв’язку між подією та її обробником існують методи bind() і bind_all():
canvas.bind_all(<подія>, функція), де подія — текстова константа, системна назва події; функція — назва функції-обробника події.
Приклад:
Змусимо круг рухатися праворуч в разі натискання на клавішу зі стрілкою «→». Опишемо функцію — обробник події:
def move_oval(event):
canvas.move(1, 5, 0)
Функція має єдиний аргумент event, через який передається інформація про подію. Об’єкт event має властивість keysym, яка набуває значення символу натиснутої клавіші. Якщо натиснуто клавішу «→», це означає, що відбулася подія '<KeyPress-Right>', і властивість event.keysym отримує значення 'Right' (з англ. вправо).
def move_oval(event):
canvas.move(1, 5, 0)
Функція має єдиний аргумент event, через який передається інформація про подію. Об’єкт event має властивість keysym, яка набуває значення символу натиснутої клавіші. Якщо натиснуто клавішу «→», це означає, що відбулася подія '<KeyPress-Right>', і властивість event.keysym отримує значення 'Right' (з англ. вправо).
Форми назв подій:
• Символ_клавіатури. Функцію action буде викликано кожного разу, коли буде натиснуто клавішу z:
назва_віджета.bind("z", action)
• 'Return' — натискання клавіші Enter.
• 'KeyPress-Up', 'KeyPress-Down', 'KeyPress-Left', 'KeyPress-Right' — натискання клавіш керування курсором.
• 'Button-1' або '1' — натиснута перша (ліва) кнопка миші.
• 'Button-3' або '3' — натиснута третя (права) кнопка миші.
Функція, яку буде викликано при настанні події, повинна приймати один аргумент. Це об’єкт класу Event, що має, серед інших, властивості, які стануть у нагоді при створенні програм: наприклад, щоб змусити об’єкти рухатися по вікну:
• x і y — координати вказівника миші на віджеті;
• keysym — набраний на клавіатурі символ;
• keysym_num — код набраного на клавіатурі символу.
• Символ_клавіатури. Функцію action буде викликано кожного разу, коли буде натиснуто клавішу z:
назва_віджета.bind("z", action)
• 'Return' — натискання клавіші Enter.
• 'KeyPress-Up', 'KeyPress-Down', 'KeyPress-Left', 'KeyPress-Right' — натискання клавіш керування курсором.
• 'Button-1' або '1' — натиснута перша (ліва) кнопка миші.
• 'Button-3' або '3' — натиснута третя (права) кнопка миші.
Функція, яку буде викликано при настанні події, повинна приймати один аргумент. Це об’єкт класу Event, що має, серед інших, властивості, які стануть у нагоді при створенні програм: наприклад, щоб змусити об’єкти рухатися по вікну:
• x і y — координати вказівника миші на віджеті;
• keysym — набраний на клавіатурі символ;
• keysym_num — код набраного на клавіатурі символу.
Приклад:
Запрограмуємо рух круга, застосовуючи всі чотири клавіші зі стрілками. В тілі функції move_oval() запрограмуємо зміну координат об’єкта залежно від того, яке значення передане для аргумента event:
def move_oval(event):
if event.keysym == 'Up': canvas.move(1, 0, –3)
elif event.keysym == 'Down': canvas.move(1, 0, 3)
elif event.keysym == 'Left': canvas.move(1, –3, 0)
elif event.keysym == 'Right': canvas.move(1, 3, 0)
У функції move_oval() перевіряється, чи містить змінна keysym значення 'Up' (вгору). Якщо так, викликається метод canvas.move(1,0, –3), і круг зміщується вгору. Якщо ні, перевіряється, чи містить змінна keysym значення 'Down' (вниз), і, якщо так, робиться крок униз. Так само опрацьовується значення 'Left' (вліво) і 'Right'.
Таким чином, при натисканні на клавішу об’єкт пересувається в заданому напрямку.
Далі повідомимо tkinter, що функцію move_oval() треба застосовувати для обробки натискання будь-якої клавіші:
canvas.bind_all('<Key>', move_oval)
def move_oval(event):
if event.keysym == 'Up': canvas.move(1, 0, –3)
elif event.keysym == 'Down': canvas.move(1, 0, 3)
elif event.keysym == 'Left': canvas.move(1, –3, 0)
elif event.keysym == 'Right': canvas.move(1, 3, 0)
У функції move_oval() перевіряється, чи містить змінна keysym значення 'Up' (вгору). Якщо так, викликається метод canvas.move(1,0, –3), і круг зміщується вгору. Якщо ні, перевіряється, чи містить змінна keysym значення 'Down' (вниз), і, якщо так, робиться крок униз. Так само опрацьовується значення 'Left' (вліво) і 'Right'.
Таким чином, при натисканні на клавішу об’єкт пересувається в заданому напрямку.
Далі повідомимо tkinter, що функцію move_oval() треба застосовувати для обробки натискання будь-якої клавіші:
canvas.bind_all('<Key>', move_oval)
Приклад:
Створимо програму, в якій реалізовано рух кульки по полотну. Об’єкт має змінювати положення у відповідь на натискання клавіш управління курсором, залишаючи слід на полотні.
from tkinter import*
def midpoint(pos): # pos — список координат x1, y1, x2, y2
return[(pos[0]+pos[2])/2, (pos[1]+pos[3])/2]
def move_oval (event):
step = 3 # Величина зміщення
P1=midpoint(canvas.coords(ball)) # Зберігаємо початкові координати
if event.keysym == 'Up': canvas.move(ball, 0, -step)
elif event.keysym == 'Down':canvas.move(ball, 0, step)
elif event.keysym == 'Left':canvas.move(ball, -step, 0)
elif event.keysym == 'Right': canvas.move(ball, step, 0)
elif event.keysym == 'A': canvas.move(ball, -step, -step) # діагональні переміщення
elif event.keysym == 'S': canvas.move(ball, step, -step) # за допомогою
elif event.keysym == 'Z': canvas.move(ball, -step, step) # клавіш A, S, Z, X.
elif event.keysym == 'X': canvas.move(ball, step, step)
canvas.create_line(P1, midpoint(canvas.coords(ball)), fill='blue', width=3)
tk = Tk()
canvas = Canvas(tk, width = 400, height = 400)
canvas.pack()
ball = canvas.create_oval(10, 10, 30, 30, fill = 'red')
canvas.bind_all('<Key>', move_oval) # виклик функції canvas.bind_all
root.mainloop()
def midpoint(pos): # pos — список координат x1, y1, x2, y2
return[(pos[0]+pos[2])/2, (pos[1]+pos[3])/2]
def move_oval (event):
step = 3 # Величина зміщення
P1=midpoint(canvas.coords(ball)) # Зберігаємо початкові координати
if event.keysym == 'Up': canvas.move(ball, 0, -step)
elif event.keysym == 'Down':canvas.move(ball, 0, step)
elif event.keysym == 'Left':canvas.move(ball, -step, 0)
elif event.keysym == 'Right': canvas.move(ball, step, 0)
elif event.keysym == 'A': canvas.move(ball, -step, -step) # діагональні переміщення
elif event.keysym == 'S': canvas.move(ball, step, -step) # за допомогою
elif event.keysym == 'Z': canvas.move(ball, -step, step) # клавіш A, S, Z, X.
elif event.keysym == 'X': canvas.move(ball, step, step)
canvas.create_line(P1, midpoint(canvas.coords(ball)), fill='blue', width=3)
tk = Tk()
canvas = Canvas(tk, width = 400, height = 400)
canvas.pack()
ball = canvas.create_oval(10, 10, 30, 30, fill = 'red')
canvas.bind_all('<Key>', move_oval) # виклик функції canvas.bind_all
root.mainloop()
Проаналізуй код програми.
Ідентифікатор створеного круга зберігатиметься в змінній ball. Слід кульки утворюватимуть відрізки, що сполучають центри послідовних положень круга. Функція midpoint() призначена для обчислення координат центра круга :
У тілі функції move_oval() змінюються координати круга залежно від того, яку клавішу натиснуто (параметр event), а також малюється відрізок між центрами круга в початковому і кінцевому положеннях.
Джерела:
Інформатика : підруч. для 7 кл. закл. загал. серед. освіти / [О. О. Бондаренко, В. В. Ластовецький, О. П. Пилипчук, Є. А. Шестопалов]. — Харків : Вид-во «Ранок», 2020