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
@@ -68,6 +71,12 @@ def set_resolution(self, screen_width: float, screen_height: float):
6871 self ._screen_width_factor = 1.0 / screen_width
6972 self ._screen_height_factor = 1.0 / screen_height
7073
74+ def set_default_color (self , color : flat .Color ):
75+ """
76+ Set which color to use when no other color is provided.
77+ """
78+ self ._default_color = color
79+
7180 @staticmethod
7281 def create_color (red : int , green : int , blue : int , alpha : int = 255 ) -> flat .Color :
7382 return flat .Color (red , green , blue , alpha )
@@ -113,6 +122,30 @@ def team_color(team: int, alt_color: bool = False) -> flat.Color:
113122 def _get_group_id (group_id : str ) -> int :
114123 return hash (str (group_id ).encode ("utf-8" )) % MAX_INT
115124
125+ @contextmanager
126+ def context (self , group_id : str = DEFAULT_GROUP_ID , default_color = None ):
127+ """
128+ Starts rendering as a context usable in with-statements.
129+ After the with-statement the rendering is automatically ended.
130+ Note, the is not possible to have two nested renderings started.
131+
132+ Example:
133+
134+ ```
135+ with renderer.context(default_color=renderer.red):
136+ renderer.draw_line_3d(car.pos, ball.pos)
137+ renderer.draw_line_3d(car.pos, goal.pos)
138+ renderer.draw_line_3d(ball.pos, goal.pos)
139+ ```
140+ """
141+ try :
142+ self .begin_rendering (group_id )
143+ if default_color :
144+ self .set_default_color (default_color )
145+ yield
146+ finally :
147+ self .end_rendering ()
148+
116149 def begin_rendering (self , group_id : str = DEFAULT_GROUP_ID ):
117150 """
118151 Begins a new render group. All render messages added after this call will be part of this group.
@@ -123,6 +156,7 @@ def begin_rendering(self, group_id: str = DEFAULT_GROUP_ID):
123156 )
124157 return
125158
159+ self ._current_renders .clear ()
126160 self ._group_id = Renderer ._get_group_id (group_id )
127161 self ._used_group_ids .add (self ._group_id )
128162
@@ -191,29 +225,29 @@ def draw_line_3d(
191225 self ,
192226 start : flat .RenderAnchor | flat .BallAnchor | flat .CarAnchor | flat .Vector3 ,
193227 end : flat .RenderAnchor | flat .BallAnchor | flat .CarAnchor | flat .Vector3 ,
194- color : flat .Color ,
228+ color : flat .Color | None = None ,
195229 ):
196230 """
197231 Draws a line between two anchors in 3d space.
198232 """
199- self .draw (flat .Line3D (_get_anchor (start ), _get_anchor (end ), color ))
233+ self .draw (flat .Line3D (_get_anchor (start ), _get_anchor (end ), color or self . _default_color ))
200234
201235 def draw_polyline_3d (
202236 self ,
203237 points : Sequence [flat .Vector3 ],
204- color : flat .Color ,
238+ color : flat .Color | None = None ,
205239 ):
206240 """
207241 Draws a line going through each of the provided points.
208242 """
209- self .draw (flat .PolyLine3D (points , color ))
243+ self .draw (flat .PolyLine3D (points , color or self . _default_color ))
210244
211245 def draw_string_3d (
212246 self ,
213247 text : str ,
214248 anchor : flat .RenderAnchor | flat .BallAnchor | flat .CarAnchor | flat .Vector3 ,
215249 scale : float ,
216- foreground : flat .Color ,
250+ foreground : flat .Color | None = None ,
217251 background : flat .Color = flat .Color (a = 0 ),
218252 h_align : flat .TextHAlign = flat .TextHAlign .Left ,
219253 v_align : flat .TextVAlign = flat .TextVAlign .Top ,
@@ -227,7 +261,7 @@ def draw_string_3d(
227261 text ,
228262 _get_anchor (anchor ),
229263 scale ,
230- foreground ,
264+ foreground or self . _default_color ,
231265 background ,
232266 h_align ,
233267 v_align ,
@@ -240,7 +274,7 @@ def draw_string_2d(
240274 x : float ,
241275 y : float ,
242276 scale : float ,
243- foreground : flat .Color ,
277+ foreground : flat .Color | None = None ,
244278 background : flat .Color = flat .Color (a = 0 ),
245279 h_align : flat .TextHAlign = flat .TextHAlign .Left ,
246280 v_align : flat .TextVAlign = flat .TextVAlign .Top ,
@@ -257,7 +291,7 @@ def draw_string_2d(
257291 x * self ._screen_width_factor ,
258292 y * self ._screen_height_factor ,
259293 scale ,
260- foreground ,
294+ foreground or self . _default_color ,
261295 background ,
262296 h_align ,
263297 v_align ,
@@ -270,7 +304,7 @@ def draw_rect_2d(
270304 y : float ,
271305 width : float ,
272306 height : float ,
273- color : flat .Color ,
307+ color : flat .Color | None = None ,
274308 h_align : flat .TextHAlign = flat .TextHAlign .Left ,
275309 v_align : flat .TextVAlign = flat .TextVAlign .Top ,
276310 ):
@@ -286,7 +320,7 @@ def draw_rect_2d(
286320 y * self ._screen_height_factor ,
287321 width * self ._screen_width_factor ,
288322 height * self ._screen_height_factor ,
289- color ,
323+ color or self . _default_color ,
290324 h_align ,
291325 v_align ,
292326 )
@@ -297,7 +331,7 @@ def draw_rect_3d(
297331 anchor : flat .RenderAnchor | flat .BallAnchor | flat .CarAnchor | flat .Vector3 ,
298332 width : float ,
299333 height : float ,
300- color : flat .Color ,
334+ color : flat .Color | None = None ,
301335 h_align : flat .TextHAlign = flat .TextHAlign .Left ,
302336 v_align : flat .TextVAlign = flat .TextVAlign .Top ,
303337 ):
@@ -312,7 +346,7 @@ def draw_rect_3d(
312346 _get_anchor (anchor ),
313347 width * self ._screen_width_factor ,
314348 height * self ._screen_height_factor ,
315- color ,
349+ color or self . _default_color ,
316350 h_align ,
317351 v_align ,
318352 )
0 commit comments