Создадим двигающийся мячик:
from tkinter import * from random import randrange as rnd, choice root = Tk() root.geometry('600x600+100+100') canv = Canvas(bg='white') canv.pack(fill=BOTH,expand=1) # начальная скорость vx = 2 vy = 1 # размер r = 10 # начальное положение (центр окна) x = 300 y = 300 def update(): global x,y # без этого будет ошибка "local variable 'x' referenced before assignment" # изменить положение x += vx y += vy # удалить мячик canv.delete('ball') # нарисовать в новом месте canv.create_oval(x-r,y-r,x+r,y+r,fill='orange', tag = 'ball') # повторить это через 30 мс (т.е. 33 раза в секунду) root.after(30,update) update() # без этой строчки перемещение не начнется root.mainloop()
Добавим отражение от стен. Для этого, после изменения координат добавим проверку на пересечение границы
if x > 550 or x < 50: # если дошел до правой или левой границы vx *= -1 # развернуться if y > 550 or y < 50: # если дошел до нижней или верхней границы vy *= -1 # развернуться
Запустите программу.
Должна появится ошибка:
Подумайте, что нужно сделать, чтобы исправить программу.
Пока мячик летает «в невесомости». Добавим тяготение (притяжение к нижней части экрана). Для этого каждый кадр будем добавлять к скорости 1:
x += vx y += vy vy += 1 if x > 550 or x < 50: vx *= -1 if y > 550 or y < 50: vy *= -1
Для того, чтобы мяк прыгал все ниже и ниже, нужно при касании нижней части экрана изменять скорость с потерей:
if y > 550 or y < 50: vy *= -0.6
Однако, этого мало: мячик трясется и скользит.
Исправим это:
from tkinter import * from random import randrange as rnd, choice root = Tk() root.geometry('600x600+100+100') canv = Canvas(bg='white') canv.pack(fill=BOTH,expand=1) vx = 2 vy = 1 r = 10 x = 300 y = 300 def update(): global x,y,vx,vy x += vx y += vy if x > 550 or x < 50: vx *= -1 if y > 550: # убрать проверку верхней границы, пусть улетает, все равно вернется vy *= -0.6 y = 550 vx *= 0.6 vy += 1 canv.delete('ball') canv.create_oval(x-r,y-r,x+r,y+r,fill='orange', tag = 'ball') root.after(30,update) update() root.mainloop()
А теперь будем «пинать» мячик вверх по щелчку мыши. Добавьте следующий код:
def click(event): global vy vy = -20 canv.bind('<1>',click)
Более интересный вариант «пинка»: направлять мяч в сторону мыши:
from tkinter import * from random import randrange as rnd, choice root = Tk() root.geometry('600x600+100+100') canv = Canvas(bg='white') canv.pack(fill=BOTH,expand=1) vx = 2 vy = 1 r = 10 x = 300 y = 300 canv.create_rectangle(50-r,50-r,550+r,550+r) def update(): global x,y,vx,vy x += vx y += vy if x > 550: vx *= -1 x = 550 # чтобы изображение мяча не выходилао за рамку if x < 50: vx *= -1 x = 50 # чтобы изображение мяча не выходилао за рамку if y > 550: vy *= -0.6 y = 550 vx *= 0.6 vy += 1 canv.delete('ball') canv.create_oval(x-r,y-r,x+r,y+r,fill='orange', tag = 'ball') root.after(30,update) def click(event): global vy,vx dx = event.x - x dy = event.y - y if dx != 0 and dy != 0: vx = 20*(dx/abs(dx)) vy = 20*(dy/abs(dy)) canv.bind('<1>',click) update() root.mainloop()