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()