From 0813eaa3c9e990f375b1b337812eedfc4a567d88 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sat, 23 Mar 2024 22:58:57 +0300 Subject: [PATCH] add anim2 --- mod_graph/anim2_control.py | 154 +++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 mod_graph/anim2_control.py diff --git a/mod_graph/anim2_control.py b/mod_graph/anim2_control.py new file mode 100644 index 0000000..fcc82e0 --- /dev/null +++ b/mod_graph/anim2_control.py @@ -0,0 +1,154 @@ +""" + https://stepik.org/lesson/468998/step/7?unit=459819 + + 3: "Квадрат в самом начале стоит в правом нижнем углу и двигается при нажатии + стрелок только вверх или влево" + 4: "Квадрат двигается при нажатии стрелок но не может выйти за пределы экрана" + + Библиотека graph: https://kpolyakov.spb.ru/download/pygraph.zip +""" + +import graph +from graph import * + +from typing import NamedTuple +import types + +consts = types.SimpleNamespace() +consts.VK_Q = 81 + + +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 __sub__(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 + + +data = {"delta": Point(0, 0), "callbacks": []} + + +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_up_left(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(260, 260) + + brushColor("Blue") + rectangle(*start_pos, *(start_pos + scene_sz)) + brushColor("Yellow") + + box_pos = start_pos + box_offset + obj = rectangle(*box_pos, *(box_pos + box_sz)) + + def update(): + delta = data["delta"] + coord = Point(xCoord(obj), yCoord(obj)) - start_pos + if ( + coord.x + delta.x < 0 + or coord.x + box_sz.x + delta.x > scene_sz.x + or coord.y + delta.y < 0 + or coord.y + box_sz.y + delta.y > scene_sz.y + or delta.x > 0 + or delta.y > 0 + ): + return + moveObjectBy(obj, delta.x, delta.y) + + data.setdefault("callbacks", []).append(update) + + +def square_free_move(start_pos=None): + start_pos = start_pos or Point(0, 0) + + make_title(4, "Квадрат двигается свободно", 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(130, 130) + + brushColor("Blue") + rectangle(*start_pos, *(start_pos + scene_sz)) + brushColor("Yellow") + + box_pos = start_pos + box_offset + obj = rectangle(*box_pos, *(box_pos + box_sz)) + + def update(): + delta = data["delta"] + coord = Point(xCoord(obj), yCoord(obj)) - start_pos + if ( + coord.x + delta.x < 0 + or coord.x + box_sz.x + delta.x > scene_sz.x + or coord.y + delta.y < 0 + or coord.y + box_sz.y + delta.y > scene_sz.y + ): + return + moveObjectBy(obj, delta.x, delta.y) + + data.setdefault("callbacks", []).append(update) + + +def keyPressed(event): + match event.keycode: + case graph.VK_LEFT: + data["delta"] = Point(-5, 0) + case graph.VK_RIGHT: + data["delta"] = Point(5, 0) + case graph.VK_UP: + data["delta"] = Point(0, -5) + case graph.VK_DOWN: + data["delta"] = Point(0, 5) + case consts.VK_Q | graph.VK_ESCAPE: + killTimer(data["update_timer"]) + close() + + +def update(): + for callback in data["callbacks"]: + callback() + data["delta"] = Point(0, 0) + + +def main(): + canvasSize(460, 800) + square_up_left() + square_free_move(Point(0, 350)) + + data["update_timer"] = onTimer(update, 40) + onKey(keyPressed) + run() + + +main()