summaryrefslogtreecommitdiffstats
path: root/pygame/main.py
diff options
context:
space:
mode:
authorvg <vgm+dev@devys.org>2022-11-09 22:28:54 +0100
committervg <vgm+dev@devys.org>2022-11-09 22:28:54 +0100
commitc3ac27e6f26bd3ebcaa8f3bd620c2d4619aa8de6 (patch)
tree443f9f74ad8ad47167b8e763ad8236985b333bcb /pygame/main.py
parent25e1987ca123ccffddd21a78adb900ec31c4f22a (diff)
downloadgamechest-c3ac27e6f26bd3ebcaa8f3bd620c2d4619aa8de6.tar.gz
gamechest-c3ac27e6f26bd3ebcaa8f3bd620c2d4619aa8de6.tar.bz2
gamechest-c3ac27e6f26bd3ebcaa8f3bd620c2d4619aa8de6.zip
git-sync on dita
Diffstat (limited to 'pygame/main.py')
-rwxr-xr-xpygame/main.py307
1 files changed, 307 insertions, 0 deletions
diff --git a/pygame/main.py b/pygame/main.py
new file mode 100755
index 0000000..948b95a
--- /dev/null
+++ b/pygame/main.py
@@ -0,0 +1,307 @@
+#!/usr/bin/python3
+
+from dataclasses import dataclass
+from pathlib import Path
+
+#import pygame_sdl2 as pygame
+import pygame
+import yaml
+
+
+#WINDOW_RESOLUTION = (1280, 720)
+WINDOW_RESOLUTION = (800, 600)
+
+if pygame.ver[0] != '2':
+ raise ValueError(f'pygame2 required, got {pygame.ver}')
+
+
+class Event(Exception): pass
+class QuitEvent(Event): pass
+
+
+@dataclass
+class AppState:
+ menu_selected_index: int = 0
+
+
+class GuiApp:
+
+ def __init__(self):
+ pygame.init()
+ #print(pygame.display.list_modes())
+ self.window = pygame.display.set_mode(WINDOW_RESOLUTION)
+ self.clock = pygame.time.Clock()
+ self.menu_font = pygame.font.Font(pygame.font.get_default_font(), 32)
+ self.font_antialias = True
+ #self.font_antialias = False
+ self.menu_color = (0, 0, 200)
+
+ def process_input(self, event=None):
+ if event is None:
+ event = pygame.event.poll()
+ if event.type == pygame.KEYDOWN:
+ print('event', event, 'key name', pygame.key.name(event.key))
+ if event.key in (pygame.K_q, pygame.K_ESCAPE):
+ raise QuitEvent()
+ if event.type == pygame.QUIT:
+ raise QuitEvent()
+
+ def update(self):
+ pass
+
+ def render(self):
+ self.window.fill((0, 0, 0))
+
+ # Initial y
+ y = 50
+
+ # Title
+ #surface = self.titleFont.render("TANK BATTLEGROUNDS !!", True, (200, 0, 0))
+ #x = (self.window.get_width() - surface.get_width()) // 2
+ #self.window.blit(surface, (x, y))
+ #y += (200 * surface.get_height()) // 100
+
+ x = 50
+
+ # Compute menu width
+ #menuWidth = 0
+ #for item in self.menuItems:
+ # surface = self.itemFont.render(item['title'], True, (200, 0, 0))
+ # menuWidth = max(menuWidth, surface.get_width())
+ # item['surface'] = surface
+
+ surface = self.menu_font.render("I love my cat !",
+ self.font_antialias, self.menu_color)
+ self.window.blit(surface, (x, y))
+
+ ## Draw menu items
+ #x = (self.window.get_width() - menuWidth) // 2
+ #for index, item in enumerate(self.menuItems):
+ # # Item text
+ # surface = item['surface']
+ # self.window.blit(surface, (x, y))
+
+ # # Cursor
+ # if index == self.currentMenuItem:
+ # cursorX = x - self.menuCursor.get_width() - 10
+ # cursorY = y + (surface.get_height() - self.menuCursor.get_height()) // 2
+ # self.window.blit(self.menuCursor, (cursorX, cursorY))
+
+ # y += (120 * surface.get_height()) // 100
+
+
+ #pygame.draw.rect(self.window,
+ # (0,0,255),
+ # (120,120,400,240))
+
+ pygame.display.update()
+
+
+ def loop(self):
+
+ try:
+ while 1:
+ self.process_input()
+ self.update()
+ self.render()
+ self.clock.tick(30) # 30 fps
+ except QuitEvent:
+ pass
+
+ print('quitting')
+ pygame.quit()
+
+
+class GuiAppSub1(GuiApp):
+
+ def __init__(self):
+ super().__init__()
+
+ self.state = AppState()
+ self.base_window_fill_color = (0, 0, 0)
+ self.user_move_vector = (0, 0)
+ with Path('~/games/.saves/gamedata.yaml').expanduser().open() as fp:
+ self.gamedb = yaml.safe_load(fp)
+ self.menu_items = [x['title'] for x in self.gamedb['games']]
+ self.menu_font_cache = ({}, [])
+ self.menu_font_cache_max = 40
+ self.image_right_arrow = pygame.image.load('arrow-right.png')
+ #self.last_movement_update_time = self.clock.
+ self.joysticks = {}
+ self.joysticks_axis_threshold = 0
+
+ def menu_font_render(self, text):
+ cached_surface = self.menu_font_cache[0].get(text, None)
+ if cached_surface is not None:
+ self.menu_font_cache[1].remove(text)
+ self.menu_font_cache[1].append(text) # refresh mru place
+ return cached_surface
+
+ new_surface = self.menu_font.render(text,
+ self.font_antialias,
+ self.menu_color)
+
+ self.menu_font_cache[0][text] = new_surface
+ self.menu_font_cache[1].append(text)
+
+ if len(self.menu_font_cache[1]) > self.menu_font_cache_max:
+ removed_item_text = self.menu_font_cache[1].pop(0)
+ del self.menu_font_cache[0][removed_item_text]
+
+ # debug for cache miss:
+ print('cache miss for', text)
+
+ return new_surface
+
+ def process_input(self):
+ movement_up_keys = (
+ pygame.K_UP,
+ pygame.K_k,
+ )
+ movement_down_keys = (
+ pygame.K_DOWN,
+ pygame.K_j,
+ )
+ axis_change = 0
+ for event in pygame.event.get():
+ go_super = 1
+ x, y = self.user_move_vector
+ if event.type == pygame.KEYDOWN:
+ if event.key in (*movement_up_keys, *movement_down_keys):
+ y += 1 if event.key in movement_down_keys else -1
+ go_super = 0
+ elif event.key in (pygame.K_LEFT, pygame.K_RIGHT):
+ x += 1 if event.key == pygame.K_LEFT else -1
+ go_super = 0
+ elif event.type == pygame.KEYUP:
+ x, y = self.user_move_vector
+ if event.key in (*movement_up_keys, *movement_down_keys):
+ y -= 1 if event.key in movement_down_keys else -1
+ go_super = 0
+ elif event.key in (pygame.K_LEFT, pygame.K_RIGHT):
+ x -= 1 if event.key == pygame.K_LEFT else -1
+ go_super = 0
+ elif event.type in (pygame.JOYBUTTONDOWN, pygame.JOYBUTTONUP):
+ go_super = 0
+ factor = 1 if pygame.JOYBUTTONDOWN else -1
+ joystick = self.joysticks[event.instance_id]
+ print('gamepad event', event)
+ #if event.button == 0:
+ #y += 1 * factor
+ if event.type == pygame.JOYBUTTONDOWN:
+ joystick.rumble(0.3, 0.8, 40)
+ if event.button == 1:
+ raise QuitEvent()
+ #if event.button == 1:
+ #y -= 1 * factor
+ elif event.type == pygame.JOYAXISMOTION:
+ go_super = 0
+ if event.axis == 1: # left stick up-down axis
+ new_axis = self.joysticks_axis_threshold
+ #print('motion event', event)
+ if event.value > 0.70:
+ new_axis = 1 # down activated
+ elif event.value < 0.5 and event.value > -0.5:
+ new_axis = 0 # down and up deactivated
+ elif event.value < -0.70:
+ new_axis = -1 # up activated
+ if new_axis != self.joysticks_axis_threshold:
+ axis_change = 1
+ self.joysticks_axis_threshold = new_axis
+ print('threshold', self.joysticks_axis_threshold)
+ elif event.type == pygame.JOYDEVICEADDED:
+ # This event will be generated when the program starts for every
+ # joystick, filling up the list without needing to create them manually.
+ joy = pygame.joystick.Joystick(event.device_index)
+ self.joysticks[joy.get_instance_id()] = joy
+ print(f"Gamepad {joy.get_instance_id()} connected")
+ elif event.type == pygame.JOYDEVICEREMOVED:
+ del self.joysticks[event.instance_id]
+ print(f"Gamepad {event.instance_id} disconnected")
+
+ if go_super == 0:
+ if axis_change:
+ self.user_move_vector = (x, self.joysticks_axis_threshold)
+ else:
+ self.user_move_vector = (x, y)
+ print('new move vector:', self.user_move_vector)
+ else:
+ super().process_input(event)
+
+ def update(self):
+ menu_new_index = self.state.menu_selected_index
+ if self.user_move_vector[1] < 0:
+ menu_new_index -= 1
+ elif self.user_move_vector[1] > 0:
+ menu_new_index += 1
+ if menu_new_index < 0:
+ menu_new_index = 0
+ elif menu_new_index > (len(self.menu_items)-1):
+ menu_new_index = len(self.menu_items)-1
+ self.state.menu_selected_index = menu_new_index
+
+ def render(self):
+ self.window.fill(self.base_window_fill_color)
+
+ # Initial y
+ y = 50
+
+ # Title
+ #surface = self.titleFont.render("TANK BATTLEGROUNDS !!", True, (200, 0, 0))
+ #x = (self.window.get_width() - surface.get_width()) // 2
+ #self.window.blit(surface, (x, y))
+ #y += (200 * surface.get_height()) // 100
+
+ x = 50 + 64 + 5
+
+ # Compute menu width
+ #menuWidth = 0
+ #for item in self.menuItems:
+ # surface = self.itemFont.render(item['title'], True, (200, 0, 0))
+ # menuWidth = max(menuWidth, surface.get_width())
+ # item['surface'] = surface
+
+ y_pad = 5
+ font_selected_item_height = None
+ selected_item_y = y
+ for index, item in enumerate(self.menu_items):
+ surface = self.menu_font_render(item)
+ self.window.blit(surface, (x, y))
+ if self.state.menu_selected_index == index:
+ font_selected_item_height = surface.get_height()
+ selected_item_y = y
+ y += surface.get_height() + y_pad
+
+ self.window.blit(self.image_right_arrow, (50, selected_item_y - 64//2
+ + font_selected_item_height//2))
+
+
+ fps_surface = self.menu_font_render(f'{self.clock.get_fps():02.0f}')
+ fps_pos = (self.window.get_width() - fps_surface.get_width(), 0)
+ self.window.blit(fps_surface, fps_pos)
+
+ ## Draw menu items
+ #x = (self.window.get_width() - menuWidth) // 2
+ #for index, item in enumerate(self.menuItems):
+ # # Item text
+ # surface = item['surface']
+ # self.window.blit(surface, (x, y))
+
+ # # Cursor
+ # if index == self.currentMenuItem:
+ # cursorX = x - self.menuCursor.get_width() - 10
+ # cursorY = y + (surface.get_height() - self.menuCursor.get_height()) // 2
+ # self.window.blit(self.menuCursor, (cursorX, cursorY))
+
+ # y += (120 * surface.get_height()) // 100
+
+
+ #pygame.draw.rect(self.window,
+ # (0,0,255),
+ # (120,120,400,240))
+
+ pygame.display.update()
+
+
+app = GuiAppSub1()
+app.loop()