From d81df1de3b8d8af06889053ef024387e8acc745b Mon Sep 17 00:00:00 2001 From: Faraphel Date: Sun, 12 Mar 2023 11:41:56 +0100 Subject: [PATCH] settings are now saved when modified --- .gitignore | 1 + main.pyw | 15 +++++- source/gui/scene/Settings.py | 7 ++- source/gui/window/GameWindow.py | 16 ++++++ source/option/Option.py | 90 +++++++++++++++++++++++++++++++++ source/option/__init__.py | 1 + 6 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 source/option/Option.py create mode 100644 source/option/__init__.py diff --git a/.gitignore b/.gitignore index 0e48dca..00d53e3 100644 --- a/.gitignore +++ b/.gitignore @@ -140,3 +140,4 @@ dmypy.json /.save/ /.history/ +/option.json diff --git a/main.pyw b/main.pyw index b67862a..15f3433 100644 --- a/main.pyw +++ b/main.pyw @@ -1,5 +1,8 @@ +from pathlib import Path + import pyglet +from source.gui import media from source.gui.scene import MainMenu from source.gui.window import GameWindow @@ -8,12 +11,20 @@ from source.path import path_font from source.gui.better_pyglet import Label +# Change la police par défaut utilisé pour le Century Gothic pyglet.font.add_directory(path_font) Label.default_kwargs["font_name"] = "Century Gothic" # NOQA: Label à un "default_kwargs" avec la metaclass +# Change le volume sonore +media.SoundAmbient.set_volume(0.1) +media.SoundEffect.set_volume(0.1) -# Create a new window -window = GameWindow(resizable=True, vsync=True, caption="Bataille Navale") +# Créer une nouvelle fenêtre +window = GameWindow( + resizable=True, + caption="Bataille Navale", + option_path=Path("./option.json") +) try: window.set_icon(pyglet.image.load("./assets/image/icon/icon.png")) except: pass # NOQA E722 diff --git a/source/gui/scene/Settings.py b/source/gui/scene/Settings.py index fb9bcca..9e782f4 100644 --- a/source/gui/scene/Settings.py +++ b/source/gui/scene/Settings.py @@ -1,4 +1,5 @@ from math import inf +from pathlib import Path from typing import TYPE_CHECKING from source.gui import widget, texture, media @@ -30,7 +31,11 @@ class Settings(Popup): style=texture.Button.Style1 ) - self.back.add_listener("on_click_release", lambda *_: self.window.remove_scene(self)) + def callback_back(): + self.window.option.save(Path("./option.json")) + self.window.remove_scene(self) + + self.back.add_listener("on_click_release", lambda *_: callback_back()) # Plein écran diff --git a/source/gui/window/GameWindow.py b/source/gui/window/GameWindow.py index 552461a..b60c1f9 100644 --- a/source/gui/window/GameWindow.py +++ b/source/gui/window/GameWindow.py @@ -1,6 +1,9 @@ +from pathlib import Path + import pyglet.window from source.gui.window import Window +from source.option import Option from source.type import ColorRGBA @@ -11,6 +14,8 @@ class GameWindow(Window): # NOQA def __init__(self, + option_path: Path = None, + fps_color: ColorRGBA = (255, 255, 255, 200), fps_enable: bool = False, @@ -20,6 +25,17 @@ class GameWindow(Window): # NOQA self._fps_counter = pyglet.window.FPSDisplay(self, color=fps_color) self._fps_enable = fps_enable + self.option = None + + try: + if option_path.exists(): + self.option = Option.load(self, option_path) + except Exception: # NOQA + pass + + if self.option is None: + self.option = Option(window=self) + @property def fps_enable(self) -> bool: return self._fps_enable diff --git a/source/option/Option.py b/source/option/Option.py new file mode 100644 index 0000000..b25809c --- /dev/null +++ b/source/option/Option.py @@ -0,0 +1,90 @@ +import json +from pathlib import Path +from typing import TYPE_CHECKING + +from source.gui import media + +if TYPE_CHECKING: + from source.gui.window import GameWindow + + +class Option: + def __init__(self, window: "GameWindow", + volume_ambient: float = 0.1, + volume_fx: float = 0.1, + fps_show: bool = False, + fps_limit: int = 60, + vsync: bool = True + ): + self.window = window + self.volume_ambient = volume_ambient + self.volume_fx = volume_fx + self.fps_show = fps_show + self.fps_limit = fps_limit + self.vsync = vsync + + # propriété + + @property + def volume_ambient(self) -> float: + return media.SoundAmbient.get_volume() + + @volume_ambient.setter + def volume_ambient(self, value: float): + media.SoundAmbient.set_volume(value) + + @property + def volume_fx(self) -> float: + return media.SoundEffect.get_volume() + + @volume_fx.setter + def volume_fx(self, value: float): + media.SoundEffect.set_volume(value) + + @property + def fps_show(self): + return self.window.fps_enable + + @fps_show.setter + def fps_show(self, value: bool): + self.window.set_fps_enabled(value) + + @property + def fps_limit(self): + return self.window.get_fps() + + @fps_limit.setter + def fps_limit(self, value: float): + self.window.set_fps(value) + + @property + def vsync(self): + return self.window.vsync + + @vsync.setter + def vsync(self, value: bool): + self.window.set_vsync(value) + + # chargement et sauvegarde + + def to_json(self) -> dict: + return { + "volume_ambient": self.volume_ambient, + "volume_fx": self.volume_fx, + "fps_show": self.fps_show, + "fps_limit": self.fps_limit, + "vsync": self.vsync, + } + + @classmethod + def from_json(cls, window: "GameWindow", data: dict) -> "Option": + return cls(window=window, **data) + + def save(self, path: Path): + with open(path, "w", encoding="utf-8") as file: + json.dump(self.to_json(), file) + + @classmethod + def load(cls, window: "GameWindow", path: Path) -> "Option": + with open(path, "r", encoding="utf-8") as file: + return cls.from_json(window=window, data=json.load(file)) diff --git a/source/option/__init__.py b/source/option/__init__.py new file mode 100644 index 0000000..40cdd11 --- /dev/null +++ b/source/option/__init__.py @@ -0,0 +1 @@ +from .Option import Option