mima-engine 0.1.0__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.
Potentially problematic release.
This version of mima-engine might be problematic. Click here for more details.
- mima/__init__.py +1 -0
- mima/backend/__init__.py +1 -0
- mima/backend/pygame_assets.py +345 -0
- mima/backend/pygame_audio.py +75 -0
- mima/backend/pygame_backend.py +399 -0
- mima/backend/pygame_events.py +430 -0
- mima/collision.py +237 -0
- mima/engine.py +197 -0
- mima/maps/__init__.py +0 -0
- mima/maps/template.py +41 -0
- mima/maps/tile.py +20 -0
- mima/maps/tile_animation.py +7 -0
- mima/maps/tile_info.py +10 -0
- mima/maps/tile_layer.py +52 -0
- mima/maps/tiled/__init__.py +0 -0
- mima/maps/tiled/tiled_layer.py +48 -0
- mima/maps/tiled/tiled_map.py +95 -0
- mima/maps/tiled/tiled_object.py +79 -0
- mima/maps/tiled/tiled_objectgroup.py +25 -0
- mima/maps/tiled/tiled_template.py +49 -0
- mima/maps/tiled/tiled_tile.py +90 -0
- mima/maps/tiled/tiled_tileset.py +45 -0
- mima/maps/tilemap.py +159 -0
- mima/maps/tileset.py +32 -0
- mima/maps/tileset_info.py +9 -0
- mima/maps/transition_map.py +148 -0
- mima/objects/__init__.py +0 -0
- mima/objects/animated_sprite.py +198 -0
- mima/objects/attribute_effect.py +26 -0
- mima/objects/attributes.py +123 -0
- mima/objects/creature.py +332 -0
- mima/objects/dynamic.py +182 -0
- mima/objects/effects/__init__.py +0 -0
- mima/objects/effects/colorize_screen.py +36 -0
- mima/objects/effects/light.py +107 -0
- mima/objects/effects/walking_on_grass.py +38 -0
- mima/objects/effects/walking_on_water.py +41 -0
- mima/objects/loader.py +103 -0
- mima/objects/projectile.py +86 -0
- mima/objects/sprite.py +110 -0
- mima/objects/world/__init__.py +0 -0
- mima/objects/world/color_gate.py +68 -0
- mima/objects/world/color_switch.py +105 -0
- mima/objects/world/container.py +171 -0
- mima/objects/world/floor_switch.py +111 -0
- mima/objects/world/gate.py +174 -0
- mima/objects/world/light_source.py +124 -0
- mima/objects/world/logic_gate.py +163 -0
- mima/objects/world/movable.py +338 -0
- mima/objects/world/oneway.py +168 -0
- mima/objects/world/pickup.py +88 -0
- mima/objects/world/switch.py +165 -0
- mima/objects/world/teleport.py +288 -0
- mima/scene_engine.py +79 -0
- mima/scripts/__init__.py +2 -0
- mima/scripts/command.py +24 -0
- mima/scripts/commands/__init__.py +0 -0
- mima/scripts/commands/add_quest.py +19 -0
- mima/scripts/commands/change_map.py +15 -0
- mima/scripts/commands/close_dialog.py +8 -0
- mima/scripts/commands/give_item.py +24 -0
- mima/scripts/commands/give_resource.py +51 -0
- mima/scripts/commands/move_map.py +152 -0
- mima/scripts/commands/move_to.py +49 -0
- mima/scripts/commands/oneway_move.py +57 -0
- mima/scripts/commands/parallel.py +53 -0
- mima/scripts/commands/play_sound.py +13 -0
- mima/scripts/commands/present_item.py +51 -0
- mima/scripts/commands/progress_quest.py +12 -0
- mima/scripts/commands/quit_game.py +8 -0
- mima/scripts/commands/save_game.py +13 -0
- mima/scripts/commands/screen_fade.py +65 -0
- mima/scripts/commands/serial.py +46 -0
- mima/scripts/commands/set_facing_direction.py +21 -0
- mima/scripts/commands/set_spawn_map.py +14 -0
- mima/scripts/commands/show_choices.py +43 -0
- mima/scripts/commands/show_dialog.py +11 -0
- mima/scripts/commands/take_coins.py +23 -0
- mima/scripts/script_processor.py +40 -0
- mima/states/__init__.py +0 -0
- mima/states/game_state.py +162 -0
- mima/states/quest.py +72 -0
- mima/types/__init__.py +0 -0
- mima/types/alignment.py +7 -0
- mima/types/blend.py +8 -0
- mima/types/damage.py +42 -0
- mima/types/direction.py +44 -0
- mima/types/gate_color.py +7 -0
- mima/types/graphic_state.py +22 -0
- mima/types/keys.py +16 -0
- mima/types/mode.py +15 -0
- mima/types/nature.py +12 -0
- mima/types/object.py +22 -0
- mima/types/start.py +7 -0
- mima/types/terrain.py +9 -0
- mima/types/weapon_slot.py +6 -0
- mima/usables/__init__.py +0 -0
- mima/usables/item.py +31 -0
- mima/usables/weapon.py +48 -0
- mima/util/__init__.py +1 -0
- mima/util/colors.py +45 -0
- mima/util/constants.py +47 -0
- mima/util/functions.py +13 -0
- mima/util/input_defaults.py +49 -0
- mima/util/logging.py +51 -0
- mima/util/property.py +8 -0
- mima/util/runtime_config.py +133 -0
- mima/view/__init__.py +0 -0
- mima/view/camera.py +51 -0
- mima/view/scene.py +350 -0
- mima_engine-0.1.0.dist-info/METADATA +14 -0
- mima_engine-0.1.0.dist-info/RECORD +114 -0
- mima_engine-0.1.0.dist-info/WHEEL +5 -0
- mima_engine-0.1.0.dist-info/top_level.txt +1 -0
mima/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
mima/backend/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import csv
|
|
4
|
+
import logging
|
|
5
|
+
import os
|
|
6
|
+
from typing import TYPE_CHECKING, Dict, Optional
|
|
7
|
+
|
|
8
|
+
import pygame
|
|
9
|
+
|
|
10
|
+
# from ...maps.object_loader import ObjectLoader
|
|
11
|
+
from ..maps.tiled.tiled_map import TiledMap
|
|
12
|
+
from ..maps.tiled.tiled_template import TiledTemplate
|
|
13
|
+
from ..maps.tiled.tiled_tileset import TiledTileset
|
|
14
|
+
from ..util.colors import (
|
|
15
|
+
WHITE,
|
|
16
|
+
) # GB_DARK,; GB_LIGHT,; GB_MEDIUM_DARK,; GB_MEDIUM_LIGHT,; TEXT_COLOR,
|
|
17
|
+
|
|
18
|
+
# from .game.tilemap import Tilemap
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from ..util import RuntimeConfig
|
|
21
|
+
|
|
22
|
+
LOG = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class PygameAssets:
|
|
26
|
+
def __init__(self, rtc: RuntimeConfig, init_file: str):
|
|
27
|
+
self.rtc = rtc
|
|
28
|
+
self._sprites: Dict[str, pygame.Surface] = {}
|
|
29
|
+
self._tilesets: Dict[str, TiledTileset] = {}
|
|
30
|
+
self._templates: Dict[str, TiledTemplate] = {}
|
|
31
|
+
self._maps: Dict[str, TiledMap] = {}
|
|
32
|
+
self._music: Dict[str, str] = {}
|
|
33
|
+
self._sound: Dict[str, str] = {}
|
|
34
|
+
self._csvs: Dict[str, str] = {}
|
|
35
|
+
# self._items: Dict[str, Item] = {}
|
|
36
|
+
self._assets_to_load: Dict[str, str] = {}
|
|
37
|
+
self._assets_to_preload: Dict[str, str] = {}
|
|
38
|
+
self._paths: Dict[str, str] = {}
|
|
39
|
+
self.data_path = ""
|
|
40
|
+
self._preprocess_asset_file(init_file)
|
|
41
|
+
|
|
42
|
+
def _preprocess_asset_file(self, init_file: str):
|
|
43
|
+
self.data_path = os.path.dirname(init_file)
|
|
44
|
+
# path = os.path.join(self._data_path, asset_file)
|
|
45
|
+
current_type = "paths"
|
|
46
|
+
|
|
47
|
+
with open(init_file) as f:
|
|
48
|
+
for line in f.readlines():
|
|
49
|
+
line = line.strip()
|
|
50
|
+
self._assets_to_load.setdefault(current_type, [])
|
|
51
|
+
self._assets_to_preload.setdefault(current_type, [])
|
|
52
|
+
|
|
53
|
+
assets_to_load = self._assets_to_load
|
|
54
|
+
|
|
55
|
+
if "_PRELOAD]" in line:
|
|
56
|
+
assets_to_load = self._assets_to_preload
|
|
57
|
+
if "[PATHS]" in line:
|
|
58
|
+
current_type = "paths"
|
|
59
|
+
elif "[GFX" in line:
|
|
60
|
+
current_type = "gfx"
|
|
61
|
+
elif "[MAPS" in line:
|
|
62
|
+
current_type = "maps"
|
|
63
|
+
elif "[TEMPLATES" in line:
|
|
64
|
+
current_type = "templates"
|
|
65
|
+
elif "[TILESETS" in line:
|
|
66
|
+
current_type = "tilesets"
|
|
67
|
+
elif "[MUSIC" in line:
|
|
68
|
+
current_type = "music"
|
|
69
|
+
elif "[SFX" in line:
|
|
70
|
+
current_type = "sound"
|
|
71
|
+
elif "[CSV" in line:
|
|
72
|
+
current_type = "csv"
|
|
73
|
+
else:
|
|
74
|
+
if line != "" and not line.startswith("#"):
|
|
75
|
+
if current_type != "paths":
|
|
76
|
+
# print(self.data_path, current_type, line)
|
|
77
|
+
assets_to_load[current_type].append(
|
|
78
|
+
os.path.abspath(
|
|
79
|
+
os.path.join(
|
|
80
|
+
self.data_path,
|
|
81
|
+
self._paths.get(current_type, "."),
|
|
82
|
+
line,
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
else:
|
|
87
|
+
name, p = line.split("=")
|
|
88
|
+
self._paths[name] = p
|
|
89
|
+
|
|
90
|
+
def load(self):
|
|
91
|
+
for gfx in self._assets_to_load.get("gfx", []):
|
|
92
|
+
name = os.path.split(gfx)[1].split(".")[0]
|
|
93
|
+
# print(gfx, name)
|
|
94
|
+
self._load_sprite(name, gfx)
|
|
95
|
+
|
|
96
|
+
for tts in self._assets_to_load.get("tilesets", []):
|
|
97
|
+
try:
|
|
98
|
+
LOG.debug("Attempting to load tileset %s", tts)
|
|
99
|
+
name = os.path.split(tts)[1].split(".")[0]
|
|
100
|
+
self._load_tileset(name, tts)
|
|
101
|
+
except Exception as err:
|
|
102
|
+
LOG.warning("Couldn't load tileset %s: %s", tts, err)
|
|
103
|
+
|
|
104
|
+
for tmp in self._assets_to_load.get("templates", []):
|
|
105
|
+
name = os.path.split(tmp)[1].split(".")[0]
|
|
106
|
+
self._load_template(name, tmp)
|
|
107
|
+
|
|
108
|
+
for tmap in self._assets_to_load.get("maps", []):
|
|
109
|
+
name = os.path.split(tmap)[1].split(".")[0]
|
|
110
|
+
self._load_map(name, tmap)
|
|
111
|
+
|
|
112
|
+
for mus in self._assets_to_load.get("music", []):
|
|
113
|
+
name = os.path.split(mus)[1].split(".")[0]
|
|
114
|
+
self._load_music(name, mus)
|
|
115
|
+
|
|
116
|
+
for snd in self._assets_to_load.get("sound", []):
|
|
117
|
+
name = os.path.split(snd)[1].split(".")[0]
|
|
118
|
+
self._load_sound(name, snd)
|
|
119
|
+
|
|
120
|
+
for csv in self._assets_to_load.get("csv", []):
|
|
121
|
+
name = os.path.split(csv)[1].split(".")[0]
|
|
122
|
+
self._load_csv(name, csv)
|
|
123
|
+
|
|
124
|
+
def _load_csv(self, name, filename):
|
|
125
|
+
if not os.path.isfile(filename):
|
|
126
|
+
filename = os.path.join(
|
|
127
|
+
self.data_path, "csv", os.path.split(filename)[-1]
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
possible_name = os.path.split(filename)[-1][:-4]
|
|
131
|
+
if possible_name in self._csvs:
|
|
132
|
+
LOG.warning(f"CSV '{filename}' already loaded as {possible_name}.")
|
|
133
|
+
elif name in self._csvs:
|
|
134
|
+
LOG.debug(f"CSV '{name}' alread loaded. Skipping.")
|
|
135
|
+
return name
|
|
136
|
+
|
|
137
|
+
with open(filename, "r") as csv_file:
|
|
138
|
+
reader = csv.DictReader(csv_file, delimiter=",")
|
|
139
|
+
self._csvs[name] = [row for row in reader]
|
|
140
|
+
|
|
141
|
+
def _load_sprite(self, name, filename=None):
|
|
142
|
+
if filename is None:
|
|
143
|
+
filename = f"{name}.png"
|
|
144
|
+
|
|
145
|
+
# print(filename)
|
|
146
|
+
if not os.path.isfile(filename):
|
|
147
|
+
filename = os.path.join(
|
|
148
|
+
self.data_path, "gfx", os.path.split(filename)[-1]
|
|
149
|
+
)
|
|
150
|
+
# print(name, filename)
|
|
151
|
+
|
|
152
|
+
possible_name = os.path.split(filename)[-1][:-4]
|
|
153
|
+
if possible_name in self._sprites:
|
|
154
|
+
LOG.warning(
|
|
155
|
+
"Sprite '%s' is possibly already loaded with name %s.",
|
|
156
|
+
filename,
|
|
157
|
+
possible_name,
|
|
158
|
+
)
|
|
159
|
+
elif name in self._sprites:
|
|
160
|
+
LOG.debug("Sprite '%s' already loaded. Skipping.")
|
|
161
|
+
return name
|
|
162
|
+
|
|
163
|
+
self._sprites[name] = self._load_sprite_from_disk(filename)
|
|
164
|
+
|
|
165
|
+
return name
|
|
166
|
+
|
|
167
|
+
def _load_tileset(self, name, filename=None):
|
|
168
|
+
if filename is None:
|
|
169
|
+
filename = f"{name}.tsx"
|
|
170
|
+
|
|
171
|
+
if not os.path.isfile(filename):
|
|
172
|
+
filename = os.path.abspath(
|
|
173
|
+
os.path.join(
|
|
174
|
+
self.data_path,
|
|
175
|
+
self._paths.get("tilesets", "."),
|
|
176
|
+
os.path.split(filename)[-1],
|
|
177
|
+
)
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
possible_name = os.path.split(filename)[-1][:-4]
|
|
181
|
+
if possible_name in self._tilesets:
|
|
182
|
+
LOG.warning(
|
|
183
|
+
"Tileset at '%s' is possible already loaded with name %s.",
|
|
184
|
+
filename,
|
|
185
|
+
possible_name,
|
|
186
|
+
)
|
|
187
|
+
elif name in self._tilesets:
|
|
188
|
+
LOG.debug("Tileset at '%s' already loaded. Skipping", filename)
|
|
189
|
+
return name
|
|
190
|
+
self._tilesets[name] = TiledTileset(name, filename)
|
|
191
|
+
return name
|
|
192
|
+
|
|
193
|
+
def _load_template(self, name, filename=None):
|
|
194
|
+
if filename is None:
|
|
195
|
+
filename = f"{name}.tx"
|
|
196
|
+
|
|
197
|
+
if not os.path.isfile(filename):
|
|
198
|
+
filename = os.path.join(
|
|
199
|
+
self._data_path, "templates", os.path.split(filename)[-1]
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
possible_name = os.path.split(filename)[-1][:-3]
|
|
203
|
+
if possible_name in self._templates:
|
|
204
|
+
LOG.warning(
|
|
205
|
+
"Template at '%s' is possible already loaded with name %s.",
|
|
206
|
+
filename,
|
|
207
|
+
possible_name,
|
|
208
|
+
)
|
|
209
|
+
elif name in self._templates:
|
|
210
|
+
LOG.debug("Template at '%s' already loaded. Skipping", filename)
|
|
211
|
+
return name
|
|
212
|
+
|
|
213
|
+
self._templates[name] = TiledTemplate(name, filename)
|
|
214
|
+
return name
|
|
215
|
+
|
|
216
|
+
def _load_map(self, name, filename=None):
|
|
217
|
+
possible_name = os.path.split(filename)[-1][:-4]
|
|
218
|
+
if possible_name in self._maps:
|
|
219
|
+
LOG.warning(
|
|
220
|
+
"Map at '%s' is possibly already loaded with name %s.",
|
|
221
|
+
filename,
|
|
222
|
+
possible_name,
|
|
223
|
+
)
|
|
224
|
+
elif name in self._maps:
|
|
225
|
+
LOG.debug("Map at '%s' already loaded. Skipping", filename)
|
|
226
|
+
return name
|
|
227
|
+
try:
|
|
228
|
+
self._maps[name] = TiledMap(name, filename)
|
|
229
|
+
except KeyError as err:
|
|
230
|
+
print(f"Failed to load map={name}")
|
|
231
|
+
raise err
|
|
232
|
+
|
|
233
|
+
return name
|
|
234
|
+
|
|
235
|
+
def _load_music(self, name, filename=None):
|
|
236
|
+
if filename is None:
|
|
237
|
+
filename = f"{name}.ogg"
|
|
238
|
+
|
|
239
|
+
if not os.path.isfile(filename):
|
|
240
|
+
filename = os.path.join(
|
|
241
|
+
self.data_path,
|
|
242
|
+
self._paths.get("music", "."),
|
|
243
|
+
os.path.split(filename)[-1],
|
|
244
|
+
)
|
|
245
|
+
possible_name = os.path.split(filename)[-1][:-4]
|
|
246
|
+
if possible_name in self._music:
|
|
247
|
+
LOG.warning(
|
|
248
|
+
"Music at '%s' is possibly already loaded with name %s.",
|
|
249
|
+
filename,
|
|
250
|
+
possible_name,
|
|
251
|
+
)
|
|
252
|
+
elif name in self._music:
|
|
253
|
+
LOG.debug("Music at '%s already loaded. Skipping.", filename)
|
|
254
|
+
return name
|
|
255
|
+
|
|
256
|
+
self._music[name] = filename
|
|
257
|
+
return name
|
|
258
|
+
|
|
259
|
+
def _load_sound(self, name, filename=None):
|
|
260
|
+
if filename is None:
|
|
261
|
+
filename = f"{name}.ogg"
|
|
262
|
+
|
|
263
|
+
if not os.path.isfile(filename):
|
|
264
|
+
filename = os.path.join(
|
|
265
|
+
self.data_path,
|
|
266
|
+
self._paths.get("sfx", "."),
|
|
267
|
+
os.path.split(filename)[-1],
|
|
268
|
+
)
|
|
269
|
+
possible_name = os.path.split(filename)[-1][:-4]
|
|
270
|
+
if possible_name in self._sound:
|
|
271
|
+
LOG.warning(
|
|
272
|
+
"Sound at '%s' is possibly already loaded with name %s.",
|
|
273
|
+
filename,
|
|
274
|
+
possible_name,
|
|
275
|
+
)
|
|
276
|
+
elif name in self._sound:
|
|
277
|
+
LOG.debug("Sound at '%s already loaded. Skipping.", filename)
|
|
278
|
+
return name
|
|
279
|
+
|
|
280
|
+
self._sound[name] = pygame.mixer.Sound(filename)
|
|
281
|
+
return name
|
|
282
|
+
|
|
283
|
+
def _load_item(self, item):
|
|
284
|
+
LOG.debug("Loading item %s.", item.name)
|
|
285
|
+
self._items[item.name] = item
|
|
286
|
+
|
|
287
|
+
def get_sprite(self, name) -> Optional[pygame.Surface]:
|
|
288
|
+
if name is None:
|
|
289
|
+
return None
|
|
290
|
+
else:
|
|
291
|
+
if self.rtc.flags["use_color"]:
|
|
292
|
+
name_color = f"{name}_color"
|
|
293
|
+
else:
|
|
294
|
+
name_color = name
|
|
295
|
+
return self._sprites.get(name_color, self._sprites[name])
|
|
296
|
+
|
|
297
|
+
def new_sprite(self, name, surface: pygame.Surface):
|
|
298
|
+
self._sprites[name] = surface
|
|
299
|
+
|
|
300
|
+
def get_tileset(self, name):
|
|
301
|
+
if name not in self._tilesets:
|
|
302
|
+
LOG.warning("Could not find tileset %s.", name)
|
|
303
|
+
return self._tilesets["simple_sheet"]
|
|
304
|
+
return self._tilesets[name]
|
|
305
|
+
|
|
306
|
+
def get_template(self, name):
|
|
307
|
+
if name not in self._templates:
|
|
308
|
+
LOG.warning("Could not find template %s.", name)
|
|
309
|
+
return self._templates["bush01"]
|
|
310
|
+
return self._templates[name]
|
|
311
|
+
|
|
312
|
+
def get_map(self, name):
|
|
313
|
+
return self._maps[name]
|
|
314
|
+
|
|
315
|
+
def get_music(self, name):
|
|
316
|
+
return self._music[name]
|
|
317
|
+
|
|
318
|
+
def get_sound(self, name):
|
|
319
|
+
return self._sound[name]
|
|
320
|
+
|
|
321
|
+
def get_csv(self, name):
|
|
322
|
+
return self._csvs[name]
|
|
323
|
+
|
|
324
|
+
def _load_sprite_from_disk(self, filename: str) -> pygame.Surface:
|
|
325
|
+
if "color" in filename:
|
|
326
|
+
return pygame.image.load(filename).convert_alpha()
|
|
327
|
+
else:
|
|
328
|
+
image = pygame.image.load(filename).convert_alpha()
|
|
329
|
+
# var = pygame.PixelArray(image)
|
|
330
|
+
# # var.replace((0, 0, 0, 0), (255, 0, 0, 255))
|
|
331
|
+
# if "font" in filename:
|
|
332
|
+
# var.replace(WHITE.getRGB(), TEXT_COLOR.getRGBA())
|
|
333
|
+
|
|
334
|
+
# var.replace(GB_DARK.getRGBA(), self.rtc.colors["gb_dark"].getRGBA())
|
|
335
|
+
# var.replace(
|
|
336
|
+
# GB_MEDIUM_DARK.getRGBA(),
|
|
337
|
+
# self.rtc.colors["gb_medium_dark"].getRGBA(),
|
|
338
|
+
# )
|
|
339
|
+
# var.replace(
|
|
340
|
+
# GB_MEDIUM_LIGHT.getRGBA(),
|
|
341
|
+
# self.rtc.colors["gb_medium_light"].getRGBA(),
|
|
342
|
+
# )
|
|
343
|
+
# var.replace(GB_LIGHT.getRGBA(), self.rtc.colors["gb_light"].getRGBA())
|
|
344
|
+
# del var
|
|
345
|
+
return image
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, List, Tuple
|
|
4
|
+
|
|
5
|
+
import pygame
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from .pygame_assets import PygameAssets
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PygameAudio:
|
|
12
|
+
def __init__(self, assets: PygameAssets):
|
|
13
|
+
self.assets = assets
|
|
14
|
+
self.current_track: str = ""
|
|
15
|
+
self.is_playing: bool = False
|
|
16
|
+
self.sound_schedule: List[Tuple[float, str]] = []
|
|
17
|
+
self._time_so_far: float = 0.0
|
|
18
|
+
|
|
19
|
+
def update(self, elapsed_time: float):
|
|
20
|
+
self._time_so_far += elapsed_time
|
|
21
|
+
|
|
22
|
+
sounds_to_remove = []
|
|
23
|
+
for sound_tuple in self.sound_schedule:
|
|
24
|
+
if self._time_so_far >= sound_tuple[0]:
|
|
25
|
+
self._play_sound(sound_tuple[1])
|
|
26
|
+
sounds_to_remove.append(sound_tuple)
|
|
27
|
+
|
|
28
|
+
for sound in sounds_to_remove:
|
|
29
|
+
self.sound_schedule.remove(sound)
|
|
30
|
+
|
|
31
|
+
if self._time_so_far >= 10.0:
|
|
32
|
+
self._time_so_far -= 10.0
|
|
33
|
+
for idx in range(len(self.sound_schedule)):
|
|
34
|
+
self.sound_schedule[idx] = (
|
|
35
|
+
self.sound_schedule[idx][0] - 10.0,
|
|
36
|
+
self.sound_schedule[idx][1],
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def play_music(self, name: str, repeat: int = -1):
|
|
40
|
+
if self.is_playing and name == self.current_track:
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
else:
|
|
44
|
+
try:
|
|
45
|
+
self._play_music(name)
|
|
46
|
+
self.current_track = name
|
|
47
|
+
self.is_playing = True
|
|
48
|
+
except Exception as err:
|
|
49
|
+
print(f"Could not load {name}: {err}")
|
|
50
|
+
|
|
51
|
+
def _play_music(self, name: str, repeat: int = -1):
|
|
52
|
+
pygame.mixer.music.load(self.assets.get_music(name))
|
|
53
|
+
pygame.mixer.music.play(repeat)
|
|
54
|
+
|
|
55
|
+
def _play_sound(self, name: str):
|
|
56
|
+
snd = self.assets.get_sound(name)
|
|
57
|
+
snd.set_volume(100)
|
|
58
|
+
snd.play()
|
|
59
|
+
|
|
60
|
+
def stop(self):
|
|
61
|
+
if self.is_playing:
|
|
62
|
+
pygame.mixer.music.pause()
|
|
63
|
+
self.is_playing = False
|
|
64
|
+
|
|
65
|
+
def stop_sound(self, sound_to_stop: str):
|
|
66
|
+
self.assets.get_sound(sound_to_stop).set_volume(0)
|
|
67
|
+
|
|
68
|
+
def set_music_volume(self, vol: float):
|
|
69
|
+
pygame.mixer.music.set_volume(vol)
|
|
70
|
+
|
|
71
|
+
def set_sound_volume(self, vol: float):
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
def play_sound(self, sound_to_play: str, delay: float = 0.0):
|
|
75
|
+
self.sound_schedule.append((self._time_so_far + delay, sound_to_play))
|