crystalwindow 4.9__py3-none-any.whl → 5.1__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.
crystalwindow/__init__.py CHANGED
@@ -44,7 +44,7 @@ from .draw_text_helper import DrawTextManager
44
44
  from .draw_tool import CrystalDraw
45
45
 
46
46
  # === Misc Helpers ===
47
- from .fun_helpers import random_name, DebugOverlay, random_color, random_palette, lerp, random_number
47
+ from .fun_helpers import random_name, DebugOverlay, random_color, random_palette, lerp, random_number, random_pos, random_bool, random_choice_weighted, difference
48
48
  from .camera import Camera
49
49
  from .color_handler import Colors, Color
50
50
  from .websearch import SearchResult, WebBrowse
@@ -93,7 +93,7 @@ __all__ = [
93
93
 
94
94
  # --- Misc ---
95
95
  "random_name", "DebugOverlay", "Camera", "Colors", "Color",
96
- "random_palette", "lerp", "SearchResult", "WebBrowse", "random_number",
96
+ "random_palette", "lerp", "SearchResult", "WebBrowse", "random_number", "random_pos", "random_bool", "random_choice_weighted", "difference",
97
97
 
98
98
  # --- 3D ---
99
99
  "CW3DShape", "CW3D",
crystalwindow/camera.py CHANGED
@@ -5,7 +5,7 @@ class Camera:
5
5
  self.offset_y = 0
6
6
  self.speed = speed # smoothness
7
7
 
8
- def update(self, win_width, win_height):
8
+ def update(self, win_width, win_height, dt):
9
9
  # camera aims for target center
10
10
  target_x = self.target.x - win_width // 2
11
11
  target_y = self.target.y - win_height // 2
@@ -14,6 +14,29 @@ class Camera:
14
14
  self.offset_x += (target_x - self.offset_x) * self.speed
15
15
  self.offset_y += (target_y - self.offset_y) * self.speed
16
16
 
17
+ if hasattr(self, "shake"):
18
+ self.shake.update(dt)
19
+
17
20
  def apply(self, obj):
18
21
  # shift object's draw position by camera offset
19
- return obj.x - self.offset_x, obj.y - self.offset_y
22
+ sx, sy = (0, 0)
23
+ if hasattr(self, "shake"):
24
+ sx, sy = self.shake.offset
25
+
26
+ return (
27
+ obj.x -self.offset_x + sx,
28
+ obj.y -self.offset_y + sy
29
+ )
30
+
31
+ def shake_scrn(self, intensity=5, secs=1):
32
+ # the shake screen effect shakes the screen for an ammount of time/secs
33
+ from .draw_helpers import CameraShake
34
+ self.shake = CameraShake(intensity, secs)
35
+
36
+ def move_to(self, x, y):
37
+ self.offset_x = x
38
+ self.offset_y = y
39
+
40
+ def reset_pos(self):
41
+ self.offset_x = 0
42
+ self.offset_y = 0
crystalwindow/clock.py CHANGED
@@ -78,9 +78,6 @@ class Clock:
78
78
  self.delta = raw_delta
79
79
  self.frame_times.append(raw_delta)
80
80
 
81
- # Scheduler update
82
- self.scheduler.run_pending()
83
-
84
81
  return self.delta
85
82
 
86
83
  def get_fps(self):
@@ -13,11 +13,18 @@ def gradient_rect(win, rect, color_start, color_end, vertical=True):
13
13
  win.draw_rect((r,g,b), (x+i,y,1,h))
14
14
 
15
15
  class CameraShake:
16
- def __init__(self, intensity=5):
16
+ def __init__(self, intensity=5, duration=1):
17
17
  self.intensity = intensity
18
- self.offset = (0,0)
18
+ self.time_left = duration
19
+ self.offset = (0, 0)
19
20
 
20
- def update(self):
21
+ def update(self, dt):
21
22
  import random
22
- self.offset = (random.randint(-self.intensity,self.intensity),
23
- random.randint(-self.intensity,self.intensity))
23
+ if self.time_left > 0:
24
+ self.time_left -= dt
25
+ self.offset = (
26
+ random.randint(-self.intensity, self.intensity),
27
+ random.randint(-self.intensity, self.intensity)
28
+ )
29
+ else:
30
+ self.offset = (0, 0)
@@ -1,32 +1,197 @@
1
1
  import random
2
+ import time
3
+
4
+ # ============================================================
5
+ # RANDOM HELPERS
6
+ # ============================================================
2
7
 
3
- # random color helpers
4
8
  def random_color():
5
- return (random.randint(0,255), random.randint(0,255), random.randint(0,255))
9
+ return (
10
+ random.randint(0, 255),
11
+ random.randint(0, 255),
12
+ random.randint(0, 255)
13
+ )
6
14
 
7
15
  def random_palette(n=5):
8
16
  return [random_color() for _ in range(n)]
9
17
 
10
- # random name generator
11
- def random_name():
12
- syllables = ["ka","zi","lo","ra","mi","to","na","ve"]
13
- return "".join(random.choice(syllables) for _ in range(3))
18
+ def random_pastel():
19
+ return (
20
+ random.randint(150, 255),
21
+ random.randint(150, 255),
22
+ random.randint(150, 255)
23
+ )
24
+
25
+ def random_bool(chance=0.5):
26
+ return random.random() < chance
14
27
 
15
- #Choose a random number
16
28
  def random_number(min_val, max_val):
17
29
  return random.randint(min_val, max_val)
18
30
 
19
- # tween helper
31
+ def random_pos(w, h):
32
+ return (
33
+ random.randint(0, w),
34
+ random.randint(0, h)
35
+ )
36
+
37
+ def random_choice_weighted(items, weights):
38
+ return random.choices(items, weights=weights, k=1)[0]
39
+
40
+
41
+ # ============================================================
42
+ # NAME / TEXT HELPERS
43
+ # ============================================================
44
+
45
+ def random_name(syllables=3):
46
+ pool = ["ka","zi","lo","ra","mi","to","na","ve","xo","qu"]
47
+ return "".join(random.choice(pool) for _ in range(syllables))
48
+
49
+
50
+ # ============================================================
51
+ # DIFFERENCE TELLER
52
+ # ============================================================
53
+ class difference:
54
+ @staticmethod
55
+ def tell(obj1, obj2):
56
+ diffs = {}
57
+
58
+ for attr in vars(obj1):
59
+ if hasattr(obj2, attr):
60
+ v1 = getattr(obj1, attr)
61
+ v2 = getattr(obj2, attr)
62
+
63
+ if v1 != v2:
64
+ diffs[attr] = difference._distance(v1, v2)
65
+
66
+ return diffs
67
+
68
+ @staticmethod
69
+ def _distance(a, b):
70
+ if isinstance(a, (int, float)) and isinstance(b, (int, float)):
71
+ return abs(b - a)
72
+
73
+ if isinstance(a, tuple) and isinstance(b, tuple):
74
+ return sum(abs(b[i] - a[i]) for i in range(min(len(a), len(b))))
75
+
76
+ return 1
77
+
78
+ @staticmethod
79
+ def _get_name(obj):
80
+ # priority: explicit name attr
81
+ if hasattr(obj, "name"):
82
+ return obj.name
83
+
84
+ # fallback: class name
85
+ return obj.__class__.__name__
86
+
87
+ @staticmethod
88
+ def score(obj1, obj2):
89
+ name1 = difference._get_name(obj1)
90
+ name2 = difference._get_name(obj2)
91
+
92
+ diffs = difference.tell(obj1, obj2)
93
+
94
+ if not diffs:
95
+ print(f"The Difference of '{name1}' and '{name2}' are: 0%")
96
+ return 0
97
+
98
+ max_score = len(diffs) * 100
99
+ raw_score = sum(min(v, 100) for v in diffs.values())
100
+ percent = int((raw_score / max_score) * 100)
101
+
102
+ print(f"The Difference of '{name1}' and '{name2}' are: {percent}%")
103
+ return percent
104
+
105
+
106
+ # ============================================================
107
+ # MATH / TWEEN HELPERS
108
+ # ============================================================
109
+
20
110
  def lerp(a, b, t):
21
111
  return a + (b - a) * t
22
112
 
23
- # debug overlay
113
+ def clamp(val, minv=0, maxv=255):
114
+ return max(minv, min(maxv, val))
115
+
116
+ def clamp01(t):
117
+ return max(0.0, min(1.0, t))
118
+
119
+ def smoothstep(a, b, t):
120
+ t = clamp01(t)
121
+ t = t * t * (3 - 2 * t)
122
+ return a + (b - a) * t
123
+
124
+ def approach(current, target, speed):
125
+ if current < target:
126
+ return min(current + speed, target)
127
+ return max(current - speed, target)
128
+
129
+ def sign(x):
130
+ return -1 if x < 0 else (1 if x > 0 else 0)
131
+
132
+
133
+ # ============================================================
134
+ # COLOR MODIFIERS
135
+ # ============================================================
136
+
137
+ def lighten(color, amount=30):
138
+ r, g, b = color
139
+ return (
140
+ clamp(r + amount),
141
+ clamp(g + amount),
142
+ clamp(b + amount)
143
+ )
144
+
145
+ def darken(color, amount=30):
146
+ r, g, b = color
147
+ return (
148
+ clamp(r - amount),
149
+ clamp(g - amount),
150
+ clamp(b - amount)
151
+ )
152
+
153
+
154
+ # ============================================================
155
+ # TIME HELPERS
156
+ # ============================================================
157
+
158
+ def timer_passed(start_time, duration):
159
+ return (time.perf_counter() - start_time) >= duration
160
+
161
+
162
+ # ============================================================
163
+ # DEBUG OVERLAY
164
+ # ============================================================
165
+
24
166
  class DebugOverlay:
25
167
  def __init__(self):
26
168
  self.active = True
169
+ self.lines = []
170
+
171
+ def toggle(self):
172
+ self.active = not self.active
173
+
174
+ def log(self, text):
175
+ self.lines.append(str(text))
176
+ if len(self.lines) > 6:
177
+ self.lines.pop(0)
178
+
179
+ def clear(self):
180
+ self.lines.clear()
181
+
182
+ def draw(self, win, fps=0):
183
+ if not self.active:
184
+ return
185
+
186
+ y = 10
187
+ win.draw_text(f"FPS: {int(fps)}", pos=(10, y))
188
+ y += 20
189
+
190
+ if hasattr(win, "mouse_pos"):
191
+ mx, my = win.mouse_pos
192
+ win.draw_text(f"Mouse: {mx},{my}", pos=(10, y))
193
+ y += 20
27
194
 
28
- def draw(self, win, fps=60):
29
- if self.active:
30
- win.draw_text(f"FPS: {fps}", pos=(10,10))
31
- mx,my = win.mouse_pos
32
- win.draw_text(f"Mouse: {mx},{my}", pos=(10,30))
195
+ for line in self.lines:
196
+ win.draw_text(line, pos=(10, y))
197
+ y += 18
crystalwindow/gui.py CHANGED
@@ -16,13 +16,14 @@ def lerp_color(c1, c2, t):
16
16
 
17
17
  # ----------------- GUI Elements -----------------
18
18
  class Button:
19
- def __init__(self, rect, text,
19
+ def __init__(self, pos, size, text,
20
20
  color=(200,200,200),
21
21
  hover_color=(255,255,255),
22
22
  press_color=(180,180,180),
23
23
  text_color=(0,0,0)):
24
24
 
25
- self.rect = rect
25
+ self.pos = pos
26
+ self.size = size
26
27
  self.text = text
27
28
 
28
29
  self.color = color
@@ -45,7 +46,8 @@ class Button:
45
46
  # ======================================
46
47
  def update(self, win):
47
48
  mx, my = win.mouse_pos
48
- x, y, w, h = self.rect
49
+ x, y = self.pos
50
+ w, h = self.size
49
51
 
50
52
  # Reset transient states
51
53
  self._clicked = False
@@ -94,7 +96,8 @@ class Button:
94
96
  # DRAW
95
97
  # ======================================
96
98
  def draw(self, win):
97
- x, y, w, h = self.rect
99
+ x, y = self.pos
100
+ w, h = self.size
98
101
 
99
102
  # choose color by state
100
103
  if self._held:
crystalwindow/objects.py CHANGED
@@ -71,21 +71,21 @@ class Player(Sprite):
71
71
  spd = self.speed * dt * 60
72
72
 
73
73
  # movement
74
- if win.is_key_pressed("left"):
74
+ if win.key_pressed("left"):
75
75
  self.x -= spd
76
76
  self.flip_x = True
77
77
  moving = True
78
78
 
79
- if win.is_key_pressed("right"):
79
+ if win.key_pressed("right"):
80
80
  self.x += spd
81
81
  self.flip_x = False
82
82
  moving = True
83
83
 
84
- if win.is_key_pressed("up"):
84
+ if win.key_pressed("up"):
85
85
  self.y -= spd
86
86
  moving = True
87
87
 
88
- if win.is_key_pressed("down"):
88
+ if win.key_pressed("down"):
89
89
  self.y += spd
90
90
  moving = True
91
91
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crystalwindow
3
- Version: 4.9
3
+ Version: 5.1
4
4
  Summary: A Tkinter powered window + GUI toolkit made by Crystal (ME)! Easier apps, smoother UI and all-in-one helpers!, Gui, Buttons, FileHelper, Sprites, Animations, Colors, Math, Gravity, Camera, 3D and more!
5
5
  Home-page: https://pypi.org/project/crystalwindow/
6
6
  Author: CrystalBallyHereXD
@@ -1,25 +1,25 @@
1
1
  crystalwindow/FileHelper.py,sha256=U20iwND4jX1y91TOK46e8MPH8xyw7GOrZ697nPEnOPk,10706
2
- crystalwindow/__init__.py,sha256=3YBPnMJuc-jatE__Ts-cs5s2J1OWeDE7HzgCv95ykdA,2823
2
+ crystalwindow/__init__.py,sha256=dqow94sID2DEnUwiIFtmz38RrVGautAVMz1c4Wrt6BU,2953
3
3
  crystalwindow/ai.py,sha256=YIt6dNe1QljSAlNECCVa3DMUSIqQEJRIAAbQpYqFNNo,11525
4
4
  crystalwindow/animation.py,sha256=zHjrdBXQeyNaLAuaGPldJueX05OZ5j31YR8NizmR0uQ,427
5
5
  crystalwindow/assets.py,sha256=8MxPSk7W5YcBnKDh6KcLdg34uxmACf_m6feSYFCWHqA,11405
6
- crystalwindow/camera.py,sha256=tbn4X-jxMIszAUg3Iu-89gJN5nij0mjPMEzGotcLbJI,712
6
+ crystalwindow/camera.py,sha256=1PGGzCCelI6a7aWOuiqqM2OgmrHOBeyobAnSbX-tWgw,1338
7
7
  crystalwindow/chatvpn.py,sha256=Ij3wRNrMbPINO-SX9vx8xlrKRLvG7zJgzAN2T0jzSz8,2477
8
- crystalwindow/clock.py,sha256=LZUm4WoAnJuGA-efRKkLHRE9cxCs3pRhwcZZF14fIKA,5109
8
+ crystalwindow/clock.py,sha256=M7oMjnGNkFOcchqtQn_voWao4kFtxXpTJe2VUjqvGKQ,5041
9
9
  crystalwindow/collision.py,sha256=hpkHTp_KparghVK-itp_rxuYdd2GbQMxICHlUBv0rSw,472
10
10
  crystalwindow/color_handler.py,sha256=K3LipCPOjYt1NemeT-hNWf886LL59QgRN8ifHOi7-0M,3255
11
11
  crystalwindow/crystal3d.py,sha256=8n42S71NZWgBgYwP8ZWfobXFeWvNrhJY80YGK-PzI8s,5375
12
- crystalwindow/draw_helpers.py,sha256=HqjI5fTbdnA55g4LKYEuMUdIjrWaBm2U8RmeUXjcQGw,821
12
+ crystalwindow/draw_helpers.py,sha256=S1jkZbq-9NZrBPJ3tAl1abIc0M-GgNJkHfOtEnQZuS4,1019
13
13
  crystalwindow/draw_rects.py,sha256=o7siET3y35N2LPeNBGe8QhsQbOH8J-xF6fOUz07rymU,1484
14
14
  crystalwindow/draw_text_helper.py,sha256=qv5fFCuTCKWeGDk9Z_ZpOzrTFP8YYwlgQrrorwrq9Hg,1298
15
15
  crystalwindow/draw_tool.py,sha256=1YYEqjmgt4HpV3S15sTjCSmcqgHup4fD8gskTkxU0t4,1638
16
- crystalwindow/fun_helpers.py,sha256=x-OF5dlMlHgvXjtT7Om8RvzKWgizSwnzeaM0_W3-SKQ,870
16
+ crystalwindow/fun_helpers.py,sha256=UHfveBTJ3NlgFd8ZbEJpHtQL-YUWiG7Hl9CWhT06VmQ,5144
17
17
  crystalwindow/gravity.py,sha256=pZJykZzO-mKVBPsZRP55nnlvUoYQfR29wPgJcI4IbBs,2904
18
- crystalwindow/gui.py,sha256=_T4diMardg50gk0_OBpFHfJo5Coo-D3aZt3Vl6PJjxQ,5287
18
+ crystalwindow/gui.py,sha256=9JA25IztgqSYN1NnWVKK99G0rlEosXf2ATWww2rUZIQ,5353
19
19
  crystalwindow/gui_ext.py,sha256=JctpNPr7gtGdro3csyUo9ft3FFArj3JhkVlgKF0lyME,3407
20
20
  crystalwindow/math.py,sha256=slOY3KQZ99VDMUMxsSJabMyRtJcwVzEyxR2RoXspHho,963
21
21
  crystalwindow/messagebus.py,sha256=9K2P_TkdQ1rt-oouIkRg_XHwMTwykttBt-9gFYaItyI,696
22
- crystalwindow/objects.py,sha256=VCEvRrzPv-bWCiVw63rMF67KYluP6FKySgDOvOiN8QU,5413
22
+ crystalwindow/objects.py,sha256=zps-5taLGTmIvlZ76VQhvVHK2NtrrQyxBQMHGwEsCIM,5401
23
23
  crystalwindow/sprites.py,sha256=IADCQetFDQoat3qGpKkH93TdtqqgldfHl4N0HKX1Ajc,7480
24
24
  crystalwindow/tilemap.py,sha256=endJ8KcbP9EjPvL9qWsOpV4jc_Re1yH080aUyDkwufA,3378
25
25
  crystalwindow/ver_warner.py,sha256=qEN3ulc1NixBy15FFx2R3Zu0DhyJTVJwiESGAPwpynM,3373
@@ -38,8 +38,8 @@ crystalwindow/gametests/sandbox.py,sha256=Oo2tU2N0y3BPVa6T5vs_h9N6islhQrjSrr_78X
38
38
  crystalwindow/gametests/squaremove.py,sha256=ei6DMnvcgpOhmxbGv-Yqmx5EqiZjKbVlZhI7YbT2hY8,643
39
39
  crystalwindow/gametests/testtttagain.py,sha256=oIhK9MGgMVly_W2lRwD9Hn9WyPdd8JnX2HGrLTGZdxY,373
40
40
  crystalwindow/gametests/windowtesting.py,sha256=_9X6wnV1-_X_PtNS-0zu-k209NtFIwAc4vpxLPp7V2o,97
41
- crystalwindow-4.9.dist-info/licenses/LICENSE,sha256=Gt5cJRchdNt0guxyQMHKsATN5PM5mjuDhdO6Gzs9qQc,1096
42
- crystalwindow-4.9.dist-info/METADATA,sha256=9CY3r5w-s8NAWe5ynIBOWOehMyRDro-zXnhhPw1yL2Q,7523
43
- crystalwindow-4.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
- crystalwindow-4.9.dist-info/top_level.txt,sha256=PeQSld4b19XWT-zvbYkvE2Xg8sakIMbDzSzSdOSRN8o,14
45
- crystalwindow-4.9.dist-info/RECORD,,
41
+ crystalwindow-5.1.dist-info/licenses/LICENSE,sha256=Gt5cJRchdNt0guxyQMHKsATN5PM5mjuDhdO6Gzs9qQc,1096
42
+ crystalwindow-5.1.dist-info/METADATA,sha256=FZFBz4n7kKSScSqNqT1mxn5pM05SgwcCBqMmwqC29XE,7523
43
+ crystalwindow-5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
+ crystalwindow-5.1.dist-info/top_level.txt,sha256=PeQSld4b19XWT-zvbYkvE2Xg8sakIMbDzSzSdOSRN8o,14
45
+ crystalwindow-5.1.dist-info/RECORD,,