e2D 1.3.8__py3-none-any.whl → 1.3.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
e2D/envs.py CHANGED
@@ -25,7 +25,7 @@ pg.font.init()
25
25
  font_arial_16 = pg.font.SysFont("Arial", 16)
26
26
  font_arial_32 = pg.font.SysFont("Arial", 32)
27
27
  font_arial_64 = pg.font.SysFont("Arial", 64)
28
- my_arial_font_size = lambda size: pg.font.SysFont("Arial", size)
28
+ create_arial_font_size = lambda size: pg.font.SysFont("Arial", size)
29
29
 
30
30
  TEXT_FIXED_SIDES_TOP_LEFT = 0
31
31
  TEXT_FIXED_SIDES_TOP_MIDDLE = 1
e2D/plots.py CHANGED
@@ -9,7 +9,7 @@ def no_error_complex_function(function, args) -> V2|Vector2D:
9
9
  sign = lambda value: -1 if value < 0 else (1 if value > 0 else 0)
10
10
 
11
11
  class Function:
12
- def __init__(self, function, color) -> None:
12
+ def __init__(self, function, color:list[float]|tuple[float,float,float]=(255,255,255)) -> None:
13
13
  self.plot : Plot
14
14
  self.color = color
15
15
  self.function = function
@@ -28,9 +28,11 @@ class Function:
28
28
  self.points = self.get_points()
29
29
  self.render()
30
30
 
31
+ def get_derivative(self, delta:float=.01, color:None|list[float]|tuple[float,float,float]=None) -> Function:
32
+ return Function(lambda x,y: (self.function(x + delta, y) - self.function(x,y))/delta - y, color if color != None else self.color)
33
+
31
34
  def render(self) -> None:
32
35
  self.__layer_surface__.fill((0,0,0,0))
33
- # print(self.plot.dra)
34
36
  offset = self.plot.dragging - self.plot.start_dragging if (self.plot.dragging != None) and (not self.plot.settings.get("use_real_time_rendering")) else V2z
35
37
  if any(x < 1 for x in self.plot.scale):
36
38
  # draw rects
@@ -85,34 +87,56 @@ class __PlotSettings__:
85
87
  def __init__(self, plot:Plot) -> None:
86
88
  self.plot = plot
87
89
  self.settings :dict= {
88
- "use_real_time_rendering" : True,
89
- "show_corners_coords" : True,
90
-
91
- "use_inter_pixel_correction" : True,
92
-
93
- "show_zoom_info": True,
94
- "top_left_info_position" : self.plot.position + V2(20, 100),
95
- "info_spacing" : V2(0, 32),
96
- "info_precision" : 2,
97
-
98
- "distance_to_axis_for_scalar_zoom" : 10,
99
-
100
- "show_x_axis" : True,
101
- "show_y_axis" : True,
102
- "bg_color" : (25, 25, 25),
103
- "axes_default_color" : (100, 100, 100),
104
- "x_axis_color" : None,
105
- "y_axis_color" : None,
106
- "change_axes_colors_on_mouse_hover" : True,
107
- "mouse_hover_axes_color" : (200, 200, 200),
108
-
109
- "axes_default_width" : 5,
110
- "x_axis_width" : None,
111
- "y_axis_width" : None,
112
-
113
- "show_cursor_coords" : False,
114
-
115
- "zoom_on_center" : False,
90
+ # axes
91
+ "distance_to_axis_for_scalar_zoom" : 10,
92
+
93
+ # cursor
94
+ "show_cursor_coords" : False,
95
+ "zoom_on_center" : False,
96
+
97
+ # plot visual options
98
+ # plot system
99
+ "use_inter_pixel_correction" : True,
100
+ "use_real_time_rendering" : True,
101
+
102
+ # axes
103
+ "change_axes_colors_on_mouse_hover" : True,
104
+ "mouse_hover_axes_color" : rgb(200, 200, 200),
105
+ "show_axes" : True,
106
+ "show_x_axis" : True,
107
+ "show_y_axis" : True,
108
+ "axes_default_color" : rgb(100, 100, 100),
109
+ "x_axis_color" : None,
110
+ "y_axis_color" : None,
111
+ "axes_default_width" : 5,
112
+ "x_axis_width" : None,
113
+ "y_axis_width" : None,
114
+ "render_axes_on_top" : False,
115
+
116
+ # grid
117
+ "show_grid" : True,
118
+ "grid_step" : V2(PI, 1),
119
+ "grid_color" : rgb(17, 65, 68),
120
+ "grid_width" : 1,
121
+
122
+ # pointer
123
+ "show_pointer" : True,
124
+ "pointer_radius" : 15,
125
+ "pointer_color" : rgb(255, 255, 255),
126
+
127
+ #rect
128
+ "render_bg" : True,
129
+ "bg_color" : rgb(28, 29, 34),
130
+ "draw_rect" : True,
131
+ "rect_color" : rgb(255, 255, 255),
132
+ "rect_width" : 5,
133
+ "show_corners_coords" : True,
134
+
135
+ # info options
136
+ "show_zoom_info": True,
137
+ "top_left_info_position" : self.plot.position + V2(20, 100),
138
+ "info_interline_space" : V2(0, 32),
139
+ "info_precision" : 2,
116
140
  }
117
141
 
118
142
  def print_current_settings(self) -> None:
@@ -136,9 +160,8 @@ class __PlotSettings__:
136
160
  if not (key in self.settings): raise ValueError(f"The key [{key}] does not exist...")
137
161
  self.settings[key] = new_value
138
162
 
139
- def multiple_set(self, keys:list[str], new_values:list) -> None:
140
- for key, new_value in zip(keys, new_values):
141
- self.set(key, new_value)
163
+ def multiple_set(self, new_key_and_values_dict:dict) -> None:
164
+ self.settings.update(new_key_and_values_dict)
142
165
 
143
166
  def get(self, key:str) -> bool|V2|Vector2D|int|float:
144
167
  return self.settings[key]
@@ -147,8 +170,7 @@ class __PlotSettings__:
147
170
  return [self.get(key) for key in keys]
148
171
 
149
172
  class Plot:
150
- __top_left_multiplier__ = V2(1, -1)
151
- __bottom_right_multiplier__ = V2(1, -1)
173
+ __y_axis_multiplier__ = V2(1, -1)
152
174
  def __init__(self, rootEnv:"RootEnv", plot_position:V2|Vector2D, plot_size:V2|Vector2D, top_left_plot_coord:V2|Vector2D, bottom_right_plot_coord: V2|Vector2D, scale:V2|Vector2D=V2one) -> None:
153
175
  self.rootEnv = rootEnv
154
176
 
@@ -167,15 +189,15 @@ class Plot:
167
189
 
168
190
  self.functions :list[Function]= []
169
191
 
170
- self.canvas = pg.Surface(self.size())
192
+ self.canvas = pg.Surface(self.size(), pg.SRCALPHA, 32).convert_alpha()
171
193
  self.dragging = None
172
194
  self.start_dragging = V2z
173
195
  self.is_mouse_in_rect = False
174
196
  self.mouse_scalar = V2one.copy()
175
197
 
176
198
  def set_borders_by_position_and_zoom(self) -> None:
177
- self.top_left_plot_coord = self.current_offset - (.5**(.1*self.current_zoom)) * self.__top_left_multiplier__
178
- self.bottom_right_plot_coord = self.current_offset + (.5**(.1*self.current_zoom)) * self.__bottom_right_multiplier__
199
+ self.top_left_plot_coord = self.current_offset - (.5**(.1*self.current_zoom)) * self.__y_axis_multiplier__
200
+ self.bottom_right_plot_coord = self.current_offset + (.5**(.1*self.current_zoom)) * self.__y_axis_multiplier__
179
201
  self.top_left_x, self.top_left_y = self.top_left_plot_coord
180
202
  self.bottom_right_x, self.bottom_right_y = self.bottom_right_plot_coord
181
203
 
@@ -202,17 +224,35 @@ class Plot:
202
224
  return (real_position - self.position) * (self.bottom_right_plot_coord - self.top_left_plot_coord) / self.size + self.top_left_plot_coord
203
225
 
204
226
  def render(self) -> None:
205
- self.canvas.fill(self.settings.get("bg_color")) #type: ignore
206
-
227
+ # fill canvas with alpha zero color
228
+ self.canvas.fill((0,0,0,0))
229
+
230
+ # draw grid
231
+ if self.settings.get("show_grid"):
232
+ grid_step = self.settings.get("grid_step")
233
+ grid_color = self.settings.get("grid_color")
234
+ grid_width = self.settings.get("grid_width")
235
+ clamped_top_left = grid_step * (self.top_left_plot_coord / grid_step).__ceil__()
236
+ clamped_bottom_right = grid_step * (self.bottom_right_plot_coord / grid_step).__ceil__()
237
+ for x_value in np.arange(clamped_top_left.x, clamped_bottom_right.x, grid_step.x):
238
+ pg.draw.line( self.canvas, grid_color, self.__plot2real__((x_value, self.top_left_y))(), self.__plot2real__((x_value, self.bottom_right_y))(), grid_width)
239
+ for y_value in np.arange(clamped_bottom_right.y, clamped_top_left.y, grid_step.y):
240
+ pg.draw.line(self.canvas, grid_color, self.__plot2real__((self.top_left_x, y_value))(), self.__plot2real__((self.bottom_right_x, y_value))(), grid_width)
241
+
242
+ # draw functions
207
243
  for function in self.functions: function.draw()
208
244
 
209
- pg.draw.rect(self.canvas, (255,255,255), V2z() + self.size(), 5) #type: ignore
245
+ # draw rect, pointer and corner coords
246
+ if self.settings.get("draw_rect"):
247
+ pg.draw.rect(self.canvas, self.settings.get("rect_color"), V2z() + self.size(), self.settings.get("rect_width"))
210
248
 
211
- center = self.size * .5
212
- aimer_radius = 15
213
- pg.draw.line(self.canvas, (100,100,100), (center + aimer_radius)(), (center - aimer_radius)(), 1)
214
- pg.draw.line(self.canvas, (100,100,100), (center + self.__top_left_multiplier__ * aimer_radius)(), (center - self.__top_left_multiplier__ * aimer_radius)(), 1)
215
- pg.draw.circle(self.canvas, (100,100,100), (self.size * .5)(), 15, 1)
249
+ if self.settings.get("show_pointer"):
250
+ center = self.size * .5
251
+ aimer_radius = self.settings.get("pointer_radius")
252
+ pointer_color = self.settings.get("pointer_color")
253
+ pg.draw.line(self.canvas, pointer_color, (center + aimer_radius)(), (center - aimer_radius)(), 1)
254
+ pg.draw.line(self.canvas, pointer_color, (center + self.__y_axis_multiplier__ * aimer_radius)(), (center - self.__y_axis_multiplier__ * aimer_radius)(), 1)
255
+ pg.draw.circle(self.canvas, pointer_color, (self.size * .5)(), 15, 1)
216
256
 
217
257
  if self.settings.get("show_corners_coords"):
218
258
  self.rootEnv.print(str(self.top_left_plot_coord), V2z.copy(), bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
@@ -221,12 +261,14 @@ class Plot:
221
261
  self.rootEnv.print(str(V2(self.bottom_right_plot_coord.x, self.top_left_plot_coord.y)), self.size * V2(1, 0), fixed_sides=TEXT_FIXED_SIDES_TOP_RIGHT, bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
222
262
 
223
263
  def update(self) -> None:
264
+ # update mouse and center positions
224
265
  self.plot_mouse_position = self.__real2plot__(self.rootEnv.mouse.position)
225
266
  self.plot_center_real_position = self.__plot2real__(V2z) + self.position
226
267
 
227
268
  self.is_mouse_in_rect = self.position.x < self.rootEnv.mouse.position.x < self.position.x + self.size.x and \
228
269
  self.position.y < self.rootEnv.mouse.position.y < self.position.y + self.size.y
229
270
 
271
+ # render the functions when i stop dragging (when i release the left mouse key)
230
272
  if self.rootEnv.mouse.just_released[0] and self.dragging != None:
231
273
  self.dragging = None
232
274
  self.update_grid(True)
@@ -235,15 +277,19 @@ class Plot:
235
277
  self.render()
236
278
 
237
279
  if self.is_mouse_in_rect:
280
+ # mouse scalar is needed for checking if the mouse is hovering an axis, in case it is the opposite one zoom value has to be multiplied by 0 so nullifying it.
238
281
  self.mouse_scalar = V2(0 if abs(self.plot_center_real_position.x - self.rootEnv.mouse.position.x) < self.settings.get("distance_to_axis_for_scalar_zoom") else 1, 0 if abs(self.plot_center_real_position.y - self.rootEnv.mouse.position.y) < self.settings.get("distance_to_axis_for_scalar_zoom") else 1) #type: ignore
239
282
  if self.mouse_scalar.x == self.mouse_scalar.y == 0: self.mouse_scalar = V2one
240
283
  for event in self.rootEnv.events:
241
284
  if event.type == pg.MOUSEWHEEL:
242
285
  if self.settings.get("zoom_on_center"):
286
+ # this will always zoom exactly in the middle of the canvas, according to the current plot offset
243
287
  self.current_zoom += event.y * self.mouse_scalar
244
288
  else:
289
+ # this will get the pre plot mouse position, calculate the zoom and with the "after" mouse position calculate the offset that i will add to the current plot offset
245
290
  pre = self.__real2plot__(self.rootEnv.mouse.position)
246
291
  self.current_zoom += event.y * self.mouse_scalar
292
+ # i have to update the corners of the plot here to use the real2plot function correctly (i cant use shortcuts)
247
293
  self.update_grid(False)
248
294
  self.current_offset += pre - self.__real2plot__(self.rootEnv.mouse.position)
249
295
  self.update_grid(True)
@@ -251,15 +297,18 @@ class Plot:
251
297
  function.update_points()
252
298
  self.render()
253
299
 
300
+ # start dragging whenever mouse left button is just pressed
254
301
  if self.rootEnv.mouse.just_pressed[0] and self.dragging == None:
255
302
  self.dragging = self.rootEnv.mouse.position.copy()
256
303
  self.start_dragging = self.dragging.copy()
257
304
 
305
+ # update the canvas if im dragging
258
306
  if self.dragging:
259
307
  offset = (self.dragging - self.rootEnv.mouse.position)* V2(1, -1) * (abs(self.bottom_right_plot_coord - self.top_left_plot_coord) / self.size)
260
308
  self.dragging = self.rootEnv.mouse.position.copy()
261
309
  self.current_offset += offset
262
310
 
311
+ # with real time rendering i update the function render each frame whnever im dragging the canvs around
263
312
  if self.settings.get("use_real_time_rendering"):
264
313
  self.update_grid(True)
265
314
  for function in self.functions: function.update_points()
@@ -268,22 +317,32 @@ class Plot:
268
317
  self.render()
269
318
 
270
319
  def draw(self) -> None:
271
- self.rootEnv.screen.blit(self.canvas, self.position())
272
- if self.top_left_x < 0 < self.bottom_right_x and self.settings.get("show_x_axis"):
320
+ # fill canvas with bg color
321
+ if self.settings.get("render_bg"):
322
+ self.rootEnv.screen.fill(self.settings.get("bg_color"), self.position() + self.size())
323
+
324
+ # render functions before axes
325
+ if render_axes_on_top:=self.settings.get("render_axes_on_top"): self.rootEnv.screen.blit(self.canvas, self.position())
326
+
327
+ # render axes
328
+ if self.top_left_x < 0 < self.bottom_right_x and (self.settings.get("show_x_axis") and self.settings.get("show_axes")):
273
329
  pg.draw.line(self.rootEnv.screen,
274
330
  (self.settings.get("axes_default_color") if (x_color:=self.settings.get("x_axis_color"))==None else x_color) if self.mouse_scalar.x else (self.settings.get("mouse_hover_axes_color")),
275
331
  (self.__plot2real__(V2(0, self.top_left_y)) + self.position)(),
276
332
  (self.__plot2real__(V2(0, self.bottom_right_y)) + self.position)(),
277
333
  self.settings.get("axes_default_width") if (x_width:=self.settings.get("x_axis_width"))==None else x_width) #type: ignore
278
- if self.bottom_right_y < 0 < self.top_left_y and self.settings.get("show_y_axis"):
334
+ if self.bottom_right_y < 0 < self.top_left_y and (self.settings.get("show_y_axis") and self.settings.get("show_axes")):
279
335
  pg.draw.line(self.rootEnv.screen,
280
336
  (self.settings.get("axes_default_color") if (y_color:=self.settings.get("y_axis_color"))==None else y_color) if self.mouse_scalar.y else (self.settings.get("mouse_hover_axes_color")),
281
337
  (self.__plot2real__(V2(self.top_left_x, 0)) + self.position)(),
282
338
  (self.__plot2real__(V2(self.bottom_right_x, 0)) + self.position)(),
283
339
  self.settings.get("axes_default_width") if (y_width:=self.settings.get("y_axis_width"))==None else y_width) #type: ignore
340
+
341
+ # render functions after axes
342
+ if not render_axes_on_top: self.rootEnv.screen.blit(self.canvas, self.position())
284
343
 
285
344
  if self.is_mouse_in_rect and self.settings.get("show_cursor_coords"):
286
- self.rootEnv.print(str(round(self.plot_mouse_position, .1)), self.rootEnv.mouse.position, fixed_sides=TEXT_FIXED_SIDES_BOTTOM_MIDDLE) #type: ignore
345
+ self.rootEnv.print(str(self.plot_mouse_position), self.rootEnv.mouse.position, fixed_sides=TEXT_FIXED_SIDES_BOTTOM_MIDDLE) #type: ignore
287
346
 
288
347
  data = [
289
348
  [f"ZOOM:", TEXT_FIXED_SIDES_TOP_LEFT, self.settings.get("show_zoom_info")],
@@ -293,4 +352,4 @@ class Plot:
293
352
 
294
353
  for i, (d, fixed_side, show) in enumerate(data):
295
354
  if show:
296
- self.rootEnv.print(d, self.settings.get("top_left_info_position") + self.settings.get("info_spacing") * i, fixed_sides=fixed_side) #type: ignore
355
+ self.rootEnv.print(d, self.settings.get("top_left_info_position") + self.settings.get("info_interline_space") * i, fixed_sides=fixed_side) #type: ignore
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: e2D
3
- Version: 1.3.8
3
+ Version: 1.3.9
4
4
  Summary: Python library for 2D games. Streamlines dev with keyboard/mouse input, vector calculations, color manipulation, and collision detection. Simplify game creation and unleash creativity!
5
5
  Home-page: https://github.com/marick-py/e2D
6
6
  Author: Riccardo Mariani
@@ -0,0 +1,9 @@
1
+ e2D/__init__.py,sha256=L4wmmedzo_SQUIcCwPYTMJTuqYi_lASRdCwL1q0Q2rw,56327
2
+ e2D/envs.py,sha256=myRralRCZeuadguczadi7lXUPOZdNwlnTw0M3oNpNFE,3933
3
+ e2D/plots.py,sha256=WCANUHZQE0vmUR4rg9gQVShbljxZ-Dz6ae3VhNO6PSo,20418
4
+ e2D/utils.py,sha256=sq9efoNnSlJAfjvf18qDQpvO1jyz-9-mWBW3P4WMkD4,5368
5
+ e2D-1.3.9.dist-info/LICENSE,sha256=wymkNVDvj3qmjdO_rAhkRPM4t5y3_SqffGsFdgfvznU,1066
6
+ e2D-1.3.9.dist-info/METADATA,sha256=ZVXNZs-NxLBNIDlB8rBIc3HQEfeCUeC7Yu5e1yLWYb0,9608
7
+ e2D-1.3.9.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
8
+ e2D-1.3.9.dist-info/top_level.txt,sha256=3vKZ-CGzNlTCpzVMmM0Ht76krCofKw7hZ0wBf-dnKdM,4
9
+ e2D-1.3.9.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- e2D/__init__.py,sha256=L4wmmedzo_SQUIcCwPYTMJTuqYi_lASRdCwL1q0Q2rw,56327
2
- e2D/envs.py,sha256=mhq3SI2EmckXp9h6RYKzTGSKkvzlH-SyMTBhl3yDVZU,3929
3
- e2D/plots.py,sha256=VvxODi_kP92DeoAMZ2UCXdmeZiOeyqID2gLCY8XnRYA,16345
4
- e2D/utils.py,sha256=sq9efoNnSlJAfjvf18qDQpvO1jyz-9-mWBW3P4WMkD4,5368
5
- e2D-1.3.8.dist-info/LICENSE,sha256=wymkNVDvj3qmjdO_rAhkRPM4t5y3_SqffGsFdgfvznU,1066
6
- e2D-1.3.8.dist-info/METADATA,sha256=_8qvIkMK6qheCxzwtGfnrfGXHG5b_FDMq6gjE4QE9rY,9608
7
- e2D-1.3.8.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
8
- e2D-1.3.8.dist-info/top_level.txt,sha256=3vKZ-CGzNlTCpzVMmM0Ht76krCofKw7hZ0wBf-dnKdM,4
9
- e2D-1.3.8.dist-info/RECORD,,
File without changes
File without changes