11import math
22from collections .abc import Callable , Sequence
3+ from contextlib import contextmanager
34from typing import Optional
45
56from rlbot import flat
@@ -51,6 +52,8 @@ class Renderer:
5152 _group_id : Optional [int ] = None
5253 _current_renders : list [flat .RenderMessage ] = []
5354
55+ _default_color = white
56+
5457 _screen_width_factor = 1.0
5558 _screen_height_factor = 1.0
5659
@@ -72,6 +75,12 @@ def set_resolution(self, screen_width: float, screen_height: float):
7275 self ._screen_width_factor = 1.0 / screen_width
7376 self ._screen_height_factor = 1.0 / screen_height
7477
78+ def set_default_color (self , color : flat .Color ):
79+ """
80+ Set which color to use when no other color is provided.
81+ """
82+ self ._default_color = color
83+
7584 @staticmethod
7685 def create_color (red : int , green : int , blue : int , alpha : int = 255 ) -> flat .Color :
7786 return flat .Color (red , green , blue , alpha )
@@ -111,6 +120,30 @@ def team_color(team: int, alt_color: bool = False) -> flat.Color:
111120 def _get_group_id (group_id : str ) -> int :
112121 return hash (str (group_id ).encode ("utf-8" )) % MAX_INT
113122
123+ @contextmanager
124+ def context (self , group_id : str = DEFAULT_GROUP_ID , default_color = None ):
125+ """
126+ Starts rendering as a context usable in with-statements.
127+ After the with-statement the rendering is automatically ended.
128+ Note, the is not possible to have two nested renderings started.
129+
130+ Example:
131+
132+ ```
133+ with renderer.context(default_color=renderer.red):
134+ renderer.draw_line_3d(car.pos, ball.pos)
135+ renderer.draw_line_3d(car.pos, goal.pos)
136+ renderer.draw_line_3d(ball.pos, goal.pos)
137+ ```
138+ """
139+ try :
140+ self .begin_rendering (group_id )
141+ if default_color :
142+ self .set_default_color (default_color )
143+ yield
144+ finally :
145+ self .end_rendering ()
146+
114147 def begin_rendering (self , group_id : str = DEFAULT_GROUP_ID ):
115148 """
116149 Begins a new render group. All render messages added after this call will be part of this group.
@@ -189,29 +222,29 @@ def draw_line_3d(
189222 self ,
190223 start : flat .RenderAnchor | flat .BallAnchor | flat .CarAnchor | flat .Vector3 ,
191224 end : flat .RenderAnchor | flat .BallAnchor | flat .CarAnchor | flat .Vector3 ,
192- color : flat .Color ,
225+ color : flat .Color | None = None ,
193226 ):
194227 """
195228 Draws a line between two anchors in 3d space.
196229 """
197- self .draw (flat .Line3D (_get_anchor (start ), _get_anchor (end ), color ))
230+ self .draw (flat .Line3D (_get_anchor (start ), _get_anchor (end ), color or self . _default_color ))
198231
199232 def draw_polyline_3d (
200233 self ,
201234 points : Sequence [flat .Vector3 ],
202- color : flat .Color ,
235+ color : flat .Color | None = None ,
203236 ):
204237 """
205238 Draws a line going through each of the provided points.
206239 """
207- self .draw (flat .PolyLine3D (points , color ))
240+ self .draw (flat .PolyLine3D (points , color or self . _default_color ))
208241
209242 def draw_string_3d (
210243 self ,
211244 text : str ,
212245 anchor : flat .RenderAnchor | flat .BallAnchor | flat .CarAnchor | flat .Vector3 ,
213246 scale : float ,
214- foreground : flat .Color ,
247+ foreground : flat .Color | None = None ,
215248 background : flat .Color = flat .Color (a = 0 ),
216249 h_align : flat .TextHAlign = flat .TextHAlign .Left ,
217250 v_align : flat .TextVAlign = flat .TextVAlign .Top ,
@@ -225,7 +258,7 @@ def draw_string_3d(
225258 text ,
226259 _get_anchor (anchor ),
227260 scale ,
228- foreground ,
261+ foreground or self . _default_color ,
229262 background ,
230263 h_align ,
231264 v_align ,
@@ -238,7 +271,7 @@ def draw_string_2d(
238271 x : float ,
239272 y : float ,
240273 scale : float ,
241- foreground : flat .Color ,
274+ foreground : flat .Color | None = None ,
242275 background : flat .Color = flat .Color (a = 0 ),
243276 h_align : flat .TextHAlign = flat .TextHAlign .Left ,
244277 v_align : flat .TextVAlign = flat .TextVAlign .Top ,
@@ -255,7 +288,7 @@ def draw_string_2d(
255288 x * self ._screen_width_factor ,
256289 y * self ._screen_height_factor ,
257290 scale ,
258- foreground ,
291+ foreground or self . _default_color ,
259292 background ,
260293 h_align ,
261294 v_align ,
@@ -268,7 +301,7 @@ def draw_rect_2d(
268301 y : float ,
269302 width : float ,
270303 height : float ,
271- color : flat .Color ,
304+ color : flat .Color | None = None ,
272305 h_align : flat .TextHAlign = flat .TextHAlign .Left ,
273306 v_align : flat .TextVAlign = flat .TextVAlign .Top ,
274307 ):
@@ -284,7 +317,7 @@ def draw_rect_2d(
284317 y * self ._screen_height_factor ,
285318 width * self ._screen_width_factor ,
286319 height * self ._screen_height_factor ,
287- color ,
320+ color or self . _default_color ,
288321 h_align ,
289322 v_align ,
290323 )
@@ -295,7 +328,7 @@ def draw_rect_3d(
295328 anchor : flat .RenderAnchor | flat .BallAnchor | flat .CarAnchor | flat .Vector3 ,
296329 width : float ,
297330 height : float ,
298- color : flat .Color ,
331+ color : flat .Color | None = None ,
299332 h_align : flat .TextHAlign = flat .TextHAlign .Left ,
300333 v_align : flat .TextVAlign = flat .TextVAlign .Top ,
301334 ):
@@ -310,7 +343,7 @@ def draw_rect_3d(
310343 _get_anchor (anchor ),
311344 width * self ._screen_width_factor ,
312345 height * self ._screen_height_factor ,
313- color ,
346+ color or self . _default_color ,
314347 h_align ,
315348 v_align ,
316349 )
0 commit comments