From 2987bfa7edc9be5235c01d14cad6c61d88b7029b Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 09:58:44 -0400 Subject: [PATCH 01/58] Added title.py surface --- pocket_friends/game_files/surfaces/title.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 pocket_friends/game_files/surfaces/title.py diff --git a/pocket_friends/game_files/surfaces/title.py b/pocket_friends/game_files/surfaces/title.py new file mode 100644 index 0000000..8ce206b --- /dev/null +++ b/pocket_friends/game_files/surfaces/title.py @@ -0,0 +1,12 @@ +import pygame + + +class Surface(pygame.Surface): + def __init__(self, window_size): + super().__init__(window_size, pygame.SRCALPHA) + self.running = True + self.next_surface = None + + def update(self): + self.fill((0, 0, 0)) + From 36487cad9e9b79c5a3f69bd5da8d6db27f9a37c7 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 10:26:01 -0400 Subject: [PATCH 02/58] Added comments --- pocket_friends/game_files/game.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 6b6d248..cd6e8b5 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -530,7 +530,7 @@ try: on_hardware = True except ImportError: import pocket_friends.development.FakeGPIO as GPIO - + # Run as if not on hardware on_hardware = False From 787c1cc25292679a4282bdddcf8713c603955d11 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 10:40:57 -0400 Subject: [PATCH 03/58] created __init__.py in surfaces for importing --- pocket_friends/game_files/surfaces/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pocket_friends/game_files/surfaces/__init__.py diff --git a/pocket_friends/game_files/surfaces/__init__.py b/pocket_friends/game_files/surfaces/__init__.py new file mode 100644 index 0000000..e69de29 From f1c83ade970bbbc55034fe5fccac531d68a95104 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 11:02:08 -0400 Subject: [PATCH 04/58] renamed old game.py file to start with rebuild --- pocket_friends/game_files/game.py | 984 ------------------------------ 1 file changed, 984 deletions(-) delete mode 100644 pocket_friends/game_files/game.py diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py deleted file mode 100644 index cd6e8b5..0000000 --- a/pocket_friends/game_files/game.py +++ /dev/null @@ -1,984 +0,0 @@ -""" -Main file for the entire game. Controls everything except for GPIO input. -""" -from collections import deque -import importlib.util -import json -import os -from pathlib import Path -import pocket_friends -import pygame -from pygame.locals import * -from ..hardware.gpio_handler import Constants, GPIOHandler - -# FPS for the entire game to run at. -game_fps = 16 -# The resolution the game is rendered at. -game_res = 80 - -# Gets the directory of the script for importing and the save directory -script_dir = os.path.dirname(os.path.abspath(__file__)) -save_dir = os.path.join(Path.home(), '.pocket_friends') - -# Tries to make the save directory. Does nothing if it already exists. -try: - os.mkdir(save_dir) -except FileExistsError: - pass - - -class SpriteSheet: - """ - Imports a sprite sheet as separate pygame images given an image file and a json file. - """ - - def __init__(self, sprite_sheet, texture_json): - # Load in whole sprite sheet as one image. - self.sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha() - self.images = [] - - # Get the sprite sheet json file. - with open(texture_json, 'r') as json_file: - self.img_attrib = json.load(json_file) - json_file.close() - - # Count for how many images have been added in the image list - image_count = 0 - - # Get the sprite size as a tuple - sprite_size = self.img_attrib['width'], self.img_attrib['height'] - - # Iterate through every image location on the sprite sheet given the sprite size - for i in range(self.sprite_sheet.get_size()[1] // sprite_size[1]): - i *= sprite_size[1] - for j in range(self.sprite_sheet.get_size()[0] // sprite_size[0]): - j *= sprite_size[0] - - # Create a new transparent surface - sprite = pygame.Surface(sprite_size, SRCALPHA) - # Blit the sprite onto the image - sprite.blit(self.sprite_sheet, (0, 0), (j, i, sprite_size[0], sprite_size[1])) - # Add the image to the list of images - self.images.append(sprite) - - image_count += 1 - - # Break the loop if the specified number of frames has been reached. - if image_count >= self.img_attrib['frames']: - break - if image_count >= self.img_attrib['frames']: - break - - -class DataHandler: - """ - Class that handles the hardware attributes and save files. - """ - - def __init__(self): - # Attributes that are saved to a file to recover upon startup. - self.attributes = { - 'version': pocket_friends.__version__, - 'time_elapsed': 0, - 'bloop': '', - 'age': 0, - 'health': 0, - 'hunger': 0, - 'happiness': 0, - 'care_counter': 0, - 'missed_care': 0, - 'adult': 0, - 'evolution_stage': '', - } - - # Frame counter - self.frames_passed = 0 - - def write_save(self): - """ - Writes attributes of class to "save.json" file. - """ - with open(save_dir + '/save.json', 'w') as save_file: - json.dump(self.attributes, save_file) - save_file.close() - - def read_save(self): - """ - Reads from "save.json" and inserts into attributes dictionary. Creates file if it does not exist. - """ - # Open up the save file and read it into self.attributes. - try: - with open(save_dir + '/save.json', 'r') as save_file: - self.attributes = json.load(save_file) - save_file.close() - - # If there is no save file, write one with the defaults. - except FileNotFoundError: - self.write_save() - - def update(self): - """ - Run the game logic. - """ - self.frames_passed += 1 - # Run logic of the game every second. - if self.frames_passed >= game_fps: - - # Add one to the age of the bloop. - self.attributes['age'] += 1 - - # Save the data when the age of the bloop is a multiple of 10. - if self.attributes['age'] % 10 == 0: - self.write_save() - - # Reset frame counter - self.frames_passed = 0 - - -class PlaygroundFriend(pygame.sprite.Sprite): - """ - Class for the sprite of the creature on the main playground. - """ - - def __init__(self, data_handler): - pygame.sprite.Sprite.__init__(self) - - # All attributes of the bloops - self.bloop = data_handler.attributes['bloop'] - self.adult = data_handler.attributes['adult'] - self.evolution_stage = data_handler.attributes['evolution_stage'] - self.direction = 0 - - if self.evolution_stage == 'adult': - image = self.evolution_stage + self.adult - else: - image = self.evolution_stage - - # Draw the correct bloop depending on the stage - sprite_sheet = SpriteSheet(script_dir + '/resources/images/bloops/{0}/{1}.png'.format(self.bloop, image), - script_dir + '/resources/images/bloops/{0}/{1}.json'.format(self.bloop, image)) - - # Load the images from the sprite sheet - self.images = sprite_sheet.images - - # Put the egg in the middle of the screen. - self.rect = self.images[0].get_rect() - self.rect.x = (game_res / 2) - (self.rect.width / 2) - self.rect.y = (game_res / 2) - (self.rect.height / 2) - - # Start animation at the beginning of the sprite sheet. - self.index = 0 - self.image = self.images[self.index] - - self.movement_frames = game_fps / 2 # How many frames pass before the bloop moves - self.current_frame = 0 - - def pet(self): - """ - Pet the bloop! - """ - pass - - def update(self): - """ - Takes the images loaded and animates it, spacing it out equally for the framerate. - """ - - margins = 9 # Margins for how far the bloop can move from the left and the right of the screen - movement_amount = 2 # Pixels that the bloop moves in one movement - - self.current_frame += 1 - - # Check to see if the number of movement frames has passed - if self.current_frame >= self.movement_frames: - self.current_frame = 0 - - # Move only if the bloop is not in the egg stage - if self.evolution_stage != 'egg': - - # Change direction if the bloop has reached either edge of the screen - if self.rect.x < margins: - self.direction = 1 - elif self.rect.x > game_res - margins - self.rect.width: - self.direction = 0 - - # Move according to the direction. - if self.direction == 0: - self.rect.x -= movement_amount - else: - self.rect.x += movement_amount - - # Animate the bloop - self.index = (self.index + 1) % len(self.images) - self.image = self.images[self.index] - - -class SelectionEgg(pygame.sprite.Sprite): - """ - Class for the eggs on the egg selection screen. - """ - - def __init__(self, egg_color): - pygame.sprite.Sprite.__init__(self) - - self.egg_color = egg_color - - # Loads the JSON file of the egg to read in data. - with open(script_dir + '/resources/data/bloop_info/{0}.json'.format(egg_color), 'r') as save_file: - json_file = json.load(save_file) - save_file.close() - - # Gets the description off the egg from the JSON file. - self.description = json_file.get('description') - self.contentedness = json_file.get('contentedness') - self.metabolism = json_file.get('metabolism') - - # Load the egg from the given color and get the bounding rectangle for the image. - sprite_sheet = SpriteSheet(script_dir + '/resources/images/bloops/{0}/egg.png'.format(self.egg_color), - script_dir + '/resources/images/bloops/{0}/egg.json'.format(self.egg_color)) - self.images = sprite_sheet.images - - # Get the rectangle from the first image in the list - self.rect = self.images[0].get_rect() - self.index = 0 - self.image = self.images[self.index] - - def update(self): - """ - Updates the sprite object. - """ - # Animate the sprite - self.index = (self.index + 1) % len(self.images) - self.image = self.images[self.index] - - -class EggInfo: - """ - Class to draw the contentedness and metabolism value off the egg on the info screen. - """ - - def __init__(self, contentedness, metabolism, location): - self.contentedness = contentedness - self.metabolism = metabolism - self.x = location[0] - self.y = location[1] - - # Create a new surface to blit onto the other surface - self.surface = pygame.Surface((44, 15), SRCALPHA) - - # Blit the two indicator icons on screen - smiley = pygame.image.load(script_dir + '/resources/images/gui/smiley.png').convert_alpha() - self.surface.blit(smiley, (0, 0)) - apple = pygame.image.load(script_dir + '/resources/images/gui/apple.png').convert_alpha() - self.surface.blit(apple, (1, 9)) - - # Draw 5 stars. If the value of the contentedness is less than the current star, make it a blank star. - for i in range(5): - if i < self.contentedness: - star = pygame.image.load(script_dir + '/resources/images/gui/star.png').convert_alpha() - else: - star = pygame.image.load(script_dir + '/resources/images/gui/blank_star.png').convert_alpha() - self.surface.blit(star, (11 + (i * 6), 1)) - - # Draw 5 stars. If the value of the metabolism is less than the current star, make it a blank star. - for i in range(5): - if i < self.metabolism: - star = pygame.image.load(script_dir + '/resources/images/gui/star.png').convert_alpha() - else: - star = pygame.image.load(script_dir + '/resources/images/gui/blank_star.png').convert_alpha() - self.surface.blit(star, (11 + (i * 6), 10)) - - def draw(self, surface): - """ - Draw the info icons on a given surface. - :param surface: the surface to draw the icons on. - """ - # Blit the info onto the given surface. - surface.blit(self.surface, (self.x, self.y)) - - -class InfoText: - """ - Class for drawing large amounts of text on the screen at a time - """ - - def __init__(self, font, text='Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam commodo tempor ' - 'aliquet. Suspendisse placerat accumsan neque, nec volutpat nunc porta ut.'): - - self.font = font - self.text = [] # Text broken up into a list according to how it will fit on screen. - self.max_lines = 6 # Max number of lines to be shown on screen at a time. - self.offset = 0 - - # Arrow icons to indicate scrolling - self.up_arrow = pygame.image.load(script_dir + '/resources/images/gui/up_arrow.png').convert_alpha() - self.down_arrow = pygame.image.load(script_dir + '/resources/images/gui/down_arrow.png').convert_alpha() - - raw_text = text # Copy the text to a different variable to be cut up. - - margins = 4.5 - max_line_width = game_res - (margins * 2) # The maximum pixel width that drawn text can be. - cut_chars = '.,! ' # Characters that will be considered "cuts" aka when a line break can occur. - - # Prevents freezing if the end of the string does not end in a cut character - # Will fix eventually more elegantly - if raw_text[-1:] not in cut_chars: - raw_text += ' ' - - # Calculating line breaks. - while len(raw_text) > 0: - index = 0 - test_text = '' # Chunk of text to pseudo-render and test the width of. - - # Loops until the testing text has reached the size limit. - while True: - - # Break if the current index is larger than the remaining text. - if index + 1 > len(raw_text): - index -= 1 - break - - # Add one character to the testing text from the raw text. - test_text += raw_text[index] - # Get the width of the pseudo-rendered text. - text_width = font.size(test_text)[0] - - # Break if the text is larger than the defined max width. - if text_width > max_line_width: - break - index += 1 - pass - - # Gets the chunk of text to be added to the list. - text_chunk = raw_text[0:index + 1] - # Determines if the chunk of text has any break characters. - has_breaks = any(cut_chars in text_chunk for cut_chars in cut_chars) - - # If the text has break characters, start with the last character and go backwards until - # one has been found, decreasing the index each time. - if has_breaks: - while raw_text[index] not in cut_chars: - index -= 1 - text_chunk = raw_text[0:index + 1] - # If there are no break characters in the chunk, simply decrease the index by one and insert - # a dash at the end of the line to indicate the word continues. - else: - index -= 1 - text_chunk = raw_text[0:index + 1] - text_chunk += '-' - - # Append the text chunk to the list of text to draw. - self.text.append(text_chunk) - - # Cut the text to repeat the process with the new cut string. - raw_text = raw_text[index + 1:] - - def draw(self, surface): - """ - Draws the text on a given surface. - :param surface: The surface for the text to be drawn on. - """ - # Constants to help draw the text - line_separation = 7 - left_margin = 3 - top_margin = 25 - bottom_margin = 10 - - # Draw the lines on the screen - for i in range(min(len(self.text), self.max_lines)): - text = self.font.render(self.text[i + self.offset], False, (64, 64, 64)) - surface.blit(text, (left_margin, top_margin + (i * line_separation))) - - # Draw the arrows if there is more text than is on screen. - if self.offset != 0: - surface.blit(self.up_arrow, ((game_res / 2) - (self.up_arrow.get_rect().width / 2), top_margin - 3)) - if len(self.text) - (self.offset + 1) >= self.max_lines: - surface.blit(self.down_arrow, - ((game_res / 2) - (self.down_arrow.get_rect().width / 2), game_res - bottom_margin)) - - def scroll_down(self): - """ - Scrolls the text on the screen down. - """ - # Ensures that the offset cannot be too big as to try to render non-existent lines. - if len(self.text) - (self.offset + 1) >= self.max_lines: - self.offset += 1 - - def scroll_up(self): - """ - Scrolls the text on the screen up. - """ - if self.offset > 0: # Ensures a non-zero offset is not possible. - self.offset -= 1 - - -class MenuIcon(pygame.sprite.Sprite): - """ - Sprite for an icon on the main popup menu. - """ - - def __init__(self, icon): - pygame.sprite.Sprite.__init__(self) - self.icon = icon - - # Load the sprite sheet from the icon name - sprite_sheet = SpriteSheet(script_dir + '/resources/images/gui/popup_menu/{0}.png'.format(self.icon), - script_dir + '/resources/images/gui/popup_menu/{0}.json'.format(self.icon)) - self.images = sprite_sheet.images - - # Get the rectangle from the first image in the list - self.rect = self.images[0].get_rect() - self.image = self.images[0] - - def select(self): - """ - Change the icon sprite to the selected icon. - """ - self.image = self.images[1] - - def deselect(self): - """ - Change the icon sprite to the not selected icon. - """ - self.image = self.images[0] - - -class PopupMenu: - """ - Class to create a popup menu that can be hidden and shown at will - """ - - def __init__(self, position): - # Background frame of the popup menu - self.frame = pygame.image.load(script_dir + '/resources/images/gui/popup_menu/frame.png').convert_alpha() - - self.draw_menu = False # Whether or not to draw the popup menu - self.menu_sprites = pygame.sprite.Group() # Sprite group for the icons - self.selected = 0 # The currently selected icon - - # The names of the icons to be drawn - icon_names = ['apple', 'dumbbell', 'stats', 'controller', 'bed'] - - self.icons = [] - # Create an icon sprite for each name in the list and add it to the icon list - for i in icon_names: - self.icons.append(MenuIcon(i)) - - # Add each sprite in the icon list to the sprite group - for i in range(len(self.icons)): - icon = self.icons[i] - if i == self.selected: # Make the default selected icon glow - icon.select() - - # Calculate the position of the icon on screen - icon.rect.x = 10 + (i * 15) - (icon.image.get_width() / 2) - icon.rect.y = position[1] + self.frame.get_height() / 2 - icon.image.get_height() / 2 - - # Add the icon to the sprite group. - self.menu_sprites.add(icon) - - def toggle(self): - """ - Toggles the menu on or off. - """ - self.draw_menu = not self.draw_menu - - def next(self): - """ - Changes the selection to the next icon (to the right.) - """ - if self.draw_menu: # Only change if the menu is on screen - - self.icons[self.selected].deselect() # Deselect the current icon - self.selected += 1 # Change selection to the next icon - if self.selected >= len(self.icons): # Wrap around if new value is invalid - self.selected = 0 - self.icons[self.selected].select() # Select the newly selected icon - - def prev(self): - """ - Changes the selection to the previous icon (to the left.) - """ - if self.draw_menu: # Only change if the menu is on screen - - self.icons[self.selected].deselect() # Deselect the current icon - self.selected -= 1 # Change selection to the previous icon - if self.selected < 0: # Wrap around if new value is invalid - self.selected = len(self.icons) - 1 - self.icons[self.selected].select() # Select the newly selected icon - - def draw(self, surface): - """ - Draw the menu onto a given surface - :param surface: the surface to draw the menu on. - """ - # Draw the menu only if it is toggled on. - if self.draw_menu: - surface.blit(self.frame, (3, 3)) - self.menu_sprites.draw(surface) - - -# Makes Pygame draw on the display of the RPi. -os.environ["SDL_FBDEV"] = "/dev/fb1" - -# Useful for debugging on the PC. Imports a fake RPi.GPIO library if one is not found (which it can't -# be on a PC, RPi.GPIO cannot be installed outside of a Raspberry Pi. -try: - importlib.util.find_spec('RPi.GPIO') - import RPi.GPIO as GPIO - - on_hardware = True -except ImportError: - import pocket_friends.development.FakeGPIO as GPIO - # Run as if not on hardware - on_hardware = False - - -def game(): - """ - Starts the game. - """ - pygame.init() - - # Hide the cursor for the Pi display. - pygame.mouse.set_visible(False) - - # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the - # screen_size to reflect what the resolution of the new display is. - screen_size = 320 - - window = pygame.display.set_mode((screen_size, screen_size)) - surface = pygame.Surface((game_res, game_res)) - - # Only really useful for PCs. Does nothing on the Raspberry Pi. - pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) - - # Add an icon to the pygame window. - icon = pygame.image.load(script_dir + '/resources/images/icon/icon.png').convert_alpha() - pygame.display.set_icon(icon) - - clock = pygame.time.Clock() - - # Font used for small text in the game. Bigger text is usually image files. - small_font = pygame.font.Font(script_dir + '/resources/fonts/5Pts5.ttf', 10) - - # Default game state when the game first starts. - game_state = 'title' - running = True - data_handler = DataHandler() - - # A group of all the sprites on screen. Used to update all sprites at onc - all_sprites = pygame.sprite.Group() - - # Start the GPIO handler to take in buttons from the RPi HAT. - GPIOHandler.setup() - - # Dev code used to exit the game. Default Down, Down, Up, Up, Down, Down, Up, Up, A, A, B - dev_code = deque() - for button in [Constants.buttons.get('j_d'), Constants.buttons.get('j_d'), Constants.buttons.get('j_u'), - Constants.buttons.get('j_u'), Constants.buttons.get('j_d'), Constants.buttons.get('j_d'), - Constants.buttons.get('j_u'), Constants.buttons.get('j_u'), Constants.buttons.get('a'), - Constants.buttons.get('a'), Constants.buttons.get('b')]: - dev_code.append(button) - - # Log of the inputs. - input_log = deque() - - # Time since last input. Used to help regulate double presses of buttons. - last_input_tick = 0 - - def draw(): - """ - Draws the main pygame display. - """ - - # Draws all the sprites on screen and scales the screen to the correct size from the rendered size. - all_sprites.update() - all_sprites.draw(surface) - frame = pygame.transform.scale(surface, (screen_size, screen_size)) - window.blit(frame, frame.get_rect()) - - # Update the entire display. - pygame.display.flip() - - def draw_bg(): - """ - Draws the main game background image onto a given surface. - """ - bg_image = pygame.image.load(script_dir + '/resources/images/bg.png').convert() - surface.blit(bg_image, (0, 0)) - - def log_button(pressed_button): - """ - Logs the button presses to register the dev code. - :param pressed_button: The button code to be logged - """ - input_log.append(pressed_button) - if len(input_log) > len(dev_code): - input_log.popleft() - - def create_event(pressed_button): - """ - Creates a pygame event with a given keyboard code - :param pressed_button: - """ - nonlocal last_input_tick - # Register a button click so long as the last button click happened no less than two frames ago - if pygame.time.get_ticks() - last_input_tick > clock.get_time() * 2 or not on_hardware: - pygame.event.post(pygame.event.Event(KEYDOWN, {'key': pressed_button})) - pygame.event.post(pygame.event.Event(KEYUP, {'key': pressed_button})) - log_button(pressed_button) - last_input_tick = pygame.time.get_ticks() - - def check_dev_code(): - """ - Checks if the dev code has been entered. If it has, stop the program. - """ - nonlocal running - - if dev_code == input_log: - running = False - - def handle_gpio(): - """ - Handles getting GPIO button presses and making a pygame event when a press is detected. - """ - for pressed_button in Constants.buttons: - code = Constants.buttons.get(pressed_button) - - # Check if a button has been pressed. If it has, create a pygame event for it. - if GPIOHandler.get_press(code): - create_event(code) - - def keyboard_handler(): - """ - Simulates key presses to GPIO button presses. Also handles quitting the game. - """ - nonlocal running - - # Checks if a corresponding keyboard key has been pressed. If it has, emulate a button press. - for keyboard_event in pygame.event.get(): - if keyboard_event.type == pygame.QUIT: - running = False - if keyboard_event.type == pygame.KEYDOWN: - if keyboard_event.key == pygame.K_a: - create_event(Constants.buttons.get('a')) - if keyboard_event.key == pygame.K_b: - create_event(Constants.buttons.get('b')) - if keyboard_event.key == pygame.K_PERIOD: - create_event(Constants.buttons.get('j_i')) - if keyboard_event.key == pygame.K_RIGHT: - create_event(Constants.buttons.get('j_r')) - if keyboard_event.key == pygame.K_LEFT: - create_event(Constants.buttons.get('j_l')) - if keyboard_event.key == pygame.K_DOWN: - create_event(Constants.buttons.get('j_d')) - if keyboard_event.key == pygame.K_UP: - create_event(Constants.buttons.get('j_u')) - if keyboard_event.key == pygame.K_ESCAPE: - running = False - - def pre_handler(): - """ - Runs at the beginning of each loop, handles drawing the background, controlling game speed, and - controlling the GPIO button inputs and keyboard handler - """ - # Regulate the speed of the game. - clock.tick(game_fps) - - # Handle all inputs for both debugging and real GPIO button presses. - keyboard_handler() - handle_gpio() - check_dev_code() - - # Draw the background. - draw_bg() - - while running: - if game_state == 'title': - all_sprites.empty() - pre_handler() - - # Draw the title image in the middle of the screen. - title_image = pygame.image.load(script_dir + '/resources/images/title.png').convert_alpha() - surface.blit(title_image, (0, 0)) - draw() - - # Show the title for 1 second then move on to the initialization phase of the game. - pygame.time.wait(1000) - game_state = 'init' - - elif game_state == 'playground': - - # Submenu used within the playground. - submenu = 'main' - - while running and game_state == 'playground': - - all_sprites.empty() - - if submenu == 'main': - - # Create the bloop and the menu - bloop = PlaygroundFriend(data_handler) - all_sprites.add(bloop) - popup_menu = PopupMenu((3, 3)) - - while running and game_state == 'playground' and submenu == 'main': - pre_handler() - data_handler.update() - - for event in pygame.event.get(): - if event.type == pygame.KEYDOWN: - if event.key == Constants.buttons.get('j_r'): - # Move selection to the next item - popup_menu.next() - if event.key == Constants.buttons.get('j_l'): - # Move selection to the previous item - popup_menu.prev() - if event.key == Constants.buttons.get('a'): - # Change submenu to the menu the icon points to - if popup_menu.draw_menu: - submenu = popup_menu.icons[popup_menu.selected].icon - else: # Pet the bloop otherwise - bloop.pet() - if event.key == Constants.buttons.get('b'): - # Toggle the popup menu on or off - popup_menu.toggle() - - # Draw the popup menu if toggled on - popup_menu.draw(surface) - - draw() - - else: # Go to the error state if an invalid state is set. - game_state = None - - elif game_state == 'init': - all_sprites.empty() - pre_handler() - draw() - - # Read the save file. - data_handler.read_save() - - # Determines if it is a new game or not by looking at the evolution stage. If it is -1, the egg has - # not been created yet, and the game sends you to the egg selection screen. If not, the game sends - # you to the playground. - if data_handler.attributes['bloop'] == '': - game_state = 'egg_select' - else: - game_state = 'playground' - - elif game_state == 'egg_select': - - # Submenu used within the egg selection menu. - submenu = 'main' - - selected = 0 - selected_color = "" - - while running and game_state == 'egg_select': - - all_sprites.empty() - - if submenu == 'main': - - # Creates and holds the egg objects in a list. - eggs = [SelectionEgg('dev_egg'), SelectionEgg('blue'), SelectionEgg('rainbow')] - - # How many eggs per row should be displayed. - eggs_per_row = 3 - distance_between_eggs = 36 / eggs_per_row - - # Count the total rows. - total_rows = -(-len(eggs) // eggs_per_row) - distance_between_rows = 32 / eggs_per_row - - # Determine the location of each egg. - for egg in eggs: - current_row = eggs.index(egg) // eggs_per_row - rows_after = total_rows - (current_row + 1) - egg_in_row = eggs.index(egg) % eggs_per_row - eggs_after = min(len(eggs) - (current_row * eggs_per_row), eggs_per_row) - (egg_in_row + 1) - - x_offset = 32 - y_offset = 30 - - # The x coordinate of an egg is determined by which egg in the row it is, and how many eggs - # are in that row. If there is only 1 egg in a row, it is in the middle of the screen. If - # there are two, they're on equal halves and so on. - x = x_offset - (eggs_after * distance_between_eggs) + (egg_in_row * distance_between_eggs) - y = y_offset - (rows_after * distance_between_rows) + (current_row * distance_between_rows) - - egg.rect.x = x - egg.rect.y = y - - # Add the egg to the sprite list. - all_sprites.add(egg) - - def get_cursor_coords(selection): - """ - Gets the coordinates of an egg on the selection screen by index and returns it as a tuple - :param selection: index of the egg to be selected - :return: tuple of the coordinates of the selected egg - """ - cursor_x_offset = -2 - cursor_y_offset = -2 - - return eggs[selection].rect.x + cursor_x_offset, eggs[selection].rect.y + cursor_y_offset - - def sel_left(): - """ - Select the egg to the left with constraints. - """ - nonlocal selected - - if selected % eggs_per_row != 0: - selected -= 1 - - def sel_right(): - """ - Select the egg to the right with constraints. - """ - nonlocal selected - - row = selected // eggs_per_row - eggs_in_row = min(len(eggs) - (row * eggs_per_row), eggs_per_row) - - if selected % eggs_per_row != eggs_in_row - 1: - selected += 1 - - def sel_up(): - """ - Select the egg above with constraints. - """ - nonlocal selected - - if selected // eggs_per_row != 0: - selected -= eggs_per_row - - def sel_down(): - """ - Select the egg below with constraints. - """ - nonlocal selected - - if selected // eggs_per_row != total_rows - 1: - selected += eggs_per_row - - while running and game_state == 'egg_select' and submenu == 'main': - - pre_handler() - - for event in pygame.event.get(): - if event.type == pygame.KEYDOWN: - if event.key == Constants.buttons.get('j_r'): - sel_right() - if event.key == Constants.buttons.get('j_l'): - sel_left() - if event.key == Constants.buttons.get('j_d'): - sel_down() - if event.key == Constants.buttons.get('j_u'): - sel_up() - if event.key == Constants.buttons.get('a'): - # Advance to the egg info screen for the selected egg. - submenu = 'bloop_info' - - # Draws the cursor on screen. - cursor = pygame.image.load( - script_dir + '/resources/images/gui/egg_selector.png').convert_alpha() - surface.blit(cursor, get_cursor_coords(selected)) - - selected_color = eggs[selected].egg_color - - draw() - - elif submenu == 'bloop_info': - - # Draw the selected egg on screen - egg = SelectionEgg(selected_color) - egg.rect.x = 8 - egg.rect.y = 3 - all_sprites.add(egg) - - # Info screen for the eggs. - info_text = InfoText(small_font, egg.description) - info_icons = EggInfo(egg.contentedness, egg.metabolism, (32, 4)) - - while running and game_state == 'egg_select' and submenu == 'bloop_info': - - pre_handler() - - for event in pygame.event.get(): - if event.type == pygame.KEYDOWN: - if event.key == Constants.buttons.get('j_d'): - # Scroll down on the info screen. - info_text.scroll_down() - if event.key == Constants.buttons.get('j_u'): - # Scroll up on the info screen. - info_text.scroll_up() - if event.key == Constants.buttons.get('a'): - # Write save file with new attributes - data_handler.attributes['bloop'] = egg.egg_color - data_handler.attributes['health'] = 10 - data_handler.attributes['hunger'] = 10 - data_handler.attributes['happiness'] = 10 - data_handler.attributes['evolution_stage'] = 'egg' - data_handler.write_save() - - # Go to playground - game_state = 'playground' - if event.key == Constants.buttons.get('b'): - # Go back to the egg selection screen. - submenu = 'main' - - # Draw the info screen. - info_text.draw(surface) - info_icons.draw(surface) - - draw() - - else: # Go to the error state if an invalid state is set. - game_state = None - - else: - # Error screen. This appears when an invalid game state has been selected. - - all_sprites.empty() - frames_passed = 0 # Counter for frames, helps ensure the game isn't frozen. - - while running and game_state != 'title': - - pre_handler() - - # Draw the error screen - error_screen = pygame.image.load(script_dir + '/resources/images/debug/invalid.png').convert_alpha() - surface.blit(error_screen, (0, -8)) - - # Counts the frames passed. Resets every second. - frames_passed += 1 - if frames_passed >= game_fps: - frames_passed = 0 - - # Draws the frame counter. - frame_counter = small_font.render('frames: {0}'.format(frames_passed), False, (64, 64, 64)) - surface.blit(frame_counter, (1, game_res - 10)) - - for event in pygame.event.get(): - if event.type == pygame.KEYDOWN: - if event.key == Constants.buttons.get('b'): - # Reset back to the title screen. - game_state = 'title' - - draw() - - -def main(): - """ - Calls the game() function to start the game. - """ - game() - - GPIOHandler.teardown() - pygame.quit() From 7073bbb73ccd2df672e0e23107213e30d2958d9b Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 11:24:42 -0400 Subject: [PATCH 05/58] disabled dev menu launch arg --- pocket_friends/__main__.py | 19 +- .../game_files/old_main_gamefile.py | 984 ++++++++++++++++++ 2 files changed, 995 insertions(+), 8 deletions(-) create mode 100644 pocket_friends/game_files/old_main_gamefile.py diff --git a/pocket_friends/__main__.py b/pocket_friends/__main__.py index 8bc143a..c7ec3f8 100644 --- a/pocket_friends/__main__.py +++ b/pocket_friends/__main__.py @@ -2,11 +2,11 @@ Launch script for Pocket Friends. """ import os -from pathlib import Path import pygame import sys +from pathlib import Path from pocket_friends.game_files.game import main as game_main -from pocket_friends.development.dev_menu import main as dev_menu_main +#from pocket_friends.development.dev_menu import main as dev_menu_main if __name__ == '__main__': enable_dev = False @@ -14,16 +14,19 @@ if __name__ == '__main__': # enable dev mode if --dev argument is passed if len(sys.argv) > 0: for args in sys.argv: - if args == '--dev': - enable_dev = True + #if args == '--dev': [reimplement later] + # enable_dev = True if args == '--delete-save': save_dir = os.path.join(Path.home(), '.pocket_friends') os.remove(save_dir + '/save.json') - if not enable_dev: - game_main() - else: - dev_menu_main() + # Dev menu disabled for now, will reimplement later + #if not enable_dev: + # game_main() + #else: + # dev_menu_main() + + game_main() pygame.quit() sys.exit() diff --git a/pocket_friends/game_files/old_main_gamefile.py b/pocket_friends/game_files/old_main_gamefile.py new file mode 100644 index 0000000..cd6e8b5 --- /dev/null +++ b/pocket_friends/game_files/old_main_gamefile.py @@ -0,0 +1,984 @@ +""" +Main file for the entire game. Controls everything except for GPIO input. +""" +from collections import deque +import importlib.util +import json +import os +from pathlib import Path +import pocket_friends +import pygame +from pygame.locals import * +from ..hardware.gpio_handler import Constants, GPIOHandler + +# FPS for the entire game to run at. +game_fps = 16 +# The resolution the game is rendered at. +game_res = 80 + +# Gets the directory of the script for importing and the save directory +script_dir = os.path.dirname(os.path.abspath(__file__)) +save_dir = os.path.join(Path.home(), '.pocket_friends') + +# Tries to make the save directory. Does nothing if it already exists. +try: + os.mkdir(save_dir) +except FileExistsError: + pass + + +class SpriteSheet: + """ + Imports a sprite sheet as separate pygame images given an image file and a json file. + """ + + def __init__(self, sprite_sheet, texture_json): + # Load in whole sprite sheet as one image. + self.sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha() + self.images = [] + + # Get the sprite sheet json file. + with open(texture_json, 'r') as json_file: + self.img_attrib = json.load(json_file) + json_file.close() + + # Count for how many images have been added in the image list + image_count = 0 + + # Get the sprite size as a tuple + sprite_size = self.img_attrib['width'], self.img_attrib['height'] + + # Iterate through every image location on the sprite sheet given the sprite size + for i in range(self.sprite_sheet.get_size()[1] // sprite_size[1]): + i *= sprite_size[1] + for j in range(self.sprite_sheet.get_size()[0] // sprite_size[0]): + j *= sprite_size[0] + + # Create a new transparent surface + sprite = pygame.Surface(sprite_size, SRCALPHA) + # Blit the sprite onto the image + sprite.blit(self.sprite_sheet, (0, 0), (j, i, sprite_size[0], sprite_size[1])) + # Add the image to the list of images + self.images.append(sprite) + + image_count += 1 + + # Break the loop if the specified number of frames has been reached. + if image_count >= self.img_attrib['frames']: + break + if image_count >= self.img_attrib['frames']: + break + + +class DataHandler: + """ + Class that handles the hardware attributes and save files. + """ + + def __init__(self): + # Attributes that are saved to a file to recover upon startup. + self.attributes = { + 'version': pocket_friends.__version__, + 'time_elapsed': 0, + 'bloop': '', + 'age': 0, + 'health': 0, + 'hunger': 0, + 'happiness': 0, + 'care_counter': 0, + 'missed_care': 0, + 'adult': 0, + 'evolution_stage': '', + } + + # Frame counter + self.frames_passed = 0 + + def write_save(self): + """ + Writes attributes of class to "save.json" file. + """ + with open(save_dir + '/save.json', 'w') as save_file: + json.dump(self.attributes, save_file) + save_file.close() + + def read_save(self): + """ + Reads from "save.json" and inserts into attributes dictionary. Creates file if it does not exist. + """ + # Open up the save file and read it into self.attributes. + try: + with open(save_dir + '/save.json', 'r') as save_file: + self.attributes = json.load(save_file) + save_file.close() + + # If there is no save file, write one with the defaults. + except FileNotFoundError: + self.write_save() + + def update(self): + """ + Run the game logic. + """ + self.frames_passed += 1 + # Run logic of the game every second. + if self.frames_passed >= game_fps: + + # Add one to the age of the bloop. + self.attributes['age'] += 1 + + # Save the data when the age of the bloop is a multiple of 10. + if self.attributes['age'] % 10 == 0: + self.write_save() + + # Reset frame counter + self.frames_passed = 0 + + +class PlaygroundFriend(pygame.sprite.Sprite): + """ + Class for the sprite of the creature on the main playground. + """ + + def __init__(self, data_handler): + pygame.sprite.Sprite.__init__(self) + + # All attributes of the bloops + self.bloop = data_handler.attributes['bloop'] + self.adult = data_handler.attributes['adult'] + self.evolution_stage = data_handler.attributes['evolution_stage'] + self.direction = 0 + + if self.evolution_stage == 'adult': + image = self.evolution_stage + self.adult + else: + image = self.evolution_stage + + # Draw the correct bloop depending on the stage + sprite_sheet = SpriteSheet(script_dir + '/resources/images/bloops/{0}/{1}.png'.format(self.bloop, image), + script_dir + '/resources/images/bloops/{0}/{1}.json'.format(self.bloop, image)) + + # Load the images from the sprite sheet + self.images = sprite_sheet.images + + # Put the egg in the middle of the screen. + self.rect = self.images[0].get_rect() + self.rect.x = (game_res / 2) - (self.rect.width / 2) + self.rect.y = (game_res / 2) - (self.rect.height / 2) + + # Start animation at the beginning of the sprite sheet. + self.index = 0 + self.image = self.images[self.index] + + self.movement_frames = game_fps / 2 # How many frames pass before the bloop moves + self.current_frame = 0 + + def pet(self): + """ + Pet the bloop! + """ + pass + + def update(self): + """ + Takes the images loaded and animates it, spacing it out equally for the framerate. + """ + + margins = 9 # Margins for how far the bloop can move from the left and the right of the screen + movement_amount = 2 # Pixels that the bloop moves in one movement + + self.current_frame += 1 + + # Check to see if the number of movement frames has passed + if self.current_frame >= self.movement_frames: + self.current_frame = 0 + + # Move only if the bloop is not in the egg stage + if self.evolution_stage != 'egg': + + # Change direction if the bloop has reached either edge of the screen + if self.rect.x < margins: + self.direction = 1 + elif self.rect.x > game_res - margins - self.rect.width: + self.direction = 0 + + # Move according to the direction. + if self.direction == 0: + self.rect.x -= movement_amount + else: + self.rect.x += movement_amount + + # Animate the bloop + self.index = (self.index + 1) % len(self.images) + self.image = self.images[self.index] + + +class SelectionEgg(pygame.sprite.Sprite): + """ + Class for the eggs on the egg selection screen. + """ + + def __init__(self, egg_color): + pygame.sprite.Sprite.__init__(self) + + self.egg_color = egg_color + + # Loads the JSON file of the egg to read in data. + with open(script_dir + '/resources/data/bloop_info/{0}.json'.format(egg_color), 'r') as save_file: + json_file = json.load(save_file) + save_file.close() + + # Gets the description off the egg from the JSON file. + self.description = json_file.get('description') + self.contentedness = json_file.get('contentedness') + self.metabolism = json_file.get('metabolism') + + # Load the egg from the given color and get the bounding rectangle for the image. + sprite_sheet = SpriteSheet(script_dir + '/resources/images/bloops/{0}/egg.png'.format(self.egg_color), + script_dir + '/resources/images/bloops/{0}/egg.json'.format(self.egg_color)) + self.images = sprite_sheet.images + + # Get the rectangle from the first image in the list + self.rect = self.images[0].get_rect() + self.index = 0 + self.image = self.images[self.index] + + def update(self): + """ + Updates the sprite object. + """ + # Animate the sprite + self.index = (self.index + 1) % len(self.images) + self.image = self.images[self.index] + + +class EggInfo: + """ + Class to draw the contentedness and metabolism value off the egg on the info screen. + """ + + def __init__(self, contentedness, metabolism, location): + self.contentedness = contentedness + self.metabolism = metabolism + self.x = location[0] + self.y = location[1] + + # Create a new surface to blit onto the other surface + self.surface = pygame.Surface((44, 15), SRCALPHA) + + # Blit the two indicator icons on screen + smiley = pygame.image.load(script_dir + '/resources/images/gui/smiley.png').convert_alpha() + self.surface.blit(smiley, (0, 0)) + apple = pygame.image.load(script_dir + '/resources/images/gui/apple.png').convert_alpha() + self.surface.blit(apple, (1, 9)) + + # Draw 5 stars. If the value of the contentedness is less than the current star, make it a blank star. + for i in range(5): + if i < self.contentedness: + star = pygame.image.load(script_dir + '/resources/images/gui/star.png').convert_alpha() + else: + star = pygame.image.load(script_dir + '/resources/images/gui/blank_star.png').convert_alpha() + self.surface.blit(star, (11 + (i * 6), 1)) + + # Draw 5 stars. If the value of the metabolism is less than the current star, make it a blank star. + for i in range(5): + if i < self.metabolism: + star = pygame.image.load(script_dir + '/resources/images/gui/star.png').convert_alpha() + else: + star = pygame.image.load(script_dir + '/resources/images/gui/blank_star.png').convert_alpha() + self.surface.blit(star, (11 + (i * 6), 10)) + + def draw(self, surface): + """ + Draw the info icons on a given surface. + :param surface: the surface to draw the icons on. + """ + # Blit the info onto the given surface. + surface.blit(self.surface, (self.x, self.y)) + + +class InfoText: + """ + Class for drawing large amounts of text on the screen at a time + """ + + def __init__(self, font, text='Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam commodo tempor ' + 'aliquet. Suspendisse placerat accumsan neque, nec volutpat nunc porta ut.'): + + self.font = font + self.text = [] # Text broken up into a list according to how it will fit on screen. + self.max_lines = 6 # Max number of lines to be shown on screen at a time. + self.offset = 0 + + # Arrow icons to indicate scrolling + self.up_arrow = pygame.image.load(script_dir + '/resources/images/gui/up_arrow.png').convert_alpha() + self.down_arrow = pygame.image.load(script_dir + '/resources/images/gui/down_arrow.png').convert_alpha() + + raw_text = text # Copy the text to a different variable to be cut up. + + margins = 4.5 + max_line_width = game_res - (margins * 2) # The maximum pixel width that drawn text can be. + cut_chars = '.,! ' # Characters that will be considered "cuts" aka when a line break can occur. + + # Prevents freezing if the end of the string does not end in a cut character + # Will fix eventually more elegantly + if raw_text[-1:] not in cut_chars: + raw_text += ' ' + + # Calculating line breaks. + while len(raw_text) > 0: + index = 0 + test_text = '' # Chunk of text to pseudo-render and test the width of. + + # Loops until the testing text has reached the size limit. + while True: + + # Break if the current index is larger than the remaining text. + if index + 1 > len(raw_text): + index -= 1 + break + + # Add one character to the testing text from the raw text. + test_text += raw_text[index] + # Get the width of the pseudo-rendered text. + text_width = font.size(test_text)[0] + + # Break if the text is larger than the defined max width. + if text_width > max_line_width: + break + index += 1 + pass + + # Gets the chunk of text to be added to the list. + text_chunk = raw_text[0:index + 1] + # Determines if the chunk of text has any break characters. + has_breaks = any(cut_chars in text_chunk for cut_chars in cut_chars) + + # If the text has break characters, start with the last character and go backwards until + # one has been found, decreasing the index each time. + if has_breaks: + while raw_text[index] not in cut_chars: + index -= 1 + text_chunk = raw_text[0:index + 1] + # If there are no break characters in the chunk, simply decrease the index by one and insert + # a dash at the end of the line to indicate the word continues. + else: + index -= 1 + text_chunk = raw_text[0:index + 1] + text_chunk += '-' + + # Append the text chunk to the list of text to draw. + self.text.append(text_chunk) + + # Cut the text to repeat the process with the new cut string. + raw_text = raw_text[index + 1:] + + def draw(self, surface): + """ + Draws the text on a given surface. + :param surface: The surface for the text to be drawn on. + """ + # Constants to help draw the text + line_separation = 7 + left_margin = 3 + top_margin = 25 + bottom_margin = 10 + + # Draw the lines on the screen + for i in range(min(len(self.text), self.max_lines)): + text = self.font.render(self.text[i + self.offset], False, (64, 64, 64)) + surface.blit(text, (left_margin, top_margin + (i * line_separation))) + + # Draw the arrows if there is more text than is on screen. + if self.offset != 0: + surface.blit(self.up_arrow, ((game_res / 2) - (self.up_arrow.get_rect().width / 2), top_margin - 3)) + if len(self.text) - (self.offset + 1) >= self.max_lines: + surface.blit(self.down_arrow, + ((game_res / 2) - (self.down_arrow.get_rect().width / 2), game_res - bottom_margin)) + + def scroll_down(self): + """ + Scrolls the text on the screen down. + """ + # Ensures that the offset cannot be too big as to try to render non-existent lines. + if len(self.text) - (self.offset + 1) >= self.max_lines: + self.offset += 1 + + def scroll_up(self): + """ + Scrolls the text on the screen up. + """ + if self.offset > 0: # Ensures a non-zero offset is not possible. + self.offset -= 1 + + +class MenuIcon(pygame.sprite.Sprite): + """ + Sprite for an icon on the main popup menu. + """ + + def __init__(self, icon): + pygame.sprite.Sprite.__init__(self) + self.icon = icon + + # Load the sprite sheet from the icon name + sprite_sheet = SpriteSheet(script_dir + '/resources/images/gui/popup_menu/{0}.png'.format(self.icon), + script_dir + '/resources/images/gui/popup_menu/{0}.json'.format(self.icon)) + self.images = sprite_sheet.images + + # Get the rectangle from the first image in the list + self.rect = self.images[0].get_rect() + self.image = self.images[0] + + def select(self): + """ + Change the icon sprite to the selected icon. + """ + self.image = self.images[1] + + def deselect(self): + """ + Change the icon sprite to the not selected icon. + """ + self.image = self.images[0] + + +class PopupMenu: + """ + Class to create a popup menu that can be hidden and shown at will + """ + + def __init__(self, position): + # Background frame of the popup menu + self.frame = pygame.image.load(script_dir + '/resources/images/gui/popup_menu/frame.png').convert_alpha() + + self.draw_menu = False # Whether or not to draw the popup menu + self.menu_sprites = pygame.sprite.Group() # Sprite group for the icons + self.selected = 0 # The currently selected icon + + # The names of the icons to be drawn + icon_names = ['apple', 'dumbbell', 'stats', 'controller', 'bed'] + + self.icons = [] + # Create an icon sprite for each name in the list and add it to the icon list + for i in icon_names: + self.icons.append(MenuIcon(i)) + + # Add each sprite in the icon list to the sprite group + for i in range(len(self.icons)): + icon = self.icons[i] + if i == self.selected: # Make the default selected icon glow + icon.select() + + # Calculate the position of the icon on screen + icon.rect.x = 10 + (i * 15) - (icon.image.get_width() / 2) + icon.rect.y = position[1] + self.frame.get_height() / 2 - icon.image.get_height() / 2 + + # Add the icon to the sprite group. + self.menu_sprites.add(icon) + + def toggle(self): + """ + Toggles the menu on or off. + """ + self.draw_menu = not self.draw_menu + + def next(self): + """ + Changes the selection to the next icon (to the right.) + """ + if self.draw_menu: # Only change if the menu is on screen + + self.icons[self.selected].deselect() # Deselect the current icon + self.selected += 1 # Change selection to the next icon + if self.selected >= len(self.icons): # Wrap around if new value is invalid + self.selected = 0 + self.icons[self.selected].select() # Select the newly selected icon + + def prev(self): + """ + Changes the selection to the previous icon (to the left.) + """ + if self.draw_menu: # Only change if the menu is on screen + + self.icons[self.selected].deselect() # Deselect the current icon + self.selected -= 1 # Change selection to the previous icon + if self.selected < 0: # Wrap around if new value is invalid + self.selected = len(self.icons) - 1 + self.icons[self.selected].select() # Select the newly selected icon + + def draw(self, surface): + """ + Draw the menu onto a given surface + :param surface: the surface to draw the menu on. + """ + # Draw the menu only if it is toggled on. + if self.draw_menu: + surface.blit(self.frame, (3, 3)) + self.menu_sprites.draw(surface) + + +# Makes Pygame draw on the display of the RPi. +os.environ["SDL_FBDEV"] = "/dev/fb1" + +# Useful for debugging on the PC. Imports a fake RPi.GPIO library if one is not found (which it can't +# be on a PC, RPi.GPIO cannot be installed outside of a Raspberry Pi. +try: + importlib.util.find_spec('RPi.GPIO') + import RPi.GPIO as GPIO + + on_hardware = True +except ImportError: + import pocket_friends.development.FakeGPIO as GPIO + # Run as if not on hardware + on_hardware = False + + +def game(): + """ + Starts the game. + """ + pygame.init() + + # Hide the cursor for the Pi display. + pygame.mouse.set_visible(False) + + # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the + # screen_size to reflect what the resolution of the new display is. + screen_size = 320 + + window = pygame.display.set_mode((screen_size, screen_size)) + surface = pygame.Surface((game_res, game_res)) + + # Only really useful for PCs. Does nothing on the Raspberry Pi. + pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) + + # Add an icon to the pygame window. + icon = pygame.image.load(script_dir + '/resources/images/icon/icon.png').convert_alpha() + pygame.display.set_icon(icon) + + clock = pygame.time.Clock() + + # Font used for small text in the game. Bigger text is usually image files. + small_font = pygame.font.Font(script_dir + '/resources/fonts/5Pts5.ttf', 10) + + # Default game state when the game first starts. + game_state = 'title' + running = True + data_handler = DataHandler() + + # A group of all the sprites on screen. Used to update all sprites at onc + all_sprites = pygame.sprite.Group() + + # Start the GPIO handler to take in buttons from the RPi HAT. + GPIOHandler.setup() + + # Dev code used to exit the game. Default Down, Down, Up, Up, Down, Down, Up, Up, A, A, B + dev_code = deque() + for button in [Constants.buttons.get('j_d'), Constants.buttons.get('j_d'), Constants.buttons.get('j_u'), + Constants.buttons.get('j_u'), Constants.buttons.get('j_d'), Constants.buttons.get('j_d'), + Constants.buttons.get('j_u'), Constants.buttons.get('j_u'), Constants.buttons.get('a'), + Constants.buttons.get('a'), Constants.buttons.get('b')]: + dev_code.append(button) + + # Log of the inputs. + input_log = deque() + + # Time since last input. Used to help regulate double presses of buttons. + last_input_tick = 0 + + def draw(): + """ + Draws the main pygame display. + """ + + # Draws all the sprites on screen and scales the screen to the correct size from the rendered size. + all_sprites.update() + all_sprites.draw(surface) + frame = pygame.transform.scale(surface, (screen_size, screen_size)) + window.blit(frame, frame.get_rect()) + + # Update the entire display. + pygame.display.flip() + + def draw_bg(): + """ + Draws the main game background image onto a given surface. + """ + bg_image = pygame.image.load(script_dir + '/resources/images/bg.png').convert() + surface.blit(bg_image, (0, 0)) + + def log_button(pressed_button): + """ + Logs the button presses to register the dev code. + :param pressed_button: The button code to be logged + """ + input_log.append(pressed_button) + if len(input_log) > len(dev_code): + input_log.popleft() + + def create_event(pressed_button): + """ + Creates a pygame event with a given keyboard code + :param pressed_button: + """ + nonlocal last_input_tick + # Register a button click so long as the last button click happened no less than two frames ago + if pygame.time.get_ticks() - last_input_tick > clock.get_time() * 2 or not on_hardware: + pygame.event.post(pygame.event.Event(KEYDOWN, {'key': pressed_button})) + pygame.event.post(pygame.event.Event(KEYUP, {'key': pressed_button})) + log_button(pressed_button) + last_input_tick = pygame.time.get_ticks() + + def check_dev_code(): + """ + Checks if the dev code has been entered. If it has, stop the program. + """ + nonlocal running + + if dev_code == input_log: + running = False + + def handle_gpio(): + """ + Handles getting GPIO button presses and making a pygame event when a press is detected. + """ + for pressed_button in Constants.buttons: + code = Constants.buttons.get(pressed_button) + + # Check if a button has been pressed. If it has, create a pygame event for it. + if GPIOHandler.get_press(code): + create_event(code) + + def keyboard_handler(): + """ + Simulates key presses to GPIO button presses. Also handles quitting the game. + """ + nonlocal running + + # Checks if a corresponding keyboard key has been pressed. If it has, emulate a button press. + for keyboard_event in pygame.event.get(): + if keyboard_event.type == pygame.QUIT: + running = False + if keyboard_event.type == pygame.KEYDOWN: + if keyboard_event.key == pygame.K_a: + create_event(Constants.buttons.get('a')) + if keyboard_event.key == pygame.K_b: + create_event(Constants.buttons.get('b')) + if keyboard_event.key == pygame.K_PERIOD: + create_event(Constants.buttons.get('j_i')) + if keyboard_event.key == pygame.K_RIGHT: + create_event(Constants.buttons.get('j_r')) + if keyboard_event.key == pygame.K_LEFT: + create_event(Constants.buttons.get('j_l')) + if keyboard_event.key == pygame.K_DOWN: + create_event(Constants.buttons.get('j_d')) + if keyboard_event.key == pygame.K_UP: + create_event(Constants.buttons.get('j_u')) + if keyboard_event.key == pygame.K_ESCAPE: + running = False + + def pre_handler(): + """ + Runs at the beginning of each loop, handles drawing the background, controlling game speed, and + controlling the GPIO button inputs and keyboard handler + """ + # Regulate the speed of the game. + clock.tick(game_fps) + + # Handle all inputs for both debugging and real GPIO button presses. + keyboard_handler() + handle_gpio() + check_dev_code() + + # Draw the background. + draw_bg() + + while running: + if game_state == 'title': + all_sprites.empty() + pre_handler() + + # Draw the title image in the middle of the screen. + title_image = pygame.image.load(script_dir + '/resources/images/title.png').convert_alpha() + surface.blit(title_image, (0, 0)) + draw() + + # Show the title for 1 second then move on to the initialization phase of the game. + pygame.time.wait(1000) + game_state = 'init' + + elif game_state == 'playground': + + # Submenu used within the playground. + submenu = 'main' + + while running and game_state == 'playground': + + all_sprites.empty() + + if submenu == 'main': + + # Create the bloop and the menu + bloop = PlaygroundFriend(data_handler) + all_sprites.add(bloop) + popup_menu = PopupMenu((3, 3)) + + while running and game_state == 'playground' and submenu == 'main': + pre_handler() + data_handler.update() + + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + if event.key == Constants.buttons.get('j_r'): + # Move selection to the next item + popup_menu.next() + if event.key == Constants.buttons.get('j_l'): + # Move selection to the previous item + popup_menu.prev() + if event.key == Constants.buttons.get('a'): + # Change submenu to the menu the icon points to + if popup_menu.draw_menu: + submenu = popup_menu.icons[popup_menu.selected].icon + else: # Pet the bloop otherwise + bloop.pet() + if event.key == Constants.buttons.get('b'): + # Toggle the popup menu on or off + popup_menu.toggle() + + # Draw the popup menu if toggled on + popup_menu.draw(surface) + + draw() + + else: # Go to the error state if an invalid state is set. + game_state = None + + elif game_state == 'init': + all_sprites.empty() + pre_handler() + draw() + + # Read the save file. + data_handler.read_save() + + # Determines if it is a new game or not by looking at the evolution stage. If it is -1, the egg has + # not been created yet, and the game sends you to the egg selection screen. If not, the game sends + # you to the playground. + if data_handler.attributes['bloop'] == '': + game_state = 'egg_select' + else: + game_state = 'playground' + + elif game_state == 'egg_select': + + # Submenu used within the egg selection menu. + submenu = 'main' + + selected = 0 + selected_color = "" + + while running and game_state == 'egg_select': + + all_sprites.empty() + + if submenu == 'main': + + # Creates and holds the egg objects in a list. + eggs = [SelectionEgg('dev_egg'), SelectionEgg('blue'), SelectionEgg('rainbow')] + + # How many eggs per row should be displayed. + eggs_per_row = 3 + distance_between_eggs = 36 / eggs_per_row + + # Count the total rows. + total_rows = -(-len(eggs) // eggs_per_row) + distance_between_rows = 32 / eggs_per_row + + # Determine the location of each egg. + for egg in eggs: + current_row = eggs.index(egg) // eggs_per_row + rows_after = total_rows - (current_row + 1) + egg_in_row = eggs.index(egg) % eggs_per_row + eggs_after = min(len(eggs) - (current_row * eggs_per_row), eggs_per_row) - (egg_in_row + 1) + + x_offset = 32 + y_offset = 30 + + # The x coordinate of an egg is determined by which egg in the row it is, and how many eggs + # are in that row. If there is only 1 egg in a row, it is in the middle of the screen. If + # there are two, they're on equal halves and so on. + x = x_offset - (eggs_after * distance_between_eggs) + (egg_in_row * distance_between_eggs) + y = y_offset - (rows_after * distance_between_rows) + (current_row * distance_between_rows) + + egg.rect.x = x + egg.rect.y = y + + # Add the egg to the sprite list. + all_sprites.add(egg) + + def get_cursor_coords(selection): + """ + Gets the coordinates of an egg on the selection screen by index and returns it as a tuple + :param selection: index of the egg to be selected + :return: tuple of the coordinates of the selected egg + """ + cursor_x_offset = -2 + cursor_y_offset = -2 + + return eggs[selection].rect.x + cursor_x_offset, eggs[selection].rect.y + cursor_y_offset + + def sel_left(): + """ + Select the egg to the left with constraints. + """ + nonlocal selected + + if selected % eggs_per_row != 0: + selected -= 1 + + def sel_right(): + """ + Select the egg to the right with constraints. + """ + nonlocal selected + + row = selected // eggs_per_row + eggs_in_row = min(len(eggs) - (row * eggs_per_row), eggs_per_row) + + if selected % eggs_per_row != eggs_in_row - 1: + selected += 1 + + def sel_up(): + """ + Select the egg above with constraints. + """ + nonlocal selected + + if selected // eggs_per_row != 0: + selected -= eggs_per_row + + def sel_down(): + """ + Select the egg below with constraints. + """ + nonlocal selected + + if selected // eggs_per_row != total_rows - 1: + selected += eggs_per_row + + while running and game_state == 'egg_select' and submenu == 'main': + + pre_handler() + + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + if event.key == Constants.buttons.get('j_r'): + sel_right() + if event.key == Constants.buttons.get('j_l'): + sel_left() + if event.key == Constants.buttons.get('j_d'): + sel_down() + if event.key == Constants.buttons.get('j_u'): + sel_up() + if event.key == Constants.buttons.get('a'): + # Advance to the egg info screen for the selected egg. + submenu = 'bloop_info' + + # Draws the cursor on screen. + cursor = pygame.image.load( + script_dir + '/resources/images/gui/egg_selector.png').convert_alpha() + surface.blit(cursor, get_cursor_coords(selected)) + + selected_color = eggs[selected].egg_color + + draw() + + elif submenu == 'bloop_info': + + # Draw the selected egg on screen + egg = SelectionEgg(selected_color) + egg.rect.x = 8 + egg.rect.y = 3 + all_sprites.add(egg) + + # Info screen for the eggs. + info_text = InfoText(small_font, egg.description) + info_icons = EggInfo(egg.contentedness, egg.metabolism, (32, 4)) + + while running and game_state == 'egg_select' and submenu == 'bloop_info': + + pre_handler() + + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + if event.key == Constants.buttons.get('j_d'): + # Scroll down on the info screen. + info_text.scroll_down() + if event.key == Constants.buttons.get('j_u'): + # Scroll up on the info screen. + info_text.scroll_up() + if event.key == Constants.buttons.get('a'): + # Write save file with new attributes + data_handler.attributes['bloop'] = egg.egg_color + data_handler.attributes['health'] = 10 + data_handler.attributes['hunger'] = 10 + data_handler.attributes['happiness'] = 10 + data_handler.attributes['evolution_stage'] = 'egg' + data_handler.write_save() + + # Go to playground + game_state = 'playground' + if event.key == Constants.buttons.get('b'): + # Go back to the egg selection screen. + submenu = 'main' + + # Draw the info screen. + info_text.draw(surface) + info_icons.draw(surface) + + draw() + + else: # Go to the error state if an invalid state is set. + game_state = None + + else: + # Error screen. This appears when an invalid game state has been selected. + + all_sprites.empty() + frames_passed = 0 # Counter for frames, helps ensure the game isn't frozen. + + while running and game_state != 'title': + + pre_handler() + + # Draw the error screen + error_screen = pygame.image.load(script_dir + '/resources/images/debug/invalid.png').convert_alpha() + surface.blit(error_screen, (0, -8)) + + # Counts the frames passed. Resets every second. + frames_passed += 1 + if frames_passed >= game_fps: + frames_passed = 0 + + # Draws the frame counter. + frame_counter = small_font.render('frames: {0}'.format(frames_passed), False, (64, 64, 64)) + surface.blit(frame_counter, (1, game_res - 10)) + + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + if event.key == Constants.buttons.get('b'): + # Reset back to the title screen. + game_state = 'title' + + draw() + + +def main(): + """ + Calls the game() function to start the game. + """ + game() + + GPIOHandler.teardown() + pygame.quit() From d66d56630d71ab37ac84b05ebe815580bff25fbb Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 11:51:51 -0400 Subject: [PATCH 06/58] added basic running from old game.py --- .../game_files/classes/data_handler.py | 67 +++++++++++++++++++ pocket_friends/game_files/game.py | 57 ++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 pocket_friends/game_files/classes/data_handler.py create mode 100644 pocket_friends/game_files/game.py diff --git a/pocket_friends/game_files/classes/data_handler.py b/pocket_friends/game_files/classes/data_handler.py new file mode 100644 index 0000000..64e0bb1 --- /dev/null +++ b/pocket_friends/game_files/classes/data_handler.py @@ -0,0 +1,67 @@ +import pocket_friends +import json + +class DataHandler: + """ + Class that handles the hardware attributes and save files. + """ + + def __init__(self): + # Attributes that are saved to a file to recover upon startup. + self.attributes = { + 'version': pocket_friends.__version__, + 'time_elapsed': 0, + 'bloop': '', + 'age': 0, + 'health': 0, + 'hunger': 0, + 'happiness': 0, + 'care_counter': 0, + 'missed_care': 0, + 'adult': 0, + 'evolution_stage': '', + } + + # Frame counter + self.frames_passed = 0 + + def write_save(self): + """ + Writes attributes of class to "save.json" file. + """ + with open(save_dir + '/save.json', 'w') as save_file: + json.dump(self.attributes, save_file) + save_file.close() + + def read_save(self): + """ + Reads from "save.json" and inserts into attributes dictionary. Creates file if it does not exist. + """ + # Open up the save file and read it into self.attributes. + try: + with open(save_dir + '/save.json', 'r') as save_file: + self.attributes = json.load(save_file) + save_file.close() + + # If there is no save file, write one with the defaults. + except FileNotFoundError: + self.write_save() + + def update(self): + """ + Run the game logic. + """ + self.frames_passed += 1 + # Run logic of the game every second. + if self.frames_passed >= game_fps: + + # Add one to the age of the bloop. + self.attributes['age'] += 1 + + # Save the data when the age of the bloop is a multiple of 10. + if self.attributes['age'] % 10 == 0: + self.write_save() + + # Reset frame counter + self.frames_passed = 0 + diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py new file mode 100644 index 0000000..4f6f6a1 --- /dev/null +++ b/pocket_friends/game_files/game.py @@ -0,0 +1,57 @@ +import pygame +import os +from pathlib import Path +import pocket_friends + +# FPS for the entire game to run at. +game_fps = 16 +# The resolution the game is rendered at. +game_res = 80 +script_dir = os.path.dirname(os.path.abspath(__file__)) +save_dir = os.path.join(Path.home(), '.pocket_friends') +# Gets the directory of the script for importing and the save directory + + +def game(): + """ + Starts the game. + """ + pygame.init() + + # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the + # screen_size to reflect what the resolution of the new display is. + screen_size = 320 + + pygame.mouse.set_visible(False) + pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) + + window = pygame.display.set_mode((screen_size, screen_size)) + surface = pygame.Surface((game_res, game_res)) + + # Add an icon to the pygame window. + icon = pygame.image.load(script_dir + '/resources/images/icon/icon.png').convert_alpha() + pygame.display.set_icon(icon) + + clock = pygame.time.Clock() + + # Font used for small text in the game. Bigger text is usually image files. + small_font = pygame.font.Font(script_dir + '/resources/fonts/5Pts5.ttf', 10) + + # Default game state when the game first starts. + game_state = 'title' + running = True + + # A group of all the sprites on screen. Used to update all sprites at onc + all_sprites = pygame.sprite.Group() + + # Time since last input. Used to help regulate double presses of buttons. + last_input_tick = 0 + + +def main(): + """ + Calls the game() function to start the game. + """ + game() + + pygame.quit() From 6f6eaa3c6d81730a0d550a32f7b7edfb11966daa Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 12:19:39 -0400 Subject: [PATCH 07/58] moved resources into surfaces folder, moved icons to games_files --- .../game_files/{resources/images => }/icon/icon.ico | Bin .../game_files/{resources/images => }/icon/icon.png | Bin .../resources/data/bloop_info/blue.json | 0 .../resources/data/bloop_info/dev_egg.json | 0 .../resources/data/bloop_info/rainbow.json | 0 .../resources/data/bloop_info/red.json | 0 .../{ => surfaces}/resources/fonts/5Pts5.ttf | Bin .../{ => surfaces}/resources/images/bg.png | Bin .../images/bloops/_postponed/green/green.png | Bin .../images/bloops/_postponed/indigo/indigo.png | Bin .../images/bloops/_postponed/orange/orange.png | Bin .../images/bloops/_postponed/violet/violet.png | Bin .../images/bloops/_postponed/white/white.png | Bin .../images/bloops/_postponed/yellow/yellow.png | Bin .../resources/images/bloops/blue/egg.json | 0 .../resources/images/bloops/blue/egg.png | Bin .../resources/images/bloops/dev_egg/baby.json | 0 .../resources/images/bloops/dev_egg/baby.png | Bin .../resources/images/bloops/dev_egg/egg.json | 0 .../resources/images/bloops/dev_egg/egg.png | Bin .../resources/images/bloops/rainbow/egg.json | 0 .../resources/images/bloops/rainbow/egg.png | Bin .../resources/images/bloops/red/egg.json | 0 .../resources/images/bloops/red/egg.png | Bin .../resources/images/debug/invalid.png | Bin .../{ => surfaces}/resources/images/gui/apple.png | Bin .../resources/images/gui/bar_graphic.png | Bin .../resources/images/gui/bar_outline.png | Bin .../resources/images/gui/blank_star.png | Bin .../resources/images/gui/down_arrow.png | Bin .../resources/images/gui/egg_selector.png | Bin .../resources/images/gui/popup_menu/apple.json | 0 .../resources/images/gui/popup_menu/apple.png | Bin .../resources/images/gui/popup_menu/bed.json | 0 .../resources/images/gui/popup_menu/bed.png | Bin .../resources/images/gui/popup_menu/controller.json | 0 .../resources/images/gui/popup_menu/controller.png | Bin .../resources/images/gui/popup_menu/dumbbell.json | 0 .../resources/images/gui/popup_menu/dumbbell.png | Bin .../resources/images/gui/popup_menu/frame.png | Bin .../resources/images/gui/popup_menu/stats.json | 0 .../resources/images/gui/popup_menu/stats.png | Bin .../{ => surfaces}/resources/images/gui/smiley.png | Bin .../{ => surfaces}/resources/images/gui/star.png | Bin .../resources/images/gui/up_arrow.png | Bin .../{ => surfaces}/resources/images/promotional.png | Bin .../{ => surfaces}/resources/images/title.png | Bin 47 files changed, 0 insertions(+), 0 deletions(-) rename pocket_friends/game_files/{resources/images => }/icon/icon.ico (100%) rename pocket_friends/game_files/{resources/images => }/icon/icon.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/data/bloop_info/blue.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/data/bloop_info/dev_egg.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/data/bloop_info/rainbow.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/data/bloop_info/red.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/fonts/5Pts5.ttf (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bg.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/_postponed/green/green.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/_postponed/indigo/indigo.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/_postponed/orange/orange.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/_postponed/violet/violet.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/_postponed/white/white.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/_postponed/yellow/yellow.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/blue/egg.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/blue/egg.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/dev_egg/baby.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/dev_egg/baby.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/dev_egg/egg.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/dev_egg/egg.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/rainbow/egg.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/rainbow/egg.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/red/egg.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/bloops/red/egg.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/debug/invalid.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/apple.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/bar_graphic.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/bar_outline.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/blank_star.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/down_arrow.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/egg_selector.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/apple.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/apple.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/bed.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/bed.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/controller.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/controller.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/dumbbell.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/dumbbell.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/frame.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/stats.json (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/popup_menu/stats.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/smiley.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/star.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/gui/up_arrow.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/promotional.png (100%) rename pocket_friends/game_files/{ => surfaces}/resources/images/title.png (100%) diff --git a/pocket_friends/game_files/resources/images/icon/icon.ico b/pocket_friends/game_files/icon/icon.ico similarity index 100% rename from pocket_friends/game_files/resources/images/icon/icon.ico rename to pocket_friends/game_files/icon/icon.ico diff --git a/pocket_friends/game_files/resources/images/icon/icon.png b/pocket_friends/game_files/icon/icon.png similarity index 100% rename from pocket_friends/game_files/resources/images/icon/icon.png rename to pocket_friends/game_files/icon/icon.png diff --git a/pocket_friends/game_files/resources/data/bloop_info/blue.json b/pocket_friends/game_files/surfaces/resources/data/bloop_info/blue.json similarity index 100% rename from pocket_friends/game_files/resources/data/bloop_info/blue.json rename to pocket_friends/game_files/surfaces/resources/data/bloop_info/blue.json diff --git a/pocket_friends/game_files/resources/data/bloop_info/dev_egg.json b/pocket_friends/game_files/surfaces/resources/data/bloop_info/dev_egg.json similarity index 100% rename from pocket_friends/game_files/resources/data/bloop_info/dev_egg.json rename to pocket_friends/game_files/surfaces/resources/data/bloop_info/dev_egg.json diff --git a/pocket_friends/game_files/resources/data/bloop_info/rainbow.json b/pocket_friends/game_files/surfaces/resources/data/bloop_info/rainbow.json similarity index 100% rename from pocket_friends/game_files/resources/data/bloop_info/rainbow.json rename to pocket_friends/game_files/surfaces/resources/data/bloop_info/rainbow.json diff --git a/pocket_friends/game_files/resources/data/bloop_info/red.json b/pocket_friends/game_files/surfaces/resources/data/bloop_info/red.json similarity index 100% rename from pocket_friends/game_files/resources/data/bloop_info/red.json rename to pocket_friends/game_files/surfaces/resources/data/bloop_info/red.json diff --git a/pocket_friends/game_files/resources/fonts/5Pts5.ttf b/pocket_friends/game_files/surfaces/resources/fonts/5Pts5.ttf similarity index 100% rename from pocket_friends/game_files/resources/fonts/5Pts5.ttf rename to pocket_friends/game_files/surfaces/resources/fonts/5Pts5.ttf diff --git a/pocket_friends/game_files/resources/images/bg.png b/pocket_friends/game_files/surfaces/resources/images/bg.png similarity index 100% rename from pocket_friends/game_files/resources/images/bg.png rename to pocket_friends/game_files/surfaces/resources/images/bg.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/green/green.png b/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/green/green.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/green/green.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/green/green.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/indigo/indigo.png b/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/indigo/indigo.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/indigo/indigo.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/indigo/indigo.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/orange/orange.png b/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/orange/orange.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/orange/orange.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/orange/orange.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/violet/violet.png b/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/violet/violet.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/violet/violet.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/violet/violet.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/white/white.png b/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/white/white.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/white/white.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/white/white.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/yellow/yellow.png b/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/yellow/yellow.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/yellow/yellow.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/yellow/yellow.png diff --git a/pocket_friends/game_files/resources/images/bloops/blue/egg.json b/pocket_friends/game_files/surfaces/resources/images/bloops/blue/egg.json similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/blue/egg.json rename to pocket_friends/game_files/surfaces/resources/images/bloops/blue/egg.json diff --git a/pocket_friends/game_files/resources/images/bloops/blue/egg.png b/pocket_friends/game_files/surfaces/resources/images/bloops/blue/egg.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/blue/egg.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/blue/egg.png diff --git a/pocket_friends/game_files/resources/images/bloops/dev_egg/baby.json b/pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/baby.json similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/dev_egg/baby.json rename to pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/baby.json diff --git a/pocket_friends/game_files/resources/images/bloops/dev_egg/baby.png b/pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/baby.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/dev_egg/baby.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/baby.png diff --git a/pocket_friends/game_files/resources/images/bloops/dev_egg/egg.json b/pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/egg.json similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/dev_egg/egg.json rename to pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/egg.json diff --git a/pocket_friends/game_files/resources/images/bloops/dev_egg/egg.png b/pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/egg.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/dev_egg/egg.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/egg.png diff --git a/pocket_friends/game_files/resources/images/bloops/rainbow/egg.json b/pocket_friends/game_files/surfaces/resources/images/bloops/rainbow/egg.json similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/rainbow/egg.json rename to pocket_friends/game_files/surfaces/resources/images/bloops/rainbow/egg.json diff --git a/pocket_friends/game_files/resources/images/bloops/rainbow/egg.png b/pocket_friends/game_files/surfaces/resources/images/bloops/rainbow/egg.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/rainbow/egg.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/rainbow/egg.png diff --git a/pocket_friends/game_files/resources/images/bloops/red/egg.json b/pocket_friends/game_files/surfaces/resources/images/bloops/red/egg.json similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/red/egg.json rename to pocket_friends/game_files/surfaces/resources/images/bloops/red/egg.json diff --git a/pocket_friends/game_files/resources/images/bloops/red/egg.png b/pocket_friends/game_files/surfaces/resources/images/bloops/red/egg.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/red/egg.png rename to pocket_friends/game_files/surfaces/resources/images/bloops/red/egg.png diff --git a/pocket_friends/game_files/resources/images/debug/invalid.png b/pocket_friends/game_files/surfaces/resources/images/debug/invalid.png similarity index 100% rename from pocket_friends/game_files/resources/images/debug/invalid.png rename to pocket_friends/game_files/surfaces/resources/images/debug/invalid.png diff --git a/pocket_friends/game_files/resources/images/gui/apple.png b/pocket_friends/game_files/surfaces/resources/images/gui/apple.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/apple.png rename to pocket_friends/game_files/surfaces/resources/images/gui/apple.png diff --git a/pocket_friends/game_files/resources/images/gui/bar_graphic.png b/pocket_friends/game_files/surfaces/resources/images/gui/bar_graphic.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/bar_graphic.png rename to pocket_friends/game_files/surfaces/resources/images/gui/bar_graphic.png diff --git a/pocket_friends/game_files/resources/images/gui/bar_outline.png b/pocket_friends/game_files/surfaces/resources/images/gui/bar_outline.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/bar_outline.png rename to pocket_friends/game_files/surfaces/resources/images/gui/bar_outline.png diff --git a/pocket_friends/game_files/resources/images/gui/blank_star.png b/pocket_friends/game_files/surfaces/resources/images/gui/blank_star.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/blank_star.png rename to pocket_friends/game_files/surfaces/resources/images/gui/blank_star.png diff --git a/pocket_friends/game_files/resources/images/gui/down_arrow.png b/pocket_friends/game_files/surfaces/resources/images/gui/down_arrow.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/down_arrow.png rename to pocket_friends/game_files/surfaces/resources/images/gui/down_arrow.png diff --git a/pocket_friends/game_files/resources/images/gui/egg_selector.png b/pocket_friends/game_files/surfaces/resources/images/gui/egg_selector.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/egg_selector.png rename to pocket_friends/game_files/surfaces/resources/images/gui/egg_selector.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/apple.json b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/apple.json similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/apple.json rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/apple.json diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/apple.png b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/apple.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/apple.png rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/apple.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/bed.json b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/bed.json similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/bed.json rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/bed.json diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/bed.png b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/bed.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/bed.png rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/bed.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/controller.json b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/controller.json similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/controller.json rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/controller.json diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/controller.png b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/controller.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/controller.png rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/controller.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.json b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/dumbbell.json similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.json rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/dumbbell.json diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.png b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/dumbbell.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.png rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/dumbbell.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/frame.png b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/frame.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/frame.png rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/frame.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/stats.json b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/stats.json similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/stats.json rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/stats.json diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/stats.png b/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/stats.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/stats.png rename to pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/stats.png diff --git a/pocket_friends/game_files/resources/images/gui/smiley.png b/pocket_friends/game_files/surfaces/resources/images/gui/smiley.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/smiley.png rename to pocket_friends/game_files/surfaces/resources/images/gui/smiley.png diff --git a/pocket_friends/game_files/resources/images/gui/star.png b/pocket_friends/game_files/surfaces/resources/images/gui/star.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/star.png rename to pocket_friends/game_files/surfaces/resources/images/gui/star.png diff --git a/pocket_friends/game_files/resources/images/gui/up_arrow.png b/pocket_friends/game_files/surfaces/resources/images/gui/up_arrow.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/up_arrow.png rename to pocket_friends/game_files/surfaces/resources/images/gui/up_arrow.png diff --git a/pocket_friends/game_files/resources/images/promotional.png b/pocket_friends/game_files/surfaces/resources/images/promotional.png similarity index 100% rename from pocket_friends/game_files/resources/images/promotional.png rename to pocket_friends/game_files/surfaces/resources/images/promotional.png diff --git a/pocket_friends/game_files/resources/images/title.png b/pocket_friends/game_files/surfaces/resources/images/title.png similarity index 100% rename from pocket_friends/game_files/resources/images/title.png rename to pocket_friends/game_files/surfaces/resources/images/title.png From 2ffd9bd929dddea46ab644da7ce0dddab5b5bb08 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 12:20:07 -0400 Subject: [PATCH 08/58] added title screen loading at launch --- pocket_friends/game_files/game.py | 22 ++++++++++++++------- pocket_friends/game_files/surfaces/title.py | 10 +++++++--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 4f6f6a1..e329a32 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -2,6 +2,7 @@ import pygame import os from pathlib import Path import pocket_friends +from pocket_friends.game_files.surfaces import title # FPS for the entire game to run at. game_fps = 16 @@ -9,6 +10,10 @@ game_fps = 16 game_res = 80 script_dir = os.path.dirname(os.path.abspath(__file__)) save_dir = os.path.join(Path.home(), '.pocket_friends') +resources_dir = script_dir + '/surfaces/resources' +starting_surface = 'title' + + # Gets the directory of the script for importing and the save directory @@ -24,21 +29,16 @@ def game(): pygame.mouse.set_visible(False) pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) - window = pygame.display.set_mode((screen_size, screen_size)) - surface = pygame.Surface((game_res, game_res)) + surface = globals()[starting_surface].Surface((game_res, game_res), resources_dir) # Add an icon to the pygame window. - icon = pygame.image.load(script_dir + '/resources/images/icon/icon.png').convert_alpha() + icon = pygame.image.load(script_dir + '/icon/icon.png').convert_alpha() pygame.display.set_icon(icon) clock = pygame.time.Clock() - # Font used for small text in the game. Bigger text is usually image files. - small_font = pygame.font.Font(script_dir + '/resources/fonts/5Pts5.ttf', 10) - # Default game state when the game first starts. - game_state = 'title' running = True # A group of all the sprites on screen. Used to update all sprites at onc @@ -47,6 +47,14 @@ def game(): # Time since last input. Used to help regulate double presses of buttons. last_input_tick = 0 + while running: + clock.tick(game_fps) + surface.update() + frame = pygame.transform.scale(surface, (screen_size, screen_size)) + window.blit(frame, frame.get_rect()) + + pygame.display.flip() + def main(): """ diff --git a/pocket_friends/game_files/surfaces/title.py b/pocket_friends/game_files/surfaces/title.py index 8ce206b..4bf0594 100644 --- a/pocket_friends/game_files/surfaces/title.py +++ b/pocket_friends/game_files/surfaces/title.py @@ -2,11 +2,15 @@ import pygame class Surface(pygame.Surface): - def __init__(self, window_size): + def __init__(self, window_size, resources_dir): super().__init__(window_size, pygame.SRCALPHA) self.running = True self.next_surface = None - def update(self): - self.fill((0, 0, 0)) + self.bg = pygame.image.load(resources_dir + '/images/bg.png').convert_alpha() + self.title = pygame.image.load(resources_dir + '/images/title.png').convert_alpha() + + def update(self): + self.blit(self.bg, (0, 0)) + self.blit(self.title, (0, 0)) From 296b6df4a0895ac39c5d19cf8d46a6074c57d439 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 13:09:55 -0400 Subject: [PATCH 09/58] title screen moves on now to sprite selection --- pocket_friends/game_files/game.py | 20 +++++++++++++++++-- .../game_files/surfaces/__init__.py | 6 ++++++ .../game_files/surfaces/egg_select.py | 17 ++++++++++++++++ pocket_friends/game_files/surfaces/title.py | 11 +++++++++- 4 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 pocket_friends/game_files/surfaces/egg_select.py diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index e329a32..9fc4d6e 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -2,7 +2,17 @@ import pygame import os from pathlib import Path import pocket_friends -from pocket_friends.game_files.surfaces import title +import importlib + +valid_surfaces = [ + 'title', + 'egg_select' +] +surface_modules = {} + +for module in valid_surfaces: + surface_modules[module] = importlib.import_module('pocket_friends.game_files.surfaces.{0}'.format(module)) + print('imported ' + module) # FPS for the entire game to run at. game_fps = 16 @@ -30,7 +40,7 @@ def game(): pygame.mouse.set_visible(False) pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) window = pygame.display.set_mode((screen_size, screen_size)) - surface = globals()[starting_surface].Surface((game_res, game_res), resources_dir) + surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) # Add an icon to the pygame window. icon = pygame.image.load(script_dir + '/icon/icon.png').convert_alpha() @@ -53,6 +63,12 @@ def game(): frame = pygame.transform.scale(surface, (screen_size, screen_size)) window.blit(frame, frame.get_rect()) + if not surface.running: + next_surface = surface.next_surface + if next_surface not in valid_surfaces: + raise Exception('Given surface is not listed in valid surfaces!') + surface = surface_modules.get(next_surface).Surface((game_res, game_res), resources_dir, game_fps) + print(surface.name) pygame.display.flip() diff --git a/pocket_friends/game_files/surfaces/__init__.py b/pocket_friends/game_files/surfaces/__init__.py index e69de29..6867d8e 100644 --- a/pocket_friends/game_files/surfaces/__init__.py +++ b/pocket_friends/game_files/surfaces/__init__.py @@ -0,0 +1,6 @@ +import os +__all__ = [] +for module in os.listdir(os.path.dirname(os.path.abspath(__file__))): + if module != '__init__.py' and module[-3:] == '.py': + __all__.append(module) + diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py new file mode 100644 index 0000000..691276f --- /dev/null +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -0,0 +1,17 @@ +import pygame + + +class Surface(pygame.Surface): + def __init__(self, window_size, resources_dir, game_fps): + super().__init__(window_size, pygame.SRCALPHA) + self.name = 'egg_select' + self.running = True + self.next_surface = None + + self.bg = pygame.image.load(resources_dir + '/images/bg.png').convert_alpha() + self.sprites = pygame.sprite.Group() + + def update(self): + self.blit(self.bg, (0, 0)) + self.sprites.update() + self.sprites.draw(self) diff --git a/pocket_friends/game_files/surfaces/title.py b/pocket_friends/game_files/surfaces/title.py index 4bf0594..2fade0b 100644 --- a/pocket_friends/game_files/surfaces/title.py +++ b/pocket_friends/game_files/surfaces/title.py @@ -1,16 +1,25 @@ import pygame +import time class Surface(pygame.Surface): - def __init__(self, window_size, resources_dir): + def __init__(self, window_size, resources_dir, game_fps): super().__init__(window_size, pygame.SRCALPHA) + self.name = 'title' self.running = True self.next_surface = None self.bg = pygame.image.load(resources_dir + '/images/bg.png').convert_alpha() self.title = pygame.image.load(resources_dir + '/images/title.png').convert_alpha() + self.frames = 1 + self.game_fps = game_fps + self.delay = 1 def update(self): self.blit(self.bg, (0, 0)) self.blit(self.title, (0, 0)) + self.frames += 1 + if self.frames > self.game_fps * self.delay: + self.next_surface = 'egg_select' + self.running = False From bbe97f0de771b83c4acd98168a20ad0f9e7a27ec Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 13:10:08 -0400 Subject: [PATCH 10/58] added module sprites.py --- .../game_files/surfaces/objects/sprites.py | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 pocket_friends/game_files/surfaces/objects/sprites.py diff --git a/pocket_friends/game_files/surfaces/objects/sprites.py b/pocket_friends/game_files/surfaces/objects/sprites.py new file mode 100644 index 0000000..7ae91f2 --- /dev/null +++ b/pocket_friends/game_files/surfaces/objects/sprites.py @@ -0,0 +1,84 @@ +import pygame +import json + + +class SpriteSheet: + """ + Imports a sprite sheet as separate pygame images given an image file and a json file. + """ + + def __init__(self, sprite_sheet, texture_json): + # Load in whole sprite sheet as one image. + self.sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha() + self.images = [] + + # Get the sprite sheet json file. + with open(texture_json, 'r') as json_file: + self.img_attrib = json.load(json_file) + json_file.close() + + # Count for how many images have been added in the image list + image_count = 0 + + # Get the sprite size as a tuple + sprite_size = self.img_attrib['width'], self.img_attrib['height'] + + # Iterate through every image location on the sprite sheet given the sprite size + for i in range(self.sprite_sheet.get_size()[1] // sprite_size[1]): + i *= sprite_size[1] + for j in range(self.sprite_sheet.get_size()[0] // sprite_size[0]): + j *= sprite_size[0] + + # Create a new transparent surface + sprite = pygame.Surface(sprite_size, pygame.SRCALPHA) + # Blit the sprite onto the image + sprite.blit(self.sprite_sheet, (0, 0), (j, i, sprite_size[0], sprite_size[1])) + # Add the image to the list of images + self.images.append(sprite) + + image_count += 1 + + # Break the loop if the specified number of frames has been reached. + if image_count >= self.img_attrib['frames']: + break + if image_count >= self.img_attrib['frames']: + break + + +class SelectionEgg(pygame.sprite.Sprite): + """ + Class for the eggs on the egg selection screen. + """ + + def __init__(self, egg_color, resources_dir): + pygame.sprite.Sprite.__init__(self) + + self.egg_color = egg_color + + # Loads the JSON file of the egg to read in data. + with open(resources_dir + '/data/bloop_info/{0}.json'.format(egg_color), 'r') as save_file: + json_file = json.load(save_file) + save_file.close() + + # Gets the description off the egg from the JSON file. + self.description = json_file.get('description') + self.contentedness = json_file.get('contentedness') + self.metabolism = json_file.get('metabolism') + + # Load the egg from the given color and get the bounding rectangle for the image. + sprite_sheet = SpriteSheet(resources_dir + '/images/bloops/{0}/egg.png'.format(self.egg_color), + resources_dir + '/resources/images/bloops/{0}/egg.json'.format(self.egg_color)) + self.images = sprite_sheet.images + + # Get the rectangle from the first image in the list + self.rect = self.images[0].get_rect() + self.index = 0 + self.image = self.images[self.index] + + def update(self): + """ + Updates the sprite object. + """ + # Animate the sprite + self.index = (self.index + 1) % len(self.images) + self.image = self.images[self.index] From fd7e1b7492c87b0d6a48b14b0b38b5acd4baa1d4 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 13:23:55 -0400 Subject: [PATCH 11/58] added eggs on selection screen with animations --- .../game_files/surfaces/egg_select.py | 39 +++++++++++++++++++ .../surfaces/{objects => }/sprites.py | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) rename pocket_friends/game_files/surfaces/{objects => }/sprites.py (96%) diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py index 691276f..a7f2ff2 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -1,4 +1,5 @@ import pygame +from . import sprites class Surface(pygame.Surface): @@ -11,6 +12,44 @@ class Surface(pygame.Surface): self.bg = pygame.image.load(resources_dir + '/images/bg.png').convert_alpha() self.sprites = pygame.sprite.Group() + egg_list = [ + 'dev_egg', + 'blue', + 'rainbow' + ] + eggs = [] + for egg in egg_list: + eggs.append(sprites.SelectionEgg(egg, resources_dir)) + + eggs_per_row = 3 + distance_between_eggs = 36 / eggs_per_row + + # Count the total rows. + total_rows = -(-len(eggs) // eggs_per_row) + distance_between_rows = 32 / eggs_per_row + + # Determine the location of each egg. + for egg in eggs: + current_row = eggs.index(egg) // eggs_per_row + rows_after = total_rows - (current_row + 1) + egg_in_row = eggs.index(egg) % eggs_per_row + eggs_after = min(len(eggs) - (current_row * eggs_per_row), eggs_per_row) - (egg_in_row + 1) + + x_offset = 32 + y_offset = 30 + + # The x coordinate of an egg is determined by which egg in the row it is, and how many eggs + # are in that row. If there is only 1 egg in a row, it is in the middle of the screen. If + # there are two, they're on equal halves and so on. + x = x_offset - (eggs_after * distance_between_eggs) + (egg_in_row * distance_between_eggs) + y = y_offset - (rows_after * distance_between_rows) + (current_row * distance_between_rows) + + egg.rect.x = x + egg.rect.y = y + + # Add the egg to the sprite list. + self.sprites.add(egg) + def update(self): self.blit(self.bg, (0, 0)) self.sprites.update() diff --git a/pocket_friends/game_files/surfaces/objects/sprites.py b/pocket_friends/game_files/surfaces/sprites.py similarity index 96% rename from pocket_friends/game_files/surfaces/objects/sprites.py rename to pocket_friends/game_files/surfaces/sprites.py index 7ae91f2..d4f0f8d 100644 --- a/pocket_friends/game_files/surfaces/objects/sprites.py +++ b/pocket_friends/game_files/surfaces/sprites.py @@ -67,7 +67,7 @@ class SelectionEgg(pygame.sprite.Sprite): # Load the egg from the given color and get the bounding rectangle for the image. sprite_sheet = SpriteSheet(resources_dir + '/images/bloops/{0}/egg.png'.format(self.egg_color), - resources_dir + '/resources/images/bloops/{0}/egg.json'.format(self.egg_color)) + resources_dir + '/images/bloops/{0}/egg.json'.format(self.egg_color)) self.images = sprite_sheet.images # Get the rectangle from the first image in the list From da5bacf95068b53b6f148ca6a46691a90a29ead0 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 13:24:25 -0400 Subject: [PATCH 12/58] removed old importing code --- pocket_friends/game_files/surfaces/__init__.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pocket_friends/game_files/surfaces/__init__.py b/pocket_friends/game_files/surfaces/__init__.py index 6867d8e..e69de29 100644 --- a/pocket_friends/game_files/surfaces/__init__.py +++ b/pocket_friends/game_files/surfaces/__init__.py @@ -1,6 +0,0 @@ -import os -__all__ = [] -for module in os.listdir(os.path.dirname(os.path.abspath(__file__))): - if module != '__init__.py' and module[-3:] == '.py': - __all__.append(module) - From 7b8898b77b69dc7a8b5f38c66ffe1b812dca33c8 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 14:01:02 -0400 Subject: [PATCH 13/58] added input_handler.py module to help with inputs --- pocket_friends/game_files/classes/__init__.py | 0 .../game_files/classes/input_handler.py | 71 +++++++++++++++++++ pocket_friends/hardware/gpio_handler.py | 2 +- 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 pocket_friends/game_files/classes/__init__.py create mode 100644 pocket_friends/game_files/classes/input_handler.py diff --git a/pocket_friends/game_files/classes/__init__.py b/pocket_friends/game_files/classes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pocket_friends/game_files/classes/input_handler.py b/pocket_friends/game_files/classes/input_handler.py new file mode 100644 index 0000000..97afc25 --- /dev/null +++ b/pocket_friends/game_files/classes/input_handler.py @@ -0,0 +1,71 @@ +import pygame +import importlib.util +from pocket_friends.hardware.gpio_handler import Constants, GPIOHandler + + +class InputHandler: + def __init__(self, pygame_clock): + self.clock = pygame_clock + try: + importlib.util.find_spec('RPi.GPIO') + import RPi.GPIO as GPIO + self.on_hardware = True + except ImportError: + import pocket_friends.development.FakeGPIO as GPIO + self.on_hardware = False + self.last_input_tick = 0 + + def create_event(self, pressed_button): + """ + Creates a pygame event with a given keyboard code + :param pressed_button: + """ + # Register a button click so long as the last button click happened no less than two frames ago + if pygame.time.get_ticks() - self.last_input_tick > self.clock.get_time() * 2 or not self.on_hardware: + pygame.event.post(pygame.event.Event(pygame.KEYDOWN, {'key': pressed_button})) + pygame.event.post(pygame.event.Event(pygame.KEYUP, {'key': pressed_button})) + self.last_input_tick = pygame.time.get_ticks() + + def handle_gpio(self): + """ + Handles getting GPIO button presses and making a pygame event when a press is detected. + """ + for pressed_button in Constants.buttons: + code = Constants.buttons.get(pressed_button) + + # Check if a button has been pressed. If it has, create a pygame event for it. + if GPIOHandler.get_press(code): + self.create_event(code) + + def keyboard_handler(self): + """ + Simulates key presses to GPIO button presses. Also handles quitting the game. + """ + + # Checks if a corresponding keyboard key has been pressed. If it has, emulate a button press. + for keyboard_event in pygame.event.get(): + if keyboard_event.type == pygame.QUIT: + running = False + if keyboard_event.type == pygame.KEYDOWN: + if keyboard_event.key == pygame.K_a: + self.create_event(Constants.buttons.get('a')) + if keyboard_event.key == pygame.K_b: + self.create_event(Constants.buttons.get('b')) + if keyboard_event.key == pygame.K_PERIOD: + self.create_event(Constants.buttons.get('j_i')) + if keyboard_event.key == pygame.K_RIGHT: + self.create_event(Constants.buttons.get('j_r')) + if keyboard_event.key == pygame.K_LEFT: + self.create_event(Constants.buttons.get('j_l')) + if keyboard_event.key == pygame.K_DOWN: + self.create_event(Constants.buttons.get('j_d')) + if keyboard_event.key == pygame.K_UP: + self.create_event(Constants.buttons.get('j_u')) + if keyboard_event.key == pygame.K_ESCAPE: + running = False + + def update(self): + if self.on_hardware: + self.handle_gpio() + else: + self.keyboard_handler() diff --git a/pocket_friends/hardware/gpio_handler.py b/pocket_friends/hardware/gpio_handler.py index f8cd603..fd1ddd1 100644 --- a/pocket_friends/hardware/gpio_handler.py +++ b/pocket_friends/hardware/gpio_handler.py @@ -68,4 +68,4 @@ class GPIOHandler: :param button: button to be detected :return: True if the button is has been pressed, False otherwise """ - return GPIO.event_detected(button) + return GPIO.event_detected(button) \ No newline at end of file From 4e142043921af1f8452d08ca9d83e1965557a07c Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 14:03:16 -0400 Subject: [PATCH 14/58] added selection sprite, moved clock out of game.py and into individual screens --- pocket_friends/game_files/game.py | 3 - .../game_files/surfaces/egg_select.py | 100 +++++++++++++++--- pocket_friends/game_files/surfaces/title.py | 2 + 3 files changed, 90 insertions(+), 15 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 9fc4d6e..22480c1 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -46,8 +46,6 @@ def game(): icon = pygame.image.load(script_dir + '/icon/icon.png').convert_alpha() pygame.display.set_icon(icon) - clock = pygame.time.Clock() - # Default game state when the game first starts. running = True @@ -58,7 +56,6 @@ def game(): last_input_tick = 0 while running: - clock.tick(game_fps) surface.update() frame = pygame.transform.scale(surface, (screen_size, screen_size)) window.blit(frame, frame.get_rect()) diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py index a7f2ff2..57ca124 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -1,5 +1,7 @@ import pygame from . import sprites +from pocket_friends.hardware.gpio_handler import Constants +from ..classes.input_handler import InputHandler class Surface(pygame.Surface): @@ -8,8 +10,12 @@ class Surface(pygame.Surface): self.name = 'egg_select' self.running = True self.next_surface = None + self.resource_dir = resources_dir + self.clock = pygame.time.Clock() + self.game_fps = game_fps + self.input_handler = InputHandler(self.clock) - self.bg = pygame.image.load(resources_dir + '/images/bg.png').convert_alpha() + self.bg = pygame.image.load(self.resource_dir + '/images/bg.png').convert_alpha() self.sprites = pygame.sprite.Group() egg_list = [ @@ -17,23 +23,23 @@ class Surface(pygame.Surface): 'blue', 'rainbow' ] - eggs = [] + self.eggs = [] for egg in egg_list: - eggs.append(sprites.SelectionEgg(egg, resources_dir)) + self.eggs.append(sprites.SelectionEgg(egg, self.resource_dir)) - eggs_per_row = 3 - distance_between_eggs = 36 / eggs_per_row + self.eggs_per_row = 3 + distance_between_eggs = 36 / self.eggs_per_row # Count the total rows. - total_rows = -(-len(eggs) // eggs_per_row) - distance_between_rows = 32 / eggs_per_row + self.total_rows = -(-len(self.eggs) // self.eggs_per_row) + distance_between_rows = 32 / self.eggs_per_row # Determine the location of each egg. - for egg in eggs: - current_row = eggs.index(egg) // eggs_per_row - rows_after = total_rows - (current_row + 1) - egg_in_row = eggs.index(egg) % eggs_per_row - eggs_after = min(len(eggs) - (current_row * eggs_per_row), eggs_per_row) - (egg_in_row + 1) + for egg in self.eggs: + current_row = self.eggs.index(egg) // self.eggs_per_row + rows_after = self.total_rows - (current_row + 1) + egg_in_row = self.eggs.index(egg) % self.eggs_per_row + eggs_after = min(len(self.eggs) - (current_row * self.eggs_per_row), self.eggs_per_row) - (egg_in_row + 1) x_offset = 32 y_offset = 30 @@ -50,7 +56,77 @@ class Surface(pygame.Surface): # Add the egg to the sprite list. self.sprites.add(egg) + self.selected_egg = 0 + self.selected_color = '' + + def get_cursor_coords(self): + """ + Gets the coordinates of an egg on the selection screen by index and returns it as a tuple + :return: tuple of the coordinates of the selected egg + """ + cursor_x_offset = -2 + cursor_y_offset = -2 + + return (self.eggs[self.selected_egg].rect.x + cursor_x_offset, + self.eggs[self.selected_egg].rect.y + cursor_y_offset) + + def sel_left(self): + """ + Select the egg to the left with constraints. + """ + + if self.selected_egg % self.eggs_per_row != 0: + self.selected_egg -= 1 + + def sel_right(self): + """ + Select the egg to the right with constraints. + """ + + row = self.selected_egg // self.eggs_per_row + eggs_in_row = min(len(self.eggs) - (row * self.eggs_per_row), self.eggs_per_row) + + if self.selected_egg % self.eggs_per_row != eggs_in_row - 1: + self.selected_egg += 1 + + def sel_up(self): + """ + Select the egg above with constraints. + """ + + if self.selected_egg // self.eggs_per_row != 0: + self.selected_egg -= self.eggs_per_row + + def sel_down(self): + """ + Select the egg below with constraints. + """ + + if self.selected_egg // self.eggs_per_row != self.total_rows - 1: + self.selected_egg += self.eggs_per_row + def update(self): + self.clock.tick(self.game_fps) + self.blit(self.bg, (0, 0)) self.sprites.update() self.sprites.draw(self) + + self.input_handler.update() + + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + if event.key == Constants.buttons.get('j_r'): + self.sel_right() + if event.key == Constants.buttons.get('j_l'): + self.sel_left() + if event.key == Constants.buttons.get('j_d'): + self.sel_down() + if event.key == Constants.buttons.get('j_u'): + self.sel_up() + if event.key == Constants.buttons.get('a'): + pass + + cursor = pygame.image.load( + self.resource_dir + '/images/gui/egg_selector.png').convert_alpha() + self.blit(cursor, self.get_cursor_coords()) diff --git a/pocket_friends/game_files/surfaces/title.py b/pocket_friends/game_files/surfaces/title.py index 2fade0b..dbc810a 100644 --- a/pocket_friends/game_files/surfaces/title.py +++ b/pocket_friends/game_files/surfaces/title.py @@ -8,6 +8,7 @@ class Surface(pygame.Surface): self.name = 'title' self.running = True self.next_surface = None + self.clock = pygame.time.Clock() self.bg = pygame.image.load(resources_dir + '/images/bg.png').convert_alpha() self.title = pygame.image.load(resources_dir + '/images/title.png').convert_alpha() @@ -16,6 +17,7 @@ class Surface(pygame.Surface): self.delay = 1 def update(self): + self.clock.tick(self.game_fps) self.blit(self.bg, (0, 0)) self.blit(self.title, (0, 0)) From 535aa993a56ed448b118c90a3b2460fb4eac6734 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 14:05:53 -0400 Subject: [PATCH 15/58] renamed classes to io_helpers --- pocket_friends/game_files/{classes => io_helpers}/__init__.py | 0 .../game_files/{classes => io_helpers}/data_handler.py | 0 .../game_files/{classes => io_helpers}/input_handler.py | 0 pocket_friends/game_files/surfaces/egg_select.py | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) rename pocket_friends/game_files/{classes => io_helpers}/__init__.py (100%) rename pocket_friends/game_files/{classes => io_helpers}/data_handler.py (100%) rename pocket_friends/game_files/{classes => io_helpers}/input_handler.py (100%) diff --git a/pocket_friends/game_files/classes/__init__.py b/pocket_friends/game_files/io_helpers/__init__.py similarity index 100% rename from pocket_friends/game_files/classes/__init__.py rename to pocket_friends/game_files/io_helpers/__init__.py diff --git a/pocket_friends/game_files/classes/data_handler.py b/pocket_friends/game_files/io_helpers/data_handler.py similarity index 100% rename from pocket_friends/game_files/classes/data_handler.py rename to pocket_friends/game_files/io_helpers/data_handler.py diff --git a/pocket_friends/game_files/classes/input_handler.py b/pocket_friends/game_files/io_helpers/input_handler.py similarity index 100% rename from pocket_friends/game_files/classes/input_handler.py rename to pocket_friends/game_files/io_helpers/input_handler.py diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py index 57ca124..2fadf3f 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -1,7 +1,7 @@ import pygame from . import sprites from pocket_friends.hardware.gpio_handler import Constants -from ..classes.input_handler import InputHandler +from ..io_helpers.input_handler import InputHandler class Surface(pygame.Surface): From ca9406aab81e789b14829dfa3918d278df3a37f1 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 14:06:26 -0400 Subject: [PATCH 16/58] removed old codebase from files --- .../game_files/old_main_gamefile.py | 984 ------------------ 1 file changed, 984 deletions(-) delete mode 100644 pocket_friends/game_files/old_main_gamefile.py diff --git a/pocket_friends/game_files/old_main_gamefile.py b/pocket_friends/game_files/old_main_gamefile.py deleted file mode 100644 index cd6e8b5..0000000 --- a/pocket_friends/game_files/old_main_gamefile.py +++ /dev/null @@ -1,984 +0,0 @@ -""" -Main file for the entire game. Controls everything except for GPIO input. -""" -from collections import deque -import importlib.util -import json -import os -from pathlib import Path -import pocket_friends -import pygame -from pygame.locals import * -from ..hardware.gpio_handler import Constants, GPIOHandler - -# FPS for the entire game to run at. -game_fps = 16 -# The resolution the game is rendered at. -game_res = 80 - -# Gets the directory of the script for importing and the save directory -script_dir = os.path.dirname(os.path.abspath(__file__)) -save_dir = os.path.join(Path.home(), '.pocket_friends') - -# Tries to make the save directory. Does nothing if it already exists. -try: - os.mkdir(save_dir) -except FileExistsError: - pass - - -class SpriteSheet: - """ - Imports a sprite sheet as separate pygame images given an image file and a json file. - """ - - def __init__(self, sprite_sheet, texture_json): - # Load in whole sprite sheet as one image. - self.sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha() - self.images = [] - - # Get the sprite sheet json file. - with open(texture_json, 'r') as json_file: - self.img_attrib = json.load(json_file) - json_file.close() - - # Count for how many images have been added in the image list - image_count = 0 - - # Get the sprite size as a tuple - sprite_size = self.img_attrib['width'], self.img_attrib['height'] - - # Iterate through every image location on the sprite sheet given the sprite size - for i in range(self.sprite_sheet.get_size()[1] // sprite_size[1]): - i *= sprite_size[1] - for j in range(self.sprite_sheet.get_size()[0] // sprite_size[0]): - j *= sprite_size[0] - - # Create a new transparent surface - sprite = pygame.Surface(sprite_size, SRCALPHA) - # Blit the sprite onto the image - sprite.blit(self.sprite_sheet, (0, 0), (j, i, sprite_size[0], sprite_size[1])) - # Add the image to the list of images - self.images.append(sprite) - - image_count += 1 - - # Break the loop if the specified number of frames has been reached. - if image_count >= self.img_attrib['frames']: - break - if image_count >= self.img_attrib['frames']: - break - - -class DataHandler: - """ - Class that handles the hardware attributes and save files. - """ - - def __init__(self): - # Attributes that are saved to a file to recover upon startup. - self.attributes = { - 'version': pocket_friends.__version__, - 'time_elapsed': 0, - 'bloop': '', - 'age': 0, - 'health': 0, - 'hunger': 0, - 'happiness': 0, - 'care_counter': 0, - 'missed_care': 0, - 'adult': 0, - 'evolution_stage': '', - } - - # Frame counter - self.frames_passed = 0 - - def write_save(self): - """ - Writes attributes of class to "save.json" file. - """ - with open(save_dir + '/save.json', 'w') as save_file: - json.dump(self.attributes, save_file) - save_file.close() - - def read_save(self): - """ - Reads from "save.json" and inserts into attributes dictionary. Creates file if it does not exist. - """ - # Open up the save file and read it into self.attributes. - try: - with open(save_dir + '/save.json', 'r') as save_file: - self.attributes = json.load(save_file) - save_file.close() - - # If there is no save file, write one with the defaults. - except FileNotFoundError: - self.write_save() - - def update(self): - """ - Run the game logic. - """ - self.frames_passed += 1 - # Run logic of the game every second. - if self.frames_passed >= game_fps: - - # Add one to the age of the bloop. - self.attributes['age'] += 1 - - # Save the data when the age of the bloop is a multiple of 10. - if self.attributes['age'] % 10 == 0: - self.write_save() - - # Reset frame counter - self.frames_passed = 0 - - -class PlaygroundFriend(pygame.sprite.Sprite): - """ - Class for the sprite of the creature on the main playground. - """ - - def __init__(self, data_handler): - pygame.sprite.Sprite.__init__(self) - - # All attributes of the bloops - self.bloop = data_handler.attributes['bloop'] - self.adult = data_handler.attributes['adult'] - self.evolution_stage = data_handler.attributes['evolution_stage'] - self.direction = 0 - - if self.evolution_stage == 'adult': - image = self.evolution_stage + self.adult - else: - image = self.evolution_stage - - # Draw the correct bloop depending on the stage - sprite_sheet = SpriteSheet(script_dir + '/resources/images/bloops/{0}/{1}.png'.format(self.bloop, image), - script_dir + '/resources/images/bloops/{0}/{1}.json'.format(self.bloop, image)) - - # Load the images from the sprite sheet - self.images = sprite_sheet.images - - # Put the egg in the middle of the screen. - self.rect = self.images[0].get_rect() - self.rect.x = (game_res / 2) - (self.rect.width / 2) - self.rect.y = (game_res / 2) - (self.rect.height / 2) - - # Start animation at the beginning of the sprite sheet. - self.index = 0 - self.image = self.images[self.index] - - self.movement_frames = game_fps / 2 # How many frames pass before the bloop moves - self.current_frame = 0 - - def pet(self): - """ - Pet the bloop! - """ - pass - - def update(self): - """ - Takes the images loaded and animates it, spacing it out equally for the framerate. - """ - - margins = 9 # Margins for how far the bloop can move from the left and the right of the screen - movement_amount = 2 # Pixels that the bloop moves in one movement - - self.current_frame += 1 - - # Check to see if the number of movement frames has passed - if self.current_frame >= self.movement_frames: - self.current_frame = 0 - - # Move only if the bloop is not in the egg stage - if self.evolution_stage != 'egg': - - # Change direction if the bloop has reached either edge of the screen - if self.rect.x < margins: - self.direction = 1 - elif self.rect.x > game_res - margins - self.rect.width: - self.direction = 0 - - # Move according to the direction. - if self.direction == 0: - self.rect.x -= movement_amount - else: - self.rect.x += movement_amount - - # Animate the bloop - self.index = (self.index + 1) % len(self.images) - self.image = self.images[self.index] - - -class SelectionEgg(pygame.sprite.Sprite): - """ - Class for the eggs on the egg selection screen. - """ - - def __init__(self, egg_color): - pygame.sprite.Sprite.__init__(self) - - self.egg_color = egg_color - - # Loads the JSON file of the egg to read in data. - with open(script_dir + '/resources/data/bloop_info/{0}.json'.format(egg_color), 'r') as save_file: - json_file = json.load(save_file) - save_file.close() - - # Gets the description off the egg from the JSON file. - self.description = json_file.get('description') - self.contentedness = json_file.get('contentedness') - self.metabolism = json_file.get('metabolism') - - # Load the egg from the given color and get the bounding rectangle for the image. - sprite_sheet = SpriteSheet(script_dir + '/resources/images/bloops/{0}/egg.png'.format(self.egg_color), - script_dir + '/resources/images/bloops/{0}/egg.json'.format(self.egg_color)) - self.images = sprite_sheet.images - - # Get the rectangle from the first image in the list - self.rect = self.images[0].get_rect() - self.index = 0 - self.image = self.images[self.index] - - def update(self): - """ - Updates the sprite object. - """ - # Animate the sprite - self.index = (self.index + 1) % len(self.images) - self.image = self.images[self.index] - - -class EggInfo: - """ - Class to draw the contentedness and metabolism value off the egg on the info screen. - """ - - def __init__(self, contentedness, metabolism, location): - self.contentedness = contentedness - self.metabolism = metabolism - self.x = location[0] - self.y = location[1] - - # Create a new surface to blit onto the other surface - self.surface = pygame.Surface((44, 15), SRCALPHA) - - # Blit the two indicator icons on screen - smiley = pygame.image.load(script_dir + '/resources/images/gui/smiley.png').convert_alpha() - self.surface.blit(smiley, (0, 0)) - apple = pygame.image.load(script_dir + '/resources/images/gui/apple.png').convert_alpha() - self.surface.blit(apple, (1, 9)) - - # Draw 5 stars. If the value of the contentedness is less than the current star, make it a blank star. - for i in range(5): - if i < self.contentedness: - star = pygame.image.load(script_dir + '/resources/images/gui/star.png').convert_alpha() - else: - star = pygame.image.load(script_dir + '/resources/images/gui/blank_star.png').convert_alpha() - self.surface.blit(star, (11 + (i * 6), 1)) - - # Draw 5 stars. If the value of the metabolism is less than the current star, make it a blank star. - for i in range(5): - if i < self.metabolism: - star = pygame.image.load(script_dir + '/resources/images/gui/star.png').convert_alpha() - else: - star = pygame.image.load(script_dir + '/resources/images/gui/blank_star.png').convert_alpha() - self.surface.blit(star, (11 + (i * 6), 10)) - - def draw(self, surface): - """ - Draw the info icons on a given surface. - :param surface: the surface to draw the icons on. - """ - # Blit the info onto the given surface. - surface.blit(self.surface, (self.x, self.y)) - - -class InfoText: - """ - Class for drawing large amounts of text on the screen at a time - """ - - def __init__(self, font, text='Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam commodo tempor ' - 'aliquet. Suspendisse placerat accumsan neque, nec volutpat nunc porta ut.'): - - self.font = font - self.text = [] # Text broken up into a list according to how it will fit on screen. - self.max_lines = 6 # Max number of lines to be shown on screen at a time. - self.offset = 0 - - # Arrow icons to indicate scrolling - self.up_arrow = pygame.image.load(script_dir + '/resources/images/gui/up_arrow.png').convert_alpha() - self.down_arrow = pygame.image.load(script_dir + '/resources/images/gui/down_arrow.png').convert_alpha() - - raw_text = text # Copy the text to a different variable to be cut up. - - margins = 4.5 - max_line_width = game_res - (margins * 2) # The maximum pixel width that drawn text can be. - cut_chars = '.,! ' # Characters that will be considered "cuts" aka when a line break can occur. - - # Prevents freezing if the end of the string does not end in a cut character - # Will fix eventually more elegantly - if raw_text[-1:] not in cut_chars: - raw_text += ' ' - - # Calculating line breaks. - while len(raw_text) > 0: - index = 0 - test_text = '' # Chunk of text to pseudo-render and test the width of. - - # Loops until the testing text has reached the size limit. - while True: - - # Break if the current index is larger than the remaining text. - if index + 1 > len(raw_text): - index -= 1 - break - - # Add one character to the testing text from the raw text. - test_text += raw_text[index] - # Get the width of the pseudo-rendered text. - text_width = font.size(test_text)[0] - - # Break if the text is larger than the defined max width. - if text_width > max_line_width: - break - index += 1 - pass - - # Gets the chunk of text to be added to the list. - text_chunk = raw_text[0:index + 1] - # Determines if the chunk of text has any break characters. - has_breaks = any(cut_chars in text_chunk for cut_chars in cut_chars) - - # If the text has break characters, start with the last character and go backwards until - # one has been found, decreasing the index each time. - if has_breaks: - while raw_text[index] not in cut_chars: - index -= 1 - text_chunk = raw_text[0:index + 1] - # If there are no break characters in the chunk, simply decrease the index by one and insert - # a dash at the end of the line to indicate the word continues. - else: - index -= 1 - text_chunk = raw_text[0:index + 1] - text_chunk += '-' - - # Append the text chunk to the list of text to draw. - self.text.append(text_chunk) - - # Cut the text to repeat the process with the new cut string. - raw_text = raw_text[index + 1:] - - def draw(self, surface): - """ - Draws the text on a given surface. - :param surface: The surface for the text to be drawn on. - """ - # Constants to help draw the text - line_separation = 7 - left_margin = 3 - top_margin = 25 - bottom_margin = 10 - - # Draw the lines on the screen - for i in range(min(len(self.text), self.max_lines)): - text = self.font.render(self.text[i + self.offset], False, (64, 64, 64)) - surface.blit(text, (left_margin, top_margin + (i * line_separation))) - - # Draw the arrows if there is more text than is on screen. - if self.offset != 0: - surface.blit(self.up_arrow, ((game_res / 2) - (self.up_arrow.get_rect().width / 2), top_margin - 3)) - if len(self.text) - (self.offset + 1) >= self.max_lines: - surface.blit(self.down_arrow, - ((game_res / 2) - (self.down_arrow.get_rect().width / 2), game_res - bottom_margin)) - - def scroll_down(self): - """ - Scrolls the text on the screen down. - """ - # Ensures that the offset cannot be too big as to try to render non-existent lines. - if len(self.text) - (self.offset + 1) >= self.max_lines: - self.offset += 1 - - def scroll_up(self): - """ - Scrolls the text on the screen up. - """ - if self.offset > 0: # Ensures a non-zero offset is not possible. - self.offset -= 1 - - -class MenuIcon(pygame.sprite.Sprite): - """ - Sprite for an icon on the main popup menu. - """ - - def __init__(self, icon): - pygame.sprite.Sprite.__init__(self) - self.icon = icon - - # Load the sprite sheet from the icon name - sprite_sheet = SpriteSheet(script_dir + '/resources/images/gui/popup_menu/{0}.png'.format(self.icon), - script_dir + '/resources/images/gui/popup_menu/{0}.json'.format(self.icon)) - self.images = sprite_sheet.images - - # Get the rectangle from the first image in the list - self.rect = self.images[0].get_rect() - self.image = self.images[0] - - def select(self): - """ - Change the icon sprite to the selected icon. - """ - self.image = self.images[1] - - def deselect(self): - """ - Change the icon sprite to the not selected icon. - """ - self.image = self.images[0] - - -class PopupMenu: - """ - Class to create a popup menu that can be hidden and shown at will - """ - - def __init__(self, position): - # Background frame of the popup menu - self.frame = pygame.image.load(script_dir + '/resources/images/gui/popup_menu/frame.png').convert_alpha() - - self.draw_menu = False # Whether or not to draw the popup menu - self.menu_sprites = pygame.sprite.Group() # Sprite group for the icons - self.selected = 0 # The currently selected icon - - # The names of the icons to be drawn - icon_names = ['apple', 'dumbbell', 'stats', 'controller', 'bed'] - - self.icons = [] - # Create an icon sprite for each name in the list and add it to the icon list - for i in icon_names: - self.icons.append(MenuIcon(i)) - - # Add each sprite in the icon list to the sprite group - for i in range(len(self.icons)): - icon = self.icons[i] - if i == self.selected: # Make the default selected icon glow - icon.select() - - # Calculate the position of the icon on screen - icon.rect.x = 10 + (i * 15) - (icon.image.get_width() / 2) - icon.rect.y = position[1] + self.frame.get_height() / 2 - icon.image.get_height() / 2 - - # Add the icon to the sprite group. - self.menu_sprites.add(icon) - - def toggle(self): - """ - Toggles the menu on or off. - """ - self.draw_menu = not self.draw_menu - - def next(self): - """ - Changes the selection to the next icon (to the right.) - """ - if self.draw_menu: # Only change if the menu is on screen - - self.icons[self.selected].deselect() # Deselect the current icon - self.selected += 1 # Change selection to the next icon - if self.selected >= len(self.icons): # Wrap around if new value is invalid - self.selected = 0 - self.icons[self.selected].select() # Select the newly selected icon - - def prev(self): - """ - Changes the selection to the previous icon (to the left.) - """ - if self.draw_menu: # Only change if the menu is on screen - - self.icons[self.selected].deselect() # Deselect the current icon - self.selected -= 1 # Change selection to the previous icon - if self.selected < 0: # Wrap around if new value is invalid - self.selected = len(self.icons) - 1 - self.icons[self.selected].select() # Select the newly selected icon - - def draw(self, surface): - """ - Draw the menu onto a given surface - :param surface: the surface to draw the menu on. - """ - # Draw the menu only if it is toggled on. - if self.draw_menu: - surface.blit(self.frame, (3, 3)) - self.menu_sprites.draw(surface) - - -# Makes Pygame draw on the display of the RPi. -os.environ["SDL_FBDEV"] = "/dev/fb1" - -# Useful for debugging on the PC. Imports a fake RPi.GPIO library if one is not found (which it can't -# be on a PC, RPi.GPIO cannot be installed outside of a Raspberry Pi. -try: - importlib.util.find_spec('RPi.GPIO') - import RPi.GPIO as GPIO - - on_hardware = True -except ImportError: - import pocket_friends.development.FakeGPIO as GPIO - # Run as if not on hardware - on_hardware = False - - -def game(): - """ - Starts the game. - """ - pygame.init() - - # Hide the cursor for the Pi display. - pygame.mouse.set_visible(False) - - # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the - # screen_size to reflect what the resolution of the new display is. - screen_size = 320 - - window = pygame.display.set_mode((screen_size, screen_size)) - surface = pygame.Surface((game_res, game_res)) - - # Only really useful for PCs. Does nothing on the Raspberry Pi. - pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) - - # Add an icon to the pygame window. - icon = pygame.image.load(script_dir + '/resources/images/icon/icon.png').convert_alpha() - pygame.display.set_icon(icon) - - clock = pygame.time.Clock() - - # Font used for small text in the game. Bigger text is usually image files. - small_font = pygame.font.Font(script_dir + '/resources/fonts/5Pts5.ttf', 10) - - # Default game state when the game first starts. - game_state = 'title' - running = True - data_handler = DataHandler() - - # A group of all the sprites on screen. Used to update all sprites at onc - all_sprites = pygame.sprite.Group() - - # Start the GPIO handler to take in buttons from the RPi HAT. - GPIOHandler.setup() - - # Dev code used to exit the game. Default Down, Down, Up, Up, Down, Down, Up, Up, A, A, B - dev_code = deque() - for button in [Constants.buttons.get('j_d'), Constants.buttons.get('j_d'), Constants.buttons.get('j_u'), - Constants.buttons.get('j_u'), Constants.buttons.get('j_d'), Constants.buttons.get('j_d'), - Constants.buttons.get('j_u'), Constants.buttons.get('j_u'), Constants.buttons.get('a'), - Constants.buttons.get('a'), Constants.buttons.get('b')]: - dev_code.append(button) - - # Log of the inputs. - input_log = deque() - - # Time since last input. Used to help regulate double presses of buttons. - last_input_tick = 0 - - def draw(): - """ - Draws the main pygame display. - """ - - # Draws all the sprites on screen and scales the screen to the correct size from the rendered size. - all_sprites.update() - all_sprites.draw(surface) - frame = pygame.transform.scale(surface, (screen_size, screen_size)) - window.blit(frame, frame.get_rect()) - - # Update the entire display. - pygame.display.flip() - - def draw_bg(): - """ - Draws the main game background image onto a given surface. - """ - bg_image = pygame.image.load(script_dir + '/resources/images/bg.png').convert() - surface.blit(bg_image, (0, 0)) - - def log_button(pressed_button): - """ - Logs the button presses to register the dev code. - :param pressed_button: The button code to be logged - """ - input_log.append(pressed_button) - if len(input_log) > len(dev_code): - input_log.popleft() - - def create_event(pressed_button): - """ - Creates a pygame event with a given keyboard code - :param pressed_button: - """ - nonlocal last_input_tick - # Register a button click so long as the last button click happened no less than two frames ago - if pygame.time.get_ticks() - last_input_tick > clock.get_time() * 2 or not on_hardware: - pygame.event.post(pygame.event.Event(KEYDOWN, {'key': pressed_button})) - pygame.event.post(pygame.event.Event(KEYUP, {'key': pressed_button})) - log_button(pressed_button) - last_input_tick = pygame.time.get_ticks() - - def check_dev_code(): - """ - Checks if the dev code has been entered. If it has, stop the program. - """ - nonlocal running - - if dev_code == input_log: - running = False - - def handle_gpio(): - """ - Handles getting GPIO button presses and making a pygame event when a press is detected. - """ - for pressed_button in Constants.buttons: - code = Constants.buttons.get(pressed_button) - - # Check if a button has been pressed. If it has, create a pygame event for it. - if GPIOHandler.get_press(code): - create_event(code) - - def keyboard_handler(): - """ - Simulates key presses to GPIO button presses. Also handles quitting the game. - """ - nonlocal running - - # Checks if a corresponding keyboard key has been pressed. If it has, emulate a button press. - for keyboard_event in pygame.event.get(): - if keyboard_event.type == pygame.QUIT: - running = False - if keyboard_event.type == pygame.KEYDOWN: - if keyboard_event.key == pygame.K_a: - create_event(Constants.buttons.get('a')) - if keyboard_event.key == pygame.K_b: - create_event(Constants.buttons.get('b')) - if keyboard_event.key == pygame.K_PERIOD: - create_event(Constants.buttons.get('j_i')) - if keyboard_event.key == pygame.K_RIGHT: - create_event(Constants.buttons.get('j_r')) - if keyboard_event.key == pygame.K_LEFT: - create_event(Constants.buttons.get('j_l')) - if keyboard_event.key == pygame.K_DOWN: - create_event(Constants.buttons.get('j_d')) - if keyboard_event.key == pygame.K_UP: - create_event(Constants.buttons.get('j_u')) - if keyboard_event.key == pygame.K_ESCAPE: - running = False - - def pre_handler(): - """ - Runs at the beginning of each loop, handles drawing the background, controlling game speed, and - controlling the GPIO button inputs and keyboard handler - """ - # Regulate the speed of the game. - clock.tick(game_fps) - - # Handle all inputs for both debugging and real GPIO button presses. - keyboard_handler() - handle_gpio() - check_dev_code() - - # Draw the background. - draw_bg() - - while running: - if game_state == 'title': - all_sprites.empty() - pre_handler() - - # Draw the title image in the middle of the screen. - title_image = pygame.image.load(script_dir + '/resources/images/title.png').convert_alpha() - surface.blit(title_image, (0, 0)) - draw() - - # Show the title for 1 second then move on to the initialization phase of the game. - pygame.time.wait(1000) - game_state = 'init' - - elif game_state == 'playground': - - # Submenu used within the playground. - submenu = 'main' - - while running and game_state == 'playground': - - all_sprites.empty() - - if submenu == 'main': - - # Create the bloop and the menu - bloop = PlaygroundFriend(data_handler) - all_sprites.add(bloop) - popup_menu = PopupMenu((3, 3)) - - while running and game_state == 'playground' and submenu == 'main': - pre_handler() - data_handler.update() - - for event in pygame.event.get(): - if event.type == pygame.KEYDOWN: - if event.key == Constants.buttons.get('j_r'): - # Move selection to the next item - popup_menu.next() - if event.key == Constants.buttons.get('j_l'): - # Move selection to the previous item - popup_menu.prev() - if event.key == Constants.buttons.get('a'): - # Change submenu to the menu the icon points to - if popup_menu.draw_menu: - submenu = popup_menu.icons[popup_menu.selected].icon - else: # Pet the bloop otherwise - bloop.pet() - if event.key == Constants.buttons.get('b'): - # Toggle the popup menu on or off - popup_menu.toggle() - - # Draw the popup menu if toggled on - popup_menu.draw(surface) - - draw() - - else: # Go to the error state if an invalid state is set. - game_state = None - - elif game_state == 'init': - all_sprites.empty() - pre_handler() - draw() - - # Read the save file. - data_handler.read_save() - - # Determines if it is a new game or not by looking at the evolution stage. If it is -1, the egg has - # not been created yet, and the game sends you to the egg selection screen. If not, the game sends - # you to the playground. - if data_handler.attributes['bloop'] == '': - game_state = 'egg_select' - else: - game_state = 'playground' - - elif game_state == 'egg_select': - - # Submenu used within the egg selection menu. - submenu = 'main' - - selected = 0 - selected_color = "" - - while running and game_state == 'egg_select': - - all_sprites.empty() - - if submenu == 'main': - - # Creates and holds the egg objects in a list. - eggs = [SelectionEgg('dev_egg'), SelectionEgg('blue'), SelectionEgg('rainbow')] - - # How many eggs per row should be displayed. - eggs_per_row = 3 - distance_between_eggs = 36 / eggs_per_row - - # Count the total rows. - total_rows = -(-len(eggs) // eggs_per_row) - distance_between_rows = 32 / eggs_per_row - - # Determine the location of each egg. - for egg in eggs: - current_row = eggs.index(egg) // eggs_per_row - rows_after = total_rows - (current_row + 1) - egg_in_row = eggs.index(egg) % eggs_per_row - eggs_after = min(len(eggs) - (current_row * eggs_per_row), eggs_per_row) - (egg_in_row + 1) - - x_offset = 32 - y_offset = 30 - - # The x coordinate of an egg is determined by which egg in the row it is, and how many eggs - # are in that row. If there is only 1 egg in a row, it is in the middle of the screen. If - # there are two, they're on equal halves and so on. - x = x_offset - (eggs_after * distance_between_eggs) + (egg_in_row * distance_between_eggs) - y = y_offset - (rows_after * distance_between_rows) + (current_row * distance_between_rows) - - egg.rect.x = x - egg.rect.y = y - - # Add the egg to the sprite list. - all_sprites.add(egg) - - def get_cursor_coords(selection): - """ - Gets the coordinates of an egg on the selection screen by index and returns it as a tuple - :param selection: index of the egg to be selected - :return: tuple of the coordinates of the selected egg - """ - cursor_x_offset = -2 - cursor_y_offset = -2 - - return eggs[selection].rect.x + cursor_x_offset, eggs[selection].rect.y + cursor_y_offset - - def sel_left(): - """ - Select the egg to the left with constraints. - """ - nonlocal selected - - if selected % eggs_per_row != 0: - selected -= 1 - - def sel_right(): - """ - Select the egg to the right with constraints. - """ - nonlocal selected - - row = selected // eggs_per_row - eggs_in_row = min(len(eggs) - (row * eggs_per_row), eggs_per_row) - - if selected % eggs_per_row != eggs_in_row - 1: - selected += 1 - - def sel_up(): - """ - Select the egg above with constraints. - """ - nonlocal selected - - if selected // eggs_per_row != 0: - selected -= eggs_per_row - - def sel_down(): - """ - Select the egg below with constraints. - """ - nonlocal selected - - if selected // eggs_per_row != total_rows - 1: - selected += eggs_per_row - - while running and game_state == 'egg_select' and submenu == 'main': - - pre_handler() - - for event in pygame.event.get(): - if event.type == pygame.KEYDOWN: - if event.key == Constants.buttons.get('j_r'): - sel_right() - if event.key == Constants.buttons.get('j_l'): - sel_left() - if event.key == Constants.buttons.get('j_d'): - sel_down() - if event.key == Constants.buttons.get('j_u'): - sel_up() - if event.key == Constants.buttons.get('a'): - # Advance to the egg info screen for the selected egg. - submenu = 'bloop_info' - - # Draws the cursor on screen. - cursor = pygame.image.load( - script_dir + '/resources/images/gui/egg_selector.png').convert_alpha() - surface.blit(cursor, get_cursor_coords(selected)) - - selected_color = eggs[selected].egg_color - - draw() - - elif submenu == 'bloop_info': - - # Draw the selected egg on screen - egg = SelectionEgg(selected_color) - egg.rect.x = 8 - egg.rect.y = 3 - all_sprites.add(egg) - - # Info screen for the eggs. - info_text = InfoText(small_font, egg.description) - info_icons = EggInfo(egg.contentedness, egg.metabolism, (32, 4)) - - while running and game_state == 'egg_select' and submenu == 'bloop_info': - - pre_handler() - - for event in pygame.event.get(): - if event.type == pygame.KEYDOWN: - if event.key == Constants.buttons.get('j_d'): - # Scroll down on the info screen. - info_text.scroll_down() - if event.key == Constants.buttons.get('j_u'): - # Scroll up on the info screen. - info_text.scroll_up() - if event.key == Constants.buttons.get('a'): - # Write save file with new attributes - data_handler.attributes['bloop'] = egg.egg_color - data_handler.attributes['health'] = 10 - data_handler.attributes['hunger'] = 10 - data_handler.attributes['happiness'] = 10 - data_handler.attributes['evolution_stage'] = 'egg' - data_handler.write_save() - - # Go to playground - game_state = 'playground' - if event.key == Constants.buttons.get('b'): - # Go back to the egg selection screen. - submenu = 'main' - - # Draw the info screen. - info_text.draw(surface) - info_icons.draw(surface) - - draw() - - else: # Go to the error state if an invalid state is set. - game_state = None - - else: - # Error screen. This appears when an invalid game state has been selected. - - all_sprites.empty() - frames_passed = 0 # Counter for frames, helps ensure the game isn't frozen. - - while running and game_state != 'title': - - pre_handler() - - # Draw the error screen - error_screen = pygame.image.load(script_dir + '/resources/images/debug/invalid.png').convert_alpha() - surface.blit(error_screen, (0, -8)) - - # Counts the frames passed. Resets every second. - frames_passed += 1 - if frames_passed >= game_fps: - frames_passed = 0 - - # Draws the frame counter. - frame_counter = small_font.render('frames: {0}'.format(frames_passed), False, (64, 64, 64)) - surface.blit(frame_counter, (1, game_res - 10)) - - for event in pygame.event.get(): - if event.type == pygame.KEYDOWN: - if event.key == Constants.buttons.get('b'): - # Reset back to the title screen. - game_state = 'title' - - draw() - - -def main(): - """ - Calls the game() function to start the game. - """ - game() - - GPIOHandler.teardown() - pygame.quit() From bbf549c0241fe58bd7b23ba3b19fb176acf7247b Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 14:08:22 -0400 Subject: [PATCH 17/58] moved around structure --- pocket_friends/development/button_test.py | 2 +- pocket_friends/development/dev_menu.py | 4 ++-- .../FakeGPIO.py => game_files/io_helpers/fake_gpio.py} | 0 .../{hardware => game_files/io_helpers}/gpio_handler.py | 2 +- pocket_friends/game_files/io_helpers/input_handler.py | 4 ++-- pocket_friends/game_files/surfaces/egg_select.py | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) rename pocket_friends/{development/FakeGPIO.py => game_files/io_helpers/fake_gpio.py} (100%) rename pocket_friends/{hardware => game_files/io_helpers}/gpio_handler.py (97%) diff --git a/pocket_friends/development/button_test.py b/pocket_friends/development/button_test.py index f9c7ee5..43d1cc1 100644 --- a/pocket_friends/development/button_test.py +++ b/pocket_friends/development/button_test.py @@ -2,7 +2,7 @@ Module to test the GPIO input on the Raspberry Pi. """ from collections import deque -from ..hardware.gpio_handler import Constants, GPIOHandler +from pocket_friends.game_files.io_helpers.gpio_handler import Constants, GPIOHandler def button_test(): diff --git a/pocket_friends/development/dev_menu.py b/pocket_friends/development/dev_menu.py index 24e2fe4..e390769 100644 --- a/pocket_friends/development/dev_menu.py +++ b/pocket_friends/development/dev_menu.py @@ -8,13 +8,13 @@ import pygame import time from .button_test import button_test from .menus import Menu -from ..hardware.gpio_handler import GPIOHandler, Constants +from pocket_friends.game_files.io_helpers.gpio_handler import GPIOHandler, Constants try: importlib.util.find_spec('RPi.GPIO') import RPi.GPIO as GPIO except ImportError: - import pocket_friends.development.FakeGPIO as GPIO + import pocket_friends.game_files.io_helpers.fake_gpio as GPIO # Global variable to keep track of the current menu. menu = 'main' diff --git a/pocket_friends/development/FakeGPIO.py b/pocket_friends/game_files/io_helpers/fake_gpio.py similarity index 100% rename from pocket_friends/development/FakeGPIO.py rename to pocket_friends/game_files/io_helpers/fake_gpio.py diff --git a/pocket_friends/hardware/gpio_handler.py b/pocket_friends/game_files/io_helpers/gpio_handler.py similarity index 97% rename from pocket_friends/hardware/gpio_handler.py rename to pocket_friends/game_files/io_helpers/gpio_handler.py index fd1ddd1..7e842c0 100644 --- a/pocket_friends/hardware/gpio_handler.py +++ b/pocket_friends/game_files/io_helpers/gpio_handler.py @@ -8,7 +8,7 @@ try: importlib.util.find_spec('RPi.GPIO') import RPi.GPIO as GPIO except ImportError: - import pocket_friends.development.FakeGPIO as GPIO + import pocket_friends.game_files.io_helpers.fake_gpio as GPIO class Constants: diff --git a/pocket_friends/game_files/io_helpers/input_handler.py b/pocket_friends/game_files/io_helpers/input_handler.py index 97afc25..4509c29 100644 --- a/pocket_friends/game_files/io_helpers/input_handler.py +++ b/pocket_friends/game_files/io_helpers/input_handler.py @@ -1,6 +1,6 @@ import pygame import importlib.util -from pocket_friends.hardware.gpio_handler import Constants, GPIOHandler +from pocket_friends.game_files.io_helpers.gpio_handler import Constants, GPIOHandler class InputHandler: @@ -11,7 +11,7 @@ class InputHandler: import RPi.GPIO as GPIO self.on_hardware = True except ImportError: - import pocket_friends.development.FakeGPIO as GPIO + import pocket_friends.game_files.io_helpers.fake_gpio as GPIO self.on_hardware = False self.last_input_tick = 0 diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py index 2fadf3f..8fde4ad 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -1,6 +1,6 @@ import pygame from . import sprites -from pocket_friends.hardware.gpio_handler import Constants +from pocket_friends.game_files.io_helpers.gpio_handler import Constants from ..io_helpers.input_handler import InputHandler From dd621dbe7a857fcfaec9d2deb78876fbedfdfe91 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 15:24:17 -0400 Subject: [PATCH 18/58] added info screen --- pocket_friends/game_files/game.py | 7 +- .../game_files/surfaces/egg_select.py | 27 ++- .../game_files/surfaces/selection_info.py | 60 +++++++ pocket_friends/game_files/surfaces/sprites.py | 162 ++++++++++++++++++ pocket_friends/game_files/surfaces/title.py | 1 + 5 files changed, 249 insertions(+), 8 deletions(-) create mode 100644 pocket_friends/game_files/surfaces/selection_info.py diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 22480c1..59c4099 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -6,7 +6,8 @@ import importlib valid_surfaces = [ 'title', - 'egg_select' + 'egg_select', + 'selection_info' ] surface_modules = {} @@ -62,9 +63,11 @@ def game(): if not surface.running: next_surface = surface.next_surface + additional_args = surface.additional_args if next_surface not in valid_surfaces: raise Exception('Given surface is not listed in valid surfaces!') - surface = surface_modules.get(next_surface).Surface((game_res, game_res), resources_dir, game_fps) + surface = surface_modules.get(next_surface).Surface((game_res, game_res), resources_dir, + game_fps, **additional_args) print(surface.name) pygame.display.flip() diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py index 8fde4ad..7b0576f 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -5,7 +5,7 @@ from ..io_helpers.input_handler import InputHandler class Surface(pygame.Surface): - def __init__(self, window_size, resources_dir, game_fps): + def __init__(self, window_size, resources_dir, game_fps, **kwargs): super().__init__(window_size, pygame.SRCALPHA) self.name = 'egg_select' self.running = True @@ -14,10 +14,16 @@ class Surface(pygame.Surface): self.clock = pygame.time.Clock() self.game_fps = game_fps self.input_handler = InputHandler(self.clock) + self.additional_args = {} self.bg = pygame.image.load(self.resource_dir + '/images/bg.png').convert_alpha() self.sprites = pygame.sprite.Group() + preselected_color = None + for key in kwargs.keys(): + if key == 'selected_egg': + preselected_color = kwargs.get(key) + egg_list = [ 'dev_egg', 'blue', @@ -58,6 +64,11 @@ class Surface(pygame.Surface): self.selected_egg = 0 self.selected_color = '' + if preselected_color is not None: + self.selected_color = self.eggs[self.selected_egg].egg_color + for i in range(len(self.eggs)): + if self.eggs[i].egg_color == preselected_color: + self.selected_egg = i def get_cursor_coords(self): """ @@ -114,6 +125,12 @@ class Surface(pygame.Surface): self.input_handler.update() + cursor = pygame.image.load( + self.resource_dir + '/images/gui/egg_selector.png').convert_alpha() + self.blit(cursor, self.get_cursor_coords()) + + self.selected_color = self.eggs[self.selected_egg].egg_color + for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == Constants.buttons.get('j_r'): @@ -125,8 +142,6 @@ class Surface(pygame.Surface): if event.key == Constants.buttons.get('j_u'): self.sel_up() if event.key == Constants.buttons.get('a'): - pass - - cursor = pygame.image.load( - self.resource_dir + '/images/gui/egg_selector.png').convert_alpha() - self.blit(cursor, self.get_cursor_coords()) + self.additional_args = {'selected_egg': self.selected_color} + self.next_surface = 'selection_info' + self.running = False diff --git a/pocket_friends/game_files/surfaces/selection_info.py b/pocket_friends/game_files/surfaces/selection_info.py new file mode 100644 index 0000000..e991276 --- /dev/null +++ b/pocket_friends/game_files/surfaces/selection_info.py @@ -0,0 +1,60 @@ +import pygame +from . import sprites +from pocket_friends.game_files.io_helpers.gpio_handler import Constants +from .sprites import SelectionEgg +from ..io_helpers.input_handler import InputHandler + + +class Surface(pygame.Surface): + def __init__(self, window_size, resources_dir, game_fps, **kwargs): + super().__init__(window_size, pygame.SRCALPHA) + self.name = 'selection_info' + self.running = True + self.next_surface = None + self.resource_dir = resources_dir + self.clock = pygame.time.Clock() + self.game_fps = game_fps + self.input_handler = InputHandler(self.clock) + self.additional_args = {} + + self.bg = pygame.image.load(self.resource_dir + '/images/bg.png').convert_alpha() + self.sprites = pygame.sprite.Group() + + self.selected_egg = None + for key in kwargs.keys(): + if key == 'selected_egg': + self.selected_egg = kwargs.get(key) + + egg = sprites.SelectionEgg(self.selected_egg, resources_dir) + egg.rect.x = 8 + egg.rect.y = 3 + self.sprites.add(egg) + + self.info_text = sprites.InfoText(resources_dir, window_size[0], egg.description) + self.info_icons = sprites.EggInfo(resources_dir, egg.contentedness, egg.metabolism, (32, 4)) + + def update(self): + self.clock.tick(self.game_fps) + + self.blit(self.bg, (0, 0)) + self.sprites.update() + self.sprites.draw(self) + self.info_text.draw(self) + self.info_icons.draw(self) + + self.input_handler.update() + + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + if event.key == Constants.buttons.get('j_d'): + # Scroll down on the info screen. + self.info_text.scroll_down() + if event.key == Constants.buttons.get('j_u'): + # Scroll up on the info screen. + self.info_text.scroll_up() + if event.key == Constants.buttons.get('a'): + pass + if event.key == Constants.buttons.get('b'): + self.running = False + self.additional_args = {'selected_color': self.selected_egg} + self.next_surface = 'egg_select' diff --git a/pocket_friends/game_files/surfaces/sprites.py b/pocket_friends/game_files/surfaces/sprites.py index d4f0f8d..0c1e8d8 100644 --- a/pocket_friends/game_files/surfaces/sprites.py +++ b/pocket_friends/game_files/surfaces/sprites.py @@ -82,3 +82,165 @@ class SelectionEgg(pygame.sprite.Sprite): # Animate the sprite self.index = (self.index + 1) % len(self.images) self.image = self.images[self.index] + + +class InfoText: + """ + Class for drawing large amounts of text on the screen at a time + """ + + def __init__(self, resources_dir, game_res, text='Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' + 'Nam commodo tempor aliquet. Suspendisse placerat accumsan' + ' neque, nec volutpat nunc porta ut.'): + + self.font = pygame.font.Font(resources_dir + '/fonts/5Pts5.ttf', 10) + self.text = [] # Text broken up into a list according to how it will fit on screen. + self.max_lines = 6 # Max number of lines to be shown on screen at a time. + self.offset = 0 + self.game_res = game_res + + # Arrow icons to indicate scrolling + self.up_arrow = pygame.image.load(resources_dir + '/images/gui/up_arrow.png').convert_alpha() + self.down_arrow = pygame.image.load(resources_dir + '/images/gui/down_arrow.png').convert_alpha() + + raw_text = text # Copy the text to a different variable to be cut up. + + margins = 4.5 + max_line_width = self.game_res - (margins * 2) # The maximum pixel width that drawn text can be. + cut_chars = '.,! ' # Characters that will be considered "cuts" aka when a line break can occur. + + # Prevents freezing if the end of the string does not end in a cut character + # Will fix eventually more elegantly + if raw_text[-1:] not in cut_chars: + raw_text += ' ' + + # Calculating line breaks. + while len(raw_text) > 0: + index = 0 + test_text = '' # Chunk of text to pseudo-render and test the width of. + + # Loops until the testing text has reached the size limit. + while True: + + # Break if the current index is larger than the remaining text. + if index + 1 > len(raw_text): + index -= 1 + break + + # Add one character to the testing text from the raw text. + test_text += raw_text[index] + # Get the width of the pseudo-rendered text. + text_width = self.font.size(test_text)[0] + + # Break if the text is larger than the defined max width. + if text_width > max_line_width: + break + index += 1 + pass + + # Gets the chunk of text to be added to the list. + text_chunk = raw_text[0:index + 1] + # Determines if the chunk of text has any break characters. + has_breaks = any(cut_chars in text_chunk for cut_chars in cut_chars) + + # If the text has break characters, start with the last character and go backwards until + # one has been found, decreasing the index each time. + if has_breaks: + while raw_text[index] not in cut_chars: + index -= 1 + text_chunk = raw_text[0:index + 1] + # If there are no break characters in the chunk, simply decrease the index by one and insert + # a dash at the end of the line to indicate the word continues. + else: + index -= 1 + text_chunk = raw_text[0:index + 1] + text_chunk += '-' + + # Append the text chunk to the list of text to draw. + self.text.append(text_chunk) + + # Cut the text to repeat the process with the new cut string. + raw_text = raw_text[index + 1:] + + def draw(self, surface): + """ + Draws the text on a given surface. + :param surface: The surface for the text to be drawn on. + """ + # Constants to help draw the text + line_separation = 7 + left_margin = 3 + top_margin = 25 + bottom_margin = 10 + + # Draw the lines on the screen + for i in range(min(len(self.text), self.max_lines)): + text = self.font.render(self.text[i + self.offset], False, (64, 64, 64)) + surface.blit(text, (left_margin, top_margin + (i * line_separation))) + + # Draw the arrows if there is more text than is on screen. + if self.offset != 0: + surface.blit(self.up_arrow, ((self.game_res / 2) - (self.up_arrow.get_rect().width / 2), top_margin - 3)) + if len(self.text) - (self.offset + 1) >= self.max_lines: + surface.blit(self.down_arrow, + ((self.game_res / 2) - (self.down_arrow.get_rect().width / 2), self.game_res - bottom_margin)) + + def scroll_down(self): + """ + Scrolls the text on the screen down. + """ + # Ensures that the offset cannot be too big as to try to render non-existent lines. + if len(self.text) - (self.offset + 1) >= self.max_lines: + self.offset += 1 + + def scroll_up(self): + """ + Scrolls the text on the screen up. + """ + if self.offset > 0: # Ensures a non-zero offset is not possible. + self.offset -= 1 + + +class EggInfo: + """ + Class to draw the contentedness and metabolism value off the egg on the info screen. + """ + + def __init__(self, resources_dir, contentedness, metabolism, location): + self.contentedness = contentedness + self.metabolism = metabolism + self.x = location[0] + self.y = location[1] + + # Create a new surface to blit onto the other surface + self.surface = pygame.Surface((44, 15), pygame.SRCALPHA) + + # Blit the two indicator icons on screen + smiley = pygame.image.load(resources_dir + '/images/gui/smiley.png').convert_alpha() + self.surface.blit(smiley, (0, 0)) + apple = pygame.image.load(resources_dir + '/images/gui/apple.png').convert_alpha() + self.surface.blit(apple, (1, 9)) + + # Draw 5 stars. If the value of the contentedness is less than the current star, make it a blank star. + for i in range(5): + if i < self.contentedness: + star = pygame.image.load(resources_dir + '/images/gui/star.png').convert_alpha() + else: + star = pygame.image.load(resources_dir + '/images/gui/blank_star.png').convert_alpha() + self.surface.blit(star, (11 + (i * 6), 1)) + + # Draw 5 stars. If the value of the metabolism is less than the current star, make it a blank star. + for i in range(5): + if i < self.metabolism: + star = pygame.image.load(resources_dir + '/images/gui/star.png').convert_alpha() + else: + star = pygame.image.load(resources_dir + '/images/gui/blank_star.png').convert_alpha() + self.surface.blit(star, (11 + (i * 6), 10)) + + def draw(self, surface): + """ + Draw the info icons on a given surface. + :param surface: the surface to draw the icons on. + """ + # Blit the info onto the given surface. + surface.blit(self.surface, (self.x, self.y)) diff --git a/pocket_friends/game_files/surfaces/title.py b/pocket_friends/game_files/surfaces/title.py index dbc810a..ed580cd 100644 --- a/pocket_friends/game_files/surfaces/title.py +++ b/pocket_friends/game_files/surfaces/title.py @@ -9,6 +9,7 @@ class Surface(pygame.Surface): self.running = True self.next_surface = None self.clock = pygame.time.Clock() + self.additional_args = {} self.bg = pygame.image.load(resources_dir + '/images/bg.png').convert_alpha() self.title = pygame.image.load(resources_dir + '/images/title.png').convert_alpha() From bba0af49467f649fb722a42bcb789f5b18d7e9bf Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 15:25:22 -0400 Subject: [PATCH 19/58] fixed selector not going back to previous color --- pocket_friends/game_files/surfaces/egg_select.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py index 7b0576f..4ae0f98 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -21,7 +21,7 @@ class Surface(pygame.Surface): preselected_color = None for key in kwargs.keys(): - if key == 'selected_egg': + if key == 'selected_color': preselected_color = kwargs.get(key) egg_list = [ From 07aae2b0756f8d1e42a1143dc6deb05cf59434f9 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 15:26:08 -0400 Subject: [PATCH 20/58] deleted unused folder --- pocket_friends/hardware/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 pocket_friends/hardware/__init__.py diff --git a/pocket_friends/hardware/__init__.py b/pocket_friends/hardware/__init__.py deleted file mode 100644 index e69de29..0000000 From adfece1a32a7bdeea3b1f26f6343d74747b0e9ef Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 15:28:11 -0400 Subject: [PATCH 21/58] fixed doc error --- pocket_friends/game_files/io_helpers/fake_gpio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocket_friends/game_files/io_helpers/fake_gpio.py b/pocket_friends/game_files/io_helpers/fake_gpio.py index 23a82c6..2122fc2 100644 --- a/pocket_friends/game_files/io_helpers/fake_gpio.py +++ b/pocket_friends/game_files/io_helpers/fake_gpio.py @@ -1,6 +1,6 @@ """ Module used to fake the RPi.GPIO module so that -the hardware can be run without the actual hardware. +the program can be run without the actual hardware. """ # Constants used by RPi.GPIO From eff7f2c893a70bd13c7a73a40edfef48485ca70a Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 15:28:21 -0400 Subject: [PATCH 22/58] reformatted file --- pocket_friends/game_files/io_helpers/data_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocket_friends/game_files/io_helpers/data_handler.py b/pocket_friends/game_files/io_helpers/data_handler.py index 64e0bb1..47fbdab 100644 --- a/pocket_friends/game_files/io_helpers/data_handler.py +++ b/pocket_friends/game_files/io_helpers/data_handler.py @@ -1,6 +1,7 @@ import pocket_friends import json + class DataHandler: """ Class that handles the hardware attributes and save files. @@ -64,4 +65,3 @@ class DataHandler: # Reset frame counter self.frames_passed = 0 - From a8674f073e3f60b0ad032ad46141c378938b8a43 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 15:31:36 -0400 Subject: [PATCH 23/58] added documentation to input_handler.py --- pocket_friends/game_files/io_helpers/input_handler.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pocket_friends/game_files/io_helpers/input_handler.py b/pocket_friends/game_files/io_helpers/input_handler.py index 4509c29..3a45db7 100644 --- a/pocket_friends/game_files/io_helpers/input_handler.py +++ b/pocket_friends/game_files/io_helpers/input_handler.py @@ -4,8 +4,15 @@ from pocket_friends.game_files.io_helpers.gpio_handler import Constants, GPIOHan class InputHandler: + """ + Class that is implemented into surfaces in order to control the + pressing of buttons on both the real hardware and on a keyboard. + """ + def __init__(self, pygame_clock): self.clock = pygame_clock + + # If not on actual hardware, fake the GPIO in order to get it working correctly. try: importlib.util.find_spec('RPi.GPIO') import RPi.GPIO as GPIO @@ -13,6 +20,7 @@ class InputHandler: except ImportError: import pocket_friends.game_files.io_helpers.fake_gpio as GPIO self.on_hardware = False + self.last_input_tick = 0 def create_event(self, pressed_button): @@ -65,6 +73,9 @@ class InputHandler: running = False def update(self): + """ + Run the input handler and check for inputs. + """ if self.on_hardware: self.handle_gpio() else: From 327f6cadee079e63e747ed28cfe0540749641b7f Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 17:59:06 -0400 Subject: [PATCH 24/58] restructured directories to make more sense of modules and sub-modules --- pocket_friends/__init__.py | 3 + pocket_friends/__main__.py | 13 +--- pocket_friends/development/button_test.py | 2 +- pocket_friends/development/dev_menu.py | 4 +- pocket_friends/game_files/__init__.py | 0 pocket_friends/game_files/io/__init__.py | 2 + .../{io_helpers => io}/data_handler.py | 0 .../{io_helpers => io}/fake_gpio.py | 0 pocket_friends/game_files/io/gpio_handler.py | 62 +++++++++++++++ .../{io_helpers => io}/input_handler.py | 24 +++--- .../game_files/io_helpers/__init__.py | 0 .../game_files/io_helpers/gpio_handler.py | 71 ------------------ .../resources/data/bloop_info/blue.json | 0 .../resources/data/bloop_info/dev_egg.json | 0 .../resources/data/bloop_info/rainbow.json | 0 .../resources/data/bloop_info/red.json | 0 .../{surfaces => }/resources/fonts/5Pts5.ttf | Bin .../game_files/{ => resources}/icon/icon.ico | Bin .../game_files/{ => resources}/icon/icon.png | Bin .../{surfaces => }/resources/images/bg.png | Bin .../images/bloops/_postponed/green/green.png | Bin .../bloops/_postponed/indigo/indigo.png | Bin .../bloops/_postponed/orange/orange.png | Bin .../bloops/_postponed/violet/violet.png | Bin .../images/bloops/_postponed/white/white.png | Bin .../bloops/_postponed/yellow/yellow.png | Bin .../resources/images/bloops/blue/egg.json | 0 .../resources/images/bloops/blue/egg.png | Bin .../resources/images/bloops/dev_egg/baby.json | 0 .../resources/images/bloops/dev_egg/baby.png | Bin .../resources/images/bloops/dev_egg/egg.json | 0 .../resources/images/bloops/dev_egg/egg.png | Bin .../resources/images/bloops/rainbow/egg.json | 0 .../resources/images/bloops/rainbow/egg.png | Bin .../resources/images/bloops/red/egg.json | 0 .../resources/images/bloops/red/egg.png | Bin .../resources/images/debug/invalid.png | Bin .../resources/images/gui/apple.png | Bin .../resources/images/gui/bar_graphic.png | Bin .../resources/images/gui/bar_outline.png | Bin .../resources/images/gui/blank_star.png | Bin .../resources/images/gui/down_arrow.png | Bin .../resources/images/gui/egg_selector.png | Bin .../images/gui/popup_menu/apple.json | 0 .../resources/images/gui/popup_menu/apple.png | Bin .../resources/images/gui/popup_menu/bed.json | 0 .../resources/images/gui/popup_menu/bed.png | Bin .../images/gui/popup_menu/controller.json | 0 .../images/gui/popup_menu/controller.png | Bin .../images/gui/popup_menu/dumbbell.json | 0 .../images/gui/popup_menu/dumbbell.png | Bin .../resources/images/gui/popup_menu/frame.png | Bin .../images/gui/popup_menu/stats.json | 0 .../resources/images/gui/popup_menu/stats.png | Bin .../resources/images/gui/smiley.png | Bin .../resources/images/gui/star.png | Bin .../resources/images/gui/up_arrow.png | Bin .../resources/images/promotional.png | Bin .../{surfaces => }/resources/images/title.png | Bin .../game_files/surfaces/egg_select.py | 14 ++-- .../game_files/surfaces/selection_info.py | 12 +-- 61 files changed, 97 insertions(+), 110 deletions(-) delete mode 100644 pocket_friends/game_files/__init__.py create mode 100644 pocket_friends/game_files/io/__init__.py rename pocket_friends/game_files/{io_helpers => io}/data_handler.py (100%) rename pocket_friends/game_files/{io_helpers => io}/fake_gpio.py (100%) create mode 100644 pocket_friends/game_files/io/gpio_handler.py rename pocket_friends/game_files/{io_helpers => io}/input_handler.py (77%) delete mode 100644 pocket_friends/game_files/io_helpers/__init__.py delete mode 100644 pocket_friends/game_files/io_helpers/gpio_handler.py rename pocket_friends/game_files/{surfaces => }/resources/data/bloop_info/blue.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/data/bloop_info/dev_egg.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/data/bloop_info/rainbow.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/data/bloop_info/red.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/fonts/5Pts5.ttf (100%) rename pocket_friends/game_files/{ => resources}/icon/icon.ico (100%) rename pocket_friends/game_files/{ => resources}/icon/icon.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bg.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/_postponed/green/green.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/_postponed/indigo/indigo.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/_postponed/orange/orange.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/_postponed/violet/violet.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/_postponed/white/white.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/_postponed/yellow/yellow.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/blue/egg.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/blue/egg.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/dev_egg/baby.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/dev_egg/baby.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/dev_egg/egg.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/dev_egg/egg.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/rainbow/egg.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/rainbow/egg.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/red/egg.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/bloops/red/egg.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/debug/invalid.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/apple.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/bar_graphic.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/bar_outline.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/blank_star.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/down_arrow.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/egg_selector.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/apple.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/apple.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/bed.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/bed.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/controller.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/controller.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/dumbbell.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/dumbbell.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/frame.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/stats.json (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/popup_menu/stats.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/smiley.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/star.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/gui/up_arrow.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/promotional.png (100%) rename pocket_friends/game_files/{surfaces => }/resources/images/title.png (100%) diff --git a/pocket_friends/__init__.py b/pocket_friends/__init__.py index c8ad717..e5a9890 100644 --- a/pocket_friends/__init__.py +++ b/pocket_friends/__init__.py @@ -1 +1,4 @@ +"""Pocket Friends is a game where you raise your own little pocket friend! These pocket friends, called bloops, +are great little companions to have! You can feed them, play with them, and watch them grow up!""" + __version__ = 'dev_0.0.3' diff --git a/pocket_friends/__main__.py b/pocket_friends/__main__.py index c7ec3f8..298fb5f 100644 --- a/pocket_friends/__main__.py +++ b/pocket_friends/__main__.py @@ -5,8 +5,7 @@ import os import pygame import sys from pathlib import Path -from pocket_friends.game_files.game import main as game_main -#from pocket_friends.development.dev_menu import main as dev_menu_main +import pocket_friends.game_files.game as game if __name__ == '__main__': enable_dev = False @@ -14,19 +13,11 @@ if __name__ == '__main__': # enable dev mode if --dev argument is passed if len(sys.argv) > 0: for args in sys.argv: - #if args == '--dev': [reimplement later] - # enable_dev = True if args == '--delete-save': save_dir = os.path.join(Path.home(), '.pocket_friends') os.remove(save_dir + '/save.json') - # Dev menu disabled for now, will reimplement later - #if not enable_dev: - # game_main() - #else: - # dev_menu_main() - - game_main() + game.main() pygame.quit() sys.exit() diff --git a/pocket_friends/development/button_test.py b/pocket_friends/development/button_test.py index 43d1cc1..df5353c 100644 --- a/pocket_friends/development/button_test.py +++ b/pocket_friends/development/button_test.py @@ -2,7 +2,7 @@ Module to test the GPIO input on the Raspberry Pi. """ from collections import deque -from pocket_friends.game_files.io_helpers.gpio_handler import Constants, GPIOHandler +from pocket_friends.game_files.io.gpio_handler import Constants, GPIOHandler def button_test(): diff --git a/pocket_friends/development/dev_menu.py b/pocket_friends/development/dev_menu.py index e390769..9dead9b 100644 --- a/pocket_friends/development/dev_menu.py +++ b/pocket_friends/development/dev_menu.py @@ -8,13 +8,13 @@ import pygame import time from .button_test import button_test from .menus import Menu -from pocket_friends.game_files.io_helpers.gpio_handler import GPIOHandler, Constants +from pocket_friends.game_files.io.gpio_handler import GPIOHandler, Constants try: importlib.util.find_spec('RPi.GPIO') import RPi.GPIO as GPIO except ImportError: - import pocket_friends.game_files.io_helpers.fake_gpio as GPIO + import pocket_friends.game_files.io.fake_gpio as GPIO # Global variable to keep track of the current menu. menu = 'main' diff --git a/pocket_friends/game_files/__init__.py b/pocket_friends/game_files/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pocket_friends/game_files/io/__init__.py b/pocket_friends/game_files/io/__init__.py new file mode 100644 index 0000000..d266b0e --- /dev/null +++ b/pocket_friends/game_files/io/__init__.py @@ -0,0 +1,2 @@ +"""Sub-package for handling all I/O operations including keyboard input (GPIO input when connected to a Raspberry Pi) +and save data reading and writing.""" \ No newline at end of file diff --git a/pocket_friends/game_files/io_helpers/data_handler.py b/pocket_friends/game_files/io/data_handler.py similarity index 100% rename from pocket_friends/game_files/io_helpers/data_handler.py rename to pocket_friends/game_files/io/data_handler.py diff --git a/pocket_friends/game_files/io_helpers/fake_gpio.py b/pocket_friends/game_files/io/fake_gpio.py similarity index 100% rename from pocket_friends/game_files/io_helpers/fake_gpio.py rename to pocket_friends/game_files/io/fake_gpio.py diff --git a/pocket_friends/game_files/io/gpio_handler.py b/pocket_friends/game_files/io/gpio_handler.py new file mode 100644 index 0000000..01e3423 --- /dev/null +++ b/pocket_friends/game_files/io/gpio_handler.py @@ -0,0 +1,62 @@ +""" +Handle inputs from the GPIO pins on the Raspberry Pi and converting them to events to be used in other places (pygame, etc.) +""" +import importlib.util + +# If the RPi.GPIO module is not found (aka the program is not running on a Pi), import the fake +# GPIO module instead to prevent a crash. +try: + importlib.util.find_spec('RPi.GPIO') + import RPi.GPIO as GPIO +except ImportError: + import pocket_friends.game_files.io.fake_gpio as GPIO + +# Dictionary of all the buttons used and what their corresponding GPIO codes are +BUTTONS = { + 'a': 31, # A button + 'b': 29, # B button + 'j_i': 7, # Joystick in + 'j_u': 11, # Joystick up + 'j_d': 15, # Joystick down + 'j_l': 13, # Joystick left + 'j_r': 16 # Joystick right +} + + +def setup(): + """ + Primes the GPIO pins for reading the inputs of the buttons. + """ + GPIO.setmode(GPIO.BOARD) + + GPIO.setup(BUTTONS.get('a'), GPIO.IN) + GPIO.setup(BUTTONS.get('b'), GPIO.IN) + GPIO.setup(BUTTONS.get('j_i'), GPIO.IN) + GPIO.setup(BUTTONS.get('j_u'), GPIO.IN) + GPIO.setup(BUTTONS.get('j_d'), GPIO.IN) + GPIO.setup(BUTTONS.get('j_l'), GPIO.IN) + GPIO.setup(BUTTONS.get('j_r'), GPIO.IN) + + GPIO.add_event_detect(BUTTONS.get('a'), GPIO.FALLING) + GPIO.add_event_detect(BUTTONS.get('b'), GPIO.FALLING) + GPIO.add_event_detect(BUTTONS.get('j_i'), GPIO.FALLING) + GPIO.add_event_detect(BUTTONS.get('j_u'), GPIO.FALLING) + GPIO.add_event_detect(BUTTONS.get('j_d'), GPIO.FALLING) + GPIO.add_event_detect(BUTTONS.get('j_l'), GPIO.FALLING) + GPIO.add_event_detect(BUTTONS.get('j_r'), GPIO.FALLING) + + +def teardown(): + """ + Cleans up the GPIO handler. + """ + GPIO.cleanup() + + +def get_press(button): + """ + Returns true if a button has changed from not pressed to pressed. + :param button: button to be detected + :return: True if the button is has been pressed, False otherwise + """ + return GPIO.event_detected(button) diff --git a/pocket_friends/game_files/io_helpers/input_handler.py b/pocket_friends/game_files/io/input_handler.py similarity index 77% rename from pocket_friends/game_files/io_helpers/input_handler.py rename to pocket_friends/game_files/io/input_handler.py index 3a45db7..5df6cd4 100644 --- a/pocket_friends/game_files/io_helpers/input_handler.py +++ b/pocket_friends/game_files/io/input_handler.py @@ -1,6 +1,6 @@ import pygame import importlib.util -from pocket_friends.game_files.io_helpers.gpio_handler import Constants, GPIOHandler +import pocket_friends.game_files.io.gpio_handler as gpio_handler class InputHandler: @@ -18,7 +18,7 @@ class InputHandler: import RPi.GPIO as GPIO self.on_hardware = True except ImportError: - import pocket_friends.game_files.io_helpers.fake_gpio as GPIO + import pocket_friends.game_files.io.fake_gpio as GPIO self.on_hardware = False self.last_input_tick = 0 @@ -38,11 +38,11 @@ class InputHandler: """ Handles getting GPIO button presses and making a pygame event when a press is detected. """ - for pressed_button in Constants.buttons: - code = Constants.buttons.get(pressed_button) + for pressed_button in gpio_handler.BUTTONS: + code = gpio_handler.BUTTONS.get(pressed_button) # Check if a button has been pressed. If it has, create a pygame event for it. - if GPIOHandler.get_press(code): + if gpio_handler.get_press(code): self.create_event(code) def keyboard_handler(self): @@ -56,19 +56,19 @@ class InputHandler: running = False if keyboard_event.type == pygame.KEYDOWN: if keyboard_event.key == pygame.K_a: - self.create_event(Constants.buttons.get('a')) + self.create_event(gpio_handler.BUTTONS.get('a')) if keyboard_event.key == pygame.K_b: - self.create_event(Constants.buttons.get('b')) + self.create_event(gpio_handler.BUTTONS.get('b')) if keyboard_event.key == pygame.K_PERIOD: - self.create_event(Constants.buttons.get('j_i')) + self.create_event(gpio_handler.BUTTONS.get('j_i')) if keyboard_event.key == pygame.K_RIGHT: - self.create_event(Constants.buttons.get('j_r')) + self.create_event(gpio_handler.BUTTONS.get('j_r')) if keyboard_event.key == pygame.K_LEFT: - self.create_event(Constants.buttons.get('j_l')) + self.create_event(gpio_handler.BUTTONS.get('j_l')) if keyboard_event.key == pygame.K_DOWN: - self.create_event(Constants.buttons.get('j_d')) + self.create_event(gpio_handler.BUTTONS.get('j_d')) if keyboard_event.key == pygame.K_UP: - self.create_event(Constants.buttons.get('j_u')) + self.create_event(gpio_handler.BUTTONS.get('j_u')) if keyboard_event.key == pygame.K_ESCAPE: running = False diff --git a/pocket_friends/game_files/io_helpers/__init__.py b/pocket_friends/game_files/io_helpers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pocket_friends/game_files/io_helpers/gpio_handler.py b/pocket_friends/game_files/io_helpers/gpio_handler.py deleted file mode 100644 index 7e842c0..0000000 --- a/pocket_friends/game_files/io_helpers/gpio_handler.py +++ /dev/null @@ -1,71 +0,0 @@ -""" -Module that helps with the handling of taking inputs from the GPIO pins on the Raspberry -Pi and converting them to events to be used in other places (pygame, etc.) -""" -import importlib.util - -try: - importlib.util.find_spec('RPi.GPIO') - import RPi.GPIO as GPIO -except ImportError: - import pocket_friends.game_files.io_helpers.fake_gpio as GPIO - - -class Constants: - """ - Contains the constants used by the HAT to read in buttons - """ - buttons = { - 'a': 31, # A button - 'b': 29, # B button - 'j_i': 7, # Joystick in - 'j_u': 11, # Joystick up - 'j_d': 15, # Joystick down - 'j_l': 13, # Joystick left - 'j_r': 16 # Joystick right - } - - -class GPIOHandler: - """ - Class to handle the GPIO inputs from the buttons. - """ - - @staticmethod - def setup(): - """ - Primes the GPIO pins for reading the inputs of the buttons. - """ - GPIO.setmode(GPIO.BOARD) - - GPIO.setup(Constants.buttons.get('a'), GPIO.IN) - GPIO.setup(Constants.buttons.get('b'), GPIO.IN) - GPIO.setup(Constants.buttons.get('j_i'), GPIO.IN) - GPIO.setup(Constants.buttons.get('j_u'), GPIO.IN) - GPIO.setup(Constants.buttons.get('j_d'), GPIO.IN) - GPIO.setup(Constants.buttons.get('j_l'), GPIO.IN) - GPIO.setup(Constants.buttons.get('j_r'), GPIO.IN) - - GPIO.add_event_detect(Constants.buttons.get('a'), GPIO.FALLING) - GPIO.add_event_detect(Constants.buttons.get('b'), GPIO.FALLING) - GPIO.add_event_detect(Constants.buttons.get('j_i'), GPIO.FALLING) - GPIO.add_event_detect(Constants.buttons.get('j_u'), GPIO.FALLING) - GPIO.add_event_detect(Constants.buttons.get('j_d'), GPIO.FALLING) - GPIO.add_event_detect(Constants.buttons.get('j_l'), GPIO.FALLING) - GPIO.add_event_detect(Constants.buttons.get('j_r'), GPIO.FALLING) - - @staticmethod - def teardown(): - """ - Cleans up the GPIO handler. - """ - GPIO.cleanup() - - @staticmethod - def get_press(button): - """ - Returns true if a button has moved from not pressed to pressed. - :param button: button to be detected - :return: True if the button is has been pressed, False otherwise - """ - return GPIO.event_detected(button) \ No newline at end of file diff --git a/pocket_friends/game_files/surfaces/resources/data/bloop_info/blue.json b/pocket_friends/game_files/resources/data/bloop_info/blue.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/data/bloop_info/blue.json rename to pocket_friends/game_files/resources/data/bloop_info/blue.json diff --git a/pocket_friends/game_files/surfaces/resources/data/bloop_info/dev_egg.json b/pocket_friends/game_files/resources/data/bloop_info/dev_egg.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/data/bloop_info/dev_egg.json rename to pocket_friends/game_files/resources/data/bloop_info/dev_egg.json diff --git a/pocket_friends/game_files/surfaces/resources/data/bloop_info/rainbow.json b/pocket_friends/game_files/resources/data/bloop_info/rainbow.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/data/bloop_info/rainbow.json rename to pocket_friends/game_files/resources/data/bloop_info/rainbow.json diff --git a/pocket_friends/game_files/surfaces/resources/data/bloop_info/red.json b/pocket_friends/game_files/resources/data/bloop_info/red.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/data/bloop_info/red.json rename to pocket_friends/game_files/resources/data/bloop_info/red.json diff --git a/pocket_friends/game_files/surfaces/resources/fonts/5Pts5.ttf b/pocket_friends/game_files/resources/fonts/5Pts5.ttf similarity index 100% rename from pocket_friends/game_files/surfaces/resources/fonts/5Pts5.ttf rename to pocket_friends/game_files/resources/fonts/5Pts5.ttf diff --git a/pocket_friends/game_files/icon/icon.ico b/pocket_friends/game_files/resources/icon/icon.ico similarity index 100% rename from pocket_friends/game_files/icon/icon.ico rename to pocket_friends/game_files/resources/icon/icon.ico diff --git a/pocket_friends/game_files/icon/icon.png b/pocket_friends/game_files/resources/icon/icon.png similarity index 100% rename from pocket_friends/game_files/icon/icon.png rename to pocket_friends/game_files/resources/icon/icon.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bg.png b/pocket_friends/game_files/resources/images/bg.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bg.png rename to pocket_friends/game_files/resources/images/bg.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/green/green.png b/pocket_friends/game_files/resources/images/bloops/_postponed/green/green.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/green/green.png rename to pocket_friends/game_files/resources/images/bloops/_postponed/green/green.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/indigo/indigo.png b/pocket_friends/game_files/resources/images/bloops/_postponed/indigo/indigo.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/indigo/indigo.png rename to pocket_friends/game_files/resources/images/bloops/_postponed/indigo/indigo.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/orange/orange.png b/pocket_friends/game_files/resources/images/bloops/_postponed/orange/orange.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/orange/orange.png rename to pocket_friends/game_files/resources/images/bloops/_postponed/orange/orange.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/violet/violet.png b/pocket_friends/game_files/resources/images/bloops/_postponed/violet/violet.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/violet/violet.png rename to pocket_friends/game_files/resources/images/bloops/_postponed/violet/violet.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/white/white.png b/pocket_friends/game_files/resources/images/bloops/_postponed/white/white.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/white/white.png rename to pocket_friends/game_files/resources/images/bloops/_postponed/white/white.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/yellow/yellow.png b/pocket_friends/game_files/resources/images/bloops/_postponed/yellow/yellow.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/_postponed/yellow/yellow.png rename to pocket_friends/game_files/resources/images/bloops/_postponed/yellow/yellow.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/blue/egg.json b/pocket_friends/game_files/resources/images/bloops/blue/egg.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/blue/egg.json rename to pocket_friends/game_files/resources/images/bloops/blue/egg.json diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/blue/egg.png b/pocket_friends/game_files/resources/images/bloops/blue/egg.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/blue/egg.png rename to pocket_friends/game_files/resources/images/bloops/blue/egg.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/baby.json b/pocket_friends/game_files/resources/images/bloops/dev_egg/baby.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/baby.json rename to pocket_friends/game_files/resources/images/bloops/dev_egg/baby.json diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/baby.png b/pocket_friends/game_files/resources/images/bloops/dev_egg/baby.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/baby.png rename to pocket_friends/game_files/resources/images/bloops/dev_egg/baby.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/egg.json b/pocket_friends/game_files/resources/images/bloops/dev_egg/egg.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/egg.json rename to pocket_friends/game_files/resources/images/bloops/dev_egg/egg.json diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/egg.png b/pocket_friends/game_files/resources/images/bloops/dev_egg/egg.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/dev_egg/egg.png rename to pocket_friends/game_files/resources/images/bloops/dev_egg/egg.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/rainbow/egg.json b/pocket_friends/game_files/resources/images/bloops/rainbow/egg.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/rainbow/egg.json rename to pocket_friends/game_files/resources/images/bloops/rainbow/egg.json diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/rainbow/egg.png b/pocket_friends/game_files/resources/images/bloops/rainbow/egg.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/rainbow/egg.png rename to pocket_friends/game_files/resources/images/bloops/rainbow/egg.png diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/red/egg.json b/pocket_friends/game_files/resources/images/bloops/red/egg.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/red/egg.json rename to pocket_friends/game_files/resources/images/bloops/red/egg.json diff --git a/pocket_friends/game_files/surfaces/resources/images/bloops/red/egg.png b/pocket_friends/game_files/resources/images/bloops/red/egg.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/bloops/red/egg.png rename to pocket_friends/game_files/resources/images/bloops/red/egg.png diff --git a/pocket_friends/game_files/surfaces/resources/images/debug/invalid.png b/pocket_friends/game_files/resources/images/debug/invalid.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/debug/invalid.png rename to pocket_friends/game_files/resources/images/debug/invalid.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/apple.png b/pocket_friends/game_files/resources/images/gui/apple.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/apple.png rename to pocket_friends/game_files/resources/images/gui/apple.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/bar_graphic.png b/pocket_friends/game_files/resources/images/gui/bar_graphic.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/bar_graphic.png rename to pocket_friends/game_files/resources/images/gui/bar_graphic.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/bar_outline.png b/pocket_friends/game_files/resources/images/gui/bar_outline.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/bar_outline.png rename to pocket_friends/game_files/resources/images/gui/bar_outline.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/blank_star.png b/pocket_friends/game_files/resources/images/gui/blank_star.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/blank_star.png rename to pocket_friends/game_files/resources/images/gui/blank_star.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/down_arrow.png b/pocket_friends/game_files/resources/images/gui/down_arrow.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/down_arrow.png rename to pocket_friends/game_files/resources/images/gui/down_arrow.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/egg_selector.png b/pocket_friends/game_files/resources/images/gui/egg_selector.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/egg_selector.png rename to pocket_friends/game_files/resources/images/gui/egg_selector.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/apple.json b/pocket_friends/game_files/resources/images/gui/popup_menu/apple.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/apple.json rename to pocket_friends/game_files/resources/images/gui/popup_menu/apple.json diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/apple.png b/pocket_friends/game_files/resources/images/gui/popup_menu/apple.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/apple.png rename to pocket_friends/game_files/resources/images/gui/popup_menu/apple.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/bed.json b/pocket_friends/game_files/resources/images/gui/popup_menu/bed.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/bed.json rename to pocket_friends/game_files/resources/images/gui/popup_menu/bed.json diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/bed.png b/pocket_friends/game_files/resources/images/gui/popup_menu/bed.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/bed.png rename to pocket_friends/game_files/resources/images/gui/popup_menu/bed.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/controller.json b/pocket_friends/game_files/resources/images/gui/popup_menu/controller.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/controller.json rename to pocket_friends/game_files/resources/images/gui/popup_menu/controller.json diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/controller.png b/pocket_friends/game_files/resources/images/gui/popup_menu/controller.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/controller.png rename to pocket_friends/game_files/resources/images/gui/popup_menu/controller.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/dumbbell.json b/pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/dumbbell.json rename to pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.json diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/dumbbell.png b/pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/dumbbell.png rename to pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/frame.png b/pocket_friends/game_files/resources/images/gui/popup_menu/frame.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/frame.png rename to pocket_friends/game_files/resources/images/gui/popup_menu/frame.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/stats.json b/pocket_friends/game_files/resources/images/gui/popup_menu/stats.json similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/stats.json rename to pocket_friends/game_files/resources/images/gui/popup_menu/stats.json diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/stats.png b/pocket_friends/game_files/resources/images/gui/popup_menu/stats.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/popup_menu/stats.png rename to pocket_friends/game_files/resources/images/gui/popup_menu/stats.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/smiley.png b/pocket_friends/game_files/resources/images/gui/smiley.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/smiley.png rename to pocket_friends/game_files/resources/images/gui/smiley.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/star.png b/pocket_friends/game_files/resources/images/gui/star.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/star.png rename to pocket_friends/game_files/resources/images/gui/star.png diff --git a/pocket_friends/game_files/surfaces/resources/images/gui/up_arrow.png b/pocket_friends/game_files/resources/images/gui/up_arrow.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/gui/up_arrow.png rename to pocket_friends/game_files/resources/images/gui/up_arrow.png diff --git a/pocket_friends/game_files/surfaces/resources/images/promotional.png b/pocket_friends/game_files/resources/images/promotional.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/promotional.png rename to pocket_friends/game_files/resources/images/promotional.png diff --git a/pocket_friends/game_files/surfaces/resources/images/title.png b/pocket_friends/game_files/resources/images/title.png similarity index 100% rename from pocket_friends/game_files/surfaces/resources/images/title.png rename to pocket_friends/game_files/resources/images/title.png diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py index 4ae0f98..7a97d90 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -1,7 +1,7 @@ import pygame from . import sprites -from pocket_friends.game_files.io_helpers.gpio_handler import Constants -from ..io_helpers.input_handler import InputHandler +import pocket_friends.game_files.io.gpio_handler as gpio_handler +from ..io.input_handler import InputHandler class Surface(pygame.Surface): @@ -133,15 +133,15 @@ class Surface(pygame.Surface): for event in pygame.event.get(): if event.type == pygame.KEYDOWN: - if event.key == Constants.buttons.get('j_r'): + if event.key == gpio_handler.BUTTONS.get('j_r'): self.sel_right() - if event.key == Constants.buttons.get('j_l'): + if event.key == gpio_handler.BUTTONS.get('j_l'): self.sel_left() - if event.key == Constants.buttons.get('j_d'): + if event.key == gpio_handler.BUTTONS.get('j_d'): self.sel_down() - if event.key == Constants.buttons.get('j_u'): + if event.key == gpio_handler.BUTTONS.get('j_u'): self.sel_up() - if event.key == Constants.buttons.get('a'): + if event.key == gpio_handler.BUTTONS.get('a'): self.additional_args = {'selected_egg': self.selected_color} self.next_surface = 'selection_info' self.running = False diff --git a/pocket_friends/game_files/surfaces/selection_info.py b/pocket_friends/game_files/surfaces/selection_info.py index e991276..80393b6 100644 --- a/pocket_friends/game_files/surfaces/selection_info.py +++ b/pocket_friends/game_files/surfaces/selection_info.py @@ -1,8 +1,8 @@ import pygame from . import sprites -from pocket_friends.game_files.io_helpers.gpio_handler import Constants +import pocket_friends.game_files.io.gpio_handler as gpio_handler from .sprites import SelectionEgg -from ..io_helpers.input_handler import InputHandler +from ..io.input_handler import InputHandler class Surface(pygame.Surface): @@ -46,15 +46,15 @@ class Surface(pygame.Surface): for event in pygame.event.get(): if event.type == pygame.KEYDOWN: - if event.key == Constants.buttons.get('j_d'): + if event.key == gpio_handler.BUTTONS.get('j_d'): # Scroll down on the info screen. self.info_text.scroll_down() - if event.key == Constants.buttons.get('j_u'): + if event.key == gpio_handler.BUTTONS.get('j_u'): # Scroll up on the info screen. self.info_text.scroll_up() - if event.key == Constants.buttons.get('a'): + if event.key == gpio_handler.BUTTONS.get('a'): pass - if event.key == Constants.buttons.get('b'): + if event.key == gpio_handler.BUTTONS.get('b'): self.running = False self.additional_args = {'selected_color': self.selected_egg} self.next_surface = 'egg_select' From 509efa7e239b7449496f7beaabb9d47fc5fa54d8 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 18:00:25 -0400 Subject: [PATCH 25/58] fixed launching issue caused by incorrect resource reference --- pocket_friends/game_files/game.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 59c4099..352ff90 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -21,7 +21,7 @@ game_fps = 16 game_res = 80 script_dir = os.path.dirname(os.path.abspath(__file__)) save_dir = os.path.join(Path.home(), '.pocket_friends') -resources_dir = script_dir + '/surfaces/resources' +resources_dir = script_dir + '/resources' starting_surface = 'title' @@ -44,7 +44,7 @@ def game(): surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) # Add an icon to the pygame window. - icon = pygame.image.load(script_dir + '/icon/icon.png').convert_alpha() + icon = pygame.image.load(resources_dir + '/icon/icon.png').convert_alpha() pygame.display.set_icon(icon) # Default game state when the game first starts. From f56f775541ef3eda586bef6176c182c6889a234a Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Thu, 11 May 2023 18:03:51 -0400 Subject: [PATCH 26/58] renamed data_handler.py to data.py, renamed DataHandler class to SaveData --- .../io/{data_handler.py => data.py} | 30 +++++-------------- 1 file changed, 8 insertions(+), 22 deletions(-) rename pocket_friends/game_files/io/{data_handler.py => data.py} (62%) diff --git a/pocket_friends/game_files/io/data_handler.py b/pocket_friends/game_files/io/data.py similarity index 62% rename from pocket_friends/game_files/io/data_handler.py rename to pocket_friends/game_files/io/data.py index 47fbdab..5878a89 100644 --- a/pocket_friends/game_files/io/data_handler.py +++ b/pocket_friends/game_files/io/data.py @@ -2,12 +2,15 @@ import pocket_friends import json -class DataHandler: +class SaveData: """ - Class that handles the hardware attributes and save files. + Class that represents the save data of the game. """ def __init__(self): + """ + Constructs the object with all starting values. + """ # Attributes that are saved to a file to recover upon startup. self.attributes = { 'version': pocket_friends.__version__, @@ -28,7 +31,7 @@ class DataHandler: def write_save(self): """ - Writes attributes of class to "save.json" file. + Writes attributes of the save object to "save.json" file. """ with open(save_dir + '/save.json', 'w') as save_file: json.dump(self.attributes, save_file) @@ -36,7 +39,8 @@ class DataHandler: def read_save(self): """ - Reads from "save.json" and inserts into attributes dictionary. Creates file if it does not exist. + Reads from "save.json" and inserts into the save object's attributes dictionary. Creates file if it does not + exist. """ # Open up the save file and read it into self.attributes. try: @@ -47,21 +51,3 @@ class DataHandler: # If there is no save file, write one with the defaults. except FileNotFoundError: self.write_save() - - def update(self): - """ - Run the game logic. - """ - self.frames_passed += 1 - # Run logic of the game every second. - if self.frames_passed >= game_fps: - - # Add one to the age of the bloop. - self.attributes['age'] += 1 - - # Save the data when the age of the bloop is a multiple of 10. - if self.attributes['age'] % 10 == 0: - self.write_save() - - # Reset frame counter - self.frames_passed = 0 From 65365adc3d97c96e5dc961fe1b7e692d176619e3 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 11:20:00 -0400 Subject: [PATCH 27/58] updated docstrings to follow google styling, changed checking of hardware to only happen once --- pocket_friends/game_files/io/data.py | 3 -- pocket_friends/game_files/io/fake_gpio.py | 47 +++++++++++++------ pocket_friends/game_files/io/gpio_handler.py | 27 ++++++----- pocket_friends/game_files/io/input_handler.py | 47 +++++++++---------- .../game_files/surfaces/selection_info.py | 11 +++++ 5 files changed, 82 insertions(+), 53 deletions(-) diff --git a/pocket_friends/game_files/io/data.py b/pocket_friends/game_files/io/data.py index 5878a89..89dcd66 100644 --- a/pocket_friends/game_files/io/data.py +++ b/pocket_friends/game_files/io/data.py @@ -3,9 +3,6 @@ import json class SaveData: - """ - Class that represents the save data of the game. - """ def __init__(self): """ diff --git a/pocket_friends/game_files/io/fake_gpio.py b/pocket_friends/game_files/io/fake_gpio.py index 2122fc2..c3d2a0e 100644 --- a/pocket_friends/game_files/io/fake_gpio.py +++ b/pocket_friends/game_files/io/fake_gpio.py @@ -1,6 +1,6 @@ """ -Module used to fake the RPi.GPIO module so that -the program can be run without the actual hardware. +Dummy module that contains empty functions and variables that exist in RPi.GPIO. This module is to be imported +if importing RPi.GPIO fails. """ # Constants used by RPi.GPIO @@ -12,7 +12,11 @@ FALLING = 0 def setmode(new_mode): """ Fake setmode function. - :param new_mode: + Args: + new_mode: + + Returns: + """ pass @@ -20,10 +24,14 @@ def setmode(new_mode): def setup(channel, mode, initial=None, pull_up_down=None): """ Fake setup function. - :param channel: - :param mode: - :param initial: - :param pull_up_down: + Args: + channel: + mode: + initial: + pull_up_down: + + Returns: + """ pass @@ -31,10 +39,14 @@ def setup(channel, mode, initial=None, pull_up_down=None): def add_event_detect(channel, edge_type, callback=None, bouncetime=0): """ Fake function to add a non-existent event detect. - :param channel: - :param edge_type: - :param callback: - :param bouncetime: + Args: + channel: + edge_type: + callback: + bouncetime: + + Returns: + """ pass @@ -42,8 +54,11 @@ def add_event_detect(channel, edge_type, callback=None, bouncetime=0): def event_detected(channel): """ Fake function to detect an event. Always returns false. - :param channel: - :return: + Args: + channel: + + Returns: + """ return False @@ -51,6 +66,10 @@ def event_detected(channel): def cleanup(channel=None): """ Fake cleanup function. - :param channel: + Args: + channel: + + Returns: + """ pass diff --git a/pocket_friends/game_files/io/gpio_handler.py b/pocket_friends/game_files/io/gpio_handler.py index 01e3423..0dd27dc 100644 --- a/pocket_friends/game_files/io/gpio_handler.py +++ b/pocket_friends/game_files/io/gpio_handler.py @@ -1,15 +1,19 @@ -""" -Handle inputs from the GPIO pins on the Raspberry Pi and converting them to events to be used in other places (pygame, etc.) -""" +"""Handle inputs from the GPIO pins on the Raspberry Pi and converting them to events to be used in other places ( +pygame, etc.)""" import importlib.util # If the RPi.GPIO module is not found (aka the program is not running on a Pi), import the fake # GPIO module instead to prevent a crash. + +ON_HARDWARE = None # Flag to tell other methods if the program is running on hardware or not + try: importlib.util.find_spec('RPi.GPIO') import RPi.GPIO as GPIO + ON_HARDWARE = True except ImportError: import pocket_friends.game_files.io.fake_gpio as GPIO + ON_HARDWARE = False # Dictionary of all the buttons used and what their corresponding GPIO codes are BUTTONS = { @@ -24,9 +28,7 @@ BUTTONS = { def setup(): - """ - Primes the GPIO pins for reading the inputs of the buttons. - """ + """Prime the GPIO pins for reading the inputs of the buttons.""" GPIO.setmode(GPIO.BOARD) GPIO.setup(BUTTONS.get('a'), GPIO.IN) @@ -47,16 +49,17 @@ def setup(): def teardown(): - """ - Cleans up the GPIO handler. - """ + """Clean up the GPIO handler.""" GPIO.cleanup() def get_press(button): """ - Returns true if a button has changed from not pressed to pressed. - :param button: button to be detected - :return: True if the button is has been pressed, False otherwise + Checks if a given button code has been pressed and returns a bool depending on the state. + Args: + button: button to be detected + + Returns: True if the button is has been pressed, False otherwise + """ return GPIO.event_detected(button) diff --git a/pocket_friends/game_files/io/input_handler.py b/pocket_friends/game_files/io/input_handler.py index 5df6cd4..c32be51 100644 --- a/pocket_friends/game_files/io/input_handler.py +++ b/pocket_friends/game_files/io/input_handler.py @@ -1,5 +1,4 @@ import pygame -import importlib.util import pocket_friends.game_files.io.gpio_handler as gpio_handler @@ -7,36 +6,40 @@ class InputHandler: """ Class that is implemented into surfaces in order to control the pressing of buttons on both the real hardware and on a keyboard. + + Attributes: + clock (pygame.time.Clock): Pygame clock used for input time calculations. + last_input_tick (int): The tick that the last input was registered on. + """ def __init__(self, pygame_clock): + """ + Create a InputHandler object using a given Pygame clock. + + Args: + pygame_clock (pygame.time.Clock): A pygame clock to use as the clock for input time calculations. + + """ self.clock = pygame_clock - - # If not on actual hardware, fake the GPIO in order to get it working correctly. - try: - importlib.util.find_spec('RPi.GPIO') - import RPi.GPIO as GPIO - self.on_hardware = True - except ImportError: - import pocket_friends.game_files.io.fake_gpio as GPIO - self.on_hardware = False - self.last_input_tick = 0 def create_event(self, pressed_button): """ - Creates a pygame event with a given keyboard code - :param pressed_button: + Create a pygame event given a GPIO code and post it to the pygame event handler. + Args: + pressed_button (int): The GPIO code to be registered and pressed. + """ # Register a button click so long as the last button click happened no less than two frames ago - if pygame.time.get_ticks() - self.last_input_tick > self.clock.get_time() * 2 or not self.on_hardware: + if pygame.time.get_ticks() - self.last_input_tick > self.clock.get_time() * 2 or not gpio_handler.ON_HARDWARE: pygame.event.post(pygame.event.Event(pygame.KEYDOWN, {'key': pressed_button})) pygame.event.post(pygame.event.Event(pygame.KEYUP, {'key': pressed_button})) self.last_input_tick = pygame.time.get_ticks() def handle_gpio(self): """ - Handles getting GPIO button presses and making a pygame event when a press is detected. + Handle GPIO events and create events for them. """ for pressed_button in gpio_handler.BUTTONS: code = gpio_handler.BUTTONS.get(pressed_button) @@ -45,10 +48,8 @@ class InputHandler: if gpio_handler.get_press(code): self.create_event(code) - def keyboard_handler(self): - """ - Simulates key presses to GPIO button presses. Also handles quitting the game. - """ + def handle_keyboard(self): + """Handle keyboard presses and generate corresponding GPIO codes to create events.""" # Checks if a corresponding keyboard key has been pressed. If it has, emulate a button press. for keyboard_event in pygame.event.get(): @@ -73,10 +74,8 @@ class InputHandler: running = False def update(self): - """ - Run the input handler and check for inputs. - """ - if self.on_hardware: + """Run either the GPIO handler or the keyboard handler to check for input and create events.""" + if gpio_handler.ON_HARDWARE: self.handle_gpio() else: - self.keyboard_handler() + self.handle_keyboard() diff --git a/pocket_friends/game_files/surfaces/selection_info.py b/pocket_friends/game_files/surfaces/selection_info.py index 80393b6..8b8aeac 100644 --- a/pocket_friends/game_files/surfaces/selection_info.py +++ b/pocket_friends/game_files/surfaces/selection_info.py @@ -6,7 +6,18 @@ from ..io.input_handler import InputHandler class Surface(pygame.Surface): + """ + + """ def __init__(self, window_size, resources_dir, game_fps, **kwargs): + """ + + Args: + window_size: + resources_dir: + game_fps: + **kwargs: + """ super().__init__(window_size, pygame.SRCALPHA) self.name = 'selection_info' self.running = True From b97d54f49d153895f50b1ee527c42d991ee9040d Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 11:44:58 -0400 Subject: [PATCH 28/58] created new submodule to contain game elements --- pocket_friends/game_files/elements/__init__.py | 1 + .../game_files/{surfaces => elements}/sprites.py | 12 +++++++++++- pocket_friends/game_files/surfaces/egg_select.py | 2 +- pocket_friends/game_files/surfaces/selection_info.py | 3 +-- 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 pocket_friends/game_files/elements/__init__.py rename pocket_friends/game_files/{surfaces => elements}/sprites.py (94%) diff --git a/pocket_friends/game_files/elements/__init__.py b/pocket_friends/game_files/elements/__init__.py new file mode 100644 index 0000000..6867307 --- /dev/null +++ b/pocket_friends/game_files/elements/__init__.py @@ -0,0 +1 @@ +"""Sub-module for use in the game. Helps with the drawing of various objects such as sprites and text boxes.""" diff --git a/pocket_friends/game_files/surfaces/sprites.py b/pocket_friends/game_files/elements/sprites.py similarity index 94% rename from pocket_friends/game_files/surfaces/sprites.py rename to pocket_friends/game_files/elements/sprites.py index 0c1e8d8..6f0bb8e 100644 --- a/pocket_friends/game_files/surfaces/sprites.py +++ b/pocket_friends/game_files/elements/sprites.py @@ -4,10 +4,20 @@ import json class SpriteSheet: """ - Imports a sprite sheet as separate pygame images given an image file and a json file. + Class to be used by sprites in order to give them a texture and an animation. + + Attributes: + images (list) List of all the sprites in the animation separated from the sprite sheet. """ def __init__(self, sprite_sheet, texture_json): + """ + Creates a sprite sheet given a sprite image and its corresponding JSON file. + Args: + sprite_sheet (str): The path of the sprite sheet image component. + texture_json (str): The path of the sprite sheet JSON component, contains the number of frames in the + sprite sheet, and the width and height of an individual sprite from the sprite sheet. + """ # Load in whole sprite sheet as one image. self.sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha() self.images = [] diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py index 7a97d90..4ae54d1 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -1,5 +1,5 @@ import pygame -from . import sprites +from ..elements import sprites import pocket_friends.game_files.io.gpio_handler as gpio_handler from ..io.input_handler import InputHandler diff --git a/pocket_friends/game_files/surfaces/selection_info.py b/pocket_friends/game_files/surfaces/selection_info.py index 8b8aeac..94df328 100644 --- a/pocket_friends/game_files/surfaces/selection_info.py +++ b/pocket_friends/game_files/surfaces/selection_info.py @@ -1,7 +1,6 @@ import pygame -from . import sprites +from ..elements import sprites import pocket_friends.game_files.io.gpio_handler as gpio_handler -from .sprites import SelectionEgg from ..io.input_handler import InputHandler From d322949b5a1dc968d72c38ce224d0d68b97cf08e Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 11:46:08 -0400 Subject: [PATCH 29/58] changed unneeded attributes in SpriteSheet to regular variables in the constructor --- pocket_friends/game_files/elements/sprites.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pocket_friends/game_files/elements/sprites.py b/pocket_friends/game_files/elements/sprites.py index 6f0bb8e..968876a 100644 --- a/pocket_friends/game_files/elements/sprites.py +++ b/pocket_friends/game_files/elements/sprites.py @@ -19,39 +19,40 @@ class SpriteSheet: sprite sheet, and the width and height of an individual sprite from the sprite sheet. """ # Load in whole sprite sheet as one image. - self.sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha() + sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha() self.images = [] + print(type(self.images)) # Get the sprite sheet json file. with open(texture_json, 'r') as json_file: - self.img_attrib = json.load(json_file) + img_attrib = json.load(json_file) json_file.close() # Count for how many images have been added in the image list image_count = 0 # Get the sprite size as a tuple - sprite_size = self.img_attrib['width'], self.img_attrib['height'] + sprite_size = img_attrib['width'], img_attrib['height'] # Iterate through every image location on the sprite sheet given the sprite size - for i in range(self.sprite_sheet.get_size()[1] // sprite_size[1]): + for i in range(sprite_sheet.get_size()[1] // sprite_size[1]): i *= sprite_size[1] - for j in range(self.sprite_sheet.get_size()[0] // sprite_size[0]): + for j in range(sprite_sheet.get_size()[0] // sprite_size[0]): j *= sprite_size[0] # Create a new transparent surface sprite = pygame.Surface(sprite_size, pygame.SRCALPHA) # Blit the sprite onto the image - sprite.blit(self.sprite_sheet, (0, 0), (j, i, sprite_size[0], sprite_size[1])) + sprite.blit(sprite_sheet, (0, 0), (j, i, sprite_size[0], sprite_size[1])) # Add the image to the list of images self.images.append(sprite) image_count += 1 # Break the loop if the specified number of frames has been reached. - if image_count >= self.img_attrib['frames']: + if image_count >= img_attrib['frames']: break - if image_count >= self.img_attrib['frames']: + if image_count >= img_attrib['frames']: break From 4045930bd98a43db8daac39f51800ba41f1888d4 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 11:46:23 -0400 Subject: [PATCH 30/58] updated data.py docstrings --- pocket_friends/game_files/io/data.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pocket_friends/game_files/io/data.py b/pocket_friends/game_files/io/data.py index 89dcd66..e7dfeee 100644 --- a/pocket_friends/game_files/io/data.py +++ b/pocket_friends/game_files/io/data.py @@ -3,7 +3,12 @@ import json class SaveData: + """ + Class used to read and write save data for the game + Attributes: + attributes (dict): Dictionary containing all the attributes to read and write from a save file. + """ def __init__(self): """ Constructs the object with all starting values. From d8775fb1a92f53ae24d936217e34007fdfbda10c Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 13:49:26 -0400 Subject: [PATCH 31/58] updated comments, made some attributes private --- pocket_friends/game_files/elements/sprites.py | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/pocket_friends/game_files/elements/sprites.py b/pocket_friends/game_files/elements/sprites.py index 968876a..1469c89 100644 --- a/pocket_friends/game_files/elements/sprites.py +++ b/pocket_friends/game_files/elements/sprites.py @@ -58,10 +58,24 @@ class SpriteSheet: class SelectionEgg(pygame.sprite.Sprite): """ - Class for the eggs on the egg selection screen. + Sprite to render the egg on the egg selection screen. + + Attributes: + egg_color (str): The color of the egg (also its name). + description (str): The description of the egg to be displayed when selected. + contentedness (int): How likely the egg is to stay happy, ranges from 0-5. + metabolism (int): How quickly the egg will get hungry, ranges from 0-5. + rect (pygame.Rect): Pygame rectangle used to position the egg on screen. + """ def __init__(self, egg_color, resources_dir): + """ + Creates a SelectionEgg object given an egg color and a resource location. + Args: + egg_color (str): The color egg that should be rendered. + resources_dir (str): The path of the resources directory. + """ pygame.sprite.Sprite.__init__(self) self.egg_color = egg_color @@ -79,20 +93,21 @@ class SelectionEgg(pygame.sprite.Sprite): # Load the egg from the given color and get the bounding rectangle for the image. sprite_sheet = SpriteSheet(resources_dir + '/images/bloops/{0}/egg.png'.format(self.egg_color), resources_dir + '/images/bloops/{0}/egg.json'.format(self.egg_color)) - self.images = sprite_sheet.images + self._images = sprite_sheet.images # Get the rectangle from the first image in the list - self.rect = self.images[0].get_rect() - self.index = 0 - self.image = self.images[self.index] + self.rect = self._images[0].get_rect() + print(type(self.rect)) + self._index = 0 + self.image = self._images[self._index] def update(self): """ - Updates the sprite object. + Update the sprite to the next animation frame. """ # Animate the sprite - self.index = (self.index + 1) % len(self.images) - self.image = self.images[self.index] + self._index = (self._index + 1) % len(self._images) + self.image = self._images[self._index] class InfoText: From 5b2c724882c1462a98e86117a7e50d70d95969b1 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 17:34:13 -0400 Subject: [PATCH 32/58] added error screen --- pocket_friends/game_files/game.py | 5 ++- .../game_files/surfaces/error_screen.py | 41 +++++++++++++++++++ .../game_files/surfaces/selection_info.py | 4 +- 3 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 pocket_friends/game_files/surfaces/error_screen.py diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 352ff90..5e469a8 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -7,7 +7,8 @@ import importlib valid_surfaces = [ 'title', 'egg_select', - 'selection_info' + 'selection_info', + 'error_screen' ] surface_modules = {} @@ -65,7 +66,7 @@ def game(): next_surface = surface.next_surface additional_args = surface.additional_args if next_surface not in valid_surfaces: - raise Exception('Given surface is not listed in valid surfaces!') + next_surface = 'error_screen' surface = surface_modules.get(next_surface).Surface((game_res, game_res), resources_dir, game_fps, **additional_args) print(surface.name) diff --git a/pocket_friends/game_files/surfaces/error_screen.py b/pocket_friends/game_files/surfaces/error_screen.py new file mode 100644 index 0000000..5d4fe67 --- /dev/null +++ b/pocket_friends/game_files/surfaces/error_screen.py @@ -0,0 +1,41 @@ +import pygame + +from pocket_friends.game_files.io import gpio_handler +from pocket_friends.game_files.io.input_handler import InputHandler + + +class Surface(pygame.Surface): + def __init__(self, window_size, resources_dir, game_fps, **kwargs): + super().__init__(window_size, pygame.SRCALPHA) + self.name = 'error_screen' + self.running = True + self.next_surface = 'title' + self.clock = pygame.time.Clock() + self.input_handler = InputHandler(self.clock) + self.additional_args = {} + + self.bg = pygame.image.load(resources_dir + '/images/bg.png').convert_alpha() + self.title = pygame.image.load(resources_dir + '/images/debug/invalid.png').convert_alpha() + self.frames = 1 + self.game_fps = game_fps + self.delay = 1 + self.font = pygame.font.Font(resources_dir + '/fonts/5Pts5.ttf', 10) + + def update(self): + self.clock.tick(self.game_fps) + + self.blit(self.bg, (0, 0)) + self.blit(self.title, (0, -4)) + text = self.font.render('Frames: {0}'.format(self.frames), False, (64, 64, 64)) + self.blit(text, (3, 68)) + + self.frames += 1 + self.frames %= self.game_fps + + self.input_handler.update() + + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN: + if event.key == gpio_handler.BUTTONS.get('b'): + self.running = False + print('stop') diff --git a/pocket_friends/game_files/surfaces/selection_info.py b/pocket_friends/game_files/surfaces/selection_info.py index 94df328..3c18877 100644 --- a/pocket_friends/game_files/surfaces/selection_info.py +++ b/pocket_friends/game_files/surfaces/selection_info.py @@ -63,7 +63,9 @@ class Surface(pygame.Surface): # Scroll up on the info screen. self.info_text.scroll_up() if event.key == gpio_handler.BUTTONS.get('a'): - pass + self.running = False + self.additional_args = {'selected_color': self.selected_egg} + self.next_surface = 'playground' if event.key == gpio_handler.BUTTONS.get('b'): self.running = False self.additional_args = {'selected_color': self.selected_egg} From b65f112b36e71f381d6a2ec9d99008537740bd70 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 17:34:27 -0400 Subject: [PATCH 33/58] removed unused import --- pocket_friends/game_files/surfaces/title.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pocket_friends/game_files/surfaces/title.py b/pocket_friends/game_files/surfaces/title.py index ed580cd..350063e 100644 --- a/pocket_friends/game_files/surfaces/title.py +++ b/pocket_friends/game_files/surfaces/title.py @@ -1,5 +1,4 @@ import pygame -import time class Surface(pygame.Surface): From 3fa4e2190e443ab10c970448647622c1f309ebd5 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 17:34:40 -0400 Subject: [PATCH 34/58] changed python version back to 3.9 --- README.md | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 432bb01..84f6322 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ There are currently no releases of the game. To install the current version on G ## Installing From Source Requirements: -- Python 3.10 or greater +- Python 3.9 or greater - Pip - Git diff --git a/setup.py b/setup.py index 57eb41d..22c7c62 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,6 @@ setuptools.setup( classifiers=[ ], install_requires=required, - python_requires='>=3.10', + python_requires='>=3.9', include_package_data=True, ) From 5d3fc6ca49b9f75298b2c19ba27f45f6ae634ae2 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 22:57:56 -0400 Subject: [PATCH 35/58] changed python version to 3.7, changed pygame to 1.9.6 --- README.md | 2 +- requirements.txt | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 84f6322..ad0c579 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ There are currently no releases of the game. To install the current version on G ## Installing From Source Requirements: -- Python 3.9 or greater +- Python 3.7 - Pip - Git diff --git a/requirements.txt b/requirements.txt index 1581372..454329a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -pygame~=2.1.2 \ No newline at end of file +pygame~=1.9.6 \ No newline at end of file diff --git a/setup.py b/setup.py index 22c7c62..6f91597 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,6 @@ setuptools.setup( classifiers=[ ], install_requires=required, - python_requires='>=3.9', + python_requires='>=3.7', include_package_data=True, ) From 8e9e96d1bb3a68f4965ba821407d8d248fe27562 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 23:17:33 -0400 Subject: [PATCH 36/58] added hardware check --- pocket_friends/game_files/game.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 5e469a8..f921f39 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -2,8 +2,11 @@ import pygame import os from pathlib import Path import pocket_friends + import importlib +from pocket_friends.game_files.io import gpio_handler + valid_surfaces = [ 'title', 'egg_select', @@ -38,7 +41,10 @@ def game(): # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the # screen_size to reflect what the resolution of the new display is. screen_size = 320 - + if gpio_handler.ON_HARDWARE: + print('ON HARDWARE') + else: + print('NOT ON HARDWARE') pygame.mouse.set_visible(False) pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) window = pygame.display.set_mode((screen_size, screen_size)) From 9b752bde21773cf91fc2d53a0db12b7d45b2b853 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 23:21:33 -0400 Subject: [PATCH 37/58] fixed game not rendering on hardware --- pocket_friends/game_files/game.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index f921f39..2e49835 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -40,19 +40,19 @@ def game(): # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the # screen_size to reflect what the resolution of the new display is. - screen_size = 320 if gpio_handler.ON_HARDWARE: - print('ON HARDWARE') + screen_size = 240 + pygame.mouse.set_visible(False) + window = pygame.display.set_mode((screen_size, screen_size), pygame.FULLSCREEN) else: - print('NOT ON HARDWARE') - pygame.mouse.set_visible(False) - pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) - window = pygame.display.set_mode((screen_size, screen_size)) + screen_size = 240*2 + window = pygame.display.set_mode((screen_size, screen_size)) surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) # Add an icon to the pygame window. icon = pygame.image.load(resources_dir + '/icon/icon.png').convert_alpha() pygame.display.set_icon(icon) + pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) # Default game state when the game first starts. running = True From b8776a6f7fcc9230695599a1b2e719a1068f3f36 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 23:28:00 -0400 Subject: [PATCH 38/58] fixed GPIO handler error --- pocket_friends/game_files/game.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 2e49835..eaad9d1 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -41,6 +41,7 @@ def game(): # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the # screen_size to reflect what the resolution of the new display is. if gpio_handler.ON_HARDWARE: + gpio_handler.setup() screen_size = 240 pygame.mouse.set_visible(False) window = pygame.display.set_mode((screen_size, screen_size), pygame.FULLSCREEN) @@ -85,4 +86,5 @@ def main(): """ game() + gpio_handler.teardown() pygame.quit() From 526b51b7543856871c8625c6cd50a146b6c24dc4 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 23:34:15 -0400 Subject: [PATCH 39/58] disabled gpio_handler.py to always return false to ON_HARDWARE --- pocket_friends/game_files/io/gpio_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocket_friends/game_files/io/gpio_handler.py b/pocket_friends/game_files/io/gpio_handler.py index 0dd27dc..3432c84 100644 --- a/pocket_friends/game_files/io/gpio_handler.py +++ b/pocket_friends/game_files/io/gpio_handler.py @@ -10,7 +10,7 @@ ON_HARDWARE = None # Flag to tell other methods if the program is running on ha try: importlib.util.find_spec('RPi.GPIO') import RPi.GPIO as GPIO - ON_HARDWARE = True + ON_HARDWARE = False except ImportError: import pocket_friends.game_files.io.fake_gpio as GPIO ON_HARDWARE = False From d932538b4155225f173e4596986e54f4d11c11e7 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 23:36:21 -0400 Subject: [PATCH 40/58] changed resolution to 240x240 fullscreen by default --- pocket_friends/game_files/game.py | 14 ++++---------- pocket_friends/game_files/io/gpio_handler.py | 12 +++--------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index eaad9d1..6bbf7da 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -40,15 +40,10 @@ def game(): # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the # screen_size to reflect what the resolution of the new display is. - if gpio_handler.ON_HARDWARE: - gpio_handler.setup() - screen_size = 240 - pygame.mouse.set_visible(False) - window = pygame.display.set_mode((screen_size, screen_size), pygame.FULLSCREEN) - else: - screen_size = 240*2 - window = pygame.display.set_mode((screen_size, screen_size)) - surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) + + screen_size = 240 + pygame.mouse.set_visible(False) + window = pygame.display.set_mode((screen_size, screen_size), pygame.FULLSCREEN) # Add an icon to the pygame window. icon = pygame.image.load(resources_dir + '/icon/icon.png').convert_alpha() @@ -86,5 +81,4 @@ def main(): """ game() - gpio_handler.teardown() pygame.quit() diff --git a/pocket_friends/game_files/io/gpio_handler.py b/pocket_friends/game_files/io/gpio_handler.py index 3432c84..c6433c8 100644 --- a/pocket_friends/game_files/io/gpio_handler.py +++ b/pocket_friends/game_files/io/gpio_handler.py @@ -5,15 +5,9 @@ import importlib.util # If the RPi.GPIO module is not found (aka the program is not running on a Pi), import the fake # GPIO module instead to prevent a crash. -ON_HARDWARE = None # Flag to tell other methods if the program is running on hardware or not - -try: - importlib.util.find_spec('RPi.GPIO') - import RPi.GPIO as GPIO - ON_HARDWARE = False -except ImportError: - import pocket_friends.game_files.io.fake_gpio as GPIO - ON_HARDWARE = False +#ON_HARDWARE = None # Flag to tell other methods if the program is running on hardware or not +import pocket_friends.game_files.io.fake_gpio as GPIO +ON_HARDWARE = False # Dictionary of all the buttons used and what their corresponding GPIO codes are BUTTONS = { From e6cb2bd4c8ab930cd27744589baa0159bff06905 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 23:42:21 -0400 Subject: [PATCH 41/58] added --windowed parameter, fixed missing surface assignment --- pocket_friends/__main__.py | 9 ++++++--- pocket_friends/game_files/game.py | 17 +++++++++++------ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/pocket_friends/__main__.py b/pocket_friends/__main__.py index 298fb5f..7fadff4 100644 --- a/pocket_friends/__main__.py +++ b/pocket_friends/__main__.py @@ -9,15 +9,18 @@ import pocket_friends.game_files.game as game if __name__ == '__main__': enable_dev = False + windowed = False # enable dev mode if --dev argument is passed if len(sys.argv) > 0: - for args in sys.argv: - if args == '--delete-save': + for arg in sys.argv: + if arg == '--delete-save': save_dir = os.path.join(Path.home(), '.pocket_friends') os.remove(save_dir + '/save.json') + if arg == '--windowed': + windowed = True - game.main() + game.main(windowed) pygame.quit() sys.exit() diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 6bbf7da..f880125 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -32,7 +32,7 @@ starting_surface = 'title' # Gets the directory of the script for importing and the save directory -def game(): +def game(windowed=False): """ Starts the game. """ @@ -41,9 +41,14 @@ def game(): # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the # screen_size to reflect what the resolution of the new display is. - screen_size = 240 - pygame.mouse.set_visible(False) - window = pygame.display.set_mode((screen_size, screen_size), pygame.FULLSCREEN) + if windowed: + screen_size = 480 + window = pygame.display.set_mode((screen_size, screen_size)) + else: + screen_size = 240 + pygame.mouse.set_visible(False) + window = pygame.display.set_mode((screen_size, screen_size), pygame.FULLSCREEN) + surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) # Add an icon to the pygame window. icon = pygame.image.load(resources_dir + '/icon/icon.png').convert_alpha() @@ -75,10 +80,10 @@ def game(): pygame.display.flip() -def main(): +def main(windowed=False): """ Calls the game() function to start the game. """ - game() + game(windowed) pygame.quit() From c547f76b3580d34e1c4c16bb6390c57fd5eb693c Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 23:49:36 -0400 Subject: [PATCH 42/58] attempt at fixing hardware --- pocket_friends/game_files/game.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index f880125..1ebc890 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -47,7 +47,7 @@ def game(windowed=False): else: screen_size = 240 pygame.mouse.set_visible(False) - window = pygame.display.set_mode((screen_size, screen_size), pygame.FULLSCREEN) + window = pygame.display.set_mode((screen_size, screen_size)) surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) # Add an icon to the pygame window. From 07be003a5478e34d8580a14cab133a81be2bae3e Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 23:55:06 -0400 Subject: [PATCH 43/58] reordered stuff in a desperate attempt --- pocket_friends/game_files/game.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 1ebc890..f4aab4b 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -41,29 +41,22 @@ def game(windowed=False): # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the # screen_size to reflect what the resolution of the new display is. + pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) + if windowed: screen_size = 480 - window = pygame.display.set_mode((screen_size, screen_size)) else: screen_size = 240 - pygame.mouse.set_visible(False) - window = pygame.display.set_mode((screen_size, screen_size)) + window = pygame.display.set_mode((screen_size, screen_size)) surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) # Add an icon to the pygame window. icon = pygame.image.load(resources_dir + '/icon/icon.png').convert_alpha() pygame.display.set_icon(icon) - pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) # Default game state when the game first starts. running = True - # A group of all the sprites on screen. Used to update all sprites at onc - all_sprites = pygame.sprite.Group() - - # Time since last input. Used to help regulate double presses of buttons. - last_input_tick = 0 - while running: surface.update() frame = pygame.transform.scale(surface, (screen_size, screen_size)) From e9df84897a05f05315e19de24457fb2b6a7e2f27 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Fri, 12 May 2023 23:57:23 -0400 Subject: [PATCH 44/58] removed print statements --- pocket_friends/game_files/game.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index f4aab4b..74ec6bb 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -17,7 +17,6 @@ surface_modules = {} for module in valid_surfaces: surface_modules[module] = importlib.import_module('pocket_friends.game_files.surfaces.{0}'.format(module)) - print('imported ' + module) # FPS for the entire game to run at. game_fps = 16 @@ -69,7 +68,6 @@ def game(windowed=False): next_surface = 'error_screen' surface = surface_modules.get(next_surface).Surface((game_res, game_res), resources_dir, game_fps, **additional_args) - print(surface.name) pygame.display.flip() From 1fef87e1c335b1cf3ab24e2318cd5a5b720336d2 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 00:04:34 -0400 Subject: [PATCH 45/58] disabled loading other surfaces as a test --- pocket_friends/game_files/game.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 74ec6bb..576c761 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -47,8 +47,9 @@ def game(windowed=False): else: screen_size = 240 window = pygame.display.set_mode((screen_size, screen_size)) - surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) - + #surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) + surface = pygame.Surface((game_res, game_res)) + surface.fill((255, 0, 0)) # Add an icon to the pygame window. icon = pygame.image.load(resources_dir + '/icon/icon.png').convert_alpha() pygame.display.set_icon(icon) @@ -57,17 +58,17 @@ def game(windowed=False): running = True while running: - surface.update() + #surface.update() frame = pygame.transform.scale(surface, (screen_size, screen_size)) window.blit(frame, frame.get_rect()) - if not surface.running: - next_surface = surface.next_surface - additional_args = surface.additional_args - if next_surface not in valid_surfaces: - next_surface = 'error_screen' - surface = surface_modules.get(next_surface).Surface((game_res, game_res), resources_dir, - game_fps, **additional_args) + #if not surface.running: + # next_surface = surface.next_surface + # additional_args = surface.additional_args + # if next_surface not in valid_surfaces: + # next_surface = 'error_screen' + # surface = surface_modules.get(next_surface).Surface((game_res, game_res), resources_dir, + # game_fps, **additional_args) pygame.display.flip() From 6debf7326785a397bd2da24d94924eda3a605d7b Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 09:49:51 -0400 Subject: [PATCH 46/58] made screen size constant --- pocket_friends/game_files/game.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 576c761..dcf08a2 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -40,17 +40,17 @@ def game(windowed=False): # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the # screen_size to reflect what the resolution of the new display is. - pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) + # Hide the cursor for the Pi display. + pygame.mouse.set_visible(False) - if windowed: - screen_size = 480 - else: - screen_size = 240 + screen_size = 240 window = pygame.display.set_mode((screen_size, screen_size)) #surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) surface = pygame.Surface((game_res, game_res)) surface.fill((255, 0, 0)) + # Add an icon to the pygame window. + pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) icon = pygame.image.load(resources_dir + '/icon/icon.png').convert_alpha() pygame.display.set_icon(icon) From afd228d81a097c361442691d1f0c9ec490a041af Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 09:56:55 -0400 Subject: [PATCH 47/58] copied code from old codebase to see if anything happens --- pocket_friends/game_files/game.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index dcf08a2..bce6709 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -35,30 +35,39 @@ def game(windowed=False): """ Starts the game. """ - pygame.init() - # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the - # screen_size to reflect what the resolution of the new display is. + pygame.init() # Hide the cursor for the Pi display. pygame.mouse.set_visible(False) + # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the + # screen_size to reflect what the resolution of the new display is. screen_size = 240 + window = pygame.display.set_mode((screen_size, screen_size)) - #surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) surface = pygame.Surface((game_res, game_res)) - surface.fill((255, 0, 0)) + + # Only really useful for PCs. Does nothing on the Raspberry Pi. + pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) # Add an icon to the pygame window. - pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) icon = pygame.image.load(resources_dir + '/icon/icon.png').convert_alpha() pygame.display.set_icon(icon) + clock = pygame.time.Clock() + + running = True + + #surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) + surface.fill((255, 0, 0)) + # Default game state when the game first starts. running = True while running: #surface.update() + surface.fill((255, 0, 0)) frame = pygame.transform.scale(surface, (screen_size, screen_size)) window.blit(frame, frame.get_rect()) From f6e9869282e3cd47dbd8b829d21b217c62efc4e6 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 10:16:43 -0400 Subject: [PATCH 48/58] fixed rpi display not rendering anything --- pocket_friends/game_files/game.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index bce6709..782365d 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -27,8 +27,8 @@ save_dir = os.path.join(Path.home(), '.pocket_friends') resources_dir = script_dir + '/resources' starting_surface = 'title' - -# Gets the directory of the script for importing and the save directory +# Makes Pygame draw on the display of the RPi. +os.environ["SDL_FBDEV"] = "/dev/fb1" def game(windowed=False): From 38a58128391a70c21dd66a0989d53b32dfa9f110 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 10:17:30 -0400 Subject: [PATCH 49/58] re-enabled the game lol --- pocket_friends/game_files/game.py | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 782365d..50bafac 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -46,7 +46,7 @@ def game(windowed=False): screen_size = 240 window = pygame.display.set_mode((screen_size, screen_size)) - surface = pygame.Surface((game_res, game_res)) + surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) # Only really useful for PCs. Does nothing on the Raspberry Pi. pygame.display.set_caption('Pocket Friends {0}'.format(pocket_friends.__version__)) @@ -59,25 +59,18 @@ def game(windowed=False): running = True - #surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) - surface.fill((255, 0, 0)) - - # Default game state when the game first starts. - running = True - while running: - #surface.update() - surface.fill((255, 0, 0)) + surface.update() frame = pygame.transform.scale(surface, (screen_size, screen_size)) window.blit(frame, frame.get_rect()) - #if not surface.running: - # next_surface = surface.next_surface - # additional_args = surface.additional_args - # if next_surface not in valid_surfaces: - # next_surface = 'error_screen' - # surface = surface_modules.get(next_surface).Surface((game_res, game_res), resources_dir, - # game_fps, **additional_args) + if not surface.running: + next_surface = surface.next_surface + additional_args = surface.additional_args + if next_surface not in valid_surfaces: + next_surface = 'error_screen' + surface = surface_modules.get(next_surface).Surface((game_res, game_res), resources_dir, + game_fps, **additional_args) pygame.display.flip() From 35ac1cff51666956143074103aa78399e02d1a67 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 10:30:27 -0400 Subject: [PATCH 50/58] removed windowed flag, added resolution flag --- pocket_friends/__main__.py | 8 +++--- pocket_friends/game_files/game.py | 46 ++++++++++++++++--------------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/pocket_friends/__main__.py b/pocket_friends/__main__.py index 7fadff4..4c55047 100644 --- a/pocket_friends/__main__.py +++ b/pocket_friends/__main__.py @@ -9,7 +9,7 @@ import pocket_friends.game_files.game as game if __name__ == '__main__': enable_dev = False - windowed = False + resolution = 240 # enable dev mode if --dev argument is passed if len(sys.argv) > 0: @@ -17,10 +17,10 @@ if __name__ == '__main__': if arg == '--delete-save': save_dir = os.path.join(Path.home(), '.pocket_friends') os.remove(save_dir + '/save.json') - if arg == '--windowed': - windowed = True + if '--res=' in arg: + resolution = int(arg.split('=')[1]) - game.main(windowed) + game.main(resolution) pygame.quit() sys.exit() diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 50bafac..63ec1ce 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -2,10 +2,8 @@ import pygame import os from pathlib import Path import pocket_friends - import importlib -from pocket_friends.game_files.io import gpio_handler valid_surfaces = [ 'title', @@ -13,27 +11,32 @@ valid_surfaces = [ 'selection_info', 'error_screen' ] -surface_modules = {} +# Add all the surface modules to a dictionary for easy switching +surface_modules = {} for module in valid_surfaces: surface_modules[module] = importlib.import_module('pocket_friends.game_files.surfaces.{0}'.format(module)) - -# FPS for the entire game to run at. -game_fps = 16 -# The resolution the game is rendered at. -game_res = 80 -script_dir = os.path.dirname(os.path.abspath(__file__)) -save_dir = os.path.join(Path.home(), '.pocket_friends') -resources_dir = script_dir + '/resources' starting_surface = 'title' +# FPS for the game to run at. +game_fps = 16 +# The internal resolution of the game +game_res = 80 + +# Get the path for where all game resources are (images, fonts, sounds, etc.) +script_dir = os.path.dirname(os.path.abspath(__file__)) +resources_dir = script_dir + '/resources' + # Makes Pygame draw on the display of the RPi. os.environ["SDL_FBDEV"] = "/dev/fb1" -def game(windowed=False): +def game(resolution=240): """ Starts the game. + + Args: + resolution (int, optional): Resolution to display the game at. Defaults to 240. """ pygame.init() @@ -41,11 +44,7 @@ def game(windowed=False): # Hide the cursor for the Pi display. pygame.mouse.set_visible(False) - # The game is normally rendered at 80 pixels and upscaled from there. If changing displays, change the - # screen_size to reflect what the resolution of the new display is. - screen_size = 240 - - window = pygame.display.set_mode((screen_size, screen_size)) + window = pygame.display.set_mode((resolution, resolution)) surface = surface_modules.get(starting_surface).Surface((game_res, game_res), resources_dir, game_fps) # Only really useful for PCs. Does nothing on the Raspberry Pi. @@ -55,13 +54,13 @@ def game(windowed=False): icon = pygame.image.load(resources_dir + '/icon/icon.png').convert_alpha() pygame.display.set_icon(icon) - clock = pygame.time.Clock() - running = True while running: surface.update() - frame = pygame.transform.scale(surface, (screen_size, screen_size)) + + # The game is only 80x80px, however it is upscaled to whatever the running resolution is. + frame = pygame.transform.scale(surface, (resolution, resolution)) window.blit(frame, frame.get_rect()) if not surface.running: @@ -74,10 +73,13 @@ def game(windowed=False): pygame.display.flip() -def main(windowed=False): +def main(resolution=240): """ Calls the game() function to start the game. + + Args: + resolution (int, optional): Resolution to display the game at. Defaults to 240. """ - game(windowed) + game(resolution) pygame.quit() From 0f691202138048c67a5099d2914f22bab56ed393 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 10:46:34 -0400 Subject: [PATCH 51/58] removed gpio modules (rest in peace) --- pocket_friends/game_files/io/fake_gpio.py | 75 ------------------- pocket_friends/game_files/io/gpio_handler.py | 59 --------------- pocket_friends/game_files/io/input_handler.py | 34 +++------ .../game_files/surfaces/egg_select.py | 11 ++- .../game_files/surfaces/error_screen.py | 3 +- .../game_files/surfaces/selection_info.py | 9 +-- 6 files changed, 19 insertions(+), 172 deletions(-) delete mode 100644 pocket_friends/game_files/io/fake_gpio.py delete mode 100644 pocket_friends/game_files/io/gpio_handler.py diff --git a/pocket_friends/game_files/io/fake_gpio.py b/pocket_friends/game_files/io/fake_gpio.py deleted file mode 100644 index c3d2a0e..0000000 --- a/pocket_friends/game_files/io/fake_gpio.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -Dummy module that contains empty functions and variables that exist in RPi.GPIO. This module is to be imported -if importing RPi.GPIO fails. -""" - -# Constants used by RPi.GPIO -BOARD = 0 -IN = 0 -FALLING = 0 - - -def setmode(new_mode): - """ - Fake setmode function. - Args: - new_mode: - - Returns: - - """ - pass - - -def setup(channel, mode, initial=None, pull_up_down=None): - """ - Fake setup function. - Args: - channel: - mode: - initial: - pull_up_down: - - Returns: - - """ - pass - - -def add_event_detect(channel, edge_type, callback=None, bouncetime=0): - """ - Fake function to add a non-existent event detect. - Args: - channel: - edge_type: - callback: - bouncetime: - - Returns: - - """ - pass - - -def event_detected(channel): - """ - Fake function to detect an event. Always returns false. - Args: - channel: - - Returns: - - """ - return False - - -def cleanup(channel=None): - """ - Fake cleanup function. - Args: - channel: - - Returns: - - """ - pass diff --git a/pocket_friends/game_files/io/gpio_handler.py b/pocket_friends/game_files/io/gpio_handler.py deleted file mode 100644 index c6433c8..0000000 --- a/pocket_friends/game_files/io/gpio_handler.py +++ /dev/null @@ -1,59 +0,0 @@ -"""Handle inputs from the GPIO pins on the Raspberry Pi and converting them to events to be used in other places ( -pygame, etc.)""" -import importlib.util - -# If the RPi.GPIO module is not found (aka the program is not running on a Pi), import the fake -# GPIO module instead to prevent a crash. - -#ON_HARDWARE = None # Flag to tell other methods if the program is running on hardware or not -import pocket_friends.game_files.io.fake_gpio as GPIO -ON_HARDWARE = False - -# Dictionary of all the buttons used and what their corresponding GPIO codes are -BUTTONS = { - 'a': 31, # A button - 'b': 29, # B button - 'j_i': 7, # Joystick in - 'j_u': 11, # Joystick up - 'j_d': 15, # Joystick down - 'j_l': 13, # Joystick left - 'j_r': 16 # Joystick right -} - - -def setup(): - """Prime the GPIO pins for reading the inputs of the buttons.""" - GPIO.setmode(GPIO.BOARD) - - GPIO.setup(BUTTONS.get('a'), GPIO.IN) - GPIO.setup(BUTTONS.get('b'), GPIO.IN) - GPIO.setup(BUTTONS.get('j_i'), GPIO.IN) - GPIO.setup(BUTTONS.get('j_u'), GPIO.IN) - GPIO.setup(BUTTONS.get('j_d'), GPIO.IN) - GPIO.setup(BUTTONS.get('j_l'), GPIO.IN) - GPIO.setup(BUTTONS.get('j_r'), GPIO.IN) - - GPIO.add_event_detect(BUTTONS.get('a'), GPIO.FALLING) - GPIO.add_event_detect(BUTTONS.get('b'), GPIO.FALLING) - GPIO.add_event_detect(BUTTONS.get('j_i'), GPIO.FALLING) - GPIO.add_event_detect(BUTTONS.get('j_u'), GPIO.FALLING) - GPIO.add_event_detect(BUTTONS.get('j_d'), GPIO.FALLING) - GPIO.add_event_detect(BUTTONS.get('j_l'), GPIO.FALLING) - GPIO.add_event_detect(BUTTONS.get('j_r'), GPIO.FALLING) - - -def teardown(): - """Clean up the GPIO handler.""" - GPIO.cleanup() - - -def get_press(button): - """ - Checks if a given button code has been pressed and returns a bool depending on the state. - Args: - button: button to be detected - - Returns: True if the button is has been pressed, False otherwise - - """ - return GPIO.event_detected(button) diff --git a/pocket_friends/game_files/io/input_handler.py b/pocket_friends/game_files/io/input_handler.py index c32be51..926ab48 100644 --- a/pocket_friends/game_files/io/input_handler.py +++ b/pocket_friends/game_files/io/input_handler.py @@ -1,6 +1,4 @@ import pygame -import pocket_friends.game_files.io.gpio_handler as gpio_handler - class InputHandler: """ @@ -37,17 +35,6 @@ class InputHandler: pygame.event.post(pygame.event.Event(pygame.KEYUP, {'key': pressed_button})) self.last_input_tick = pygame.time.get_ticks() - def handle_gpio(self): - """ - Handle GPIO events and create events for them. - """ - for pressed_button in gpio_handler.BUTTONS: - code = gpio_handler.BUTTONS.get(pressed_button) - - # Check if a button has been pressed. If it has, create a pygame event for it. - if gpio_handler.get_press(code): - self.create_event(code) - def handle_keyboard(self): """Handle keyboard presses and generate corresponding GPIO codes to create events.""" @@ -57,25 +44,22 @@ class InputHandler: running = False if keyboard_event.type == pygame.KEYDOWN: if keyboard_event.key == pygame.K_a: - self.create_event(gpio_handler.BUTTONS.get('a')) + self.create_event(pygame.K_a) if keyboard_event.key == pygame.K_b: - self.create_event(gpio_handler.BUTTONS.get('b')) - if keyboard_event.key == pygame.K_PERIOD: - self.create_event(gpio_handler.BUTTONS.get('j_i')) + self.create_event(pygame.K_b) + if keyboard_event.key == pygame.K_KP_ENTER: + self.create_event(pygame.K_KP_ENTER) if keyboard_event.key == pygame.K_RIGHT: - self.create_event(gpio_handler.BUTTONS.get('j_r')) + self.create_event(pygame.K_RIGHT) if keyboard_event.key == pygame.K_LEFT: - self.create_event(gpio_handler.BUTTONS.get('j_l')) + self.create_event(pygame.K_LEFT) if keyboard_event.key == pygame.K_DOWN: - self.create_event(gpio_handler.BUTTONS.get('j_d')) + self.create_event(pygame.K_DOWN) if keyboard_event.key == pygame.K_UP: - self.create_event(gpio_handler.BUTTONS.get('j_u')) + self.create_event(pygame.K_UP) if keyboard_event.key == pygame.K_ESCAPE: running = False def update(self): """Run either the GPIO handler or the keyboard handler to check for input and create events.""" - if gpio_handler.ON_HARDWARE: - self.handle_gpio() - else: - self.handle_keyboard() + self.handle_keyboard() diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py index 4ae54d1..50f097d 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -1,6 +1,5 @@ import pygame from ..elements import sprites -import pocket_friends.game_files.io.gpio_handler as gpio_handler from ..io.input_handler import InputHandler @@ -133,15 +132,15 @@ class Surface(pygame.Surface): for event in pygame.event.get(): if event.type == pygame.KEYDOWN: - if event.key == gpio_handler.BUTTONS.get('j_r'): + if event.key == pygame.K_RIGHT: self.sel_right() - if event.key == gpio_handler.BUTTONS.get('j_l'): + if event.key == pygame.K_LEFT: self.sel_left() - if event.key == gpio_handler.BUTTONS.get('j_d'): + if event.key == pygame.K_DOWN: self.sel_down() - if event.key == gpio_handler.BUTTONS.get('j_u'): + if event.key == pygame.K_UP: self.sel_up() - if event.key == gpio_handler.BUTTONS.get('a'): + if event.key == pygame.K_a: self.additional_args = {'selected_egg': self.selected_color} self.next_surface = 'selection_info' self.running = False diff --git a/pocket_friends/game_files/surfaces/error_screen.py b/pocket_friends/game_files/surfaces/error_screen.py index 5d4fe67..cb5a5cf 100644 --- a/pocket_friends/game_files/surfaces/error_screen.py +++ b/pocket_friends/game_files/surfaces/error_screen.py @@ -1,6 +1,5 @@ import pygame -from pocket_friends.game_files.io import gpio_handler from pocket_friends.game_files.io.input_handler import InputHandler @@ -36,6 +35,6 @@ class Surface(pygame.Surface): for event in pygame.event.get(): if event.type == pygame.KEYDOWN: - if event.key == gpio_handler.BUTTONS.get('b'): + if event.key == pygame.K_b: self.running = False print('stop') diff --git a/pocket_friends/game_files/surfaces/selection_info.py b/pocket_friends/game_files/surfaces/selection_info.py index 3c18877..2e69572 100644 --- a/pocket_friends/game_files/surfaces/selection_info.py +++ b/pocket_friends/game_files/surfaces/selection_info.py @@ -1,6 +1,5 @@ import pygame from ..elements import sprites -import pocket_friends.game_files.io.gpio_handler as gpio_handler from ..io.input_handler import InputHandler @@ -56,17 +55,17 @@ class Surface(pygame.Surface): for event in pygame.event.get(): if event.type == pygame.KEYDOWN: - if event.key == gpio_handler.BUTTONS.get('j_d'): + if event.key == pygame.K_DOWN: # Scroll down on the info screen. self.info_text.scroll_down() - if event.key == gpio_handler.BUTTONS.get('j_u'): + if event.key == pygame.K_UP: # Scroll up on the info screen. self.info_text.scroll_up() - if event.key == gpio_handler.BUTTONS.get('a'): + if event.key == pygame.K_a: self.running = False self.additional_args = {'selected_color': self.selected_egg} self.next_surface = 'playground' - if event.key == gpio_handler.BUTTONS.get('b'): + if event.key == pygame.K_b: self.running = False self.additional_args = {'selected_color': self.selected_egg} self.next_surface = 'egg_select' From 2b2c2d946a3e73fa7057b029cc42eef915cb5206 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 10:48:59 -0400 Subject: [PATCH 52/58] added a bool to disable tick checking if needed --- pocket_friends/game_files/io/input_handler.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pocket_friends/game_files/io/input_handler.py b/pocket_friends/game_files/io/input_handler.py index 926ab48..e04f7f0 100644 --- a/pocket_friends/game_files/io/input_handler.py +++ b/pocket_friends/game_files/io/input_handler.py @@ -1,5 +1,6 @@ import pygame + class InputHandler: """ Class that is implemented into surfaces in order to control the @@ -11,15 +12,17 @@ class InputHandler: """ - def __init__(self, pygame_clock): + def __init__(self, pygame_clock, tick_check=True): """ Create a InputHandler object using a given Pygame clock. Args: - pygame_clock (pygame.time.Clock): A pygame clock to use as the clock for input time calculations. + pygame_clock (:obj:`pygame.time.Clock`): A pygame clock to use as the clock for input time calculations. + tick_check (bool, optional): Bool to ignore inputs that happen to quickly after another. Defaults to True. """ self.clock = pygame_clock + self.tick_check = tick_check self.last_input_tick = 0 def create_event(self, pressed_button): @@ -30,7 +33,11 @@ class InputHandler: """ # Register a button click so long as the last button click happened no less than two frames ago - if pygame.time.get_ticks() - self.last_input_tick > self.clock.get_time() * 2 or not gpio_handler.ON_HARDWARE: + if self.tick_check: + if pygame.time.get_ticks() - self.last_input_tick > self.clock.get_time() * 2: + pygame.event.post(pygame.event.Event(pygame.KEYDOWN, {'key': pressed_button})) + pygame.event.post(pygame.event.Event(pygame.KEYUP, {'key': pressed_button})) + else: pygame.event.post(pygame.event.Event(pygame.KEYDOWN, {'key': pressed_button})) pygame.event.post(pygame.event.Event(pygame.KEYUP, {'key': pressed_button})) self.last_input_tick = pygame.time.get_ticks() From 63a87c12dd97e438392adb58ef4a0a4359249899 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 10:50:25 -0400 Subject: [PATCH 53/58] removed some old print statements --- pocket_friends/game_files/elements/sprites.py | 2 -- pocket_friends/game_files/surfaces/error_screen.py | 1 - 2 files changed, 3 deletions(-) diff --git a/pocket_friends/game_files/elements/sprites.py b/pocket_friends/game_files/elements/sprites.py index 1469c89..467ac7e 100644 --- a/pocket_friends/game_files/elements/sprites.py +++ b/pocket_friends/game_files/elements/sprites.py @@ -21,7 +21,6 @@ class SpriteSheet: # Load in whole sprite sheet as one image. sprite_sheet = pygame.image.load(sprite_sheet).convert_alpha() self.images = [] - print(type(self.images)) # Get the sprite sheet json file. with open(texture_json, 'r') as json_file: @@ -97,7 +96,6 @@ class SelectionEgg(pygame.sprite.Sprite): # Get the rectangle from the first image in the list self.rect = self._images[0].get_rect() - print(type(self.rect)) self._index = 0 self.image = self._images[self._index] diff --git a/pocket_friends/game_files/surfaces/error_screen.py b/pocket_friends/game_files/surfaces/error_screen.py index cb5a5cf..b0e0551 100644 --- a/pocket_friends/game_files/surfaces/error_screen.py +++ b/pocket_friends/game_files/surfaces/error_screen.py @@ -37,4 +37,3 @@ class Surface(pygame.Surface): if event.type == pygame.KEYDOWN: if event.key == pygame.K_b: self.running = False - print('stop') From 4904ed21844007f7098211b748e68d82e9b87b79 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 11:47:36 -0400 Subject: [PATCH 54/58] fixed documentation --- .../game_files/elements/__init__.py | 2 +- pocket_friends/game_files/elements/sprites.py | 19 +++++++++++++------ pocket_friends/game_files/io/__init__.py | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/pocket_friends/game_files/elements/__init__.py b/pocket_friends/game_files/elements/__init__.py index 6867307..7f96f12 100644 --- a/pocket_friends/game_files/elements/__init__.py +++ b/pocket_friends/game_files/elements/__init__.py @@ -1 +1 @@ -"""Sub-module for use in the game. Helps with the drawing of various objects such as sprites and text boxes.""" +"""Submodule for use in the game. Helps with the drawing of various objects such as sprites and text boxes.""" diff --git a/pocket_friends/game_files/elements/sprites.py b/pocket_friends/game_files/elements/sprites.py index 467ac7e..1752dab 100644 --- a/pocket_friends/game_files/elements/sprites.py +++ b/pocket_friends/game_files/elements/sprites.py @@ -113,9 +113,14 @@ class InfoText: Class for drawing large amounts of text on the screen at a time """ - def __init__(self, resources_dir, game_res, text='Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' - 'Nam commodo tempor aliquet. Suspendisse placerat accumsan' - ' neque, nec volutpat nunc porta ut.'): + def __init__(self, resources_dir, game_res, text='Test text.'): + """ + Creates an InfoText object to be used on a surface. + Args: + resources_dir (str): The full path of the game's resources directory + game_res (int): The internal resolution of the game. Used for correct scaling. + text (:obj:`str`, optional): The given text to render. Defaults to "Test text."' + """ self.font = pygame.font.Font(resources_dir + '/fonts/5Pts5.ttf', 10) self.text = [] # Text broken up into a list according to how it will fit on screen. @@ -188,8 +193,9 @@ class InfoText: def draw(self, surface): """ - Draws the text on a given surface. - :param surface: The surface for the text to be drawn on. + Draw the text on a given surface. + Args: + surface (:obj:`pygame.Surface`): The surface to draw the text on """ # Constants to help draw the text line_separation = 7 @@ -264,7 +270,8 @@ class EggInfo: def draw(self, surface): """ Draw the info icons on a given surface. - :param surface: the surface to draw the icons on. + Args: + surface (:obj:`pygame.Surface`): The surface to draw the text on """ # Blit the info onto the given surface. surface.blit(self.surface, (self.x, self.y)) diff --git a/pocket_friends/game_files/io/__init__.py b/pocket_friends/game_files/io/__init__.py index d266b0e..8828bf5 100644 --- a/pocket_friends/game_files/io/__init__.py +++ b/pocket_friends/game_files/io/__init__.py @@ -1,2 +1,2 @@ -"""Sub-package for handling all I/O operations including keyboard input (GPIO input when connected to a Raspberry Pi) +"""Subpackage for handling all I/O operations including keyboard input (GPIO input when connected to a Raspberry Pi) and save data reading and writing.""" \ No newline at end of file From 41ab0406f847473e877036600006ef7dc66ee605 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 11:47:48 -0400 Subject: [PATCH 55/58] removed unused import --- pocket_friends/game_files/game.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game_files/game.py index 63ec1ce..19ebd74 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game_files/game.py @@ -1,6 +1,5 @@ import pygame import os -from pathlib import Path import pocket_friends import importlib @@ -28,7 +27,7 @@ script_dir = os.path.dirname(os.path.abspath(__file__)) resources_dir = script_dir + '/resources' # Makes Pygame draw on the display of the RPi. -os.environ["SDL_FBDEV"] = "/dev/fb1" +os.environ['SDL_FBDEV'] = '/dev/fb1' def game(resolution=240): From 83a7e98a7fd4f9ea9653cb8a2d1d3ce10574568b Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 13:07:33 -0400 Subject: [PATCH 56/58] created surface.py and GameSurface class --- compile.py | 2 +- pocket_friends/development/menus.py | 2 +- pocket_friends/game_files/elements/surface.py | 46 +++++++++++++++++++ .../game_files/surfaces/egg_select.py | 29 ++---------- .../game_files/surfaces/error_screen.py | 24 +++------- .../game_files/surfaces/selection_info.py | 42 ++++------------- pocket_friends/game_files/surfaces/title.py | 26 +++++------ 7 files changed, 82 insertions(+), 89 deletions(-) create mode 100644 pocket_friends/game_files/elements/surface.py diff --git a/compile.py b/compile.py index c46b9b8..47c4954 100644 --- a/compile.py +++ b/compile.py @@ -4,7 +4,7 @@ import pocket_friends script_dir = os.path.dirname(os.path.abspath(__file__)) -PyInstaller.__main__.run([ +PyInstaller.__main__.preprocess([ '{0}/pocket_friends/__main__.py'.format(script_dir), '--clean', '--noconsole', diff --git a/pocket_friends/development/menus.py b/pocket_friends/development/menus.py index 45cd56b..6e8d62d 100644 --- a/pocket_friends/development/menus.py +++ b/pocket_friends/development/menus.py @@ -63,7 +63,7 @@ class Menu: :param kwargs: keyword arguments to be passed to the function """ try: - return self._options[self._selection].run(*args, **kwargs) + return self._options[self._selection].preprocess(*args, **kwargs) except IndexError as ex: raise Exception('menu has no options, cannot run a non-existent option') from ex diff --git a/pocket_friends/game_files/elements/surface.py b/pocket_friends/game_files/elements/surface.py new file mode 100644 index 0000000..663f499 --- /dev/null +++ b/pocket_friends/game_files/elements/surface.py @@ -0,0 +1,46 @@ +"""Module to aid in the drawing of surfaces to make switching from one screen to another easier.""" +import pygame +from ..io.input_handler import InputHandler + + +class GameSurface(pygame.Surface): + """ + Class to be used as the backbone of all game surfaces. + Attributes: + running (bool): Boolean to tell whether the surface is running or not. + next_surface (:obj:`str`): What the next surface should be after halting. + resource_dir (:obj:`str`): The path of the game's main resource directory. + game_fps (int): How many frames per second the game will run at. + additional_args (dict): Additional arguments to send to the next surface after halting. + """ + def __init__(self, game_res, resources_dir, game_fps): + """ + Create a GameSurface object. + Args: + game_res (int): The internal resolution of the surface. + resources_dir (:obj:`str`): The path of the game's main resource directory. + game_fps: (int): How many frames per second the game will run at. + """ + super().__init__(game_res, pygame.SRCALPHA) + self.running = True + self.next_surface = None + self.resource_dir = resources_dir + self._clock = pygame.time.Clock() + self.game_fps = game_fps + self._input_handler = InputHandler(self._clock) + self.additional_args = {} + + self._bg = pygame.image.load(self.resource_dir + '/images/bg.png').convert_alpha() + self.sprites = pygame.sprite.Group() + + def preprocess(self): + """ + Advance the surface by one frame and draw the background. + """ + self._clock.tick(self.game_fps) + + self.blit(self._bg, (0, 0)) + self.sprites.update() + self.sprites.draw(self) + + self._input_handler.update() diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/game_files/surfaces/egg_select.py index 50f097d..bc8edcf 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/game_files/surfaces/egg_select.py @@ -1,22 +1,9 @@ import pygame -from ..elements import sprites -from ..io.input_handler import InputHandler +from ..elements import sprites, surface - -class Surface(pygame.Surface): - def __init__(self, window_size, resources_dir, game_fps, **kwargs): - super().__init__(window_size, pygame.SRCALPHA) - self.name = 'egg_select' - self.running = True - self.next_surface = None - self.resource_dir = resources_dir - self.clock = pygame.time.Clock() - self.game_fps = game_fps - self.input_handler = InputHandler(self.clock) - self.additional_args = {} - - self.bg = pygame.image.load(self.resource_dir + '/images/bg.png').convert_alpha() - self.sprites = pygame.sprite.Group() +class Surface(surface.GameSurface): + def __init__(self, game_res, resources_dir, game_fps, **kwargs): + super().__init__(game_res, resources_dir, game_fps) preselected_color = None for key in kwargs.keys(): @@ -116,13 +103,7 @@ class Surface(pygame.Surface): self.selected_egg += self.eggs_per_row def update(self): - self.clock.tick(self.game_fps) - - self.blit(self.bg, (0, 0)) - self.sprites.update() - self.sprites.draw(self) - - self.input_handler.update() + self.preprocess() cursor = pygame.image.load( self.resource_dir + '/images/gui/egg_selector.png').convert_alpha() diff --git a/pocket_friends/game_files/surfaces/error_screen.py b/pocket_friends/game_files/surfaces/error_screen.py index b0e0551..026a12a 100644 --- a/pocket_friends/game_files/surfaces/error_screen.py +++ b/pocket_friends/game_files/surfaces/error_screen.py @@ -1,29 +1,21 @@ import pygame - +from ..elements import surface from pocket_friends.game_files.io.input_handler import InputHandler -class Surface(pygame.Surface): - def __init__(self, window_size, resources_dir, game_fps, **kwargs): - super().__init__(window_size, pygame.SRCALPHA) - self.name = 'error_screen' - self.running = True - self.next_surface = 'title' - self.clock = pygame.time.Clock() - self.input_handler = InputHandler(self.clock) - self.additional_args = {} - - self.bg = pygame.image.load(resources_dir + '/images/bg.png').convert_alpha() - self.title = pygame.image.load(resources_dir + '/images/debug/invalid.png').convert_alpha() +class Surface(surface.GameSurface): + def __init__(self, game_res, resources_dir, game_fps, **kwargs): + super().__init__(game_res, resources_dir, game_fps) self.frames = 1 self.game_fps = game_fps self.delay = 1 self.font = pygame.font.Font(resources_dir + '/fonts/5Pts5.ttf', 10) + self.title = pygame.image.load(resources_dir + '/images/debug/invalid.png').convert_alpha() + self.next_surface = 'title' def update(self): - self.clock.tick(self.game_fps) + self.preprocess() - self.blit(self.bg, (0, 0)) self.blit(self.title, (0, -4)) text = self.font.render('Frames: {0}'.format(self.frames), False, (64, 64, 64)) self.blit(text, (3, 68)) @@ -31,8 +23,6 @@ class Surface(pygame.Surface): self.frames += 1 self.frames %= self.game_fps - self.input_handler.update() - for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_b: diff --git a/pocket_friends/game_files/surfaces/selection_info.py b/pocket_friends/game_files/surfaces/selection_info.py index 2e69572..071c6f4 100644 --- a/pocket_friends/game_files/surfaces/selection_info.py +++ b/pocket_friends/game_files/surfaces/selection_info.py @@ -1,33 +1,16 @@ import pygame -from ..elements import sprites +from ..elements import sprites, surface from ..io.input_handler import InputHandler -class Surface(pygame.Surface): - """ +class Surface(surface.GameSurface): + def __init__(self, game_res, resources_dir, game_fps, **kwargs): + super().__init__(game_res, resources_dir, game_fps) - """ - def __init__(self, window_size, resources_dir, game_fps, **kwargs): - """ - - Args: - window_size: - resources_dir: - game_fps: - **kwargs: - """ - super().__init__(window_size, pygame.SRCALPHA) - self.name = 'selection_info' - self.running = True - self.next_surface = None - self.resource_dir = resources_dir - self.clock = pygame.time.Clock() - self.game_fps = game_fps - self.input_handler = InputHandler(self.clock) - self.additional_args = {} - - self.bg = pygame.image.load(self.resource_dir + '/images/bg.png').convert_alpha() - self.sprites = pygame.sprite.Group() + preselected_color = None + for key in kwargs.keys(): + if key == 'selected_color': + preselected_color = kwargs.get(key) self.selected_egg = None for key in kwargs.keys(): @@ -39,20 +22,15 @@ class Surface(pygame.Surface): egg.rect.y = 3 self.sprites.add(egg) - self.info_text = sprites.InfoText(resources_dir, window_size[0], egg.description) + self.info_text = sprites.InfoText(resources_dir, game_res[0], egg.description) self.info_icons = sprites.EggInfo(resources_dir, egg.contentedness, egg.metabolism, (32, 4)) def update(self): - self.clock.tick(self.game_fps) + self.preprocess() - self.blit(self.bg, (0, 0)) - self.sprites.update() - self.sprites.draw(self) self.info_text.draw(self) self.info_icons.draw(self) - self.input_handler.update() - for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_DOWN: diff --git a/pocket_friends/game_files/surfaces/title.py b/pocket_friends/game_files/surfaces/title.py index 350063e..9f05801 100644 --- a/pocket_friends/game_files/surfaces/title.py +++ b/pocket_friends/game_files/surfaces/title.py @@ -1,26 +1,24 @@ import pygame +from ..elements import surface -class Surface(pygame.Surface): - def __init__(self, window_size, resources_dir, game_fps): - super().__init__(window_size, pygame.SRCALPHA) - self.name = 'title' - self.running = True - self.next_surface = None - self.clock = pygame.time.Clock() - self.additional_args = {} +class Surface(surface.GameSurface): + def __init__(self, game_res, resources_dir, game_fps): + super().__init__(game_res, resources_dir, game_fps) - self.bg = pygame.image.load(resources_dir + '/images/bg.png').convert_alpha() - self.title = pygame.image.load(resources_dir + '/images/title.png').convert_alpha() - self.frames = 1 - self.game_fps = game_fps + self.frames = 0 self.delay = 1 + self.title = pygame.image.load(resources_dir + '/images/title.png').convert_alpha() + def update(self): - self.clock.tick(self.game_fps) - self.blit(self.bg, (0, 0)) + """ + Advance the surface logic by one frame. + """ + self.preprocess() self.blit(self.title, (0, 0)) + print(self.frames) self.frames += 1 if self.frames > self.game_fps * self.delay: self.next_surface = 'egg_select' From 06755ee937f285d87cada20933de56998af6713b Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sat, 13 May 2023 13:11:47 -0400 Subject: [PATCH 57/58] rearragned project, removed unneeded game_files folder --- pocket_friends/__init__.py | 2 +- pocket_friends/__main__.py | 2 +- .../{game_files => }/elements/__init__.py | 0 pocket_friends/{game_files => }/elements/sprites.py | 0 pocket_friends/{game_files => }/elements/surface.py | 0 pocket_friends/{game_files => }/game.py | 2 +- pocket_friends/{game_files => }/io/__init__.py | 0 pocket_friends/{game_files => }/io/data.py | 0 pocket_friends/{game_files => }/io/input_handler.py | 0 .../resources/data/bloop_info/blue.json | 0 .../resources/data/bloop_info/dev_egg.json | 0 .../resources/data/bloop_info/rainbow.json | 0 .../resources/data/bloop_info/red.json | 0 .../{game_files => }/resources/fonts/5Pts5.ttf | Bin .../{game_files => }/resources/icon/icon.ico | Bin .../{game_files => }/resources/icon/icon.png | Bin .../{game_files => }/resources/images/bg.png | Bin .../images/bloops/_postponed/green/green.png | Bin .../images/bloops/_postponed/indigo/indigo.png | Bin .../images/bloops/_postponed/orange/orange.png | Bin .../images/bloops/_postponed/violet/violet.png | Bin .../images/bloops/_postponed/white/white.png | Bin .../images/bloops/_postponed/yellow/yellow.png | Bin .../resources/images/bloops/blue/egg.json | 0 .../resources/images/bloops/blue/egg.png | Bin .../resources/images/bloops/dev_egg/baby.json | 0 .../resources/images/bloops/dev_egg/baby.png | Bin .../resources/images/bloops/dev_egg/egg.json | 0 .../resources/images/bloops/dev_egg/egg.png | Bin .../resources/images/bloops/rainbow/egg.json | 0 .../resources/images/bloops/rainbow/egg.png | Bin .../resources/images/bloops/red/egg.json | 0 .../resources/images/bloops/red/egg.png | Bin .../resources/images/debug/invalid.png | Bin .../{game_files => }/resources/images/gui/apple.png | Bin .../resources/images/gui/bar_graphic.png | Bin .../resources/images/gui/bar_outline.png | Bin .../resources/images/gui/blank_star.png | Bin .../resources/images/gui/down_arrow.png | Bin .../resources/images/gui/egg_selector.png | Bin .../resources/images/gui/popup_menu/apple.json | 0 .../resources/images/gui/popup_menu/apple.png | Bin .../resources/images/gui/popup_menu/bed.json | 0 .../resources/images/gui/popup_menu/bed.png | Bin .../resources/images/gui/popup_menu/controller.json | 0 .../resources/images/gui/popup_menu/controller.png | Bin .../resources/images/gui/popup_menu/dumbbell.json | 0 .../resources/images/gui/popup_menu/dumbbell.png | Bin .../resources/images/gui/popup_menu/frame.png | Bin .../resources/images/gui/popup_menu/stats.json | 0 .../resources/images/gui/popup_menu/stats.png | Bin .../resources/images/gui/smiley.png | Bin .../{game_files => }/resources/images/gui/star.png | Bin .../resources/images/gui/up_arrow.png | Bin .../resources/images/promotional.png | Bin .../{game_files => }/resources/images/title.png | Bin .../{game_files => }/surfaces/__init__.py | 0 .../{game_files => }/surfaces/egg_select.py | 4 +++- .../{game_files => }/surfaces/error_screen.py | 3 +-- .../{game_files => }/surfaces/selection_info.py | 4 ++-- pocket_friends/{game_files => }/surfaces/title.py | 2 +- 61 files changed, 10 insertions(+), 9 deletions(-) rename pocket_friends/{game_files => }/elements/__init__.py (100%) rename pocket_friends/{game_files => }/elements/sprites.py (100%) rename pocket_friends/{game_files => }/elements/surface.py (100%) rename pocket_friends/{game_files => }/game.py (98%) rename pocket_friends/{game_files => }/io/__init__.py (100%) rename pocket_friends/{game_files => }/io/data.py (100%) rename pocket_friends/{game_files => }/io/input_handler.py (100%) rename pocket_friends/{game_files => }/resources/data/bloop_info/blue.json (100%) rename pocket_friends/{game_files => }/resources/data/bloop_info/dev_egg.json (100%) rename pocket_friends/{game_files => }/resources/data/bloop_info/rainbow.json (100%) rename pocket_friends/{game_files => }/resources/data/bloop_info/red.json (100%) rename pocket_friends/{game_files => }/resources/fonts/5Pts5.ttf (100%) rename pocket_friends/{game_files => }/resources/icon/icon.ico (100%) rename pocket_friends/{game_files => }/resources/icon/icon.png (100%) rename pocket_friends/{game_files => }/resources/images/bg.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/_postponed/green/green.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/_postponed/indigo/indigo.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/_postponed/orange/orange.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/_postponed/violet/violet.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/_postponed/white/white.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/_postponed/yellow/yellow.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/blue/egg.json (100%) rename pocket_friends/{game_files => }/resources/images/bloops/blue/egg.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/dev_egg/baby.json (100%) rename pocket_friends/{game_files => }/resources/images/bloops/dev_egg/baby.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/dev_egg/egg.json (100%) rename pocket_friends/{game_files => }/resources/images/bloops/dev_egg/egg.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/rainbow/egg.json (100%) rename pocket_friends/{game_files => }/resources/images/bloops/rainbow/egg.png (100%) rename pocket_friends/{game_files => }/resources/images/bloops/red/egg.json (100%) rename pocket_friends/{game_files => }/resources/images/bloops/red/egg.png (100%) rename pocket_friends/{game_files => }/resources/images/debug/invalid.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/apple.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/bar_graphic.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/bar_outline.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/blank_star.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/down_arrow.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/egg_selector.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/apple.json (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/apple.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/bed.json (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/bed.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/controller.json (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/controller.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/dumbbell.json (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/dumbbell.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/frame.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/stats.json (100%) rename pocket_friends/{game_files => }/resources/images/gui/popup_menu/stats.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/smiley.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/star.png (100%) rename pocket_friends/{game_files => }/resources/images/gui/up_arrow.png (100%) rename pocket_friends/{game_files => }/resources/images/promotional.png (100%) rename pocket_friends/{game_files => }/resources/images/title.png (100%) rename pocket_friends/{game_files => }/surfaces/__init__.py (100%) rename pocket_friends/{game_files => }/surfaces/egg_select.py (98%) rename pocket_friends/{game_files => }/surfaces/error_screen.py (90%) rename pocket_friends/{game_files => }/surfaces/selection_info.py (95%) rename pocket_friends/{game_files => }/surfaces/title.py (93%) diff --git a/pocket_friends/__init__.py b/pocket_friends/__init__.py index e5a9890..cb23a34 100644 --- a/pocket_friends/__init__.py +++ b/pocket_friends/__init__.py @@ -1,4 +1,4 @@ """Pocket Friends is a game where you raise your own little pocket friend! These pocket friends, called bloops, are great little companions to have! You can feed them, play with them, and watch them grow up!""" -__version__ = 'dev_0.0.3' +__version__ = 'dev_0.0.4' diff --git a/pocket_friends/__main__.py b/pocket_friends/__main__.py index 4c55047..7347b8a 100644 --- a/pocket_friends/__main__.py +++ b/pocket_friends/__main__.py @@ -5,7 +5,7 @@ import os import pygame import sys from pathlib import Path -import pocket_friends.game_files.game as game +import pocket_friends.game as game if __name__ == '__main__': enable_dev = False diff --git a/pocket_friends/game_files/elements/__init__.py b/pocket_friends/elements/__init__.py similarity index 100% rename from pocket_friends/game_files/elements/__init__.py rename to pocket_friends/elements/__init__.py diff --git a/pocket_friends/game_files/elements/sprites.py b/pocket_friends/elements/sprites.py similarity index 100% rename from pocket_friends/game_files/elements/sprites.py rename to pocket_friends/elements/sprites.py diff --git a/pocket_friends/game_files/elements/surface.py b/pocket_friends/elements/surface.py similarity index 100% rename from pocket_friends/game_files/elements/surface.py rename to pocket_friends/elements/surface.py diff --git a/pocket_friends/game_files/game.py b/pocket_friends/game.py similarity index 98% rename from pocket_friends/game_files/game.py rename to pocket_friends/game.py index 19ebd74..fc38328 100644 --- a/pocket_friends/game_files/game.py +++ b/pocket_friends/game.py @@ -14,7 +14,7 @@ valid_surfaces = [ # Add all the surface modules to a dictionary for easy switching surface_modules = {} for module in valid_surfaces: - surface_modules[module] = importlib.import_module('pocket_friends.game_files.surfaces.{0}'.format(module)) + surface_modules[module] = importlib.import_module('pocket_friends.surfaces.{0}'.format(module)) starting_surface = 'title' # FPS for the game to run at. diff --git a/pocket_friends/game_files/io/__init__.py b/pocket_friends/io/__init__.py similarity index 100% rename from pocket_friends/game_files/io/__init__.py rename to pocket_friends/io/__init__.py diff --git a/pocket_friends/game_files/io/data.py b/pocket_friends/io/data.py similarity index 100% rename from pocket_friends/game_files/io/data.py rename to pocket_friends/io/data.py diff --git a/pocket_friends/game_files/io/input_handler.py b/pocket_friends/io/input_handler.py similarity index 100% rename from pocket_friends/game_files/io/input_handler.py rename to pocket_friends/io/input_handler.py diff --git a/pocket_friends/game_files/resources/data/bloop_info/blue.json b/pocket_friends/resources/data/bloop_info/blue.json similarity index 100% rename from pocket_friends/game_files/resources/data/bloop_info/blue.json rename to pocket_friends/resources/data/bloop_info/blue.json diff --git a/pocket_friends/game_files/resources/data/bloop_info/dev_egg.json b/pocket_friends/resources/data/bloop_info/dev_egg.json similarity index 100% rename from pocket_friends/game_files/resources/data/bloop_info/dev_egg.json rename to pocket_friends/resources/data/bloop_info/dev_egg.json diff --git a/pocket_friends/game_files/resources/data/bloop_info/rainbow.json b/pocket_friends/resources/data/bloop_info/rainbow.json similarity index 100% rename from pocket_friends/game_files/resources/data/bloop_info/rainbow.json rename to pocket_friends/resources/data/bloop_info/rainbow.json diff --git a/pocket_friends/game_files/resources/data/bloop_info/red.json b/pocket_friends/resources/data/bloop_info/red.json similarity index 100% rename from pocket_friends/game_files/resources/data/bloop_info/red.json rename to pocket_friends/resources/data/bloop_info/red.json diff --git a/pocket_friends/game_files/resources/fonts/5Pts5.ttf b/pocket_friends/resources/fonts/5Pts5.ttf similarity index 100% rename from pocket_friends/game_files/resources/fonts/5Pts5.ttf rename to pocket_friends/resources/fonts/5Pts5.ttf diff --git a/pocket_friends/game_files/resources/icon/icon.ico b/pocket_friends/resources/icon/icon.ico similarity index 100% rename from pocket_friends/game_files/resources/icon/icon.ico rename to pocket_friends/resources/icon/icon.ico diff --git a/pocket_friends/game_files/resources/icon/icon.png b/pocket_friends/resources/icon/icon.png similarity index 100% rename from pocket_friends/game_files/resources/icon/icon.png rename to pocket_friends/resources/icon/icon.png diff --git a/pocket_friends/game_files/resources/images/bg.png b/pocket_friends/resources/images/bg.png similarity index 100% rename from pocket_friends/game_files/resources/images/bg.png rename to pocket_friends/resources/images/bg.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/green/green.png b/pocket_friends/resources/images/bloops/_postponed/green/green.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/green/green.png rename to pocket_friends/resources/images/bloops/_postponed/green/green.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/indigo/indigo.png b/pocket_friends/resources/images/bloops/_postponed/indigo/indigo.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/indigo/indigo.png rename to pocket_friends/resources/images/bloops/_postponed/indigo/indigo.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/orange/orange.png b/pocket_friends/resources/images/bloops/_postponed/orange/orange.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/orange/orange.png rename to pocket_friends/resources/images/bloops/_postponed/orange/orange.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/violet/violet.png b/pocket_friends/resources/images/bloops/_postponed/violet/violet.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/violet/violet.png rename to pocket_friends/resources/images/bloops/_postponed/violet/violet.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/white/white.png b/pocket_friends/resources/images/bloops/_postponed/white/white.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/white/white.png rename to pocket_friends/resources/images/bloops/_postponed/white/white.png diff --git a/pocket_friends/game_files/resources/images/bloops/_postponed/yellow/yellow.png b/pocket_friends/resources/images/bloops/_postponed/yellow/yellow.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/_postponed/yellow/yellow.png rename to pocket_friends/resources/images/bloops/_postponed/yellow/yellow.png diff --git a/pocket_friends/game_files/resources/images/bloops/blue/egg.json b/pocket_friends/resources/images/bloops/blue/egg.json similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/blue/egg.json rename to pocket_friends/resources/images/bloops/blue/egg.json diff --git a/pocket_friends/game_files/resources/images/bloops/blue/egg.png b/pocket_friends/resources/images/bloops/blue/egg.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/blue/egg.png rename to pocket_friends/resources/images/bloops/blue/egg.png diff --git a/pocket_friends/game_files/resources/images/bloops/dev_egg/baby.json b/pocket_friends/resources/images/bloops/dev_egg/baby.json similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/dev_egg/baby.json rename to pocket_friends/resources/images/bloops/dev_egg/baby.json diff --git a/pocket_friends/game_files/resources/images/bloops/dev_egg/baby.png b/pocket_friends/resources/images/bloops/dev_egg/baby.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/dev_egg/baby.png rename to pocket_friends/resources/images/bloops/dev_egg/baby.png diff --git a/pocket_friends/game_files/resources/images/bloops/dev_egg/egg.json b/pocket_friends/resources/images/bloops/dev_egg/egg.json similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/dev_egg/egg.json rename to pocket_friends/resources/images/bloops/dev_egg/egg.json diff --git a/pocket_friends/game_files/resources/images/bloops/dev_egg/egg.png b/pocket_friends/resources/images/bloops/dev_egg/egg.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/dev_egg/egg.png rename to pocket_friends/resources/images/bloops/dev_egg/egg.png diff --git a/pocket_friends/game_files/resources/images/bloops/rainbow/egg.json b/pocket_friends/resources/images/bloops/rainbow/egg.json similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/rainbow/egg.json rename to pocket_friends/resources/images/bloops/rainbow/egg.json diff --git a/pocket_friends/game_files/resources/images/bloops/rainbow/egg.png b/pocket_friends/resources/images/bloops/rainbow/egg.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/rainbow/egg.png rename to pocket_friends/resources/images/bloops/rainbow/egg.png diff --git a/pocket_friends/game_files/resources/images/bloops/red/egg.json b/pocket_friends/resources/images/bloops/red/egg.json similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/red/egg.json rename to pocket_friends/resources/images/bloops/red/egg.json diff --git a/pocket_friends/game_files/resources/images/bloops/red/egg.png b/pocket_friends/resources/images/bloops/red/egg.png similarity index 100% rename from pocket_friends/game_files/resources/images/bloops/red/egg.png rename to pocket_friends/resources/images/bloops/red/egg.png diff --git a/pocket_friends/game_files/resources/images/debug/invalid.png b/pocket_friends/resources/images/debug/invalid.png similarity index 100% rename from pocket_friends/game_files/resources/images/debug/invalid.png rename to pocket_friends/resources/images/debug/invalid.png diff --git a/pocket_friends/game_files/resources/images/gui/apple.png b/pocket_friends/resources/images/gui/apple.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/apple.png rename to pocket_friends/resources/images/gui/apple.png diff --git a/pocket_friends/game_files/resources/images/gui/bar_graphic.png b/pocket_friends/resources/images/gui/bar_graphic.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/bar_graphic.png rename to pocket_friends/resources/images/gui/bar_graphic.png diff --git a/pocket_friends/game_files/resources/images/gui/bar_outline.png b/pocket_friends/resources/images/gui/bar_outline.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/bar_outline.png rename to pocket_friends/resources/images/gui/bar_outline.png diff --git a/pocket_friends/game_files/resources/images/gui/blank_star.png b/pocket_friends/resources/images/gui/blank_star.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/blank_star.png rename to pocket_friends/resources/images/gui/blank_star.png diff --git a/pocket_friends/game_files/resources/images/gui/down_arrow.png b/pocket_friends/resources/images/gui/down_arrow.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/down_arrow.png rename to pocket_friends/resources/images/gui/down_arrow.png diff --git a/pocket_friends/game_files/resources/images/gui/egg_selector.png b/pocket_friends/resources/images/gui/egg_selector.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/egg_selector.png rename to pocket_friends/resources/images/gui/egg_selector.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/apple.json b/pocket_friends/resources/images/gui/popup_menu/apple.json similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/apple.json rename to pocket_friends/resources/images/gui/popup_menu/apple.json diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/apple.png b/pocket_friends/resources/images/gui/popup_menu/apple.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/apple.png rename to pocket_friends/resources/images/gui/popup_menu/apple.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/bed.json b/pocket_friends/resources/images/gui/popup_menu/bed.json similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/bed.json rename to pocket_friends/resources/images/gui/popup_menu/bed.json diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/bed.png b/pocket_friends/resources/images/gui/popup_menu/bed.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/bed.png rename to pocket_friends/resources/images/gui/popup_menu/bed.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/controller.json b/pocket_friends/resources/images/gui/popup_menu/controller.json similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/controller.json rename to pocket_friends/resources/images/gui/popup_menu/controller.json diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/controller.png b/pocket_friends/resources/images/gui/popup_menu/controller.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/controller.png rename to pocket_friends/resources/images/gui/popup_menu/controller.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.json b/pocket_friends/resources/images/gui/popup_menu/dumbbell.json similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.json rename to pocket_friends/resources/images/gui/popup_menu/dumbbell.json diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.png b/pocket_friends/resources/images/gui/popup_menu/dumbbell.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/dumbbell.png rename to pocket_friends/resources/images/gui/popup_menu/dumbbell.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/frame.png b/pocket_friends/resources/images/gui/popup_menu/frame.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/frame.png rename to pocket_friends/resources/images/gui/popup_menu/frame.png diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/stats.json b/pocket_friends/resources/images/gui/popup_menu/stats.json similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/stats.json rename to pocket_friends/resources/images/gui/popup_menu/stats.json diff --git a/pocket_friends/game_files/resources/images/gui/popup_menu/stats.png b/pocket_friends/resources/images/gui/popup_menu/stats.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/popup_menu/stats.png rename to pocket_friends/resources/images/gui/popup_menu/stats.png diff --git a/pocket_friends/game_files/resources/images/gui/smiley.png b/pocket_friends/resources/images/gui/smiley.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/smiley.png rename to pocket_friends/resources/images/gui/smiley.png diff --git a/pocket_friends/game_files/resources/images/gui/star.png b/pocket_friends/resources/images/gui/star.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/star.png rename to pocket_friends/resources/images/gui/star.png diff --git a/pocket_friends/game_files/resources/images/gui/up_arrow.png b/pocket_friends/resources/images/gui/up_arrow.png similarity index 100% rename from pocket_friends/game_files/resources/images/gui/up_arrow.png rename to pocket_friends/resources/images/gui/up_arrow.png diff --git a/pocket_friends/game_files/resources/images/promotional.png b/pocket_friends/resources/images/promotional.png similarity index 100% rename from pocket_friends/game_files/resources/images/promotional.png rename to pocket_friends/resources/images/promotional.png diff --git a/pocket_friends/game_files/resources/images/title.png b/pocket_friends/resources/images/title.png similarity index 100% rename from pocket_friends/game_files/resources/images/title.png rename to pocket_friends/resources/images/title.png diff --git a/pocket_friends/game_files/surfaces/__init__.py b/pocket_friends/surfaces/__init__.py similarity index 100% rename from pocket_friends/game_files/surfaces/__init__.py rename to pocket_friends/surfaces/__init__.py diff --git a/pocket_friends/game_files/surfaces/egg_select.py b/pocket_friends/surfaces/egg_select.py similarity index 98% rename from pocket_friends/game_files/surfaces/egg_select.py rename to pocket_friends/surfaces/egg_select.py index bc8edcf..525dac0 100644 --- a/pocket_friends/game_files/surfaces/egg_select.py +++ b/pocket_friends/surfaces/egg_select.py @@ -1,5 +1,7 @@ import pygame -from ..elements import sprites, surface +from pocket_friends.elements import sprites +from pocket_friends.elements import surface + class Surface(surface.GameSurface): def __init__(self, game_res, resources_dir, game_fps, **kwargs): diff --git a/pocket_friends/game_files/surfaces/error_screen.py b/pocket_friends/surfaces/error_screen.py similarity index 90% rename from pocket_friends/game_files/surfaces/error_screen.py rename to pocket_friends/surfaces/error_screen.py index 026a12a..1aa1800 100644 --- a/pocket_friends/game_files/surfaces/error_screen.py +++ b/pocket_friends/surfaces/error_screen.py @@ -1,6 +1,5 @@ import pygame -from ..elements import surface -from pocket_friends.game_files.io.input_handler import InputHandler +from pocket_friends.elements import surface class Surface(surface.GameSurface): diff --git a/pocket_friends/game_files/surfaces/selection_info.py b/pocket_friends/surfaces/selection_info.py similarity index 95% rename from pocket_friends/game_files/surfaces/selection_info.py rename to pocket_friends/surfaces/selection_info.py index 071c6f4..3d9bb30 100644 --- a/pocket_friends/game_files/surfaces/selection_info.py +++ b/pocket_friends/surfaces/selection_info.py @@ -1,6 +1,6 @@ import pygame -from ..elements import sprites, surface -from ..io.input_handler import InputHandler +from pocket_friends.elements import sprites +from pocket_friends.elements import surface class Surface(surface.GameSurface): diff --git a/pocket_friends/game_files/surfaces/title.py b/pocket_friends/surfaces/title.py similarity index 93% rename from pocket_friends/game_files/surfaces/title.py rename to pocket_friends/surfaces/title.py index 9f05801..57087c6 100644 --- a/pocket_friends/game_files/surfaces/title.py +++ b/pocket_friends/surfaces/title.py @@ -1,5 +1,5 @@ import pygame -from ..elements import surface +from pocket_friends.elements import surface class Surface(surface.GameSurface): From 6a0201da85d06ba3fb8c4c22e9cf2f3599b9e947 Mon Sep 17 00:00:00 2001 From: Nicholas Dyer Date: Sun, 14 May 2023 17:10:34 -0400 Subject: [PATCH 58/58] removed redundant starting function --- pocket_friends/__main__.py | 2 +- pocket_friends/game.py | 12 +----------- pocket_friends/surfaces/__init__.py | 0 3 files changed, 2 insertions(+), 12 deletions(-) delete mode 100644 pocket_friends/surfaces/__init__.py diff --git a/pocket_friends/__main__.py b/pocket_friends/__main__.py index 7347b8a..c742d8a 100644 --- a/pocket_friends/__main__.py +++ b/pocket_friends/__main__.py @@ -20,7 +20,7 @@ if __name__ == '__main__': if '--res=' in arg: resolution = int(arg.split('=')[1]) - game.main(resolution) + game.start_game(resolution) pygame.quit() sys.exit() diff --git a/pocket_friends/game.py b/pocket_friends/game.py index fc38328..f4019ca 100644 --- a/pocket_friends/game.py +++ b/pocket_friends/game.py @@ -30,7 +30,7 @@ resources_dir = script_dir + '/resources' os.environ['SDL_FBDEV'] = '/dev/fb1' -def game(resolution=240): +def start_game(resolution=240): """ Starts the game. @@ -71,14 +71,4 @@ def game(resolution=240): game_fps, **additional_args) pygame.display.flip() - -def main(resolution=240): - """ - Calls the game() function to start the game. - - Args: - resolution (int, optional): Resolution to display the game at. Defaults to 240. - """ - game(resolution) - pygame.quit() diff --git a/pocket_friends/surfaces/__init__.py b/pocket_friends/surfaces/__init__.py deleted file mode 100644 index e69de29..0000000