diff options
author | vg <vgm+dev@devys.org> | 2023-01-02 16:49:22 +0100 |
---|---|---|
committer | vg <vgm+dev@devys.org> | 2023-01-02 16:49:22 +0100 |
commit | f79d73440fa6b4e3f2641c86a477b5e5630d7fad (patch) | |
tree | 7f3fad78682d271dca8ebfd69091fce378634050 /pygame/main.py | |
parent | ae768bc9758237bb6f99911dfa66ea5895bbca29 (diff) | |
download | gamechest-f79d73440fa6b4e3f2641c86a477b5e5630d7fad.tar.gz gamechest-f79d73440fa6b4e3f2641c86a477b5e5630d7fad.tar.bz2 gamechest-f79d73440fa6b4e3f2641c86a477b5e5630d7fad.zip |
git-sync on dita
Diffstat (limited to 'pygame/main.py')
-rwxr-xr-x | pygame/main.py | 441 |
1 files changed, 0 insertions, 441 deletions
diff --git a/pygame/main.py b/pygame/main.py deleted file mode 100755 index ba61077..0000000 --- a/pygame/main.py +++ /dev/null @@ -1,441 +0,0 @@ -#!/usr/bin/python3 - -from dataclasses import dataclass -from pathlib import Path - -#import pygame_sdl2 as pygame -import pygame -import yaml - -from profiledb import ProfileDB - -from gamechest.cliactions import run -from gamechest.gamedb import GameDB - - -#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 Parameters: - key_delay = 330 - key_interval = 1000//25 - - - - -class GuiApp: - - def __init__(self): - pygame.init() - pygame.key.set_repeat(Parameters.key_delay, Parameters.key_interval) - #print(pygame.display.list_modes()) - self.window = pygame.display.set_mode(WINDOW_RESOLUTION) - self.clock = pygame.time.Clock() - self.cycles_per_second = 60 - #self.render_factor_div = 2 # 60/2 => 30fps - #self.input_factor_div = 6 # 60/6 => 10 input repeat per second - 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) - self.render_timer = 0 - self.render_timeout = 1000//30 # 30 fps - - def process_input(self, last_frame_time, 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, last_frame_time): - pass - - def render(self, last_frame_time): - self.render_timer += last_frame_time - if self.render_timer < self.render_timeout: - return - self.render_timer = 0 - - 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): - #current_render_div = self.render_factor_div - #current_input_div = self.input_factor_div - last_frame_time = 1 # equivalent to 0 but avoid div0 - last_render_time = 1 - try: - while 1: - #current_render_div -= 1 - #current_input_div -= 1 - self.process_input(last_frame_time) - #self.update(current_input_div) - self.update(last_frame_time) - self.render(last_frame_time) - #if current_render_div <= 0: - # self.render(last_render_time) - # current_render_div = self.render_factor_div - # last_render_time = 0 - #if current_input_div <= 0: - # current_input_div = self.input_factor_div - last_frame_time = self.clock.tick(self.cycles_per_second) - #last_render_time += last_frame_time - except QuitEvent: - pass - - print('quitting') - pygame.quit() - - -class ProfileDataObserver: - - def event_current_profile_changed(self, new_profile): - pass - - -class ObservedSubject: - def __init__(self): - self.observers = [] - - def add_observer(self, observer): - self.observers.append(observer) - - def del_observer(self, observer): - self.observers.remove(observer) - - def notify_event(self, event_name, *args, **kws): - for observer in self.observers: - getattr(observer, event_name)(*args, **kws) - - -class ProfileData(ObservedSubject): - - def __init__(self): - super().__init__() - self.profiledb = ProfileDB() - self.profiles_len = len(self.profiledb.get_profiles()) - self.current_profile_index = 0 - - def change_active_profile(self, new_index): - if new_index < 0: - new_index = 0 - elif new_index >= self.profiles_len: - new_index = self.profiles_len-1 - if self.current_profile_index != new_index: - print('new index', self.current_profile_index, '->', new_index) - self.current_profile_index = new_index - print(id(self), 'new index', self.current_profile_index) - self.notify_event('event_current_profile_changed', - self.get_current_profile()) - - def change_profile_increase(self): - self.change_active_profile(self.current_profile_index +1) - - def change_profile_decrease(self): - self.change_active_profile(self.current_profile_index -1) - - def get_current_profile(self): - return self.profiledb.get_profiles()[self.current_profile_index]['name'] - - def get_current_display(self): - return self.profiledb.get_profiles()[self.current_profile_index]['display'] - - -class ProfileRenderer(ProfileDataObserver): - - def __init__(self, profiledata): - self.profiledata = profiledata - self.surface_to_render = None - profiledata.add_observer(self) - self.font_filename = pygame.font.match_font('bitstreamverasans') - print('ProfileRenderer font:', self.font_filename) - self.font = pygame.font.Font(self.font_filename, 24) - self.font_antialias = True - self.font_fg_color = (0, 200, 200) - - def event_current_profile_changed(self, new_profile): - self.surface_to_render = None - print('changing rendering profile to', new_profile) - - def render(self, surface): - if self.surface_to_render is None: - profile_name = self.profiledata.get_current_profile() - new_surface = self.font.render(self.profiledata.get_current_display(), self.font_antialias, self.font_fg_color) - self.surface_to_render = new_surface - surface.blit(self.surface_to_render, (50, 50)) - - -class GuiAppSub1(GuiApp): - - def __init__(self): - super().__init__() - self.input_timer = 0 - self.input_timeout = 1000//10 - 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.game_db = GameDB() - #self.menu_items = [x['title'] for x in self.gamedb['games']] - self.menu_items = list(self.game_db.get_ids()) - self.menu_font_cache = ({}, []) - self.menu_font_cache_max = 40 - self.image_right_arrow = pygame.image.load('arrow-right.png').convert() - #self.last_movement_update_time = self.clock. - self.joysticks = {} - self.joysticks_axis_threshold = 0 - self.profile_data = ProfileData() - self.profile_renderer = ProfileRenderer(self.profile_data) - - - 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, last_frame_time): - - 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 = 0 - go_super = 0 - elif event.key in (pygame.K_LEFT, pygame.K_RIGHT): - x = 0 - go_super = 0 - elif event.type in (pygame.JOYBUTTONDOWN, pygame.JOYBUTTONUP): - go_super = 0 - factor = 1 if pygame.JOYBUTTONDOWN else 0 - 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(last_frame_time, event) - - def update(self, last_frame_time): - #self.input_timer += last_frame_time - #if self.input_timer < self.input_timeout: - # return - #self.input_timer = 0 - - 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 - - if self.user_move_vector[0] < 0: - self.profile_data.change_profile_decrease() - elif self.user_move_vector[0] > 0: - self.profile_data.change_profile_increase() - - self.user_move_vector = (0, 0) - - def render(self, last_frame_time): - 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)) - self.profile_renderer.render(self.window) - - pygame.display.update() - - -app = GuiAppSub1() -app.loop() |