From e3a67eff6a559a22df69d6b85cfd6af1d911846f Mon Sep 17 00:00:00 2001 From: Faraphel Date: Thu, 9 Mar 2023 15:00:48 +0100 Subject: [PATCH] implemented settings --- NOTE.md | 3 ++- source/gui/scene/Settings.py | 23 +++++++-------------- source/gui/window/GameWindow.py | 2 +- source/gui/window/Window.py | 36 +++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/NOTE.md b/NOTE.md index f58f880..945f905 100644 --- a/NOTE.md +++ b/NOTE.md @@ -6,8 +6,9 @@ A faire : - test avec "assert" (cahier des charges) - mode d'emploi (video + pdf) expliquant le fonctionnement -2. Visuel : +2. Bonus : - animations de fin, mettre la musique, ... + - sauvegarder les paramètres dans un fichier - Voir les TODOs 3. Bug : diff --git a/source/gui/scene/Settings.py b/source/gui/scene/Settings.py index e995e03..5c1086f 100644 --- a/source/gui/scene/Settings.py +++ b/source/gui/scene/Settings.py @@ -1,3 +1,5 @@ +import itertools +from math import inf from typing import TYPE_CHECKING import pyglet.app @@ -46,7 +48,7 @@ class Settings(Popup): ) self.fullscreen.add_listener( - "on_click_release", + "on_state_change", lambda widget, *_: self.window.set_fullscreen(widget.state) ) @@ -72,7 +74,7 @@ class Settings(Popup): ) self.vsync.add_listener( - "on_click_release", + "on_state_change", lambda widget, *_: self.window.set_vsync(widget.state) ) @@ -98,7 +100,7 @@ class Settings(Popup): ) self.show_fps.add_listener( - "on_click_release", + "on_state_change", lambda widget, *_: self.window.set_fps_enabled(widget.state) ) @@ -120,26 +122,15 @@ class Settings(Popup): style=texture.Scroller.Style1, from_=1, - value=60, + value=fps if (fps := self.window.get_fps()) <= 240 else 250, to=250, text_transform=lambda value: round(value) if value <= 240 else "Illimité" ) - def change_fps(widget): - pyglet.clock.unschedule(pyglet.app.event_loop._redraw_windows) # NOQA - - if widget.value <= 240: - pyglet.clock.schedule_interval( - pyglet.app.event_loop._redraw_windows, # NOQA - 1 / widget.value - ) - else: - pyglet.clock.schedule(pyglet.app.event_loop._redraw_windows) # NOQA - self.fps_limit.add_listener( "on_value_change", - change_fps + lambda widget, *_: self.window.set_fps(widget.value if widget.value <= 240 else inf) ) self.add_widget( diff --git a/source/gui/window/GameWindow.py b/source/gui/window/GameWindow.py index d070321..552461a 100644 --- a/source/gui/window/GameWindow.py +++ b/source/gui/window/GameWindow.py @@ -21,7 +21,7 @@ class GameWindow(Window): # NOQA self._fps_enable = fps_enable @property - def fps_enable(self): + def fps_enable(self) -> bool: return self._fps_enable def set_fps_enabled(self, value: bool): diff --git a/source/gui/window/Window.py b/source/gui/window/Window.py index e51ae3a..9c394a5 100644 --- a/source/gui/window/Window.py +++ b/source/gui/window/Window.py @@ -1,3 +1,5 @@ +import itertools +from math import inf from typing import Type, TYPE_CHECKING import pyglet @@ -24,6 +26,40 @@ class Window(pyglet.window.Window, EventPropagationMixin): # NOQA def childs(self): return self._scenes + # FPS + + @staticmethod + def get_fps() -> float: + # on récupère la fonction responsable du rafraichissement de la fenêtre + refresh_func = pyglet.app.event_loop._redraw_windows # NOQA + + # on récupère l'événement correspondant dans l'horloge de l'application + refresh_event = next(filter( + lambda item: item.func is refresh_func, + itertools.chain( + pyglet.clock._default._schedule_interval_items, # NOQA + pyglet.clock._default._schedule_items # NOQA + ) + )) + + # renvoie infini s'il n'y avait pas de fréquence, sinon 1 / fréquence pour avoir le nombre de FPS + return inf if isinstance(refresh_event, pyglet.clock._ScheduledItem) else 1 / refresh_event.interval # NOQA + + @staticmethod + def set_fps(value: float): + # on récupère la fonction responsable du rafraichissement de la fenêtre + refresh_func = pyglet.app.event_loop._redraw_windows # NOQA + + # désactive le rafraichissement de la fenêtre + pyglet.clock.unschedule(refresh_func) + + if value == inf: + # si la valeur est infinie, rafraichi dès que possible + pyglet.clock.schedule(refresh_func) + else: + # sinon rafraichi à la fréquence indiquée (1 / FPS) + pyglet.clock.schedule_interval(refresh_func, 1 / value) + # Scene Managing def set_scene(self, scene_class: Type["Scene"], *scene_args, **scene_kwargs) -> "Scene":