crystalwindow 4.8__tar.gz → 5.0__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.
Files changed (53) hide show
  1. {crystalwindow-4.8/crystalwindow.egg-info → crystalwindow-5.0}/PKG-INFO +1 -1
  2. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/__init__.py +12 -2
  3. crystalwindow-5.0/crystalwindow/camera.py +42 -0
  4. crystalwindow-5.0/crystalwindow/chatvpn.py +82 -0
  5. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/clock.py +11 -3
  6. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/draw_helpers.py +12 -5
  7. crystalwindow-5.0/crystalwindow/fun_helpers.py +197 -0
  8. crystalwindow-5.0/crystalwindow/messagebus.py +33 -0
  9. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/objects.py +4 -4
  10. {crystalwindow-4.8 → crystalwindow-5.0/crystalwindow.egg-info}/PKG-INFO +1 -1
  11. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow.egg-info/SOURCES.txt +2 -0
  12. {crystalwindow-4.8 → crystalwindow-5.0}/setup.py +1 -1
  13. crystalwindow-4.8/crystalwindow/camera.py +0 -19
  14. crystalwindow-4.8/crystalwindow/fun_helpers.py +0 -32
  15. {crystalwindow-4.8 → crystalwindow-5.0}/LICENSE +0 -0
  16. {crystalwindow-4.8 → crystalwindow-5.0}/MANIFEST.in +0 -0
  17. {crystalwindow-4.8 → crystalwindow-5.0}/README.md +0 -0
  18. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/FileHelper.py +0 -0
  19. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/Icons/default_icon.png +0 -0
  20. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/Icons/file_icons.png +0 -0
  21. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/ai.py +0 -0
  22. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/animation.py +0 -0
  23. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/assets.py +0 -0
  24. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/collision.py +0 -0
  25. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/color_handler.py +0 -0
  26. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/crystal3d.py +0 -0
  27. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/docs/getting_started.md +0 -0
  28. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/docs/index.md +0 -0
  29. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/draw_rects.py +0 -0
  30. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/draw_text_helper.py +0 -0
  31. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/draw_tool.py +0 -0
  32. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gametests/3dsquare.py +0 -0
  33. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gametests/__init__.py +0 -0
  34. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gametests/__main__.py +0 -0
  35. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gametests/gravitytest.py +0 -0
  36. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gametests/guitesting.py +0 -0
  37. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gametests/sandbox.py +0 -0
  38. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gametests/squaremove.py +0 -0
  39. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gametests/testtttagain.py +0 -0
  40. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gametests/windowtesting.py +0 -0
  41. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gravity.py +0 -0
  42. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gui.py +0 -0
  43. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/gui_ext.py +0 -0
  44. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/math.py +0 -0
  45. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/sprites.py +0 -0
  46. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/tilemap.py +0 -0
  47. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/ver_warner.py +0 -0
  48. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/websearch.py +0 -0
  49. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow/window.py +0 -0
  50. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow.egg-info/dependency_links.txt +0 -0
  51. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow.egg-info/requires.txt +0 -0
  52. {crystalwindow-4.8 → crystalwindow-5.0}/crystalwindow.egg-info/top_level.txt +0 -0
  53. {crystalwindow-4.8 → crystalwindow-5.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crystalwindow
3
- Version: 4.8
3
+ Version: 5.0
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
@@ -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
@@ -52,6 +52,11 @@ from .websearch import SearchResult, WebBrowse
52
52
  # === 3D Engine ===
53
53
  from .crystal3d import CW3DShape, CW3D
54
54
 
55
+ # === Chatting/VPN Engine =====
56
+ from .chatvpn import ChatVPN, ChatVPNServer
57
+
58
+ # ==== Message Bus ====
59
+ from .messagebus import send_message, view_message, clear_messages
55
60
 
56
61
  __all__ = [
57
62
  # --- Core ---
@@ -88,9 +93,14 @@ __all__ = [
88
93
 
89
94
  # --- Misc ---
90
95
  "random_name", "DebugOverlay", "Camera", "Colors", "Color",
91
- "random_palette", "lerp", "SearchResult", "WebBrowse", "random_number",
96
+ "random_palette", "lerp", "SearchResult", "WebBrowse", "random_number", "random_pos", "random_bool", "random_choice_weighted", "difference",
92
97
 
93
98
  # --- 3D ---
94
99
  "CW3DShape", "CW3D",
95
100
 
101
+ # --- ChatVPN ---
102
+ "ChatVPN", "ChatVPNServer",
103
+
104
+ # --- Message Bus ---
105
+ "send_message", "view_message", "clear_messages",
96
106
  ]
@@ -0,0 +1,42 @@
1
+ class Camera:
2
+ def __init__(self, target, speed=0.1):
3
+ self.target = target # sprite or obj w/ x,y
4
+ self.offset_x = 0
5
+ self.offset_y = 0
6
+ self.speed = speed # smoothness
7
+
8
+ def update(self, win_width, win_height, dt):
9
+ # camera aims for target center
10
+ target_x = self.target.x - win_width // 2
11
+ target_y = self.target.y - win_height // 2
12
+
13
+ # smooth lerp follow
14
+ self.offset_x += (target_x - self.offset_x) * self.speed
15
+ self.offset_y += (target_y - self.offset_y) * self.speed
16
+
17
+ if hasattr(self, "shake"):
18
+ self.shake.update(dt)
19
+
20
+ def apply(self, obj):
21
+ # shift object's draw position by camera offset
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
@@ -0,0 +1,82 @@
1
+ import socket
2
+ import threading
3
+ import json
4
+
5
+
6
+ # ====================================================
7
+ # ChatVPN SERVER (built into this file)
8
+ # ====================================================
9
+ class ChatVPNServer:
10
+ def __init__(self, host="0.0.0.0", port=9001):
11
+ self.host = host
12
+ self.port = port
13
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
14
+ self.sock.bind((self.host, self.port))
15
+ self.clients = set()
16
+ self.running = False
17
+
18
+ def start(self):
19
+ if self.running:
20
+ return
21
+ self.running = True
22
+ print(f"[ChatVPN-Server] running on {self.host}:{self.port}")
23
+ threading.Thread(target=self._loop, daemon=True).start()
24
+
25
+ def _loop(self):
26
+ while self.running:
27
+ data, addr = self.sock.recvfrom(4096)
28
+
29
+ if addr not in self.clients:
30
+ self.clients.add(addr)
31
+ print(f"[ChatVPN-Server] new client: {addr}")
32
+
33
+ for c in self.clients:
34
+ if c != addr:
35
+ self.sock.sendto(data, c)
36
+
37
+ def stop(self):
38
+ self.running = False
39
+ self.sock.close()
40
+ print("[ChatVPN-Server] stopped.")
41
+
42
+
43
+ # ====================================================
44
+ # ChatVPN CLIENT
45
+ # ====================================================
46
+ class ChatVPN:
47
+ def __init__(self, server_ip: str, port: int = 9001):
48
+ self.server = (server_ip, port)
49
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
50
+ self.running = False
51
+ self._on_msg = None
52
+
53
+ def start(self):
54
+ if self.running:
55
+ return
56
+ self.running = True
57
+ threading.Thread(target=self._recv_loop, daemon=True).start()
58
+ print(f"[ChatVPN-Client] connected to {self.server}")
59
+
60
+ def send(self, text: str):
61
+ packet = json.dumps({"type": "text", "data": text}).encode()
62
+ self.sock.sendto(packet, self.server)
63
+
64
+ def on_msg(self, func):
65
+ self._on_msg = func
66
+
67
+ def _recv_loop(self):
68
+ while self.running:
69
+ try:
70
+ data, _ = self.sock.recvfrom(4096)
71
+ except OSError:
72
+ break
73
+
74
+ try:
75
+ obj = json.loads(data.decode())
76
+ msg = obj.get("data", "")
77
+ except:
78
+ msg = data.decode()
79
+
80
+ if self._on_msg:
81
+ self._on_msg(msg)
82
+
@@ -45,6 +45,7 @@ class Clock:
45
45
 
46
46
  # FPS
47
47
  self.target_fps = target_fps
48
+ self.timer = CountdownTimer()
48
49
  self.min_frame_time = 1 / target_fps if target_fps else 0
49
50
  self.frame_times = deque(maxlen=smooth_fps)
50
51
 
@@ -77,9 +78,6 @@ class Clock:
77
78
  self.delta = raw_delta
78
79
  self.frame_times.append(raw_delta)
79
80
 
80
- # Scheduler update
81
- self.scheduler.run_pending()
82
-
83
81
  return self.delta
84
82
 
85
83
  def get_fps(self):
@@ -145,3 +143,13 @@ class Clock:
145
143
  def timestamp(self):
146
144
  """High-precision monotonic timestamp."""
147
145
  return time.perf_counter()
146
+
147
+ #TIMER
148
+ def start_timer(self, seconds: float):
149
+ self.timer.start(seconds)
150
+
151
+ def timer_ended(self):
152
+ return self.timer.is_finished()
153
+
154
+ def timer_remaining(self):
155
+ return self.timer.get_remaining()
@@ -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)
@@ -0,0 +1,197 @@
1
+ import random
2
+ import time
3
+
4
+ # ============================================================
5
+ # RANDOM HELPERS
6
+ # ============================================================
7
+
8
+ def random_color():
9
+ return (
10
+ random.randint(0, 255),
11
+ random.randint(0, 255),
12
+ random.randint(0, 255)
13
+ )
14
+
15
+ def random_palette(n=5):
16
+ return [random_color() for _ in range(n)]
17
+
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
27
+
28
+ def random_number(min_val, max_val):
29
+ return random.randint(min_val, max_val)
30
+
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
+
110
+ def lerp(a, b, t):
111
+ return a + (b - a) * t
112
+
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
+
166
+ class DebugOverlay:
167
+ def __init__(self):
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
194
+
195
+ for line in self.lines:
196
+ win.draw_text(line, pos=(10, y))
197
+ y += 18
@@ -0,0 +1,33 @@
1
+ # crystalwindow/messagebus.py
2
+
3
+ class MessageBus:
4
+ def __init__(self):
5
+ self._queue = []
6
+
7
+ def send(self, name: str, data=None):
8
+ self._queue.append({
9
+ "name": name,
10
+ "data": data
11
+ })
12
+
13
+ def poll(self, name: str):
14
+ for msg in self._queue:
15
+ if msg["name"] == name:
16
+ self._queue.remove(msg)
17
+ return msg["data"]
18
+ return None
19
+
20
+ def clear(self):
21
+ self._queue.clear()
22
+
23
+
24
+ _bus = MessageBus()
25
+
26
+ def send_message(name: str, data=None):
27
+ _bus.send(name, data)
28
+
29
+ def view_message(name: str):
30
+ return _bus.poll(name)
31
+
32
+ def clear_messages():
33
+ _bus.clear()
@@ -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.8
3
+ Version: 5.0
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
@@ -8,6 +8,7 @@ crystalwindow/ai.py
8
8
  crystalwindow/animation.py
9
9
  crystalwindow/assets.py
10
10
  crystalwindow/camera.py
11
+ crystalwindow/chatvpn.py
11
12
  crystalwindow/clock.py
12
13
  crystalwindow/collision.py
13
14
  crystalwindow/color_handler.py
@@ -21,6 +22,7 @@ crystalwindow/gravity.py
21
22
  crystalwindow/gui.py
22
23
  crystalwindow/gui_ext.py
23
24
  crystalwindow/math.py
25
+ crystalwindow/messagebus.py
24
26
  crystalwindow/objects.py
25
27
  crystalwindow/sprites.py
26
28
  crystalwindow/tilemap.py
@@ -7,7 +7,7 @@ with open("README.md", encoding="utf-8") as f:
7
7
 
8
8
  setup(
9
9
  name="crystalwindow",
10
- version="4.8", # Force metadata refresh
10
+ version="5.0", # Force metadata refresh
11
11
  packages=find_packages(include=["crystalwindow", "crystalwindow.*"]),
12
12
 
13
13
  include_package_data=True, # include package_data files
@@ -1,19 +0,0 @@
1
- class Camera:
2
- def __init__(self, target, speed=0.1):
3
- self.target = target # sprite or obj w/ x,y
4
- self.offset_x = 0
5
- self.offset_y = 0
6
- self.speed = speed # smoothness
7
-
8
- def update(self, win_width, win_height):
9
- # camera aims for target center
10
- target_x = self.target.x - win_width // 2
11
- target_y = self.target.y - win_height // 2
12
-
13
- # smooth lerp follow
14
- self.offset_x += (target_x - self.offset_x) * self.speed
15
- self.offset_y += (target_y - self.offset_y) * self.speed
16
-
17
- def apply(self, obj):
18
- # shift object's draw position by camera offset
19
- return obj.x - self.offset_x, obj.y - self.offset_y
@@ -1,32 +0,0 @@
1
- import random
2
-
3
- # random color helpers
4
- def random_color():
5
- return (random.randint(0,255), random.randint(0,255), random.randint(0,255))
6
-
7
- def random_palette(n=5):
8
- return [random_color() for _ in range(n)]
9
-
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))
14
-
15
- #Choose a random number
16
- def random_number(min_val, max_val):
17
- return random.randint(min_val, max_val)
18
-
19
- # tween helper
20
- def lerp(a, b, t):
21
- return a + (b - a) * t
22
-
23
- # debug overlay
24
- class DebugOverlay:
25
- def __init__(self):
26
- self.active = True
27
-
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))
File without changes
File without changes
File without changes
File without changes