add anim1.py
This commit is contained in:
parent
77b0ef184d
commit
47c826a5f8
131
mod_graph/anim1.py
Normal file
131
mod_graph/anim1.py
Normal file
@ -0,0 +1,131 @@
|
||||
"""
|
||||
Анимация квадратов
|
||||
https://stepik.org/lesson/468998/step/4?unit=459819
|
||||
|
||||
3: "Квадрат двигается справа налево"
|
||||
4: "Два квадрата двигаются в противоположных направлениях"
|
||||
|
||||
Библиотека graph: https://kpolyakov.spb.ru/download/pygraph.zip
|
||||
"""
|
||||
|
||||
from graph import *
|
||||
|
||||
from typing import NamedTuple
|
||||
|
||||
|
||||
class Point(NamedTuple):
|
||||
"""
|
||||
Вспомогательный класс для упрощения работы с координатами (сложение)
|
||||
"""
|
||||
|
||||
x: int | float
|
||||
y: int | float
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self.__class__(self.x + other.x, self.y + other.y)
|
||||
if isinstance(other, (int, float)):
|
||||
return self.__class__(self.x + other, self.y + other)
|
||||
return NotImplemented
|
||||
|
||||
|
||||
def make_title(n, name, start, font=("Arial", 15), n_color="indigo"):
|
||||
pos = Point(10, 20) + start
|
||||
n_width = Point(35, 0)
|
||||
l1 = label(f"«{n}»", *pos, font=font, foreground=n_color)
|
||||
l2 = label(f": {name}", *(pos + n_width), font=font)
|
||||
return l1, l2
|
||||
|
||||
|
||||
def square_left_to_right(start_pos=None):
|
||||
start_pos = start_pos or Point(0, 0)
|
||||
|
||||
make_title(3, "Квадрат двигается справа налево", start_pos)
|
||||
title_height = Point(0, 60)
|
||||
|
||||
start_pos = start_pos + title_height
|
||||
scene_sz = Point(300, 300)
|
||||
box_sz = Point(40, 40)
|
||||
box_offset = Point(220, 5)
|
||||
|
||||
brushColor("Blue")
|
||||
rectangle(*start_pos, *(start_pos + scene_sz)) # Размер фона
|
||||
brushColor("Yellow")
|
||||
obj = rectangle(
|
||||
*(start_pos + box_offset), *(start_pos + box_offset + box_sz)
|
||||
) # Создаем объект, который у нас в виде прямоугольника
|
||||
|
||||
data = {"done": False} # состояние объекта для контроля таймера из вне функции
|
||||
|
||||
def update(): # Создаем процедуру, которая отвечает за анимацию
|
||||
# Она будет перемещать объект obj по оси x на -5 по оси y на 0 пикселей
|
||||
moveObjectBy(obj, -5, 0)
|
||||
if xCoord(obj) <= 1: # Если x координата меньше 1
|
||||
killTimer(timer)
|
||||
data["done"] = True
|
||||
|
||||
timer = onTimer(update, 40) # Каждые 50 мс будет запускаться процедура update
|
||||
return (data,)
|
||||
|
||||
|
||||
def two_squares(start_pos=None):
|
||||
start_pos = start_pos or Point(0, 0)
|
||||
|
||||
make_title(4, "Два квадрата двигаются в\nпротивоположных направлениях", start_pos)
|
||||
title_height = Point(0, 90)
|
||||
|
||||
start_pos = start_pos + title_height
|
||||
scene_sz = Point(300, 300)
|
||||
box_sz = Point(40, 40)
|
||||
box1_offset = Point(220, 5)
|
||||
box2_offset = Point(0, 250)
|
||||
|
||||
brushColor("Blue")
|
||||
rectangle(*start_pos, *(start_pos + scene_sz))
|
||||
brushColor("Yellow")
|
||||
box1 = rectangle(*(start_pos + box1_offset), *(start_pos + box1_offset + box_sz))
|
||||
box2 = rectangle(*(start_pos + box2_offset), *(start_pos + box2_offset + box_sz))
|
||||
timer1 = None
|
||||
timer2 = None
|
||||
|
||||
data1 = {"done": False}
|
||||
data2 = {"done": False}
|
||||
|
||||
def update_box1():
|
||||
moveObjectBy(box1, -5, 0)
|
||||
if xCoord(box1) <= 1:
|
||||
killTimer(timer1)
|
||||
data1["done"] = True
|
||||
|
||||
def update_box2():
|
||||
moveObjectBy(box2, 5, 0)
|
||||
if xCoord(box2) >= scene_sz.x - box_sz.x:
|
||||
killTimer(timer2)
|
||||
data2["done"] = True
|
||||
|
||||
timer1 = onTimer(update_box1, 40)
|
||||
timer2 = onTimer(update_box2, 40)
|
||||
|
||||
return data1, data2
|
||||
|
||||
|
||||
def main():
|
||||
canvasSize(400, 800)
|
||||
state = [
|
||||
*square_left_to_right(),
|
||||
*two_squares(Point(0, 350))
|
||||
]
|
||||
|
||||
watch_timer = None
|
||||
|
||||
# выход по завершении всех анимаций
|
||||
def watch_done():
|
||||
if all(x["done"] for x in state):
|
||||
killTimer(watch_timer)
|
||||
close()
|
||||
|
||||
watch_timer = onTimer(watch_done, 6000)
|
||||
run()
|
||||
|
||||
|
||||
main()
|
Loading…
Reference in New Issue
Block a user