1 from __future__
import division
2 from geom
import vector
, line
, ellipse
16 def __init__ (self
, owner
):
18 self
.oval
= ellipse ()
28 def jump (self
, v
, dt
, key
):
34 if self
.__airtime
is None:
36 seg2
= seg1
.transform (self
.oval
)
38 if abs (seg2
.dist () - 1) < JUMP_RANGE
:
39 self
.vel
+= seg1
.perp ().normed (v
* dt
)
41 elif self
.__airtime
< MAX_AIRTIME
:
42 self
.vel
+= seg1
.perp ().normed (v
* dt
)
44 elif self
.__airtime
is not None:
47 self
.vel
+= seg2
.normed (v
* (self
.__airtime
- MAX_AIRTIME
) / 2)
58 def update (self
, dt
):
59 from copy
import deepcopy
62 surf
, contact
, frac
= None, None, 1
64 oval
= deepcopy (self
.oval
)
65 oval
.pos
+= dt
* self
.vel
66 oval
.angle
+= dt
* self
.spin
68 for w
in self
.owner
.walls
:
69 line1
= w
.seg
.transform (self
.oval
)
70 line2
= w
.seg
.transform (oval
)
75 if dist2
> 1 + TOLERANCE
or dist2
> dist1
:
76 # actor is above wall or moving up
79 # trajectories of the endpoints
80 line3
= line (line1
.p1
, line2
.p1
)
81 line4
= line (line1
.p2
, line2
.p2
)
87 # actor is beyond the left edge
89 elif dist1
> 0 and dist3
> -1:
90 # actor might touch the left edge
91 units
= [t
for t
in line3
.units () if 0 <= t
< frac
]
95 surf
, contact
, frac
= w
, line3 (t
), t
96 except ZeroDivisionError:
100 dist4
= line4
.dist ()
103 # actor is beyond the right edge
105 elif dist1
> 0 and dist4
< 1:
106 # actor might touch the right edge
107 units
= [t
for t
in line4
.units () if 0 <= t
< frac
]
111 surf
, contact
, frac
= w
, line4 (t
), t
112 except ZeroDivisionError:
115 if dist1
< 1 - TOLERANCE
:
119 # actor is in the middle
120 t
= (1 + TOLERANCE
- dist1
) / (dist2
- dist1
)
123 tline
= line (line3 (t
), line4 (t
))
124 tpoint
= tline
.p1
.proj (tline
.perp ())
126 if (tpoint
.cross (tline
.p1
).z
< 0 and
127 tpoint
.cross (tline
.p2
).z
> 0):
128 # actor is definitely touching wall
129 surf
, contact
, frac
= w
, tpoint
, t
130 except ZeroDivisionError:
133 self
.oval
.pos
+= frac
* dt
* self
.vel
134 self
.oval
.angle
+= frac
* dt
* self
.spin
136 if isinstance (surf
, wall
):
138 dir = self
.vel
.proj (surf
.seg
.dir ())
140 perp
= surf
.seg
.perp ()
141 self
.oval
.pos
+= perp
.normed (EPSILON
)
142 perp
= self
.vel
.proj (perp
)
144 perp
= -surf
.bounce
* perp
146 if perp
.normsq () < MIN_BOUNCE
* MIN_BOUNCE
:
149 if speed
< surf
.stiction
* norm
:
152 speed
-= surf
.friction
* norm
155 dir = dir.normed (speed
)
156 except ZeroDivisionError:
159 perp
.x
, perp
.y
= 0, 0
162 self
.vel
= perp
+ dir
163 actor
.update (self
, dt
* (1 - TOLERANCE
- frac
))
164 except ZeroDivisionError:
168 raise NotImplementedError ('actor.render')