diff options
Diffstat (limited to 'src/sliceitoff/menu')
-rw-r--r-- | src/sliceitoff/menu/__init__.py | 5 | ||||
-rw-r--r-- | src/sliceitoff/menu/anykey.py | 9 | ||||
-rw-r--r-- | src/sliceitoff/menu/explodeout.py | 38 | ||||
-rw-r--r-- | src/sliceitoff/menu/initials.py | 50 | ||||
-rw-r--r-- | src/sliceitoff/menu/mainmenu.py | 18 | ||||
-rw-r--r-- | src/sliceitoff/menu/menu.py | 70 | ||||
-rw-r--r-- | src/sliceitoff/menu/settings.py | 28 | ||||
-rw-r--r-- | src/sliceitoff/menu/show.py | 24 |
8 files changed, 242 insertions, 0 deletions
diff --git a/src/sliceitoff/menu/__init__.py b/src/sliceitoff/menu/__init__.py new file mode 100644 index 0000000..f26089f --- /dev/null +++ b/src/sliceitoff/menu/__init__.py @@ -0,0 +1,5 @@ +""" menu - Menus, ScreenShow, Initial input... """ +from .mainmenu import MainMenu, MainMenuItems +from .settings import SettingsMenu +from .show import Show +from .initials import Initials diff --git a/src/sliceitoff/menu/anykey.py b/src/sliceitoff/menu/anykey.py new file mode 100644 index 0000000..0916ec3 --- /dev/null +++ b/src/sliceitoff/menu/anykey.py @@ -0,0 +1,9 @@ +""" menu.anykey - Event waiting. Used for skipping screens. """ +import pygame + +def anykey(): + """ Anything but mouse movement gives True """ + for event in pygame.event.get(): + if event.type in (pygame.MOUSEBUTTONDOWN, pygame.KEYDOWN, pygame.QUIT): + return True + return False diff --git a/src/sliceitoff/menu/explodeout.py b/src/sliceitoff/menu/explodeout.py new file mode 100644 index 0000000..7732781 --- /dev/null +++ b/src/sliceitoff/menu/explodeout.py @@ -0,0 +1,38 @@ +""" menu.explodeout - For showing explogind effect and waiting for a key """ +import pygame + +from sliceitoff.sfx import sfx +from .anykey import anykey + +class ExplodeOutGroup(pygame.sprite.Group): + """ Sprite group that just counts down feadeout/explosion or a key """ + def __init__(self, active = True): + super().__init__() + self.explode = False + self.active = active + self.fadeout = 1_000 + + def update(self, dt = 0, **kwargs): + """ Just does the explosion and marks group inactive """ + if not self.active: + return False + + super().update(dt = dt, explode = self.explode, **kwargs) + + if self.explode: + if self.fadeout <= 0: + self.active = False + else: + if anykey(): + self.fadeout = 0 + self.active = False + self.fadeout -= dt + return True + return True + + def do_fadeout(self): + """ Just kicks off exploding phase """ + if self.explode: + return + sfx.play("glass") + self.explode = True diff --git a/src/sliceitoff/menu/initials.py b/src/sliceitoff/menu/initials.py new file mode 100644 index 0000000..ca52b16 --- /dev/null +++ b/src/sliceitoff/menu/initials.py @@ -0,0 +1,50 @@ +""" menu.initials - Use will be asked for initials """ +import pygame + +from sliceitoff.screens import initials_screen + +from .explodeout import ExplodeOutGroup + +class Initials(ExplodeOutGroup): + """ Sprite group that asks initials to self.name from user """ + def __init__(self): + super().__init__() + self.add(initials_screen("")) + self.name = "" + + def update(self, dt = 0, **kwargs): + """ Does it all. Reads keyboard and updates screen """ + if not super().update(dt = dt, **kwargs): + return + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + self.do_fadeout() + break + if event.type == pygame.KEYDOWN: + if event.key in ( + pygame.K_ESCAPE, + pygame.K_KP_ENTER, + pygame.K_RETURN): + self.do_fadeout() + break + if event.key in ( + pygame.K_RSHIFT, + pygame.K_LSHIFT, + pygame.K_RCTRL, + pygame.K_LCTRL, + pygame.K_RALT, + pygame.K_LALT, + pygame.K_RMETA, + pygame.K_LMETA, + pygame.K_LSUPER, + pygame.K_RSUPER, + pygame.K_SPACE): + continue + if event.key in (pygame.K_BACKSPACE, pygame.K_DELETE): + self.name = self.name [:-1] + elif pygame.key.name(event.key): + self.name += pygame.key.name(event.key)[0].upper() + self.name = self.name[:3] + self.empty() + self.add(initials_screen(self.name)) diff --git a/src/sliceitoff/menu/mainmenu.py b/src/sliceitoff/menu/mainmenu.py new file mode 100644 index 0000000..9ba9096 --- /dev/null +++ b/src/sliceitoff/menu/mainmenu.py @@ -0,0 +1,18 @@ +""" menu.mainmenu - Let's user choose """ +from enum import IntEnum + +from sliceitoff.screens import mainmenu_screen +from .menu import Menu + +class MainMenuItems(IntEnum): + """ Items in the menu. Should match mainmenu_screen """ + NEWGAME = 0 + HISCORES = 1 + INSTRUCT = 2 + SETTINGS = 3 + QUIT = 4 + +class MainMenu(Menu): + """ Main menu """ + def __init__(self): + super().__init__(mainmenu_screen, len(MainMenuItems)) diff --git a/src/sliceitoff/menu/menu.py b/src/sliceitoff/menu/menu.py new file mode 100644 index 0000000..c0d63af --- /dev/null +++ b/src/sliceitoff/menu/menu.py @@ -0,0 +1,70 @@ +""" menu.menu - Skeleton for menus """ +import pygame + +from sliceitoff.display import Scaling + +from .explodeout import ExplodeOutGroup + +MOUSE_TRESHOLD = 100 + +class Menu(ExplodeOutGroup): + """ sprite group with imputs to make selection """ + def __init__(self, screen, items): + super().__init__() + self.items = items + self.selection = 0 + self.mousey = 0 + self.screen = screen + self.add(self.screen(self.selection)) + + def do_selection(self): + """ Default selection handler. Every action just ends menu. """ + self.do_fadeout() + + def update(self, dt = 0, **kwargs): + """ Does it all. Reads keyboard and updates screen """ + if not super().update(dt = dt, **kwargs) or self.explode: + return + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + self.selection = self.items - 1 + self.do_selection() + break + if event.type == pygame.MOUSEBUTTONDOWN and event.button <= 3: + self.do_selection() + break + if event.type == pygame.KEYDOWN: + if self.process_key(event.key): + break + elif event.type == pygame.MOUSEMOTION: + self.process_mouse_motion() + self.empty() + self.add(self.screen(self.selection)) + + def process_mouse_motion(self): + """ Mouse movement up or down moves menu selection """ + self.mousey += pygame.mouse.get_rel()[1] + pygame.mouse.set_pos(Scaling.center) + if abs(self.mousey) > MOUSE_TRESHOLD: + self.selection += 1 if self.mousey > 0 else -1 + self.selection %= self.items + self.mousey = 0 + + def process_key(self, key): + """ Processes known key presses """ + match key: + case pygame.K_KP_ENTER | pygame.K_RETURN | pygame.K_RIGHT: + self.do_selection() + return True + case pygame.K_ESCAPE | pygame.K_q | pygame.K_LEFT: + self.selection = self.items - 1 + self.do_selection() + return True + case pygame.K_UP: + self.selection -= 1 + self.selection %= self.items + case pygame.K_DOWN: + self.selection += 1 + self.selection %= self.items + return False diff --git a/src/sliceitoff/menu/settings.py b/src/sliceitoff/menu/settings.py new file mode 100644 index 0000000..2d3f594 --- /dev/null +++ b/src/sliceitoff/menu/settings.py @@ -0,0 +1,28 @@ +""" menu.settings - Settings dialog """ +from enum import IntEnum + +from sliceitoff.sfx import sfx +from sliceitoff.screens import settings_screen +from .menu import Menu + + +class SettingsItems(IntEnum): + """ Items in the menu. Should match settings_screen """ + SFX = 0 + MUSIC = 1 + BACK = 2 + +class SettingsMenu(Menu): + """ Settings menu """ + def __init__(self): + super().__init__(settings_screen, len(SettingsItems)) + + def do_selection(self): + """ Custom actions for menu entries """ + match self.selection: + case SettingsItems.BACK: + self.do_fadeout() + case SettingsItems.SFX: + sfx.sfx_up() + case SettingsItems.MUSIC: + sfx.music_up() diff --git a/src/sliceitoff/menu/show.py b/src/sliceitoff/menu/show.py new file mode 100644 index 0000000..5c122d8 --- /dev/null +++ b/src/sliceitoff/menu/show.py @@ -0,0 +1,24 @@ +""" menu.show - Sprite group that show sprites and skips if key is pressed """ +from .anykey import anykey +from .explodeout import ExplodeOutGroup + +class Show(ExplodeOutGroup): + """ To show some sprites and quit on any key """ + def __init__(self, sprites = None, active = True): + super().__init__(active = active) + self.add(sprites) + self.timeout = 15_000 + + def update(self, dt = 0, **kwargs): + """ First timeout then fadeout and then inactivity """ + if not super().update(dt = dt, **kwargs): + return + if anykey(): + self.do_fadeout() + if self.timeout <= 0: + self.do_fadeout() + self.timeout -= dt + + def sprites(self): + """ Return sprites only when active """ + return super().sprites() if self.active else [] |