66import math
77from typing import NamedTuple , Callable , TypeVar , Generator
88from enum import Enum
9- from dataclasses import dataclass
109from functools import partialmethod
1110
1211
@@ -54,16 +53,12 @@ def running(self):
5453 return bool (self ._motions )
5554
5655
57- @dataclass
5856class Motion :
59- """
60-
61- """
62- canvas : tk .Canvas
63- id : int
64- end : Coord
65-
66- speed : int = 1
57+ def __init__ (self , canvas : tk .Canvas , id : str , end : Coord , speed : float = 1 ):
58+ self .canvas = canvas
59+ self .id = id
60+ self .end = end
61+ self .speed = speed ** 3
6762
6863 def __iter__ (self ):
6964 return self .start ()
@@ -82,9 +77,8 @@ def start(self) -> Generator[Callable]:
8277 The entry point for generating move commands.
8378 """
8479 self .time = time .time ()
85- self .start = self .current
86- self .distance = self .start .distance (self .end )
87- self .speed = self .speed ** 3
80+ self .beg = self .current
81+ self .distance = self .beg .distance (self .end )
8882 while self .current != self .end :
8983 yield self .move
9084
@@ -102,13 +96,16 @@ def time(self, val):
10296
10397 @property
10498 def increment (self ):
105- mult = (self .time * self .speed ) / self .distance
106- point = (self .end - self .start ) * mult + self .start
107-
108- if point .distance (self .end ) > self .journey :
99+ future = self .future
100+ if future .distance (self .end ) > self .journey :
109101 return self .end - self .current
110102 else :
111- return point - self .current
103+ return future - self .current
104+
105+ @property
106+ def future (self ):
107+ mult = (self .time * self .speed ) / self .distance
108+ return (self .end - self .beg ) * mult + self .beg
112109
113110 @property
114111 def current (self ):
@@ -119,6 +116,56 @@ def journey(self):
119116 return self .current .distance (self .end )
120117
121118
119+ class BounceBall (Motion ):
120+
121+ def kick (self , direction : Point , speed = 8 ):
122+ self .direction = direction
123+ self .speed = speed
124+ self .end = self .direction + self .current
125+
126+ @property
127+ def increment (self ):
128+ self .canvas .update ()
129+ self .end += self .get_bounce ()
130+ return self .future - self .current
131+
132+ def get_bounce (self ):
133+ x1 , y1 , x2 , y2 = self .canvas .bbox (self .id )
134+
135+ bounce = Coord (0 , 0 )
136+ if x1 <= self .bound_x1 :
137+ print ('x1' , x1 , self .bound_x1 )
138+ bounce += Direction .RIGHT
139+ if y1 >= self .bound_y1 :
140+ print ('y1' , y1 , self .bound_y1 )
141+ bounce += Direction .UP
142+ if x2 >= self .bound_x2 :
143+ print ('x2' , x2 , self .bound_x2 )
144+ bounce += Direction .LEFT
145+ if y2 >= self .bound_y2 :
146+ print ('y2' , y2 , self .bound_y2 )
147+ bounce += Direction .DOWN
148+ return bounce
149+
150+ @property
151+ def bound_x1 (self ):
152+ return self .canvas .winfo_x ()
153+
154+ @property
155+ def bound_y1 (self ):
156+ return self .canvas .winfo_y ()
157+
158+ @property
159+ def bound_x2 (self ):
160+ # self.canvas.update()
161+ return self .bound_x1 + self .canvas .winfo_width ()
162+
163+ @property
164+ def bound_y2 (self ):
165+ # self.canvas.update()
166+ return self .bound_y1 + self .canvas .winfo_height ()
167+
168+
122169class Coord (NamedTuple ):
123170 """
124171 Helper class for managing coordinate values.
@@ -149,10 +196,10 @@ class Coord(NamedTuple):
149196 Operand = TypeVar ('Operand' , 'Coord' , float )
150197
151198 def __apply (self , op : Callable , other : Coord .Operand ) -> Coord :
152- if not isinstance (other , self .__class__ ):
153- other = self .__class__ (other , other )
154199 if isinstance (other , Direction ):
155200 other = other .value
201+ elif not isinstance (other , self .__class__ ):
202+ other = self .__class__ (other , other )
156203
157204 x = op (self .x , other .x )
158205 y = op (self .y , other .y )
@@ -183,6 +230,9 @@ def distance(self, other: Coord) -> float:
183230 diff = other - self
184231 return math .hypot (* diff )
185232
233+ def flip (self ):
234+ return Coord (0 , 0 ) - self
235+
186236 __add__ = partialmethod (__apply , operator .add )
187237 __sub__ = partialmethod (__apply , operator .sub )
188238 __mul__ = partialmethod (__apply , operator .mul )
0 commit comments