VertexEngine 1.2rc4__4-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.
@@ -0,0 +1,224 @@
1
+ """VertexEngine.Vertex: VWidget, Layouts, Dialogs, App Management"""
2
+
3
+ import sys
4
+ from PyQt6.QtWidgets import (
5
+ QApplication, QWidget, QVBoxLayout, QHBoxLayout,
6
+ QDialog, QLabel, QPushButton, QLineEdit
7
+ )
8
+ from PyQt6.QtCore import Qt
9
+
10
+ # ------------------------
11
+ # Base widget wrapper
12
+ # ------------------------
13
+ class VWidget(QWidget):
14
+ """Base widget wrapper. Handles dark mode and size; no layout by default."""
15
+
16
+ def __init__(self, parent=None, width=None, height=None, dark_mode=False):
17
+ super().__init__(parent)
18
+ if width and height:
19
+ self.setFixedSize(width, height)
20
+ self.dark_mode = dark_mode
21
+ if dark_mode:
22
+ self.set_dark_mode(True)
23
+
24
+ def set_dark_mode(self, enabled=True):
25
+ self.dark_mode = enabled
26
+ if enabled:
27
+ self.setStyleSheet("""
28
+ QWidget {
29
+ background-color: #2c3e50;
30
+ color: #ecf0f1;
31
+ }
32
+ QPushButton {
33
+ background-color: #2980b9;
34
+ color: white;
35
+ }
36
+ """)
37
+ else:
38
+ self.setStyleSheet("")
39
+
40
+
41
+ # ------------------------
42
+ # Layout wrappers
43
+ # ------------------------
44
+ class VBox(VWidget):
45
+ """Vertical layout wrapper."""
46
+
47
+ def __init__(self, *args, padding=10, margin=10, **kwargs):
48
+ super().__init__(*args, **kwargs)
49
+ self.layout = QVBoxLayout()
50
+ self.layout.setContentsMargins(margin, margin, margin, margin)
51
+ self.layout.setSpacing(padding)
52
+ self.setLayout(self.layout)
53
+
54
+ def add(self, widget):
55
+ self.layout.addWidget(widget)
56
+
57
+ def clear(self):
58
+ while self.layout.count():
59
+ child = self.layout.takeAt(0)
60
+ if child.widget():
61
+ child.widget().deleteLater()
62
+
63
+
64
+ class HBox(VWidget):
65
+ """Horizontal layout wrapper."""
66
+
67
+ def __init__(self, *args, padding=10, margin=10, **kwargs):
68
+ super().__init__(*args, **kwargs)
69
+ self.layout = QHBoxLayout()
70
+ self.layout.setContentsMargins(margin, margin, margin, margin)
71
+ self.layout.setSpacing(padding)
72
+ self.setLayout(self.layout)
73
+
74
+ def add(self, widget):
75
+ self.layout.addWidget(widget)
76
+
77
+ def clear(self):
78
+ while self.layout.count():
79
+ child = self.layout.takeAt(0)
80
+ if child.widget():
81
+ child.widget().deleteLater()
82
+
83
+
84
+ # ------------------------
85
+ # Application wrapper
86
+ # ------------------------
87
+ class App(QApplication):
88
+ def __init__(self):
89
+ super().__init__(sys.argv)
90
+
91
+ def run(self):
92
+ sys.exit(self.exec())
93
+
94
+
95
+ # ------------------------
96
+ # Dialog base class
97
+ # ------------------------
98
+ class Dialog(QDialog):
99
+ def __init__(self, parent=None, title="Dialog", size=(400, 200), modal=True):
100
+ super().__init__(parent)
101
+ self.setWindowTitle(title)
102
+ self.resize(*size)
103
+ self.setModal(modal)
104
+ self.setWindowFlags(self.windowFlags() | Qt.WindowType.Window)
105
+
106
+ def open_dialog(self):
107
+ self.exec()
108
+
109
+ def close_dialog(self):
110
+ self.close()
111
+
112
+
113
+ # ------------------------
114
+ # Message dialog
115
+ # ------------------------
116
+ class MessageDialog(Dialog):
117
+ def __init__(self, parent=None, message="", title="Message"):
118
+ super().__init__(parent, title, (300, 150))
119
+ layout = QVBoxLayout()
120
+ self.setLayout(layout)
121
+
122
+ label = QLabel(message)
123
+ layout.addWidget(label)
124
+
125
+ ok = QPushButton("OK")
126
+ ok.clicked.connect(self.accept)
127
+ layout.addWidget(ok)
128
+
129
+
130
+ # ------------------------
131
+ # Confirm dialog
132
+ # ------------------------
133
+ class ConfirmDialog(Dialog):
134
+ def __init__(self, parent=None, message="", title="Confirm"):
135
+ super().__init__(parent, title, (350, 160))
136
+ layout = QVBoxLayout()
137
+ self.setLayout(layout)
138
+
139
+ layout.addWidget(QLabel(message))
140
+
141
+ buttons = QHBoxLayout()
142
+ yes = QPushButton("Yes")
143
+ no = QPushButton("No")
144
+ yes.clicked.connect(self.accept)
145
+ no.clicked.connect(self.reject)
146
+ buttons.addWidget(yes)
147
+ buttons.addWidget(no)
148
+ layout.addLayout(buttons)
149
+
150
+ @staticmethod
151
+ def ask(parent=None, message="", title="Confirm"):
152
+ dlg = ConfirmDialog(parent, message, title)
153
+ return dlg.exec() == QDialog.DialogCode.Accepted
154
+
155
+
156
+ # ------------------------
157
+ # Input dialog
158
+ # ------------------------
159
+ class InputDialog(Dialog):
160
+ def __init__(self, parent=None, label="Enter:", title="Input"):
161
+ super().__init__(parent, title, (350, 180))
162
+ self.input = QLineEdit()
163
+
164
+ layout = QVBoxLayout()
165
+ self.setLayout(layout)
166
+
167
+ layout.addWidget(QLabel(label))
168
+ layout.addWidget(self.input)
169
+
170
+ ok = QPushButton("OK")
171
+ ok.clicked.connect(self.accept)
172
+ layout.addWidget(ok)
173
+
174
+ def value(self):
175
+ return self.input.text()
176
+
177
+ @staticmethod
178
+ def get(parent=None, label="Enter:", title="Input"):
179
+ dlg = InputDialog(parent, label, title)
180
+ if dlg.exec():
181
+ return dlg.value()
182
+ return None
183
+
184
+
185
+ # ------------------------
186
+ # Static dialog helper
187
+ # ------------------------
188
+ class Dialogs:
189
+ @staticmethod
190
+ def message(parent=None, text=""):
191
+ MessageDialog(parent, text).open_dialog()
192
+
193
+ @staticmethod
194
+ def confirm(parent=None, text=""):
195
+ return ConfirmDialog.ask(parent, text)
196
+
197
+ @staticmethod
198
+ def input(parent=None, text=""):
199
+ return InputDialog.get(parent, text)
200
+
201
+
202
+ # ------------------------
203
+ # Example usage
204
+ # ------------------------
205
+ if __name__ == "__main__":
206
+ app = App()
207
+
208
+ main = VBox(dark_mode=True, width=500, height=400)
209
+ main.add(QLabel("Welcome to the VWidget wrapper!"))
210
+
211
+ btn_msg = QPushButton("Show Message")
212
+ btn_msg.clicked.connect(lambda: Dialogs.message(main, "Hello!"))
213
+ main.add(btn_msg)
214
+
215
+ btn_confirm = QPushButton("Ask Confirm")
216
+ btn_confirm.clicked.connect(lambda: print(Dialogs.confirm(main, "Are you sure?")))
217
+ main.add(btn_confirm)
218
+
219
+ btn_input = QPushButton("Ask Input")
220
+ btn_input.clicked.connect(lambda: print(Dialogs.input(main, "Enter your name:")))
221
+ main.add(btn_input)
222
+
223
+ main.show()
224
+ app.run()
@@ -0,0 +1,70 @@
1
+ """WARNING: This library of Vertex is not made for games, if you want to make a game window, use the `GameEngine` Class instead."""
2
+ from PyQt6.QtWidgets import QMainWindow, QVBoxLayout, QWidget, QApplication
3
+ import sys
4
+ from VertexEngine import VertexUI
5
+ # ===== Base window class =====
6
+ class BaseWindow(QMainWindow):
7
+ def __init__(self, title="Base Window", width=400, height=300):
8
+ super().__init__()
9
+ self.setWindowTitle(title)
10
+ self.setGeometry(100, 100, width, height)
11
+ self.central_widget = QWidget()
12
+ self.setCentralWidget(self.central_widget)
13
+ self.layout = QVBoxLayout()
14
+ self.central_widget.setLayout(self.layout)
15
+ print(f"[DEBUG] Initialized window '{title}' with size {width}x{height}")
16
+
17
+ def add_label(self, text):
18
+ label = VertexUI.Text(text)
19
+ self.layout.addWidget(label)
20
+ print(f"[DEBUG] Added label: '{text}'")
21
+
22
+ def add_button(self, text, callback=None):
23
+ button = VertexUI.FancyButton(text)
24
+ if callback:
25
+ button.clicked.connect(callback)
26
+ self.layout.addWidget(button)
27
+ print(f"[DEBUG] Added button: '{text}'")
28
+
29
+ # ===== Fancy themed window =====
30
+ class FancyWindow(BaseWindow):
31
+ def __init__(self, title="Fancy Window", width=500, height=400, theme_color="#FF69B4"):
32
+ super().__init__(title, width, height)
33
+ self.theme_color = theme_color
34
+ self.apply_theme()
35
+
36
+ def apply_theme(self):
37
+ self.setStyleSheet(f"""
38
+ QMainWindow {{
39
+ background-color: {self.theme_color};
40
+ }}
41
+ QLabel {{
42
+ color: white;
43
+ font-size: 18px;
44
+ }}
45
+ QPushButton {{
46
+ background-color: white;
47
+ color: {self.theme_color};
48
+ border-radius: 5px;
49
+ padding: 5px 10px;
50
+ }}
51
+ """)
52
+ print(f"[DEBUG] Applied theme color: {self.theme_color}")
53
+
54
+ # ===== Random fun window with auto-close button =====
55
+ class FunWindow(BaseWindow):
56
+ def __init__(self, title="Fun Window"):
57
+ super().__init__(title)
58
+ self.add_label("Welcome to FunWindow! 🎉")
59
+ self.add_button("Close me", self.close)
60
+
61
+ if __name__ == "__main__":
62
+ app = QApplication(sys.argv)
63
+
64
+ # Choose your boredom mode
65
+ window = FancyWindow(theme_color="#8A2BE2")
66
+ window.add_label("This is super fancy 💎")
67
+ window.add_button("Click me!", lambda: print("You clicked the fancy button!"))
68
+
69
+ window.show()
70
+ sys.exit(app.exec())
@@ -0,0 +1,322 @@
1
+ # VertexEngine/__init__.py
2
+ # Copyright (C) 2025
3
+ # This library/SDK is free. You can redistribute it.
4
+ # Tyrel Gomez (email as annbasilan)
5
+ # annbasilan0828@gmail.com
6
+ """Vertex 3 is an SDK for RainOS GameDev. It's also supported by many others.
7
+
8
+ Supported OSes
9
+ --------------
10
+ - RainOS
11
+ - Windows
12
+ - MacOS,
13
+ - OS X
14
+ - BeOS
15
+ - FreeBSD
16
+ - IRIX
17
+ - and Linux
18
+
19
+ It is written on top of the excellent Pygame library which is ran on the even more excellent SDL library which runs on every Desktop OS with SDL."""
20
+ import pygame
21
+ from .engine import GameEngine
22
+ from .scenes import Scene, SceneManager
23
+ from .assets import AssetManager
24
+ from .audio import AudioManager
25
+ from pygame.base import * # pylint: disable=wildcard-import; lgtm[py/polluting-import]
26
+ from pygame import * # pylint: disable=wildcard-import; lgtm[py/polluting-import]
27
+ import sys
28
+ from PyQt6.QtWidgets import QPushButton, QLineEdit
29
+ from PyQt6.QtGui import QFont
30
+ from PyQt6.QtWidgets import QPushButton
31
+ from PyQt6.QtGui import QCursor
32
+ from PyQt6.QtCore import Qt
33
+ from PyQt6.QtWidgets import QLabel
34
+ from typing_extensions import deprecated as dep
35
+
36
+ class VertexScreen():
37
+ """Draw on VertexEngine's Screen."""
38
+ def __init__(self):
39
+ pass
40
+ class Draw():
41
+ "The Draw class to draw on VertexEngine"
42
+ def __init__(self):
43
+ pass
44
+ def rect(self, surface, color, rect=None):
45
+ """Draw a Rectangle of a solid color."""
46
+ pygame.draw.rect(surface, color, rect)
47
+ def polygon(self, surface, color, points, width):
48
+ "Draw a polygon by marking points on the screen to make an n-gon"
49
+ pygame.draw.polygon(surface, color, points, width)
50
+ def circle(self, circle_surface, color, center, radius, width, draw_top_right, draw_top_left, draw_bottom_right, draw_bottom_left):
51
+ """Draw a Circle with radius, color, etc."""
52
+ pygame.draw.circle(circle_surface, color, center, radius, width, draw_top_right, draw_top_left, draw_bottom_left, draw_bottom_right)
53
+ def ellipse(self, surface, color, rect, width):
54
+ """Draw an elipse with surface, color, rect and width"""
55
+ pygame.draw.ellipse(surface, color, rect, width)
56
+ def arc(self, surface, color, rect, start_angle, stop_angle, width):
57
+ "Draw an arc with a lot of values"
58
+ pygame.draw.arc(surface, color, rect, start_angle, stop_angle, width)
59
+ def line(self, surface, color, start_pos, end_pos, width):
60
+ """Draw a line"""
61
+ pygame.draw.line(surface, color, start_pos, end_pos, width)
62
+ def lines(self, surface, color, closed, points, width):
63
+ '''Draw a pair of lines'''
64
+ pygame.draw.lines(surface, color, closed, points, width)
65
+ def aaline(
66
+ self,
67
+ surface,
68
+ color,
69
+ start_pos,
70
+ end_pos,
71
+ blend,
72
+ ):
73
+ '''Draw an aaline'''
74
+ pygame.draw.aaline(surface, color, start_pos, end_pos, blend)
75
+ def aalines(
76
+ self,
77
+ surface,
78
+ color,
79
+ closed,
80
+ points,
81
+ blend
82
+ ):
83
+ '''Draw a set of aalines'''
84
+ pygame.draw.aalines(surface, color, closed, points, blend)
85
+ class Font():
86
+ """VertexEngine's offical Font Engine"""
87
+ def __init__(self, path=None, size=24, antialias=True):
88
+ self.font = pygame.font.Font(path, size)
89
+ self.size = size
90
+ self.antialias = antialias
91
+
92
+ def draw(
93
+ self,
94
+ surface,
95
+ text,
96
+ pos,
97
+ color=(255, 255, 255),
98
+ align="topleft",
99
+ center=False,
100
+ shadow=False,
101
+ shadow_color=(0, 0, 0),
102
+ shadow_offset=(2, 2),
103
+ outline=False,
104
+ outline_color=(0, 0, 0),
105
+ outline_thickness=1
106
+ ):
107
+ text_surf = self.font.render(text, self.antialias, color)
108
+ rect = text_surf.get_rect()
109
+
110
+ if center:
111
+ rect.center = pos
112
+ else:
113
+ setattr(rect, align, pos)
114
+
115
+ # 🔲 Outline
116
+ if outline:
117
+ for dx in range(-outline_thickness, outline_thickness + 1):
118
+ for dy in range(-outline_thickness, outline_thickness + 1):
119
+ if dx == 0 and dy == 0:
120
+ continue
121
+ outline_surf = self.font.render(text, self.antialias, outline_color)
122
+ surface.blit(outline_surf, rect.move(dx, dy))
123
+
124
+ # 🌑 Shadow
125
+ if shadow:
126
+ shadow_surf = self.font.render(text, self.antialias, shadow_color)
127
+ shadow_rect = rect.move(shadow_offset)
128
+ surface.blit(shadow_surf, shadow_rect)
129
+
130
+ surface.blit(text_surf, rect)
131
+
132
+ @dep("Unlike internal APIs, this one is fully deprecated, NEVER USE THIS. EVER :)")
133
+ def draw_text(
134
+ surface,
135
+ text,
136
+ font,
137
+ color,
138
+ pos,
139
+ align="topleft",
140
+ shadow=False,
141
+ shadow_color=(0, 0, 0),
142
+ shadow_offset=(2, 2)
143
+ ):
144
+ text_surf = font.render(text, True, color)
145
+ text_rect = text_surf.get_rect()
146
+
147
+ setattr(text_rect, align, pos)
148
+
149
+ if shadow:
150
+ shadow_surf = font.render(text, True, shadow_color)
151
+ shadow_rect = shadow_surf.get_rect()
152
+ setattr(shadow_rect, align, (pos[0] + shadow_offset[0], pos[1] + shadow_offset[1]))
153
+ surface.blit(shadow_surf, shadow_rect)
154
+
155
+ surface.blit(text_surf, text_rect)
156
+ class Rect():
157
+ '''Define a rect to pass into VertexScreen.Draw.rect()'''
158
+ def __init__(self, left, top, width, height):
159
+ pygame.Rect(left, top, width, height)
160
+
161
+ class VertexUI():
162
+ # QPushButton *button = new QPushButton(tr("Ro&ck && Roll"), this)
163
+ def __init__(self):
164
+ pass
165
+
166
+ class FancyButton(QPushButton):
167
+ def __init__(
168
+ self,
169
+ text="Button",
170
+ width=120,
171
+ height=40,
172
+ bg_color="#4CAF50",
173
+ hover_color="#45A049",
174
+ text_color="white",
175
+ border_radius=10,
176
+ border_color="#388E3C",
177
+ border_width=2,
178
+ font_name="Arial",
179
+ font_size=12,
180
+ font_weight=QFont.Weight.Bold,
181
+ parent=None
182
+ ):
183
+ super().__init__(text, parent)
184
+
185
+ # Store params
186
+ self.bg_color = bg_color
187
+ self.hover_color = hover_color
188
+ self.text_color = text_color
189
+ self.border_radius = border_radius
190
+ self.border_color = border_color
191
+ self.border_width = border_width
192
+ self.setFont(QFont(font_name, font_size, font_weight))
193
+ self.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
194
+ self.setMinimumSize(width, height)
195
+
196
+ # Apply default style
197
+ self.setStyleSheet(self.default_style())
198
+
199
+ def enterEvent(self, event):
200
+ self.setStyleSheet(self.hover_style())
201
+ super().enterEvent(event)
202
+
203
+ def leaveEvent(self, event):
204
+ self.setStyleSheet(self.default_style())
205
+ super().leaveEvent(event)
206
+
207
+ def default_style(self):
208
+ return f"""
209
+ QPushButton {{
210
+ background-color: {self.bg_color};
211
+ color: {self.text_color};
212
+ border-radius: {self.border_radius}px;
213
+ border: {self.border_width}px solid {self.border_color};
214
+ }}
215
+ """
216
+
217
+ def hover_style(self):
218
+ return f"""
219
+ QPushButton {{
220
+ background-color: {self.hover_color};
221
+ color: {self.text_color};
222
+ border-radius: {self.border_radius}px;
223
+ border: {self.border_width}px solid {self.border_color};
224
+ }}
225
+ """
226
+
227
+ class Text(QLabel):
228
+ def __init__(
229
+ self,
230
+ text="Text",
231
+ font_name="Arial",
232
+ font_size=14,
233
+ font_weight=QFont.Weight.Normal,
234
+ text_color="#FFFFFF",
235
+ bg_color=None,
236
+ padding=8,
237
+ border_radius=8,
238
+ alignment=Qt.AlignmentFlag.AlignCenter,
239
+ parent=None
240
+ ):
241
+ super().__init__(text, parent)
242
+
243
+ self.setFont(QFont(font_name, font_size, font_weight))
244
+ self.setAlignment(alignment)
245
+
246
+ bg = "transparent" if bg_color is None else bg_color
247
+
248
+ self.setStyleSheet(f"""
249
+ QLabel {{
250
+ color: {text_color};
251
+ background-color: {bg};
252
+ padding: {padding}px;
253
+ border-radius: {border_radius}px;
254
+ }}
255
+ """)
256
+
257
+ def set_text(self, text):
258
+ self.setText(text)
259
+
260
+ def set_color(self, color):
261
+ self.setStyleSheet(self.styleSheet() + f"color: {color};")
262
+
263
+ class InputField(QLineEdit):
264
+ def __init__(
265
+ self,
266
+ placeholder="Enter text...",
267
+ width=240,
268
+ height=36,
269
+ font_name="Arial",
270
+ font_size=12,
271
+ text_color="#FFFFFF",
272
+ bg_color="#1E1E1E",
273
+ border_color="#555555",
274
+ focus_color="#00E5FF",
275
+ border_radius=8,
276
+ padding=8,
277
+ parent=None
278
+ ):
279
+ super().__init__(parent)
280
+
281
+ self.setPlaceholderText(placeholder)
282
+ self.setFont(QFont(font_name, font_size))
283
+ self.setMinimumSize(width, height)
284
+
285
+ self.text_color = text_color
286
+ self.bg_color = bg_color
287
+ self.border_color = border_color
288
+ self.focus_color = focus_color
289
+ self.border_radius = border_radius
290
+ self.padding = padding
291
+
292
+ self.apply_style(focused=False)
293
+
294
+ def apply_style(self, focused=False):
295
+ border = self.focus_color if focused else self.border_color
296
+
297
+ self.setStyleSheet(f"""
298
+ QLineEdit {{
299
+ color: {self.text_color};
300
+ background-color: {self.bg_color};
301
+ border: 2px solid {border};
302
+ border-radius: {self.border_radius}px;
303
+ padding: {self.padding}px;
304
+ }}
305
+ QLineEdit::placeholder {{
306
+ color: #888888;
307
+ }}
308
+ """)
309
+
310
+ def focusInEvent(self, event):
311
+ self.apply_style(focused=True)
312
+ super().focusInEvent(event)
313
+
314
+ def focusOutEvent(self, event):
315
+ self.apply_style(focused=False)
316
+ super().focusOutEvent(event)
317
+
318
+ def get_value(self):
319
+ return self.text()
320
+
321
+ def set_value(self, value):
322
+ self.setText(value)
VertexEngine/assets.py ADDED
@@ -0,0 +1,63 @@
1
+ import pygame
2
+ from PyQt6.QtGui import QImage
3
+ import typing_extensions as typing
4
+
5
+ @typing.deprecated('This is not a public API, use AssetManager pls :D')
6
+ class QtRenderer:
7
+ def create_texture(self, image_asset):
8
+ surf = image_asset.surface
9
+ width, height = surf.get_size()
10
+
11
+ # Ensure predictable format
12
+ surf = surf.convert_alpha() if surf.get_alpha() else surf.convert()
13
+
14
+ # pygame → raw RGBA
15
+ pixel_data = pygame.image.tostring(surf, "RGBA", False)
16
+
17
+ # Create REAL QImage (no OpenGL required)
18
+ qimage = QImage(
19
+ pixel_data,
20
+ width,
21
+ height,
22
+ QImage.Format.Format_RGBA8888
23
+ )
24
+
25
+ # IMPORTANT: deep copy so data survives after function returns
26
+ qimage = qimage.copy()
27
+
28
+ return Texture(qimage)
29
+
30
+ @typing.deprecated('This is not a public API, use AssetManager pls :D')
31
+ class Texture:
32
+ def __init__(self, qimage: QImage):
33
+ self.image = qimage
34
+ self.width = qimage.width()
35
+ self.height = qimage.height()
36
+
37
+ def __repr__(self):
38
+ return f"<Texture {self.width}x{self.height} (QImage)>"
39
+
40
+ @typing.deprecated('This is not a public API, use AssetManager pls :D')
41
+ class ImageAsset:
42
+ def __init__(self, surface):
43
+ self.surface = surface # pygame.Surface
44
+
45
+ class AssetManager:
46
+ def __init__(self):
47
+ self.images = {}
48
+
49
+ def load_image(self, name: str, path: str):
50
+ if name in self.images:
51
+ return self.images[name]
52
+
53
+ try:
54
+ surface = pygame.image.load(path).convert_alpha()
55
+ self.images[name] = surface
56
+ return surface
57
+
58
+ except FileNotFoundError:
59
+ print(f"[Warning] Image '{path}' not found!")
60
+ return None
61
+
62
+ def get_image(self, name: str):
63
+ return self.images.get(name)
VertexEngine/audio.py ADDED
@@ -0,0 +1,25 @@
1
+ import pygame
2
+
3
+ class AudioManager:
4
+ def __init__(self):
5
+ pygame.mixer.init()
6
+ self.sounds = {}
7
+ self.music = None
8
+
9
+ def load_sound(self, name, path):
10
+ self.sounds[name] = pygame.mixer.Sound(path)
11
+
12
+ def play_sound(self, name, loops=0):
13
+ if name in self.sounds:
14
+ self.sounds[name].play(loops=loops)
15
+
16
+ def load_music(self, path):
17
+ self.music = path
18
+ pygame.mixer.music.load(path)
19
+
20
+ def play_music(self, loops=-1):
21
+ if self.music:
22
+ pygame.mixer.music.play(loops=loops)
23
+
24
+ def stop_music(self):
25
+ pygame.mixer.music.stop()