diff --git a/README.md b/README.md index 2d9bd71..ea0c98b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# BrickMania + **BrickMania** is a modern take on the classic **BrickBreaker** game. @@ -9,16 +9,16 @@ A special thanks to [@khsaad](https://github.com/khsaad04), [@aarthex](https://g --- -## How to Play -### Keyboard Controls + + - Move the block using the **WASD** or **Arrow** keys. - Pause or resume the game by pressing the **Spacebar**. - To quit the game while it’s not running, press the **Q** key. - To go back to main menu press **Left Shift** key. -### Options + On the start menu, you can select certain options that modify gameplay. Currently, these settings do not persist across restarts, but this feature is planned for future updates. @@ -26,7 +26,7 @@ You can navigate the options using the arrow keys. - **Mute Music** / **Unmute Music**: Mutes / Unmutes the game’s music and sounds. -### Special Moves + Special moves are powerful abilities with cooldowns. There are currently **2** special moves available: @@ -34,14 +34,14 @@ Special moves are powerful abilities with cooldowns. There are currently **2** s - Every 60 seconds, you’ll unlock the **Brick Destruction** powerup, which instantly destroys all remaining bricks on the board. -### Powerups + Powerups are items that drop randomly as you play, either after destroying bricks or at specific intervals. - After breaking a brick, there’s a chance an **Extra Ball** powerup will begin to fall. Catch it, and you’ll gain an additional ball that can help you clear more bricks! However, be cautious—each extra ball makes the game significantly faster! -### Game Mechanics + - If you stay stationary for too long (5 seconds), the paddle will move on its own. diff --git a/helpers/__init__.py b/helpers/__init__.py index 95fc683..b363444 100644 --- a/helpers/__init__.py +++ b/helpers/__init__.py @@ -1,7 +1,7 @@ __all__ = [ - # Classes + "Settings", - # Constants + "SCALE", "WIDTH", "HEIGHT", diff --git a/helpers/loading_combinations.py b/helpers/loading_combinations.py index 81753fc..fc2f140 100644 --- a/helpers/loading_combinations.py +++ b/helpers/loading_combinations.py @@ -15,7 +15,7 @@ ) -# Trigonometric and Hyperbolic Functions + def sec(x): """Secant of x.""" return 1 / cos(x) @@ -31,7 +31,7 @@ def cot(x): return 1 / tan(x) -# Inverse Hyperbolic Functions + def inv_sinh(x): """Inverse hyperbolic sine of x.""" return 1 / sinh(x) @@ -47,7 +47,7 @@ def inv_tanh(x): return 1 / tanh(x) -# Inverse Trigonometric Functions + def inv_asin(x): """Inverse sine of x.""" return 1 / asin(x) @@ -63,7 +63,7 @@ def inv_atan(x): return 1 / atan(x) -# Combinations of functions + combs = ( (sin, cos), (sin, tan), diff --git a/main.py b/main.py index 43a6082..485edf4 100644 --- a/main.py +++ b/main.py @@ -26,22 +26,22 @@ def __init__( scale=SCALE, ) -> None: pygame.init() - # window + self.height = height self.width = width self.scale = scale self.screen = pygame.display.set_mode((self.width, self.height)) - # colors + self.colors = Color() - # game variables + self.clock = pygame.time.Clock() self._music_files = track_path, track1, track2, track3 self.music_is_playing = False self.is_main_menu = True self.volume = 0.0 - # entity variables + self.trails = {} - # pages + self.main_menu = MainMenu(self.screen, self.height, self.width, self.scale, self) self.settings_page = Settings( self.screen, @@ -69,8 +69,8 @@ def run_loading_screen(self): """Call the dynamic loading screen function.""" result = ( loading_screen(self.colors) - ) # The loading screen runs until user presses Enter or Shift - return result # Return value determines the next action (e.g., continue or go back) + ) + return result def gameloop(self): while True: @@ -82,7 +82,7 @@ def gameloop(self): self.screen.fill(self.colors.BLACK) - # Handle main menu and get selected option + if self.is_main_menu: selected_option = self.main_menu.generate( self.colors, brick_width, brick_height, self.clock @@ -93,13 +93,13 @@ def gameloop(self): pygame.quit() sys.exit() - # Process selected option - if selected_option == 0: # Start the game + + if selected_option == 0: self.is_main_menu = False back_to_main_menu = ( self.run_loading_screen() - ) # Show the animated loading screen - if not back_to_main_menu: # User pressed Enter to continue + ) + if not back_to_main_menu: self.is_main_menu = self.game_page.runner( self.colors, brick_height, @@ -107,12 +107,12 @@ def gameloop(self): self.trails, self.clock, ) - else: # User pressed Shift to return to the main menu + else: self.is_main_menu = True - elif selected_option == 1: # Settings + elif selected_option == 1: self.is_main_menu = False - self.is_main_menu = self.settings_page.display()#self.colors) - elif selected_option == 2: # Info + self.is_main_menu = self.settings_page.display() + elif selected_option == 2: self.is_main_menu = False self.is_main_menu = self.info_page.scroll(self.colors) diff --git a/models/__init__.py b/models/__init__.py index 24104e7..ad9082d 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,5 +1,5 @@ __all__ = [ - # Classes + "Ball", "Brick", "Color", @@ -7,11 +7,11 @@ "Player", "PowerUp", "SpecialBall", - # Functions + "create_new_bricks", "draw_bricks", "drop_powerup", - # Types + "ColorType", ] diff --git a/models/ball.py b/models/ball.py index e254418..bcd581f 100644 --- a/models/ball.py +++ b/models/ball.py @@ -16,7 +16,7 @@ def __init__( ball_speed_x=ball_speed_x, ball_speed_y=ball_speed_y, ) -> None: - # Initialization of ball properties + self.screen = screen self.height = height - 150 self.width = width @@ -36,15 +36,15 @@ def draw_ball(self, screen, color, ball_id, x, y, ball_trails): """Draw the ball and its trail.""" max_alpha = 50 - # Initialize trail for this ball + trail = ball_trails.setdefault(ball_id, []) trail.append((x, y)) - # Limit the trail length + if len(trail) > trail_length: trail.pop(0) - # Draw the trail + for i, (tx, ty) in enumerate(trail): alpha = max_alpha - int(max_alpha * (i / trail_length)) trail_surface = pygame.Surface( @@ -58,7 +58,7 @@ def draw_ball(self, screen, color, ball_id, x, y, ball_trails): ) screen.blit(trail_surface, (tx - self.ball_radius, ty - self.ball_radius)) - # Draw the ball's core with a shaded effect + for depth in range(self.ball_radius, 0, -1): shade_factor = depth / self.ball_radius shaded_color = ( @@ -68,7 +68,7 @@ def draw_ball(self, screen, color, ball_id, x, y, ball_trails): ) pygame.draw.circle(screen, shaded_color, (int(x), int(y)), depth) - # Draw the highlight on the ball + highlight_color = ( min(color[0] + 80, 255), min(color[1] + 80, 255), @@ -86,7 +86,7 @@ def move_ball(self, dt, player: Player): self.x += self.dx * dt self.y += self.dy * dt - # Check collisions with walls + if self.x <= self.ball_radius or self.x >= self.width - self.ball_radius: self.dx = -self.dx self.x = max(self.ball_radius, min(self.x, self.width - self.ball_radius)) @@ -95,11 +95,11 @@ def move_ball(self, dt, player: Player): self.dy = abs(self.dy) self.y = self.ball_radius - # Check if ball crosses the bottom boundary + if self.y >= self.height - self.ball_radius - 60 and not self.ball_crossed_line: self.ball_crossed_line = True - # Handle paddle collision + self._handle_paddle_collision(player) return self.x, self.y, self.dx, self.dy @@ -114,7 +114,7 @@ def _handle_paddle_collision(self, player: Player): < self.y + self.ball_radius < player.y_start + player.player_height ): - # Adjust ball direction based on paddle hit location + paddle_center = player.x_start + player.player_width / 2 self.dx = self.ball_speed_x * ( (self.x - paddle_center) / (player.player_width / 2) diff --git a/models/player.py b/models/player.py index 35ce22b..ac5a3c0 100644 --- a/models/player.py +++ b/models/player.py @@ -23,26 +23,26 @@ def __init__( self.player_width = player_width self.player_speed = player_speed - # Calculate player position at start + self.x_start = (self.width * self.scale - self.player_width) // 2 self.y_start = self.height * scale - self.player_height - 70 - self.x_end = self.x_start + self.player_width # Unused currently - self.y_end = self.y_start - self.player_height # Unused currently + self.x_end = self.x_start + self.player_width + self.y_end = self.y_start - self.player_height def draw_player(self, color): """Draw the player character as a rectangle with a 3D-like gradient effect.""" - gradient_steps = 10 # Number of gradient steps to create depth effect + gradient_steps = 10 base_color = color.BLUE for i in range(gradient_steps): - # Calculate color variations for the gradient effect - # As `i` increases, the rectangle becomes darker to simulate depth + + shade_factor = i / gradient_steps r = int(base_color[0] * (1 - shade_factor)) g = int(base_color[1] * (1 - shade_factor)) b = int(base_color[2] * (1 - shade_factor)) - # Adjust the rectangle's position slightly to create a layered effect + pygame.draw.rect( self.screen, (r, g, b), @@ -64,4 +64,4 @@ def move_player(self, dt, keys, min_limit, max_limit): ) and self.x_start < WIDTH - self.player_width - max_limit: self.x_start += self.player_speed * dt - return time.time() # Time used for tracking, though this is unused + return time.time() diff --git a/models/special_ball.py b/models/special_ball.py index bc7ddc9..2b87ed8 100644 --- a/models/special_ball.py +++ b/models/special_ball.py @@ -22,21 +22,21 @@ def move(self, ball_radius, width, dt): def draw(self, screen, ball_radius, color): """Draw the ball on the screen with a 3D-like gradient effect.""" - gradient_steps = 10 # Number of gradient steps to create the depth effect + gradient_steps = 10 base_color = color.RED - # Create the gradient effect by drawing multiple circles + for i in range(gradient_steps): - # Calculate the shading for each circle, giving the effect of light direction + shade_factor = i / gradient_steps r = int(base_color[0] * (1 - shade_factor)) g = int(base_color[1] * (1 - shade_factor)) b = int(base_color[2] * (1 - shade_factor)) - # Draw each circle slightly smaller and with darker color for the 3D effect + circle( screen, - (r, g, b), # Adjusted color for each layer + (r, g, b), (self.x, self.y), - ball_radius - i # Each layer gets progressively smaller + ball_radius - i ) diff --git a/pages/__init__.py b/pages/__init__.py index 4eaddc3..da35768 100644 --- a/pages/__init__.py +++ b/pages/__init__.py @@ -1,11 +1,11 @@ __all__ = [ - # Classes + "Info", "MainGame", "MainMenu", "Page", "Settings", - # Functions + "loading_screen", ] diff --git a/pages/info_page.py b/pages/info_page.py index a80ae10..0556452 100644 --- a/pages/info_page.py +++ b/pages/info_page.py @@ -50,10 +50,10 @@ class Info(Page): def __init__(self, screen, height, width, scale, game): super().__init__(screen, height, width, scale, game) self.fonts = ( - pygame.font.Font(None, 20), # Font - pygame.font.Font(None, 30), # Bold - pygame.font.Font(None, 24), # Subtitle - pygame.font.Font(None, 26), # Bottom + pygame.font.Font(None, 20), + pygame.font.Font(None, 30), + pygame.font.Font(None, 24), + pygame.font.Font(None, 26), ) self.sprite_width = self.sprite_height = 50 self.top_margin = 50 diff --git a/pages/loading_screen.py b/pages/loading_screen.py index f16677c..1b138f2 100644 --- a/pages/loading_screen.py +++ b/pages/loading_screen.py @@ -25,7 +25,7 @@ def loading_screen(color): """Display a dynamic loading screen with animations and tips.""" - # Randomly select functions for animation + func1, func2 = random.choice(combs) radius = 30 spinner_segments = 12 @@ -37,7 +37,7 @@ def loading_screen(color): time = 0 move_speed = 2 - # Fonts and tips + tip_font = SysFont("Arial", 24) tips = [ "Use the paddle to deflect the ball!", @@ -48,40 +48,40 @@ def loading_screen(color): ] tip = choice(tips) - # Rotation angles + rotation_angle_x = 30 rotation_angle_y = 45 while True: - # Clear screen and set background color + screen.fill(color.BLACK) clock.tick(60) - # Display game title + loading_text = tip_font.render("BrickMania", True, color.WHITE) screen.blit( loading_text, (WIDTH // 2 - loading_text.get_width() // 2, HEIGHT // 2 - 123), ) - # Display random tip + tip_text = tip_font.render("Tip: " + tip, True, color.WHITE) screen.blit( tip_text, (WIDTH // 2 - tip_text.get_width() // 2, HEIGHT // 2 + 123) ) - # Animate spinner movement + spinner_center[0] = WIDTH // 2 + 100 * math.sin(time * 0.02) + uniform(-2, 2) spinner_center[1] = HEIGHT // 2 + 50 * math.cos(time * 0.03) + uniform(-2, 2) - # Calculate spinner scale factor + scale_factor_x = 1 + (spinner_center[0] - WIDTH // 2) / WIDTH scale_factor_y = 1 - (spinner_center[1] - HEIGHT // 2) / HEIGHT scale_factor = max(0.5, min(2, scale_factor_x * scale_factor_y)) def rotate_3d(x, y, z, angle_x, angle_y): """Rotate a point in 3D space around X and Y axes.""" - # Rotate around the X-axis + new_y = y * math.cos(math.radians(angle_x)) - z * math.sin( math.radians(angle_x) ) @@ -90,7 +90,7 @@ def rotate_3d(x, y, z, angle_x, angle_y): ) y, z = new_y, new_z - # Rotate around the Y-axis + new_x = x * math.cos(math.radians(angle_y)) + z * math.sin( math.radians(angle_y) ) @@ -101,12 +101,12 @@ def rotate_3d(x, y, z, angle_x, angle_y): return x, y, z - # Draw spinner segments + for i in range(spinner_segments): segment_angle_start = angle + (i * angle_per_segment) segment_angle_end = segment_angle_start + angle_per_segment - # Compute segment start and end points in 3D + x1 = ( radius * scale_factor @@ -127,7 +127,7 @@ def rotate_3d(x, y, z, angle_x, angle_y): ) z2 = 0 - # Rotate points in 3D space + start_x1, start_y1, _ = rotate_3d( x1, y1, z1, rotation_angle_x, rotation_angle_y ) @@ -141,7 +141,7 @@ def rotate_3d(x, y, z, angle_x, angle_y): -x2, -y2, z2, rotation_angle_x, rotation_angle_y ) - # Adjust to spinner center + start_x1 += spinner_center[0] start_y1 += spinner_center[1] end_x1 += spinner_center[0] @@ -151,15 +151,15 @@ def rotate_3d(x, y, z, angle_x, angle_y): end_x2 += spinner_center[0] end_y2 += spinner_center[1] - # Draw lines for spinner segments + line(screen, color.BLUE, (end_x1, end_y1), (end_x2, end_y2), 3) line(screen, color.RED, (start_x1, start_y1), (start_x2, start_y2), 3) - # Update angles and time + angle += spinner_speed time += move_speed - # Display bottom instructions + bottom_text = bottom_font.render("Press Enter to Continue", True, (92, 95, 119)) screen.blit( bottom_text, @@ -171,23 +171,23 @@ def rotate_3d(x, y, z, angle_x, angle_y): bottom_text = bottom_font.render("Press Shift to go back", True, (92, 95, 119)) screen.blit(bottom_text, (10, HEIGHT - bottom_text.get_height() - 10)) - # Handle events + for e in event.get(): if e.type == QUIT: quit() exit() if e.type == KEYDOWN: if e.key == K_RETURN: - return # Proceed to the next screen + return if e.key in (K_RSHIFT, K_LSHIFT): - return True # Return to the previous screen + return True if e.type == MOUSEMOTION and e.buttons[0]: - # Adjust rotation angles with mouse drag + rotation_angle_x = max(0, min(90, rotation_angle_x + e.rel[1] * 0.5)) rotation_angle_y += e.rel[0] * 0.5 if e.type == MOUSEWHEEL: - # Adjust spinner speed with mouse wheel + spinner_speed = 2 if e.y > 0 else -2 - # Update the display + flip() diff --git a/pages/main_game_page.py b/pages/main_game_page.py index 8d3534f..a953eb4 100644 --- a/pages/main_game_page.py +++ b/pages/main_game_page.py @@ -248,7 +248,7 @@ def runner(self, color: Color, brick_height, brick_width, trails, clock): self.last_x_time = current_time if keys[pygame.K_RSHIFT]: - # Reset the balls and the player + self.balls = [ Ball( screen=self.screen, @@ -269,7 +269,7 @@ def runner(self, color: Color, brick_height, brick_width, trails, clock): if all(ball.y >= self.height - 60 for ball in self.balls): user_exited = self.game_over(self.score, color, self.data) if user_exited: - # Reset the balls and the player + self.balls = [ Ball( screen=self.screen, @@ -283,7 +283,7 @@ def runner(self, color: Color, brick_height, brick_width, trails, clock): ) return True else: - # Reset the balls and the player + self.balls = [ Ball( screen=self.screen, diff --git a/pages/main_menu_page.py b/pages/main_menu_page.py index 00701ae..977d2f1 100644 --- a/pages/main_menu_page.py +++ b/pages/main_menu_page.py @@ -21,9 +21,9 @@ def __init__( ) -> None: super().__init__(screen, height, width, scale, game) self.fonts = fonts or ( - pygame.font.SysFont(None, int(72 * self.scale)), # Title - pygame.font.SysFont(None, int(25 * self.scale)), # Bottom - pygame.font.SysFont(None, int(48 * self.scale)), # Menu + pygame.font.SysFont(None, int(72 * self.scale)), + pygame.font.SysFont(None, int(25 * self.scale)), + pygame.font.SysFont(None, int(48 * self.scale)), ) self.selected_option: int = 0 self.options = options or ("Main Game", "Settings", "Info") @@ -46,7 +46,7 @@ def generate( tile.move(self.height, self.width) tile.draw(self.screen) - # BrickMania Text + title_text = self.fonts[0].render(self.texts[0], True, color.YELLOW) self.screen.blit( title_text, @@ -56,7 +56,7 @@ def generate( ), ) - # Bottom Text + quit_text = self.fonts[1].render(self.texts[1], True, color.GREY) bottom_text = self.fonts[1].render(self.texts[2], True, color.GREY) self.screen.blit( @@ -79,7 +79,7 @@ def generate( ), ) - # Menu Text + for i, option in enumerate(self.options): c = [color.YELLOW, color.BLUE][i != self.selected_option] option_text = self.fonts[2].render(option, True, c) diff --git a/pages/settings_page.py b/pages/settings_page.py index 5cf5321..d212be0 100644 --- a/pages/settings_page.py +++ b/pages/settings_page.py @@ -22,14 +22,14 @@ def __init__( ) self.selected_option: int = 0 self.settings_options = settings_options or ["Music", "Colors"] - self.color_keys = list(self.game.colors.__dict__.keys()) # List of color names - self.selected_color_index = 0 # To track which color is being edited - self.color_edit_component = 0 # 0: Red, 1: Green, 2: Blue + self.color_keys = list(self.game.colors.__dict__.keys()) + self.selected_color_index = 0 + self.color_edit_component = 0 def display(self) -> bool: """Main settings menu where options are displayed.""" while True: - self.screen.fill(self.game.colors.BLACK) # Use self.game.colors + self.screen.fill(self.game.colors.BLACK) header_font = self.fonts[0] header_text = header_font.render("Settings", True, self.game.colors.WHITE) @@ -61,12 +61,12 @@ def display(self) -> bool: self.settings_options ) elif e.key == pygame.K_RETURN: - if self.selected_option == 0: # Music + if self.selected_option == 0: self.display_music_settings() - elif self.selected_option == 1: # Colors + elif self.selected_option == 1: self.display_color_settings() elif e.key == pygame.K_RSHIFT: - return True # Go back to the main menu + return True pygame.display.flip() @@ -78,7 +78,7 @@ def display_music_settings(self) -> None: bar_y = self.height // 2 while True: - self.screen.fill(self.game.colors.BLACK) # Use self.game.colors + self.screen.fill(self.game.colors.BLACK) header_font = self.fonts[0] header_text = header_font.render( @@ -113,7 +113,7 @@ def display_music_settings(self) -> None: quit() exit() if e.type == pygame.KEYDOWN: - if e.key == pygame.K_RSHIFT: # Go back to the main settings menu + if e.key == pygame.K_RSHIFT: return elif e.key == pygame.K_RIGHT: self.game.volume = min(self.game.volume + 0.1, 1.0) @@ -134,16 +134,16 @@ def display_music_settings(self) -> None: def display_color_settings(self) -> None: """Display the Color settings screen with RGB values and editing functionality.""" - editing_mode = False # Whether the user is editing the selected color - numeric_input = "" # To store user input for numeric values + editing_mode = False + numeric_input = "" - self.selected_color_index = 0 # Start with the first color selected - self.color_edit_component = 0 # Start editing the "R" component + self.selected_color_index = 0 + self.color_edit_component = 0 while True: - self.screen.fill(self.game.colors.BLACK) # Clear the screen + self.screen.fill(self.game.colors.BLACK) - # Header + header_font = self.fonts[0] header_text = header_font.render("Color Settings", True, self.game.colors.WHITE) header_rect = header_text.get_rect(center=(self.width // 2, int(50 * self.scale))) @@ -151,37 +151,37 @@ def display_color_settings(self) -> None: options_font = self.fonts[1] - # Iterate through all colors + for i, color_name in enumerate(self.color_keys): color_value = getattr(self.game.colors, color_name) highlight = self.game.colors.YELLOW if i == self.selected_color_index else self.game.colors.WHITE - # Render the color name and RGB values + color_label_text = options_font.render( f"{color_name} (R: {color_value[0]}, G: {color_value[1]}, B: {color_value[2]})", True, highlight ) color_label_rect = color_label_text.get_rect(center=(self.width // 2 - 100, 150 + i * 50)) self.screen.blit(color_label_text, color_label_rect) - # Draw a rectangle showing the actual color beside the text + pygame.draw.rect( self.screen, color_value, (self.width // 2 + 200, 140 + i * 50, 40, 40) ) - # Draw an arrow on the left side of the selected color + if i == self.selected_color_index: arrow_text = options_font.render("→", True, self.game.colors.YELLOW) arrow_rect = arrow_text.get_rect(center=(self.width // 2 - 300, 150 + i * 50)) self.screen.blit(arrow_text, arrow_rect) - # If editing mode, display RGB edit UI + if editing_mode: selected_color_name = self.color_keys[self.selected_color_index] selected_color = list(getattr(self.game.colors, selected_color_name)) - # Display RGB component being edited + for j, component in enumerate(["R", "G", "B"]): highlight = self.game.colors.YELLOW if j == self.color_edit_component else self.game.colors.WHITE component_text = options_font.render( @@ -190,17 +190,17 @@ def display_color_settings(self) -> None: component_rect = component_text.get_rect(center=(self.width // 2 + (j - 1) * 100, 525)) self.screen.blit(component_text, component_rect) - # Display the numeric input below the RGB components if the user is typing + if numeric_input: numeric_input_text = options_font.render( f"Input: {numeric_input}", True, self.game.colors.YELLOW ) numeric_input_rect = numeric_input_text.get_rect( - center=(self.width // 2, 575) # Position below the RGB values + center=(self.width // 2, 575) ) self.screen.blit(numeric_input_text, numeric_input_rect) - # Handle user input + for event in pygame.event.get(): if event.type == pygame.QUIT: quit() @@ -209,13 +209,13 @@ def display_color_settings(self) -> None: if event.type == pygame.KEYDOWN: if event.key in [pygame.K_LSHIFT, pygame.K_RSHIFT]: if editing_mode: - # Exit editing mode and return to color selection + editing_mode = False numeric_input = "" print("Exited editing mode, back to navigation mode.") else: return - elif not editing_mode: # Navigation Mode + elif not editing_mode: if event.key == pygame.K_DOWN: self.selected_color_index = (self.selected_color_index + 1) % len(self.color_keys) print(f"Selected color: {self.color_keys[self.selected_color_index]}") @@ -223,10 +223,10 @@ def display_color_settings(self) -> None: self.selected_color_index = (self.selected_color_index - 1) % len(self.color_keys) print(f"Selected color: {self.color_keys[self.selected_color_index]}") elif event.key == pygame.K_RETURN: - editing_mode = True # Enter editing mode + editing_mode = True print("Entered editing mode.") - elif editing_mode: # Editing Mode + elif editing_mode: selected_color_name = self.color_keys[self.selected_color_index] selected_color = list(getattr(self.game.colors, selected_color_name)) @@ -241,14 +241,14 @@ def display_color_settings(self) -> None: selected_color[self.color_edit_component] = max(0, selected_color[self.color_edit_component] - 1) setattr(self.game.colors, selected_color_name, tuple(selected_color)) elif event.key == pygame.K_RETURN: - # Apply numeric input if provided + if numeric_input: value = min(255, max(0, int(numeric_input))) selected_color[self.color_edit_component] = value setattr(self.game.colors, selected_color_name, tuple(selected_color)) - numeric_input = "" # Clear numeric input + numeric_input = "" else: - editing_mode = False # Exit editing mode + editing_mode = False print("Exited editing mode, back to navigation mode.") elif event.key == pygame.K_BACKSPACE: numeric_input = numeric_input[:-1]