1+ import math
12from collections .abc import Callable , Sequence
23from typing import Optional
34
@@ -50,6 +51,9 @@ class Renderer:
5051 _group_id : Optional [int ] = None
5152 _current_renders : list [flat .RenderMessage ] = []
5253
54+ _screen_width_factor = 1.0
55+ _screen_height_factor = 1.0
56+
5357 def __init__ (self , game_interface : SocketRelay ):
5458 self ._render_group : Callable [[flat .RenderGroup ], None ] = (
5559 game_interface .send_render_group
@@ -59,10 +63,37 @@ def __init__(self, game_interface: SocketRelay):
5963 game_interface .remove_render_group
6064 )
6165
66+ def set_resolution (self , screen_width : float , screen_height : float ):
67+ """
68+ By default, the renderer uses screen-space coordinates for 2d, e.g. 0.1 is 10% of screen width.
69+ Use this function to declare the screen's size in pixels, if you prefer working in pixel coordinates.
70+ After setting this, `draw_string_2d('Hi', 100, 200, ...)` will draw 'Hi' at pixel coordinates (100, 200).
71+ """
72+ self ._screen_width_factor = 1.0 / screen_width
73+ self ._screen_height_factor = 1.0 / screen_height
74+
6275 @staticmethod
6376 def create_color (red : int , green : int , blue : int , alpha : int = 255 ) -> flat .Color :
6477 return flat .Color (red , green , blue , alpha )
6578
79+ @staticmethod
80+ def create_color_hsv (hue : float , saturation : float , value : float ) -> flat .Color :
81+ i = math .floor (hue * 6 )
82+ f = hue * 6 - i
83+ p = value * (1 - saturation )
84+ q = value * (1 - f * saturation )
85+ t = value * (1 - (1 - f ) * saturation )
86+
87+ match i % 6 :
88+ case 0 : r , g , b = value , t , p
89+ case 1 : r , g , b = q , value , p
90+ case 2 : r , g , b = p , value , t
91+ case 3 : r , g , b = p , q , value
92+ case 4 : r , g , b = t , p , value
93+ case 5 : r , g , b = value , p , q
94+
95+ return flat .Color (math .floor (r * 255 ), math .floor (g * 255 ), math .floor (b * 255 ))
96+
6697 @staticmethod
6798 def team_color (team : int , alt_color : bool = False ) -> flat .Color :
6899 """
@@ -215,13 +246,14 @@ def draw_string_2d(
215246 """
216247 Draws text in 2d space.
217248 X and y uses screen-space coordinates, i.e. 0.1 is 10% of the screen width/height.
249+ Use `set_resolution` to change to pixel coordinates.
218250 Characters of the font are 20 pixels tall and 10 pixels wide when `scale == 1.0`.
219251 """
220252 self .draw (
221253 flat .String2D (
222254 text ,
223- x ,
224- y ,
255+ x * self . _screen_width_factor ,
256+ y * self . _screen_height_factor ,
225257 scale ,
226258 foreground ,
227259 background ,
@@ -243,14 +275,15 @@ def draw_rect_2d(
243275 """
244276 Draws a rectangle anchored in 2d space.
245277 X, y, width, and height uses screen-space coordinates, i.e. 0.1 is 10% of the screen width/height.
278+ Use `set_resolution` to change to pixel coordinates.
246279 """
247280
248281 self .draw (
249282 flat .Rect2D (
250- x ,
251- y ,
252- width ,
253- height ,
283+ x * self . _screen_width_factor ,
284+ y * self . _screen_height_factor ,
285+ width * self . _screen_width_factor ,
286+ height * self . _screen_height_factor ,
254287 color ,
255288 h_align ,
256289 v_align ,
@@ -269,13 +302,14 @@ def draw_rect_3d(
269302 """
270303 Draws a rectangle anchored in 3d space.
271304 Width and height are screen-space sizes, i.e. 0.1 is 10% of the screen width/height.
305+ Use `set_resolution` to change to pixel coordinates.
272306 The size does not change based on distance to the camera.
273307 """
274308 self .draw (
275309 flat .Rect3D (
276310 _get_anchor (anchor ),
277- width ,
278- height ,
311+ width * self . _screen_width_factor ,
312+ height * self . _screen_height_factor ,
279313 color ,
280314 h_align ,
281315 v_align ,
0 commit comments