e2D 1.4.9__tar.gz → 1.4.10__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
1
  Metadata-Version: 2.1
2
2
  Name: e2D
3
- Version: 1.4.9
3
+ Version: 1.4.10
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
@@ -105,6 +105,9 @@ class Vector2D:
105
105
  d = (self.x - other.x)**2 + (self.y - other.y)**2
106
106
  return (d**(1/2) if sqrd else d)
107
107
 
108
+ def angle(self:"Vector2D") -> int|float:
109
+ return _mt.atan2(self.y, self.x)
110
+
108
111
  def angle_to(self:"Vector2D", other:"float|int|Vector2D|list|tuple") -> int|float:
109
112
  """
110
113
  # Calculate the angle between the current Vector2D other and another other.
e2d-1.4.10/e2D/envs.py ADDED
@@ -0,0 +1,220 @@
1
+ from __future__ import annotations
2
+
3
+ from .utils import *
4
+ import pygame as pg
5
+ from pygame.event import Event
6
+ from time import time as __tm__
7
+ import math as _mt
8
+ """ CODE EXAMPLE FOR RootEnv
9
+ from e2D.envs import *
10
+
11
+ class Env:
12
+ def __init__(self) -> None:
13
+ pass
14
+
15
+ def draw(self) -> None:
16
+ pass
17
+
18
+ def update(self) -> None:
19
+ pass
20
+
21
+ (rootEnv:=RootEnv()).init(Env())
22
+ while not rootEnv.quit:
23
+ rootEnv.frame()
24
+ """
25
+
26
+ pg.init()
27
+ pg.font.init()
28
+ FONT_ARIAL_16 = pg.font.SysFont("Arial", 16)
29
+ FONT_ARIAL_32 = pg.font.SysFont("Arial", 32)
30
+ FONT_ARIAL_64 = pg.font.SysFont("Arial", 64)
31
+ new_font = lambda size, name="Arial", bold=False, italic=False: pg.font.SysFont(name, size, bold, italic)
32
+
33
+ TEXT_FIXED_SIDES_TOP_LEFT = 0
34
+ TEXT_FIXED_SIDES_TOP_MIDDLE = 1
35
+ TEXT_FIXED_SIDES_TOP_RIGHT = 2
36
+ TEXT_FIXED_SIDES_MIDDLE_LEFT = 3
37
+ TEXT_FIXED_SIDES_MIDDLE_MIDDLE = 4
38
+ TEXT_FIXED_SIDES_MIDDLE_RIGHT = 5
39
+ TEXT_FIXED_SIDES_BOTTOM_LEFT = 6
40
+ TEXT_FIXED_SIDES_BOTTOM_MIDDLE = 7
41
+ TEXT_FIXED_SIDES_BOTTOM_RIGHT = 8
42
+
43
+ FIXED_SIDES_MULTIPLIER = [V2(x,y) for y in [0, .5, 1] for x in [0, .5, 1]]
44
+
45
+ INPUT_CELL_ASCII_TYPE = 0
46
+ INPUT_CELL_ALPHANUM_TYPE = 1
47
+ INPUT_CELL_ALPHA_TYPE = 2
48
+ INPUT_CELL_NUM_TYPE = 3
49
+
50
+ class Utils:
51
+ def __init__(self) -> None:
52
+ self.rootEnv : RootEnv = None # type: ignore
53
+ self.surface : pg.Surface
54
+ def draw(self) -> None: pass
55
+ def update(self) -> None: pass
56
+
57
+ class InputCell(Utils):
58
+ def __init__(self,
59
+ initial_value:str,
60
+ position:V2|Vector2D,
61
+ size:V2|Vector2D,
62
+ prefix:str|None=None,
63
+ text_color:tuple[int,int,int]|list[int]=(255,255,255),
64
+ bg_color:None|tuple[int,int,int]|list[int]=None,
65
+ border_color:None|tuple[int,int,int]|list[int]=(255,255,255),
66
+ border_width:float=0,
67
+ border_radius:int|list[int]|tuple[int,int,int,int]=-1,
68
+ margin:V2|Vector2D=V2z,
69
+ fixed_sides:int=TEXT_FIXED_SIDES_MIDDLE_MIDDLE,
70
+ font:pg.font.Font=FONT_ARIAL_32,
71
+ personalized_surface:pg.Surface|None=None,
72
+ on_enter_pressed=None,
73
+ check_when_adding=None) -> None:
74
+ super().__init__()
75
+
76
+ self.on_enter_pressed = on_enter_pressed
77
+ self.check_when_adding = check_when_adding
78
+ self.prefix = prefix if prefix != None else ""
79
+
80
+ self.text_color = text_color
81
+ self.font = font
82
+ self.surface = personalized_surface
83
+ self.bg_color = bg_color
84
+ # size = V2(*self.text_box.get_size()) + self.margin * 2
85
+ self.size = size
86
+ self.position = (position - size * FIXED_SIDES_MULTIPLIER[fixed_sides] + margin)
87
+ self.bg_rect = [0, 0] + size()
88
+ self.margin_rect = (margin * -1)() + size()
89
+ self.border_color = border_color
90
+ self.border_radius = [border_radius]*4 if not any(isinstance(border_radius, cls) for cls in {tuple, list}) else border_radius
91
+ self.border_width = border_width
92
+
93
+ self.value = initial_value
94
+ self.update_text()
95
+
96
+ self.text_surface = pg.Surface(self.size(), pg.SRCALPHA, 32).convert_alpha()
97
+
98
+ def draw(self) -> None:
99
+ self.text_surface.fill((0,0,0,0))
100
+ if self.bg_color != None:
101
+ pg.draw.rect(self.text_surface, self.bg_color, self.bg_rect, 0, -1, *self.border_radius)
102
+
103
+ self.text_surface.blit(self.text_box, self.text_position())
104
+
105
+ if self.rootEnv.selected_util != self:
106
+ if self.border_width:
107
+ pg.draw.rect(self.text_surface, self.border_color, self.margin_rect, self.border_width, -1, *self.border_radius)
108
+ else:
109
+ pg.draw.rect(self.text_surface, [127 + 127 * _mt.sin(self.rootEnv.get_time_from_start() * 10)]*3, self.margin_rect, self.border_width if self.border_width else 10, -1, *self.border_radius)
110
+
111
+ self.surface.blit(self.text_surface, self.position())
112
+
113
+ def update(self) -> None:
114
+ if self.rootEnv.mouse.just_pressed[0]:
115
+ if self.position.x < self.rootEnv.mouse.position.x < self.position.x + self.size.x and\
116
+ self.position.y < self.rootEnv.mouse.position.y < self.position.y + self.size.y:
117
+ self.rootEnv.selected_util = self if self.rootEnv.selected_util != self else None
118
+ self.update_text()
119
+ if self.rootEnv.selected_util == self:
120
+ for event in self.rootEnv.events:
121
+ if event.type == pg.TEXTINPUT:
122
+ self.value += event.text if self.check_when_adding == None else self.check_when_adding(event.text)
123
+ elif event.type == pg.KEYDOWN and event.key == pg.K_BACKSPACE:
124
+ self.value = self.value[:-1]
125
+ if self.rootEnv.keyboard.get_key(pg.K_DELETE):
126
+ self.value = self.value[:-1]
127
+ if self.rootEnv.keyboard.get_key(pg.K_RETURN, KEY_MODE_JUST_PRESSED):
128
+ if callable(self.on_enter_pressed): self.on_enter_pressed(self.value)
129
+ if self.rootEnv.keyboard.get_key(pg.K_ESCAPE, KEY_MODE_JUST_PRESSED):
130
+ self.rootEnv.selected_util = self if self.rootEnv.selected_util != self else None
131
+ self.update_text()
132
+
133
+ def update_text(self) -> None:
134
+ self.text_box = self.font.render(self.prefix + self.value, True, self.text_color)
135
+ if self.rootEnv != None and self.rootEnv.selected_util == self:
136
+ # self.text_position = self.position + self.size * V2(.85, .5) - V2(*self.text_box.get_size()) * V2(1, .5) - self.position
137
+ self.text_position = self.position + self.size * .5 - V2(*self.text_box.get_size()) * V2(.5, .5) - self.position
138
+ else:
139
+ self.text_position = self.position + self.size * .5 - V2(*self.text_box.get_size()) * V2(.5, .5) - self.position
140
+
141
+ class RootEnv:
142
+ def __init__(self, screen_size:V2|Vector2D=V2(1920, 1080), vsync:bool=True, target_fps:int=60, show_fps=True, quit_on_key_pressed:None|int=pg.K_x, window_flag:int=0, clear_screen_each_frame:bool=True) -> None:
143
+ self.quit = False
144
+ self.screen_size :V2|Vector2D= screen_size
145
+ self.screen = pg.display.set_mode(self.screen_size(), vsync=vsync, flags=window_flag)
146
+ self.target_fps = target_fps
147
+ self.current_fps = self.target_fps if self.target_fps != 0 else 1
148
+ self.delta = 1 / self.current_fps
149
+ self.current_frame = 0
150
+ self.show_fps = show_fps
151
+ self.clock = pg.time.Clock()
152
+ self.keyboard = Keyboard(self)
153
+ self.mouse = Mouse(self)
154
+ self.events :list[Event]= []
155
+ self.background_color = rgb(0,0,0)
156
+ self._quit_on_key_pressed = quit_on_key_pressed
157
+ self.clear_screen_each_frame = clear_screen_each_frame
158
+ self.starting_time :float= __tm__()
159
+ self.utils :list[Utils]= []
160
+ self.selected_util :Utils|None = None
161
+
162
+ def add_utils(self, *utils:Utils) -> None:
163
+ for util in utils:
164
+ if util.surface == None: util.surface = self.screen
165
+ util.rootEnv = self
166
+ self.utils.extend(utils)
167
+
168
+ def remove_utils(self, *utils:list[Utils]) -> None:
169
+ for u in utils: self.utils.remove(u)
170
+
171
+ def get_time_from_start(self) -> float:
172
+ return __tm__() - self.starting_time
173
+
174
+ def init(self, sub_env) -> None:
175
+ self.env = sub_env
176
+
177
+ def clear(self) -> None:
178
+ self.screen.fill(self.background_color)
179
+
180
+ def clear_rect(self, position:V2|Vector2D, size:V2|Vector2D) -> None:
181
+ self.screen.fill(self.background_color, position() + size())
182
+
183
+ def print(self, text:str, position:V2|Vector2D, color:tuple[float,float,float]=(255,255,255), fixed_sides=TEXT_FIXED_SIDES_TOP_LEFT, font:pg.font.Font=FONT_ARIAL_32, bg_color:None|tuple[int,int,int]|list[int]=None, border_color:None|tuple[int,int,int]|list[int]=(255,255,255), border_width:float=0, border_radius:int|list[int]|tuple[int,int,int,int]=-1, margin:V2|Vector2D=V2z, personalized_surface:pg.Surface|None=None) -> None:
184
+ text_box = font.render(text, True, color)
185
+ size = V2(*text_box.get_size()) + margin * 2
186
+ position = position - size * FIXED_SIDES_MULTIPLIER[fixed_sides] + margin
187
+ if not any(isinstance(border_radius, cls) for cls in {tuple, list}): border_radius = [border_radius]*4
188
+ surface = (self.screen if personalized_surface == None else personalized_surface)
189
+ if bg_color != None:
190
+ pg.draw.rect(surface, bg_color, (position - margin)() + size(), 0, -1, *border_radius)
191
+ if border_width:
192
+ pg.draw.rect(surface, border_color, (position - margin)() + size(), border_width, -1, *border_radius)
193
+ surface.blit(text_box, position())
194
+
195
+ def __draw__(self) -> None:
196
+ self.clock.tick(self.target_fps)
197
+ self.current_fps = self.clock.get_fps()
198
+ self.delta = 1 / (self.current_fps if self.current_fps != 0 else 1)
199
+ if self.clear_screen_each_frame: self.clear()
200
+ if self.show_fps: self.print(str(round(self.current_fps,2)), self.screen_size * .01, bg_color=(0,0,0))
201
+
202
+ self.env.draw()
203
+ for util in self.utils: util.draw()
204
+ pg.display.update()
205
+
206
+ def __update__(self) -> None:
207
+ self.mouse.update()
208
+ self.keyboard.update()
209
+ self.env.update()
210
+ for util in self.utils: util.update()
211
+
212
+ def frame(self) -> None:
213
+ self.events = pg.event.get()
214
+ self.current_frame += 1
215
+ self.__update__()
216
+ self.__draw__()
217
+
218
+ for event in self.events:
219
+ 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):
220
+ self.quit = True
@@ -66,18 +66,30 @@ class Line(Object):
66
66
  pg.draw.line(self.__layer_surface__, self.color, self.point_a.center(), self.point_b.center(), self.width)
67
67
 
68
68
  class Point(Object):
69
- def __init__(self, position, label:str="", radius:float=1, color:list[float]|tuple[float,float,float]=(255,255,255)) -> None:
69
+ def __init__(self, position, label:str="", radius:float=1, color:list[float]|tuple[float,float,float]=(255,255,255),
70
+ label_color:tuple[float, float, float]=(255, 255, 255), label_position_offset:Vector2D|V2=V2z, label_fixed_sides:int=TEXT_FIXED_SIDES_TOP_LEFT, label_font:pg.font.Font=FONT_ARIAL_32, label_bg_color:tuple[int,int,int]|list[int]|None=None, label_border_color:tuple[int,int,int]|list[int]|None=None, label_border_width:float=0, label_border_radius:int|list[int]|tuple[int,int,int,int]=-1, label_margin:V2=V2z) -> None:
70
71
  super().__init__()
71
72
  self.position = position
72
73
  self.radius = radius
73
74
  self.color = color
74
75
  self.label = label
76
+ self.label_color = label_color
77
+ self.label_position_offset = label_position_offset
78
+ self.label_fixed_sides = label_fixed_sides
79
+ self.label_font = label_font
80
+ self.label_bg_color = label_bg_color
81
+ self.label_border_color = label_border_color
82
+ self.label_border_width = label_border_width
83
+ self.label_border_radius = label_border_radius
84
+ self.label_margin = label_margin
85
+
75
86
  self.rect :list[float]= [0, 0, 0, 0]
76
87
  self.center = V2z.copy()
77
88
 
78
89
  def update(self) -> None:
79
90
  radius = self.radius * self.plot.size / (self.plot.bottom_right_plot_coord - self.plot.top_left_plot_coord) * self.plot.__y_axis_multiplier__
80
91
  self.center = self.plot.__plot2real__(self.position)
92
+ self.text_position = self.plot.__plot2real__(self.position + self.label_position_offset)
81
93
  position = self.center - radius * .5
82
94
  self.rect = position() + radius()
83
95
  self.__render__()
@@ -85,6 +97,7 @@ class Point(Object):
85
97
  def __render__(self) -> None:
86
98
  self.__layer_surface__.fill((0,0,0,0))
87
99
  pg.draw.ellipse(self.__layer_surface__, self.color, self.rect)
100
+ self.plot.rootEnv.print(self.label, self.text_position, color=self.label_color, fixed_sides=self.label_fixed_sides, font=self.label_font, bg_color=self.label_bg_color, border_color=self.label_border_color, border_width=self.label_border_width, border_radius=self.label_border_radius, margin=self.label_margin, personalized_surface=self.__layer_surface__)
88
101
 
89
102
  class MathFunction(Function):
90
103
  def __init__(self, function, domain:list[float]=[-np.inf, np.inf], codomain:list[float]=[-np.inf, np.inf], color:list[float]|tuple[float,float,float]=(255,255,255)) -> None:
@@ -250,6 +263,8 @@ class __PlotSettings__:
250
263
  # cursor
251
264
  "zoom_on_center" : False,
252
265
  "warp_mouse" : True,
266
+ "movable" : True,
267
+ "zoomable" : True,
253
268
 
254
269
  # plot visual options
255
270
  # plot system
@@ -284,7 +299,7 @@ class __PlotSettings__:
284
299
  # cursor
285
300
  "show_cursor_coords" : False,
286
301
 
287
- #rect
302
+ # rect
288
303
  "render_bg" : True,
289
304
  "bg_color" : rgb(28, 29, 34),
290
305
  "draw_rect" : True,
@@ -296,7 +311,7 @@ class __PlotSettings__:
296
311
  "show_zoom_info": True,
297
312
  "top_left_info_position" : self.plot.position + V2(15, 75),
298
313
  "info_interline_space" : V2(0, 24),
299
- "info_font" : create_arial_font_size(24),
314
+ "info_font" : new_font(24),
300
315
  "info_precision" : 2,
301
316
  }
302
317
 
@@ -401,7 +416,7 @@ class Plot:
401
416
  clamped_top_left = grid_step * (self.top_left_plot_coord / grid_step).__ceil__()
402
417
  clamped_bottom_right = grid_step * (self.bottom_right_plot_coord / grid_step).__ceil__()
403
418
  for x_value in np.arange(clamped_top_left.x, clamped_bottom_right.x, grid_step.x): #type: ignore
404
- 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) #type: ignore
419
+ 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) #type: ignore
405
420
  for y_value in np.arange(clamped_bottom_right.y, clamped_top_left.y, grid_step.y): #type: ignore
406
421
  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) #type: ignore
407
422
 
@@ -442,27 +457,29 @@ class Plot:
442
457
  self.focus()
443
458
 
444
459
  if self.is_mouse_in_rect:
445
- # 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.
446
- 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
447
- if self.mouse_scalar.x == self.mouse_scalar.y == 0: self.mouse_scalar = V2one
448
- for event in self.rootEnv.events:
449
- if event.type == pg.MOUSEWHEEL:
450
- if self.settings.get("zoom_on_center"):
451
- # this will always zoom exactly in the middle of the canvas, according to the current plot offset
452
- self.current_zoom += event.y * self.mouse_scalar
453
- else:
454
- # 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
455
- pre = self.__real2plot__(self.rootEnv.mouse.position)
456
- self.current_zoom += event.y * self.mouse_scalar
457
- # i have to update the corners of the plot here to use the real2plot function correctly (i cant use shortcuts)
458
- self.update_grid(False)
459
- self.current_offset += pre - self.__real2plot__(self.rootEnv.mouse.position)
460
- self.focus()
460
+ if self.settings.get("zoomable"):
461
+ # 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.
462
+ 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
463
+ if self.mouse_scalar.x == self.mouse_scalar.y == 0: self.mouse_scalar = V2one
464
+ for event in self.rootEnv.events:
465
+ if event.type == pg.MOUSEWHEEL:
466
+ if self.settings.get("zoom_on_center"):
467
+ # this will always zoom exactly in the middle of the canvas, according to the current plot offset
468
+ self.current_zoom += event.y * self.mouse_scalar
469
+ else:
470
+ # 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
471
+ pre = self.__real2plot__(self.rootEnv.mouse.position)
472
+ self.current_zoom += event.y * self.mouse_scalar
473
+ # i have to update the corners of the plot here to use the real2plot function correctly (i cant use shortcuts)
474
+ self.update_grid(False)
475
+ self.current_offset += pre - self.__real2plot__(self.rootEnv.mouse.position)
476
+ self.focus()
461
477
 
462
- # start dragging whenever mouse left button is just pressed
463
- if self.rootEnv.mouse.just_pressed[0] and self.dragging == None:
464
- self.dragging = self.rootEnv.mouse.position.copy()
465
- self.start_dragging = self.dragging.copy()
478
+ if self.settings.get("movable"):
479
+ # start dragging whenever mouse left button is just pressed
480
+ if self.rootEnv.mouse.just_pressed[0] and self.dragging == None:
481
+ self.dragging = self.rootEnv.mouse.position.copy()
482
+ self.start_dragging = self.dragging.copy()
466
483
 
467
484
  # update the canvas if im dragging
468
485
  if self.dragging:
@@ -7,7 +7,7 @@ KEY_MODE_JUST_PRESSED = 1
7
7
  KEY_MODE_JUST_RELEASED = 2
8
8
 
9
9
  SCANCODES = {"":0,"backspace":8,"tab":9,"return":13,"escape":27,"space":32,"!":33,"\"":34,"#":35,"$":36,"%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,"-":45,".":46,"/":47,"0":48,"1":49,"2":50,"3":51,"4":52,"5":53,"6":54,"7":55,"8":56,"9":57,":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64,"[":91,"\\":92,"]":93,"^":94,"_":95,"`":96,"a":97,"b":98,"c":99,"d":100,"e":101,"f":102,"g":103,"h":104,"i":105,"j":106,"k":107,"l":108,"m":109,"n":110,"o":111,"p":112,"q":113,"r":114,"s":115,"t":116,"u":117,"v":118,"w":119,"x":120,"y":121,"z":122,"delete":127,"caps lock":1073741881,"f1":1073741882,"f2":1073741883,"f3":1073741884,"f4":1073741885,"f5":1073741886,"f6":1073741887,"f7":1073741888,"f8":1073741889,"f9":1073741890,"f10":1073741891,"f11":1073741892,"f12":1073741893,"print screen":1073741894,"scroll lock":1073741895,"break":1073741896,"insert":1073741897,"home":1073741898,"page up":1073741899,"end":1073741901,"page down":1073741902,"right":1073741903,"left":1073741904,"down":1073741905,"up":1073741906,"numlock":1073741907,"[/]":1073741908,"[*]":1073741909,"[-]":1073741910,"[+]":1073741911,"enter":1073741912,"[1]":1073741913,"[2]":1073741914,"[3]":1073741915,"[4]":1073741916,"[5]":1073741917,"[6]":1073741918,"[7]":1073741919,"[8]":1073741920,"[9]":1073741921,"[0]":1073741922,"[.]":1073741923,"power":1073741926,"equals":1073741927,"f13":1073741928,"f14":1073741929,"f15":1073741930,"help":1073741941,"menu":1073741942,"sys req":1073741978,"clear":1073741980,"euro":1073742004,"CurrencySubUnit":1073742005,"left ctrl":1073742048,"left shift":1073742049,"left alt":1073742050,"left meta":1073742051,"right ctrl":1073742052,"right shift":1073742053,"right alt":1073742054,"right meta":1073742055,"alt gr":1073742081,"AC Back":1073742094}
10
- SCANCODES_NUMS = [i for i in SCANCODES.values()]
10
+ SCANCODES_NUMS = {SCANCODES[key]:i for i,key in enumerate(SCANCODES)}
11
11
 
12
12
  class Mouse:
13
13
  def __init__(self, parent) -> None:
@@ -37,13 +37,14 @@ class Keyboard:
37
37
  def __init__(self, parent) -> None:
38
38
  self.parent = parent
39
39
  self.__pressed__ :list= [False for _ in SCANCODES_NUMS]
40
- self.__just_pressed__ :list= [False for _ in range(len(self.__pressed__))]
41
- self.__just_released__ :list= [False for _ in range(len(self.__pressed__))]
40
+ self.__just_pressed__ :list= [False for _ in SCANCODES_NUMS]
41
+ self.__just_released__ :list= [False for _ in SCANCODES_NUMS]
42
42
  self.update()
43
43
 
44
44
  def update(self) -> None:
45
+ tmp_pressed = pg.key.get_pressed()
45
46
  last_pressed = self.__pressed__.copy()
46
- self.__pressed__ :list= [pg.key.get_pressed()[i] for i in SCANCODES_NUMS] # type: ignore
47
+ self.__pressed__ :list= [tmp_pressed[i] for i in SCANCODES_NUMS] # type: ignore
47
48
  self.__just_pressed__ = [self.__pressed__[i] and not last_pressed[i] for i in range(len(SCANCODES_NUMS))]
48
49
  self.__just_released__ = [not self.__pressed__[i] and last_pressed[i] for i in range(len(SCANCODES_NUMS))]
49
50
 
@@ -82,4 +83,4 @@ class Keyboard:
82
83
  ll = self.__just_pressed__
83
84
  elif mode == KEY_MODE_JUST_RELEASED:
84
85
  ll = self.__just_released__
85
- return ll[SCANCODES_NUMS.index(scan_code)]
86
+ return ll[SCANCODES_NUMS[scan_code]]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: e2D
3
- Version: 1.4.9
3
+ Version: 1.4.10
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
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = e2D
3
- version = 1.4.9
3
+ version = 1.4.10
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!
e2D-1.4.9/e2D/envs.py DELETED
@@ -1,108 +0,0 @@
1
- from __future__ import annotations
2
- from .utils import *
3
- import pygame as pg
4
- from time import time as __tm__
5
-
6
- """ CODE EXAMPLE FOR RootEnv
7
- from e2D.envs import *
8
-
9
- class Env:
10
- def __init__(self) -> None:
11
- pass
12
-
13
- def draw(self) -> None:
14
- pass
15
-
16
- def update(self) -> None:
17
- pass
18
-
19
- (rootEnv:=RootEnv()).init(Env())
20
- while not rootEnv.quit:
21
- rootEnv.frame()
22
- """
23
-
24
- pg.init()
25
- pg.font.init()
26
- FONT_ARIAL_16 = pg.font.SysFont("Arial", 16)
27
- FONT_ARIAL_32 = pg.font.SysFont("Arial", 32)
28
- FONT_ARIAL_64 = pg.font.SysFont("Arial", 64)
29
- create_arial_font_size = lambda size: pg.font.SysFont("Arial", size)
30
-
31
- TEXT_FIXED_SIDES_TOP_LEFT = 0
32
- TEXT_FIXED_SIDES_TOP_MIDDLE = 1
33
- TEXT_FIXED_SIDES_TOP_RIGHT = 2
34
- TEXT_FIXED_SIDES_MIDDLE_LEFT = 3
35
- TEXT_FIXED_SIDES_MIDDLE_MIDDLE = 4
36
- TEXT_FIXED_SIDES_MIDDLE_RIGHT = 5
37
- TEXT_FIXED_SIDES_BOTTOM_LEFT = 6
38
- TEXT_FIXED_SIDES_BOTTOM_MIDDLE = 7
39
- TEXT_FIXED_SIDES_BOTTOM_RIGHT = 8
40
-
41
- class RootEnv:
42
- __fixed_sides_multiplier = [V2(x,y) for y in [0, .5, 1] for x in [0, .5, 1]]
43
- def __init__(self, screen_size:V2|Vector2D=V2(1920, 1080), vsync:bool=True, target_fps:int=60, show_fps=True, quit_on_key_pressed:None|int=pg.K_x, window_flag:int=0, clear_screen_each_frame:bool=True) -> None:
44
- self.quit = False
45
- self.screen_size :V2|Vector2D= screen_size
46
- self.screen = pg.display.set_mode(self.screen_size(), vsync=vsync, flags=window_flag)
47
- self.target_fps = target_fps
48
- self.current_fps = self.target_fps if self.target_fps != 0 else 1
49
- self.delta = 1 / self.current_fps
50
- self.current_frame = 0
51
- self.show_fps = show_fps
52
- self.clock = pg.time.Clock()
53
- self.keyboard = Keyboard(self)
54
- self.mouse = Mouse(self)
55
- self.events :list= []
56
- self.background_color = rgb(0,0,0)
57
- self._quit_on_key_pressed = quit_on_key_pressed
58
- self.clear_screen_each_frame = clear_screen_each_frame
59
- self.starting_time = __tm__()
60
-
61
- def get_time_from_start(self) -> float:
62
- return __tm__() - self.starting_time
63
-
64
- def init(self, sub_env) -> None:
65
- self.env = sub_env
66
-
67
- def clear(self) -> None:
68
- self.screen.fill(self.background_color)
69
-
70
- def clear_rect(self, position:V2|Vector2D, size:V2|Vector2D) -> None:
71
- self.screen.fill(self.background_color, position() + size())
72
-
73
- def print(self, text:str, position:V2|Vector2D, color:tuple[float,float,float]=(255,255,255), fixed_sides=TEXT_FIXED_SIDES_TOP_LEFT, font:pg.font.Font=FONT_ARIAL_32, bg_color:None|tuple[int,int,int]|list[int]=None, border_color:None|tuple[int,int,int]|list[int]=None, border_width:float=0, border_radius:int|list[int]|tuple[int,int,int,int]=-1, margin:V2|Vector2D=V2z, personalized_surface:pg.Surface|None=None) -> None:
74
- text_box = font.render(text, True, color)
75
- size = V2(*text_box.get_size()) + margin * 2
76
- position = position - size * self.__fixed_sides_multiplier[fixed_sides] + margin
77
- if not any(isinstance(border_radius, cls) for cls in {tuple, list}): border_radius = [border_radius]*4
78
- surface = (self.screen if personalized_surface == None else personalized_surface)
79
- if bg_color != None:
80
- pg.draw.rect(surface, bg_color, (position - margin)() + size(), 0, -1, *border_radius)
81
- if border_width:
82
- pg.draw.rect(surface, border_color, (position - margin)() + size(), border_width, -1, *border_radius)
83
- surface.blit(text_box, position())
84
-
85
- def __draw__(self) -> None:
86
- self.clock.tick(self.target_fps)
87
- self.current_fps = self.clock.get_fps()
88
- self.delta = 1 / (self.current_fps if self.current_fps != 0 else 1)
89
- if self.clear_screen_each_frame: self.clear()
90
- if self.show_fps: self.print(str(round(self.current_fps,2)), self.screen_size * .01, bg_color=(0,0,0))
91
-
92
- self.env.draw()
93
- pg.display.update()
94
-
95
- def __update__(self) -> None:
96
- self.mouse.update()
97
- self.keyboard.update()
98
- self.env.update()
99
-
100
- def frame(self) -> None:
101
- self.__update__()
102
- self.__draw__()
103
-
104
- self.current_frame += 1
105
- self.events = pg.event.get()
106
- for event in self.events:
107
- if event.type == pg.QUIT or ((event.type == pg.KEYDOWN and event.key == self._quit_on_key_pressed) if self._quit_on_key_pressed != None else False):
108
- self.quit = True
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes