Прыгающий мячик

Создадим двигающийся мячик:

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          # развернуться

Запустите программу.
Должна появится ошибка:
snimok-ekrana-ot-2016-10-25-14-35-35

Подумайте, что нужно сделать, чтобы исправить программу.

Пока мячик летает «в невесомости». Добавим тяготение (притяжение к нижней части экрана). Для этого каждый кадр будем добавлять к скорости 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()

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *