e2D 1.4.14__tar.gz → 1.4.16__tar.gz

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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: e2D
3
- Version: 1.4.14
3
+ Version: 1.4.16
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
@@ -458,7 +458,6 @@ class Vector2D:
458
458
  @classmethod
459
459
  def new_down_left_norm(cls) -> "Vector2D": return V2down_left_norm.copy
460
460
 
461
- from .cvb import *
462
461
 
463
462
  V2 = Vector2D
464
463
 
@@ -469,10 +468,10 @@ V2two = Vector2D(2.0, 2.0)
469
468
  V2pi = Vector2D(PI, PI)
470
469
  V2inf = Vector2D(float("inf"), float("inf"))
471
470
 
472
- V2neg_one = Vector2D(1.0, 1.0)
473
- V2neg_two = Vector2D(2.0, 2.0)
474
- V2neg_pi = Vector2D(PI, PI)
475
- V2neg_inf = Vector2D(float("inf"), float("inf"))
471
+ V2neg_one = V2one.mult(-1)
472
+ V2neg_two = V2two.mult(-1)
473
+ V2neg_pi = V2pi.mult(-1)
474
+ V2neg_inf = V2inf.mult(-1)
476
475
 
477
476
  V2up = Vector2D(0, 1)
478
477
  V2right = Vector2D(1, 0)
@@ -0,0 +1,463 @@
1
+ from colorsys import hsv_to_rgb as __hsv_to_rgb_def__, hls_to_rgb as __hls_to_rgb_def__, rgb_to_hls as __rgb_to_hls__, rgb_to_hsv as __rgb_to_hsv__
2
+ from typing import Any, Callable, Generator, Literal
3
+ from pygame.color import Color as __color_pygame__
4
+ from random import randint as __randint__
5
+
6
+ RGB_COLOR_MODE = "rgb"
7
+ RGBA_COLOR_MODE = "rgba"
8
+ BGR_COLOR_MODE = "bgr"
9
+ BGRA_COLOR_MODE = "bgra"
10
+ GRAY_COLOR_MODE = "g"
11
+ HSV_COLOR_MODE = "hsv"
12
+ HLS_COLOR_MODE = "hls"
13
+ # CMYK_COLOR_MODE = "cmyk"
14
+ # LAB_COLOR_MODE = "lab"
15
+
16
+ __LITERAL_COLOR_MODES__ = Literal["rgb","rgba","bgr","bgra","g","hsv","hls"] #,"cmyk","lab"]
17
+
18
+ def __hsv_to_rgb__(h:int|float, s:int|float, v:int|float) -> tuple[int|float, int|float, int|float]:
19
+ r,g,b = __hsv_to_rgb_def__(h, s, v)
20
+ return r*255, g*255, b*255
21
+
22
+ def __hls_to_rgb__(h:int|float, s:int|float, v:int|float) -> tuple[int|float, int|float, int|float]:
23
+ r,g,b = __hls_to_rgb_def__(h, s, v)
24
+ return r*255, g*255, b*255
25
+
26
+ __conversion_table__ :dict[__LITERAL_COLOR_MODES__, dict[__LITERAL_COLOR_MODES__, Callable]]= {
27
+ "rgb": {
28
+ "rgba": lambda r,g,b: (r, g, b, 255.0),
29
+ "bgr": lambda r,g,b: (b, g, r),
30
+ "bgra": lambda r,g,b: (b, g, r, 255.0),
31
+ "g": lambda r,g,b: (.2989*r+.587*g+.114*b,),
32
+ "hsv": lambda r,g,b: __rgb_to_hsv__(r/255.0, g/255.0, b/255.0),
33
+ "hls": lambda r,g,b: __rgb_to_hls__(r/255.0, g/255.0, b/255.0),
34
+ },
35
+ "rgba": {
36
+ "rgb": lambda r,g,b,a: (r, g, b),
37
+ "bgr": lambda r,g,b,a: (b, g, r),
38
+ "bgra": lambda r,g,b,a: (b, g, r, a),
39
+ "g": lambda r,g,b,a: (.2989*r+.587*g+.114*b,),
40
+ "hsv": lambda r,g,b,a: __rgb_to_hsv__(r/255.0, g/255.0, b/255.0),
41
+ "hls": lambda r,g,b,a: __rgb_to_hls__(r/255.0, g/255.0, b/255.0),
42
+ },
43
+ "bgr": {
44
+ "rgb": lambda b,g,r: (r, g, b),
45
+ "rgba": lambda b,g,r: (r, g, b, 255.0),
46
+ "bgra": lambda b,g,r: (b, g, r, 255.0),
47
+ "g": lambda b,g,r: (.2989*r+.587*g+.114*b,),
48
+ "hsv": lambda b,g,r: __rgb_to_hsv__(r/255.0, g/255.0, b/255.0),
49
+ "hls": lambda b,g,r: __rgb_to_hls__(r/255.0, g/255.0, b/255.0),
50
+ },
51
+ "bgra": {
52
+ "rgb": lambda b,g,r,a: (r, g, b),
53
+ "rgba": lambda b,g,r,a: (b, g, r, a),
54
+ "bgr": lambda b,g,r,a: (b, g, r),
55
+ "g": lambda b,g,r,a: (.2989*r+.587*g+.114*b,),
56
+ "hsv": lambda b,g,r,a: __rgb_to_hsv__(r/255.0, g/255.0, b/255.0),
57
+ "hls": lambda b,g,r,a: __rgb_to_hls__(r/255.0, g/255.0, b/255.0),
58
+ },
59
+ "g": {
60
+ "rgb": lambda g: (g, g, g),
61
+ "rgba": lambda g: (g, g, g, 255.0),
62
+ "bgr": lambda g: (g, g, g),
63
+ "bgra": lambda g: (g, g, g, 255.0),
64
+ "hsv": lambda g: __rgb_to_hsv__(g/255.0, g/255.0, g/255.0),
65
+ "hls": lambda g: __rgb_to_hls__(g/255.0, g/255.0, g/255.0),
66
+ },
67
+ "hsv": {
68
+ "rgb": lambda h,s,v: __hsv_to_rgb__(h,s,v),
69
+ "rgba": lambda h,s,v: (*__hsv_to_rgb__(h,s,v), 255.0),
70
+ "bgr": lambda h,s,v: __hsv_to_rgb__(h,s,v)[::-1],
71
+ "bgra": lambda h,s,v: (*__hsv_to_rgb__(h,s,v)[::-1], 255.0),
72
+ "g": lambda h,s,v: (sum(m*v for m,v in zip((.2989, .587, .114), __hsv_to_rgb__(h,s,v))),),
73
+ "hls": lambda h,s,v: __rgb_to_hls__(*__hsv_to_rgb_def__(h,s,v)),
74
+ },
75
+ "hls": {
76
+ "rgb": lambda h,l,s: __hls_to_rgb__(h,l,s),
77
+ "rgba": lambda h,l,s: (*__hls_to_rgb__(h,l,s), 255.0),
78
+ "bgr": lambda h,l,s: __hls_to_rgb__(h,l,s)[::-1],
79
+ "bgra": lambda h,l,s: (*__hls_to_rgb__(h,l,s)[::-1], 255.0),
80
+ "g": lambda h,l,s: (sum(m*v for m,v in zip((.2989, .587, .114), __hls_to_rgb__(h,l,s))),),
81
+ "hsv": lambda h,l,s: __rgb_to_hsv__(*__hls_to_rgb_def__(h,l,s)),
82
+ },
83
+ }
84
+
85
+ class Color:
86
+ def __init__(self, *values, mode:__LITERAL_COLOR_MODES__=RGB_COLOR_MODE) -> None:
87
+ self.__dict__ = dict(zip(mode, values))
88
+ self.mode :__LITERAL_COLOR_MODES__= mode
89
+
90
+ @classmethod
91
+ def new_rgb(cls, r:int|float, g:int|float, b:int|float) -> "Color":
92
+ return Color(r,g,b, mode=RGB_COLOR_MODE)
93
+ @classmethod
94
+ def new_rgba(cls, r:int|float, g:int|float, b:int|float, a:int|float) -> "Color":
95
+ return Color(r,g,b,a, mode=RGBA_COLOR_MODE)
96
+ @classmethod
97
+ def new_bgr(cls, b:int|float, g:int|float, r:int|float) -> "Color":
98
+ return Color(b,g,r, mode=BGR_COLOR_MODE)
99
+ @classmethod
100
+ def new_bgra(cls, b:int|float, g:int|float, r:int|float, a:int|float) -> "Color":
101
+ return Color(b,g,r,a, mode=BGRA_COLOR_MODE)
102
+ @classmethod
103
+ def new_g(cls, g) -> "Color":
104
+ return Color(g, mode=GRAY_COLOR_MODE)
105
+ @classmethod
106
+ def new_hsv(cls, h:int|float, s:int|float, v:int|float) -> "Color":
107
+ return Color(h,s,v, mode=HSV_COLOR_MODE)
108
+ @classmethod
109
+ def new_hls(cls, h:int|float, l:int|float, s:int|float) -> "Color":
110
+ return Color(h,l,s, mode=HLS_COLOR_MODE)
111
+ # @classmethod
112
+ # def new_cmyk(cls, c:int|float, m:int|float, y:int|float, k:int|float) -> Color:
113
+ # return Color(c,m,y,k, mode=CMYK_COLOR_MODE)
114
+ # @classmethod
115
+ # def new_lab(cls, l:int|float, a:int|float, b:int|float) -> Color:
116
+ # return Color(l,a,b, mode=LAB_COLOR_MODE)
117
+
118
+ @property
119
+ def values(self) -> tuple[int|float, ...]:
120
+ return tuple(self.__dict__.values())[:-1]
121
+
122
+ @property
123
+ def keys(self) -> tuple[str, ...]:
124
+ return tuple(self.__dict__.keys())[:-1]
125
+
126
+ @property
127
+ def items(self) -> tuple[tuple[str, int|float], ...]:
128
+ return tuple(self.__dict__.items())[:-1]
129
+
130
+ def copy(self) -> "Color":
131
+ return Color(*self.values, mode=self.mode)
132
+
133
+ def to_mode(self, mode:__LITERAL_COLOR_MODES__) -> "Color":
134
+ if mode == self.mode: return self.copy()
135
+ return Color(*__conversion_table__[self.mode][mode](*self.values), mode=mode)
136
+
137
+ def to_rgb(self) -> "Color":
138
+ if self.mode == RGB_COLOR_MODE: return self.copy()
139
+ return Color(*__conversion_table__[self.mode][RGB_COLOR_MODE](*self.values), mode=RGB_COLOR_MODE)
140
+ def to_rgba(self) -> "Color":
141
+ if self.mode == RGBA_COLOR_MODE: return self.copy()
142
+ return Color(*__conversion_table__[self.mode][RGBA_COLOR_MODE](*self.values), mode=RGBA_COLOR_MODE)
143
+ def to_bgr(self) -> "Color":
144
+ if self.mode == BGR_COLOR_MODE: return self.copy()
145
+ return Color(*__conversion_table__[self.mode][BGR_COLOR_MODE](*self.values), mode=BGR_COLOR_MODE)
146
+ def to_bgra(self) -> "Color":
147
+ if self.mode == BGRA_COLOR_MODE: return self.copy()
148
+ return Color(*__conversion_table__[self.mode][BGRA_COLOR_MODE](*self.values), mode=BGRA_COLOR_MODE)
149
+ def to_g(self) -> "Color":
150
+ if self.mode == GRAY_COLOR_MODE: return self.copy()
151
+ return Color(*__conversion_table__[self.mode][GRAY_COLOR_MODE](*self.values), mode=GRAY_COLOR_MODE)
152
+ def to_hsv(self) -> "Color":
153
+ if self.mode == HSV_COLOR_MODE: return self.copy()
154
+ return Color(*__conversion_table__[self.mode][HSV_COLOR_MODE](*self.values), mode=HSV_COLOR_MODE)
155
+ def to_hls(self) -> "Color":
156
+ if self.mode == HLS_COLOR_MODE: return self.copy()
157
+ return Color(*__conversion_table__[self.mode][HLS_COLOR_MODE](*self.values), mode=HLS_COLOR_MODE)
158
+
159
+ def __repr__(self) -> str:
160
+ return self.__str__()
161
+
162
+ def __str__(self) -> str:
163
+ return "Color(" + ", ".join(f"{k}:{v}" for k, v in self.items) + ")"
164
+
165
+ def __call__(self) -> __color_pygame__:
166
+ return __color_pygame__(*map(int, self.to_rgba().values))
167
+
168
+ # fast operations Vector2D.operation(both,x,y)
169
+ def add(self, all3=.0, r=.0, g=.0, b=.0) -> "Color":
170
+ c_color = self.to_rgb()
171
+ return Color(c_color.r + (r + all3), c_color.g + (g + all3), c_color.b + (b + all3)).to_mode(self.mode) # type: ignore
172
+
173
+ def sub(self, all3=.0, r=.0, g=.0, b=.0) -> "Color":
174
+ c_color = self.to_rgb()
175
+ return Color(c_color.r - (r + all3), c_color.g - (g + all3), c_color.b - (b + all3)).to_mode(self.mode) # type: ignore
176
+
177
+ def mult(self, all3=1.0, r=1.0, g=1.0, b=1.0) -> "Color":
178
+ c_color = self.to_rgb()
179
+ return Color(c_color.r * r * all3, c_color.g * g * all3, c_color.b * b * all3).to_mode(self.mode) # type: ignore
180
+
181
+ def pow(self, all3=1.0, r=1.0, g=1.0, b=1.0) -> "Color":
182
+ c_color = self.to_rgb()
183
+ return Color(c_color.r ** (r + all3), c_color.g ** (g + all3), c_color.b ** (b + all3)).to_mode(self.mode) # type: ignore
184
+
185
+ def mod(self, all3=1.0, r=1.0, g=1.0, b=1.0) -> "Color":
186
+ c_color = self.to_rgb()
187
+ return Color(c_color.r % (r + all3), c_color.g % (g + all3), c_color.b % (b + all3)).to_mode(self.mode) # type: ignore
188
+
189
+ def div(self, all3=1.0, r=1.0, g=1.0, b=1.0) -> "Color":
190
+ c_color = self.to_rgb()
191
+ return Color(c_color.r / r / all3, c_color.g / g / all3, c_color.b / b / all3).to_mode(self.mode) # type: ignore
192
+
193
+ def fdiv(self, all3=1.0, r=1.0, g=1.0, b=1.0) -> "Color":
194
+ c_color = self.to_rgb()
195
+ return Color(c_color.r // r // all3, c_color.g // g // all3, c_color.b // b // all3).to_mode(self.mode) # type: ignore
196
+
197
+ # fast inplace operations Vector2D.ioperation(both,x,y)
198
+ def set(self, both=.0, x=.0, y=.0) -> "Color":
199
+ self.x = x + both
200
+ self.y = y + both
201
+ return self
202
+
203
+ def iadd(self, all3=.0, r=.0, g=.0, b=.0) -> "Color":
204
+ c_color = self.to_rgb()
205
+ c_color.r += r + all3 # type: ignore
206
+ c_color.g += g + all3 # type: ignore
207
+ c_color.b += b + all3 # type: ignore
208
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
209
+ return self
210
+
211
+ def isub(self, all3=.0, r=.0, g=.0, b=.0) -> "Color":
212
+ c_color = self.to_rgb()
213
+ c_color.r -= r + all3 # type: ignore
214
+ c_color.g -= g + all3 # type: ignore
215
+ c_color.b -= b + all3 # type: ignore
216
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
217
+ return self
218
+
219
+ def imult(self, all3=1.0, r=1.0, g=1.0, b=1.0) -> "Color":
220
+ c_color = self.to_rgb()
221
+ c_color.r *= r * all3 # type: ignore
222
+ c_color.g *= g * all3 # type: ignore
223
+ c_color.b *= b * all3 # type: ignore
224
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
225
+ return self
226
+
227
+ def ipow(self, all3=1.0, r=1.0, g=1.0, b=1.0) -> "Color":
228
+ c_color = self.to_rgb()
229
+ c_color.r **= r + all3 # type: ignore
230
+ c_color.g **= g + all3 # type: ignore
231
+ c_color.b **= b + all3 # type: ignore
232
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
233
+ return self
234
+
235
+ def imod(self, all3=1.0, r=1.0, g=1.0, b=1.0) -> "Color":
236
+ c_color = self.to_rgb()
237
+ c_color.r %= r + all3 # type: ignore
238
+ c_color.g %= g + all3 # type: ignore
239
+ c_color.b %= b + all3 # type: ignore
240
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
241
+ return self
242
+
243
+ def idiv(self, all3=1.0, r=1.0, g=1.0, b=1.0) -> "Color":
244
+ c_color = self.to_rgb()
245
+ c_color.r /= r * all3 # type: ignore
246
+ c_color.g /= g * all3 # type: ignore
247
+ c_color.b /= b * all3 # type: ignore
248
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
249
+ return self
250
+
251
+ def ifdiv(self, all3=1.0, r=1.0, g=1.0, b=1.0) -> "Color":
252
+ c_color = self.to_rgb()
253
+ c_color.r //= r * all3 # type: ignore
254
+ c_color.g //= g * all3 # type: ignore
255
+ c_color.b //= b * all3 # type: ignore
256
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
257
+ return self
258
+
259
+ # normal operations Vector2D + a
260
+ def __add__(self, other) -> "Color":
261
+ other = Color.__normalize__(other)
262
+ c_color = self.to_rgb()
263
+ return Color(c_color.r + other.r, c_color.g + other.g, c_color.b + other.b).to_mode(self.mode) # type: ignore
264
+
265
+ def __sub__(self, other) -> "Color":
266
+ other = Color.__normalize__(other)
267
+ c_color = self.to_rgb()
268
+ return Color(c_color.r - other.r, c_color.g - other.g, c_color.b - other.b).to_mode(self.mode) # type: ignore
269
+
270
+ def __mul__(self, other) -> "Color":
271
+ other = Color.__normalize__(other)
272
+ c_color = self.to_rgb()
273
+ return Color(c_color.r * other.r, c_color.g * other.g, c_color.b * other.b).to_mode(self.mode) # type: ignore
274
+
275
+ def __mod__(self, other) -> "Color":
276
+ other = Color.__normalize__(other)
277
+ c_color = self.to_rgb()
278
+ return Color(c_color.r % other.r, c_color.g % other.g, c_color.b % other.b).to_mode(self.mode) # type: ignore
279
+
280
+ def __pow__(self, other) -> "Color":
281
+ other = Color.__normalize__(other)
282
+ c_color = self.to_rgb()
283
+ return Color(c_color.r ** other.r, c_color.g ** other.g, c_color.b ** other.b).to_mode(self.mode) # type: ignore
284
+
285
+ def __truediv__(self, other) -> "Color":
286
+ other = Color.__normalize__(other)
287
+ c_color = self.to_rgb()
288
+ return Color(c_color.r / other.r, c_color.g / other.g, c_color.b / other.b).to_mode(self.mode) # type: ignore
289
+
290
+ def __floordiv__(self, other) -> "Color":
291
+ other = Color.__normalize__(other)
292
+ c_color = self.to_rgb()
293
+ return Color(c_color.r // other.r, c_color.g // other.g, c_color.b // other.b).to_mode(self.mode) # type: ignore
294
+
295
+ # right operations a + Vector2D
296
+ def __radd__(self, other) -> "Color":
297
+ return self.__add__(other)
298
+
299
+ def __rsub__(self, other) -> "Color":
300
+ other = Color.__normalize__(other)
301
+ c_color = self.to_rgb()
302
+ return Color(other.r - c_color.r, other.g - c_color.g, other.b - c_color.b).to_mode(self.mode) # type: ignore
303
+
304
+ def __rmul__(self, other) -> "Color":
305
+ return self.__mul__(other)
306
+
307
+ def __rmod__(self, other) -> "Color":
308
+ other = Color.__normalize__(other)
309
+ c_color = self.to_rgb()
310
+ return Color(other.r % c_color.r, other.g % c_color.g, other.b % c_color.b).to_mode(self.mode) # type: ignore
311
+
312
+ def __rpow__(self, other) -> "Color":
313
+ other = Color.__normalize__(other)
314
+ c_color = self.to_rgb()
315
+ return Color(other.r ** c_color.r, other.g ** c_color.g, other.b ** c_color.b).to_mode(self.mode) # type: ignore
316
+
317
+ def __rtruediv__(self, other) -> "Color":
318
+ other = Color.__normalize__(other)
319
+ c_color = self.to_rgb()
320
+ return Color(other.r / c_color.r, other.g / c_color.g, other.b / c_color.b).to_mode(self.mode) # type: ignore
321
+
322
+ def __rfloordiv__(self, other) -> "Color":
323
+ other = Color.__normalize__(other)
324
+ c_color = self.to_rgb()
325
+ return Color(other.r // c_color.r, other.g // c_color.g, other.b // c_color.b).to_mode(self.mode) # type: ignore
326
+
327
+ # in-place operations Vector2D += a
328
+ def __iadd__(self, other) -> "Color":
329
+ other = Color.__normalize__(other)
330
+ c_color = self.to_rgb()
331
+ c_color.r += other.r # type: ignore
332
+ c_color.g += other.g # type: ignore
333
+ c_color.b += other.b # type: ignore
334
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
335
+ return self
336
+
337
+ def __isub__(self, other) -> "Color":
338
+ other = Color.__normalize__(other)
339
+ c_color = self.to_rgb()
340
+ c_color.r -= other.r # type: ignore
341
+ c_color.g -= other.g # type: ignore
342
+ c_color.b -= other.b # type: ignore
343
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
344
+ return self
345
+
346
+ def __imul__(self, other) -> "Color":
347
+ other = Color.__normalize__(other)
348
+ c_color = self.to_rgb()
349
+ c_color.r *= other.r # type: ignore
350
+ c_color.g *= other.g # type: ignore
351
+ c_color.b *= other.b # type: ignore
352
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
353
+ return self
354
+
355
+ def __itruediv__(self, other) -> "Color":
356
+ other = Color.__normalize__(other)
357
+ c_color = self.to_rgb()
358
+ c_color.r **= other.r # type: ignore
359
+ c_color.g **= other.g # type: ignore
360
+ c_color.b **= other.b # type: ignore
361
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
362
+ return self
363
+
364
+ def __imod__(self, other) -> "Color":
365
+ other = Color.__normalize__(other)
366
+ c_color = self.to_rgb()
367
+ c_color.r %= other.r # type: ignore
368
+ c_color.g %= other.g # type: ignore
369
+ c_color.b %= other.b # type: ignore
370
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
371
+ return self
372
+
373
+ def __ipow__(self, other) -> "Color":
374
+ other = Color.__normalize__(other)
375
+ c_color = self.to_rgb()
376
+ c_color.r /= other.r # type: ignore
377
+ c_color.g /= other.g # type: ignore
378
+ c_color.b /= other.b # type: ignore
379
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
380
+ return self
381
+
382
+ def __ifloordiv__(self, other) -> "Color":
383
+ other = Color.__normalize__(other)
384
+ c_color = self.to_rgb()
385
+ c_color.r //= other.r # type: ignore
386
+ c_color.g //= other.g # type: ignore
387
+ c_color.b //= other.b # type: ignore
388
+ self.__dict__ = c_color.to_mode(self.mode).__dict__
389
+ return self
390
+
391
+ # comparasion
392
+ def __eq__(self, other) -> bool:
393
+ try: other = Color.__normalize__(other)
394
+ except: return False
395
+ c_color = self.to_rgb()
396
+ return c_color.r == other.r and c_color.g == other.g and c_color.b == other.b # type: ignore
397
+
398
+ def __ne__(self, other) -> bool:
399
+ return not self.__eq__(other)
400
+
401
+ def __abs__(self) -> "Color":
402
+ c_color = self.to_rgb()
403
+ return Color(abs(c_color.r), abs(c_color.g), abs(c_color.b)).to_mode(self.mode) # type: ignore
404
+
405
+ def __round__(self, n=1) -> "Color":
406
+ n = Color.__normalize__(n)
407
+ c_color = self.to_rgb()
408
+ return Color(round(c_color.r / n.r) * n.r, round(c_color.g / n.g) * n.g, round(c_color.b / n.b) * n.b).to_mode(self.mode) # type: ignore
409
+
410
+ def __floor__(self, n=1) -> "Color":
411
+ n = Color.__normalize__(n)
412
+ c_color = self.to_rgb()
413
+ return Color((c_color.r / n.r).__floor__() * n.r, (c_color.g / n.g).__floor__() * n.g, (c_color.b / n.b).__floor__() * n.b).to_mode(self.mode) # type: ignore
414
+
415
+ def __ceil__(self, n=1) -> "Color":
416
+ n = Color.__normalize__(n)
417
+ c_color = self.to_rgb()
418
+ return Color((c_color.r / n.r).__ceil__() * n.r, (c_color.g / n.g).__ceil__() * n.g, (c_color.b / n.b).__ceil__() * n.b).to_mode(self.mode) # type: ignore
419
+
420
+ def __float__(self) -> "Color":
421
+ c_color = self.to_rgb()
422
+ return Color(float(c_color.r), float(c_color.g), float(c_color.b)).to_mode(self.mode) # type: ignore
423
+
424
+ def __getitem__(self, n) -> int|float:
425
+ return self.values[n] if isinstance(n, int) else self.values[self.keys.index(n)]
426
+
427
+ def __iter__(self) -> Generator[float, Any, None]:
428
+ for val in self.values:
429
+ yield val
430
+
431
+ @classmethod
432
+ def __normalize__(cls, other) -> "Color":
433
+ if isinstance(other, Color):
434
+ return other
435
+ if isinstance(other, (int, float)):
436
+ return cls(other, other, other)
437
+ if isinstance(other, (list, tuple)):
438
+ return cls(*other[:3])
439
+ try:
440
+ return cls(*other.values, mode=other.mode)
441
+ except:
442
+ raise TypeError(f"The value {other} of type {type(other)} is not a num type: [{int|float}] nor an array type: [{list|tuple}]")
443
+
444
+ @classmethod
445
+ def white(cls) -> "Color": return Color(255,255,255)
446
+ @classmethod
447
+ def black(cls) -> "Color": return Color(0,0,0)
448
+ @classmethod
449
+ def red(cls) -> "Color": return Color(255,0,0)
450
+ @classmethod
451
+ def green(cls) -> "Color": return Color(0,255,0)
452
+ @classmethod
453
+ def blue(cls) -> "Color": return Color(0,0,255)
454
+
455
+ @classmethod
456
+ def randomize(cls) -> "Color":
457
+ return Color(__randint__(0,255), __randint__(0,255), __randint__(0,255))
458
+
459
+ WHITE_COLOR_PYG = Color.white()()
460
+ BLACK_COLOR_PYG = Color.black()()
461
+ RED_COLOR_PYG = Color.red()()
462
+ GREEN_COLOR_PYG = Color.green()()
463
+ BLUE_COLOR_PYG = Color.blue()()
@@ -38,7 +38,7 @@ class RootEnv:
38
38
  def __init__(self,
39
39
  screen_size : Vector2D = Vector2D(1920, 1080),
40
40
  target_fps : int = 60,
41
- show_fps = True,
41
+ show_fps : bool = True,
42
42
  quit_on_key_pressed : None|int = pg.K_x,
43
43
  vsync : bool = True,
44
44
  window_flags : int = pg.DOUBLEBUF,
@@ -59,12 +59,11 @@ class RootEnv:
59
59
  self.current_frame = 0
60
60
  self.show_fps = show_fps
61
61
  self.events :list[pg.event.Event]= []
62
- self.background_color = rgb(0,0,0)
62
+ self.background_color = Color.black()
63
63
  self.clear_screen_each_frame = clear_screen_each_frame
64
64
  self.utils :dict[int|str, Util]= {}
65
65
  self.selected_util :Util|None = None
66
66
  self.__quit_on_key_pressed__ = quit_on_key_pressed
67
-
68
67
 
69
68
  @property
70
69
  def screen_size(self) -> Vector2D:
@@ -72,6 +71,7 @@ class RootEnv:
72
71
 
73
72
  @screen_size.setter
74
73
  def screen_size(self, new_size:Vector2D) -> None:
74
+ self.__screen_size__ = new_size
75
75
  self.screen = pg.display.set_mode(self.__screen_size__(), vsync=self.__vsync__, flags=self.__flags__)
76
76
 
77
77
  @property
@@ -81,22 +81,23 @@ class RootEnv:
81
81
  def get_teoric_max_fps(self) -> float:
82
82
  rawdelta = self.clock.get_rawtime()
83
83
  return (1000 / rawdelta) if rawdelta != 0 else 1
84
-
84
+
85
85
  def update_screen_mode(self, vsync:None|bool=None, flags=None) -> None:
86
- pass
87
-
86
+ self.__vsync__ = vsync
87
+ self.__flags__ = flags
88
+
88
89
  def sleep(self, seconds:int|float, precise_delay=False) -> None:
89
90
  if precise_delay:
90
91
  pg.time.delay(seconds * 1000)
91
92
  else:
92
93
  pg.time.wait(seconds * 1000)
93
-
94
+
94
95
  def add_utils(self, *utils:Util) -> None:
95
96
  for util in utils:
96
97
  if util.surface == None: util.surface = self.screen
97
98
  util.rootEnv = self
98
99
  self.utils[util.id] = util
99
-
100
+
100
101
  def remove_utils(self, *utils:int|str|Util) -> None:
101
102
  for uid in utils:
102
103
  if uid in self.utils:
@@ -105,55 +106,55 @@ class RootEnv:
105
106
  del self.utils[uid.id]
106
107
  else:
107
108
  raise Exception(f"Unknown util type: {uid}")
108
-
109
+
109
110
  @property
110
111
  def runtime_seconds(self) -> float:
111
112
  return pg.time.get_ticks() / 1e3
112
-
113
+
113
114
  def init(self, sub_env:DefEnv) -> None:
114
115
  self.env = sub_env
115
-
116
+
116
117
  def clear(self) -> None:
117
- self.screen.fill(self.background_color)
118
-
118
+ self.screen.fill(self.background_color())
119
+
119
120
  def clear_rect(self, position:Vector2D, size:Vector2D) -> None:
120
121
  self.screen.fill(self.background_color, position() + size())
121
-
122
+
122
123
  def print(self,
123
124
  text : str,
124
125
  position : Vector2D,
125
- color : tuple[float,float,float] = (255,255,255),
126
+ color : Color = Color.white(),
126
127
  pivot_position : __LITERAL_PIVOT_POSITIONS__ = "top_left",
127
128
  font : pg.font.Font = FONT_ARIAL_32,
128
- bg_color : None|tuple[int,int,int]|list[int] = None,
129
- border_color : None|tuple[int,int,int]|list[int] = (255,255,255),
130
- border_width : float = 0,
129
+ bg_color : None|Color = None,
130
+ border_color : Color = Color.white(),
131
+ border_width : float = 0.0,
131
132
  border_radius : int|list[int]|tuple[int,int,int,int] = -1,
132
133
  margin : Vector2D = Vector2D.zero(),
133
134
  personalized_surface : pg.Surface|None = None
134
135
  ) -> None:
135
- text_box = font.render(text, True, color)
136
+ text_box = font.render(text, True, color())
136
137
  size = Vector2D(*text_box.get_size()) + margin * 2
137
138
  pivotted_position = position - size * __PIVOT_POSITIONS_MULTIPLIER__[pivot_position] + margin
138
139
  if not any(isinstance(border_radius, cls) for cls in {tuple, list}): border_radius = [border_radius]*4
139
140
  surface = (self.screen if personalized_surface == None else personalized_surface)
140
141
  if bg_color != None:
141
- pg.draw.rect(surface, bg_color, (pivotted_position - margin)() + size(), 0, -1, *border_radius)
142
+ pg.draw.rect(surface, bg_color(), (pivotted_position - margin)() + size(), 0, -1, *border_radius)
142
143
  if border_width:
143
- pg.draw.rect(surface, border_color, (pivotted_position - margin)() + size(), border_width, -1, *border_radius)
144
+ pg.draw.rect(surface, border_color(), (pivotted_position - margin)() + size(), border_width, -1, *border_radius)
144
145
  surface.blit(text_box, pivotted_position())
145
146
 
146
147
  def __draw__(self) -> None:
147
148
  self.clock.tick(self.target_fps)
148
149
  self.current_fps = self.clock.get_fps()
149
150
  if self.clear_screen_each_frame: self.clear()
150
-
151
+
151
152
  self.env.draw()
152
153
  for util in self.utils.values(): util.draw()
153
-
154
- if self.show_fps: self.print(str(round(self.current_fps,2)), self.screen_size * .01, bg_color=(0,0,0))
154
+
155
+ if self.show_fps: self.print(str(round(self.current_fps,2)), self.screen_size * .01, bg_color=Color.black())
155
156
  pg.display.flip()
156
-
157
+
157
158
  def __update__(self) -> None:
158
159
  self.mouse.update()
159
160
  self.keyboard.update()
@@ -168,4 +169,5 @@ class RootEnv:
168
169
 
169
170
  for event in self.events:
170
171
  if event.type == pg.QUIT or ((event.type == pg.KEYDOWN and event.key == self.__quit_on_key_pressed__ and self.selected_util == None) if self.__quit_on_key_pressed__ != None else False):
172
+ pg.quit()
171
173
  self.quit = True
@@ -125,7 +125,7 @@ class Point(Object):
125
125
  class MathFunction(Function):
126
126
  def __init__(self,
127
127
  id:int|str,
128
- function:Callable[[int|float, int|float], int|float],
128
+ function:Callable[[np.ndarray, np.ndarray], np.ndarray],
129
129
  domain:list[float]=[-np.inf, np.inf],
130
130
  codomain:list[float]=[-np.inf, np.inf],
131
131
  color:list[float]|tuple[float,float,float]=(255,255,255)) -> None:
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
  from typing import Any, Callable, Literal
3
3
  import pygame as pg
4
4
  from e2D import *
5
+ from e2D.colors import *
5
6
 
6
7
  import math as _mt
7
8
 
@@ -12,7 +13,8 @@ __LITERAL_KEY_MODE_TYPES__ = Literal["pressed", "just_pressed", "just_released"]
12
13
 
13
14
  __LITERAL_FONTS__ = Literal['arial', 'arialblack', 'bahnschrift', 'calibri', 'cambria', 'cambriamath', 'candara', 'comicsansms', 'consolas', 'constantia', 'corbel', 'couriernew', 'ebrima', 'franklingothicmedium', 'gabriola', 'gadugi', 'georgia', 'impact', 'inkfree', 'javanesetext', 'leelawadeeui', 'leelawadeeuisemilight', 'lucidaconsole', 'lucidasans', 'malgungothic', 'malgungothicsemilight', 'microsofthimalaya', 'microsoftjhenghei', 'microsoftjhengheiui', 'microsoftnewtailue', 'microsoftphagspa', 'microsoftsansserif', 'microsofttaile', 'microsoftyahei', 'microsoftyaheiui', 'microsoftyibaiti', 'mingliuextb', 'pmingliuextb', 'mingliuhkscsextb', 'mongolianbaiti', 'msgothic', 'msuigothic', 'mspgothic', 'mvboli', 'myanmartext', 'nirmalaui', 'nirmalauisemilight', 'palatinolinotype', 'segoemdl2assets', 'segoeprint', 'segoescript', 'segoeui', 'segoeuiblack', 'segoeuiemoji', 'segoeuihistoric', 'segoeuisemibold', 'segoeuisemilight', 'segoeuisymbol', 'simsun', 'nsimsun', 'simsunextb', 'sitkasmall', 'sitkatext', 'sitkasubheading', 'sitkaheading', 'sitkadisplay', 'sitkabanner', 'sylfaen', 'symbol', 'tahoma', 'timesnewroman', 'trebuchetms', 'verdana', 'webdings', 'wingdings', 'yugothic', 'yugothicuisemibold', 'yugothicui', 'yugothicmedium', 'yugothicuiregular', 'yugothicregular', 'yugothicuisemilight', 'holomdl2assets', 'bizudgothic', 'bizudpgothictruetype', 'bizudminchomedium', 'bizudpminchomediumtruetype', 'meiryo', 'meiryoui', 'msmincho', 'mspmincho', 'uddigikyokashonb', 'uddigikyokashonpb', 'uddigikyokashonkb', 'uddigikyokashonr', 'uddigikyokashonpr', 'uddigikyokashonkr', 'yumincho', 'lcd', 'glassgauge', 'maiandragd', 'maiandragddemi', 'newsgothic', 'quartz', 'kievitoffcpro', 'agencyfbgrassetto', 'agencyfb', 'algerian', 'bookantiquagrassetto', 'bookantiquagrassettocorsivo', 'bookantiquacorsivo', 'arialcorsivo', 'arialrounded', 'baskervilleoldface', 'bauhaus93', 'bell', 'bellgrassetto', 'bellcorsivo', 'bernardcondensed', 'bookantiqua', 'bodonigrassetto', 'bodonigrassettocorsivo', 'bodoniblackcorsivo', 'bodoniblack', 'bodonicondensedgrassetto', 'bodonicondensedgrassettocorsivo', 'bodonicondensedcorsivo', 'bodonicondensed', 'bodonicorsivo', 'bodonipostercompressed', 'bodoni', 'bookmanoldstyle', 'bookmanoldstylegrassetto', 'bookmanoldstylegrassettocorsivo', 'bookmanoldstylecorsivo', 'bradleyhanditc', 'britannic', 'berlinsansfbgrassetto', 'berlinsansfbdemigrassetto', 'berlinsansfb', 'broadway', 'brushscriptcorsivo', 'bookshelfsymbol7', 'californianfbgrassetto', 'californianfbcorsivo', 'californianfb', 'calisto', 'calistograssetto', 'calistograssettocorsivo', 'calistocorsivo', 'castellar', 'centuryschoolbook', 'centaur', 'century', 'chiller', 'colonna', 'cooperblack', 'copperplategothic', 'curlz', 'dubai', 'dubaimedium', 'dubairegular', 'elephant', 'elephantcorsivo', 'engravers', 'erasitc', 'erasdemiitc', 'erasmediumitc', 'felixtitling', 'forte', 'franklingothicbook', 'franklingothicbookcorsivo', 'franklingothicdemi', 'franklingothicdemicond', 'franklingothicdemicorsivo', 'franklingothicheavy', 'franklingothicheavycorsivo', 'franklingothicmediumcond', 'freestylescript', 'frenchscript', 'footlight', 'garamond', 'garamondgrassetto', 'garamondcorsivo', 'gigi', 'gillsansgrassettocorsivo', 'gillsansgrassetto', 'gillsanscondensed', 'gillsanscorsivo', 'gillsansultracondensed', 'gillsansultra', 'gillsans', 'gloucesterextracondensed', 'gillsansextcondensed', 'centurygothic', 'centurygothicgrassetto', 'centurygothicgrassettocorsivo', 'centurygothiccorsivo', 'goudyoldstyle', 'goudyoldstylegrassetto', 'goudyoldstylecorsivo', 'goudystout', 'harlowsolid', 'harrington', 'haettenschweiler', 'hightowertext', 'hightowertextcorsivo', 'imprintshadow', 'informalroman', 'blackadderitc', 'kristenitc', 'jokerman', 'juiceitc', 'kunstlerscript', 'widelatin', 'lucidabright', 'lucidacalligraphy', 'leelawadee', 'leelawadeegrassetto', 'lucidafax', 'lucidafaxdemigrassetto', 'lucidafaxdemigrassettocorsivo', 'lucidafaxcorsivo', 'lucidahandwritingcorsivo', 'lucidasansdemigrassetto', 'lucidasansdemigrassettocorsivo', 'lucidasanscorsivo', 'lucidasanstypewriter', 'lucidasanstypewritergrassetto', 'lucidasanstypewritergrassettooblique', 'lucidasanstypewriteroblique', 'magnetograssetto', 'maturascriptcapitals', 'mistral', 'modernno20', 'microsoftuighurgrassetto', 'microsoftuighur', 'monotypecorsiva', 'extra', 'niagaraengraved', 'niagarasolid', 'ocraextended', 'oldenglishtext', 'onyx', 'msoutlook', 'palacescript', 'papyrus', 'parchment', 'perpetuagrassettocorsivo', 'perpetuagrassetto', 'perpetuacorsivo', 'perpetuatitlinggrassetto', 'perpetuatitlingchiarissimo', 'perpetua', 'playbill', 'poorrichard', 'pristina', 'rage', 'ravie', 'msreferencesansserif', 'msreferencespecialty', 'rockwellcondensedgrassetto', 'rockwellcondensed', 'rockwell', 'rockwellgrassetto', 'rockwellgrassettocorsivo', 'rockwellextra', 'rockwellcorsivo', 'centuryschoolbookgrassetto', 'centuryschoolbookgrassettocorsivo', 'centuryschoolbookcorsivo', 'script', 'showcardgothic', 'snapitc', 'stencil', 'twcengrassettocorsivo', 'twcengrassetto', 'twcencondensedgrassetto', 'twcencondensedextra', 'twcencondensed', 'twcencorsivo', 'twcen', 'tempussansitc', 'vinerhanditc', 'vivaldicorsivo', 'vladimirscript', 'wingdings2', 'wingdings3', 'cascadiacoderegular', 'cascadiamonoregular', 'edwardianscriptitcnormale', 'stoneharbourregular', 'mregular', 'xirodregular', 'minecraft']
14
15
 
15
- NEW_FONT :Callable[[int, __LITERAL_FONTS__, bool, bool], pg.font.Font]= lambda size, name="arial", bold=False, italic=False: pg.font.SysFont(name, size, bold, italic)
16
+ def NEW_FONT(size, name:__LITERAL_FONTS__="arial", bold:bool=False, italic:bool=False) -> pg.font.Font:
17
+ return pg.font.SysFont(name, size, bold, italic)
16
18
  FONT_ARIAL_16 = NEW_FONT(16)
17
19
  FONT_ARIAL_32 = NEW_FONT(32)
18
20
  FONT_ARIAL_64 = NEW_FONT(64)
@@ -74,7 +76,7 @@ class Mouse:
74
76
 
75
77
  class Keyboard:
76
78
  def __init__(self) -> None:
77
- self.__pressed__ :list= pg.key.get_pressed()
79
+ self.__pressed__ :pg.key.ScancodeWrapper= pg.key.get_pressed()
78
80
  self.update()
79
81
 
80
82
  def update(self) -> None:
@@ -91,7 +93,6 @@ class Keyboard:
91
93
  else:
92
94
  raise Exception(f"Unknown mode type: {mode}")
93
95
 
94
-
95
96
  class Util:
96
97
  def __init__(self) -> None:
97
98
  self.rootEnv = None
@@ -108,9 +109,9 @@ class InputCell(Util):
108
109
  position : Vector2D,
109
110
  size : Vector2D,
110
111
  prefix : str|None = None,
111
- text_color : tuple[int,int,int]|list[int] = (255,255,255),
112
- bg_color : None|tuple[int,int,int]|list[int] = None,
113
- border_color : None|tuple[int,int,int]|list[int] = (255,255,255),
112
+ text_color : Color = Color.white(),
113
+ bg_color : None|Color = None,
114
+ border_color : Color = Color.white(),
114
115
  border_width : float = 0,
115
116
  border_radius : int|list[int]|tuple[int,int,int,int] = -1,
116
117
  margin : Vector2D = Vector2D.zero(),
@@ -148,13 +149,13 @@ class InputCell(Util):
148
149
  def draw(self) -> None:
149
150
  self.text_surface.fill((0,0,0,0))
150
151
  if self.bg_color != None:
151
- pg.draw.rect(self.text_surface, self.bg_color, self.bg_rect, 0, -1, *self.border_radius)
152
+ pg.draw.rect(self.text_surface, self.bg_color(), self.bg_rect, 0, -1, *self.border_radius)
152
153
 
153
154
  self.text_surface.blit(self.text_box, self.text_position())
154
155
 
155
156
  if self.rootEnv.selected_util != self:
156
157
  if self.border_width:
157
- pg.draw.rect(self.text_surface, self.border_color, self.margin_rect, self.border_width, -1, *self.border_radius)
158
+ pg.draw.rect(self.text_surface, self.border_color(), self.margin_rect, self.border_width, -1, *self.border_radius)
158
159
  else:
159
160
  pg.draw.rect(self.text_surface, [127 + 127 * _mt.sin(self.rootEnv.runtime_seconds * 10)]*3, self.margin_rect, self.border_width if self.border_width else 10, -1, *self.border_radius)
160
161
 
@@ -182,7 +183,7 @@ class InputCell(Util):
182
183
  self.update_text()
183
184
 
184
185
  def update_text(self) -> None:
185
- self.text_box = self.font.render(self.prefix + self.value, True, self.text_color)
186
+ self.text_box = self.font.render(self.prefix + self.value, True, self.text_color())
186
187
  if self.rootEnv != None and self.rootEnv.selected_util == self:
187
188
  # self.text_position = self.position + self.size * Vector2D(.85, .5) - Vector2D(*self.text_box.get_size()) * Vector2D(1, .5) - self.position
188
189
  self.text_position = self.position + self.size * .5 - Vector2D(*self.text_box.get_size()) * Vector2D(.5, .5) - self.position
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: e2D
3
- Version: 1.4.14
3
+ Version: 1.4.16
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
@@ -4,6 +4,7 @@ pyproject.toml
4
4
  setup.cfg
5
5
  e2D/__init__.py
6
6
  e2D/__init__.pyi
7
+ e2D/colors.py
7
8
  e2D/envs.py
8
9
  e2D/plots.py
9
10
  e2D/utils.py
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = e2D
3
- version = 1.4.14
3
+ version = 1.4.16
4
4
  author = Riccardo Mariani
5
5
  author_email = ricomari2006@gmail.com
6
6
  description = Python library for 2D games. Streamlines dev with keyboard/mouse input, vector calculations, color manipulation, and collision detection. Simplify game creation and unleash creativity!
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes