py_stepik/mod_graph/anim2_control.py
2024-03-23 22:58:57 +03:00

155 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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()