summaryrefslogtreecommitdiff
path: root/src/sliceitoff/menu
diff options
context:
space:
mode:
authorViljami Ilola <+@hix.fi>2024-04-27 16:26:22 +0300
committerViljami Ilola <+@hix.fi>2024-04-27 16:26:22 +0300
commit9f8247dc4da89219b6eede08d58d96964391a077 (patch)
treea6f7dc46275a3988fc528072f5e70caba461fae0 /src/sliceitoff/menu
parentd64c6b122eacd7b33bbda3a62093b492c786b1f9 (diff)
refactor menus and screen showing under menu subpkg
Diffstat (limited to 'src/sliceitoff/menu')
-rw-r--r--src/sliceitoff/menu/__init__.py5
-rw-r--r--src/sliceitoff/menu/anykey.py9
-rw-r--r--src/sliceitoff/menu/explodeout.py38
-rw-r--r--src/sliceitoff/menu/initials.py50
-rw-r--r--src/sliceitoff/menu/mainmenu.py18
-rw-r--r--src/sliceitoff/menu/menu.py70
-rw-r--r--src/sliceitoff/menu/settings.py28
-rw-r--r--src/sliceitoff/menu/show.py24
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 []