diff --git a/images/assets/01_sprites.png b/images/assets/01_sprites.png index b529c4f..0a5d039 100644 Binary files a/images/assets/01_sprites.png and b/images/assets/01_sprites.png differ diff --git a/images/assets/02_sprites.png b/images/assets/02_sprites.png index 711aacc..45e85c3 100644 Binary files a/images/assets/02_sprites.png and b/images/assets/02_sprites.png differ diff --git a/images/assets/03_sprites.png b/images/assets/03_sprites.png index 79a01cf..44ec2c3 100644 Binary files a/images/assets/03_sprites.png and b/images/assets/03_sprites.png differ diff --git a/images/assets/11_sprites.png b/images/assets/11_sprites.png index 3412a30..d1ba08e 100644 Binary files a/images/assets/11_sprites.png and b/images/assets/11_sprites.png differ diff --git a/images/assets/12_sprites.png b/images/assets/12_sprites.png index d399385..429be9d 100644 Binary files a/images/assets/12_sprites.png and b/images/assets/12_sprites.png differ diff --git a/images/assets/21_sprites.png b/images/assets/21_sprites.png index 6ac26f5..b7fec13 100644 Binary files a/images/assets/21_sprites.png and b/images/assets/21_sprites.png differ diff --git a/images/assets/piece32.png b/images/assets/piece32.png index c9ead02..21516f8 100644 Binary files a/images/assets/piece32.png and b/images/assets/piece32.png differ diff --git a/images/assets/piece45.png b/images/assets/piece45.png index a5c47ee..1130006 100644 Binary files a/images/assets/piece45.png and b/images/assets/piece45.png differ diff --git a/images/assets/piece60.png b/images/assets/piece60.png index 03f970e..8de0864 100644 Binary files a/images/assets/piece60.png and b/images/assets/piece60.png differ diff --git a/main.py b/main.py index cce1265..fdf59c1 100644 --- a/main.py +++ b/main.py @@ -23,10 +23,9 @@ STATS_FILE = "main_stats.json" black = (0, 0, 0) white = (255, 255, 255) +transparent = (255, 0, 128) # Data loading and saving - - def load_data(data): try: with open(data, "r") as file: @@ -79,8 +78,8 @@ if settings_data["size"] == SIZE_CHOICES[0]: puzzle_size = (128, 128) non_movable_area = pygame.Rect(8, 19, 128, 128) timer_area = pygame.Rect(22, 1, 55, 12) - win_area = pygame.Rect(128//2+10, 128//2+14, 128, 128) - size = [20, 25, 100, 15] + win_area = pygame.Rect(74, 78, 128, 128) + size = [20, 25, 116, 15] cons = [15, 195, 12, 3, 9] scaled_size = (18, 21, 108, 108) area = (72, 142) @@ -97,8 +96,8 @@ elif settings_data["size"] == SIZE_CHOICES[1]: puzzle_size = (180, 180) non_movable_area = pygame.Rect(11, 26, 180, 180) timer_area = pygame.Rect(27, 2, 86, 16) - win_area = pygame.Rect(71, 98, 55, 12) - size = [30, 35, 110, 25] + win_area = pygame.Rect(104, 108, 180, 180) + size = [30, 35, 161, 25] cons = [25, 247, 18, 3, 13] scaled_size = (22, 26, 158, 158) area = (100, 200) @@ -115,8 +114,8 @@ else: puzzle_size = (360, 360) non_movable_area = pygame.Rect(18, 48, 360, 360) timer_area = pygame.Rect(49, 5, 86, 32) - win_area = pygame.Rect(200, 100, 55, 12) - size = [50, 55, 120, 35] + win_area = pygame.Rect(200, 214, 360, 360) + size = [50, 55, 328, 35] cons = [35, 455, 25, 13, 26] scaled_size = (43, 48, 310, 310) area = (197, 390) @@ -134,8 +133,6 @@ clock = pygame.time.Clock() hwnd = pygame.display.get_wm_info()["window"] # Sprites generation - - class SpriteSheet: def __init__(self, sheet_path): self.sheet = pygame.image.load(sheet_path).convert_alpha() @@ -256,8 +253,6 @@ class Button: screen.blit(self.img, self.rect) # Ability to move window - - def move_win(coordinates): hwnd = pygame.display.get_wm_info()["window"] w, h = pygame.display.get_surface().get_size() @@ -265,8 +260,6 @@ def move_win(coordinates): set_shadow_style(hwnd) # Generating shadow - - def set_shadow_style(hwnd): try: DWMWA_NCRENDERING_POLICY = 2 @@ -285,8 +278,6 @@ def set_shadow_style(hwnd): print(e) # Text render - - def render_text(text, position, screen, color=text_color, centered=False): font = pygame.font.SysFont(FONT, FONT_SIZE) text_render = font.render(text, True, color) @@ -298,8 +289,6 @@ def render_text(text, position, screen, color=text_color, centered=False): screen.blit(text_render, position) # MENU MODE - - def browse(): root = Tk() root.withdraw() @@ -335,15 +324,13 @@ def render_albums(): y = size_to_y[settings_data["size"]] for hover_index, album in enumerate(storage["albums"]): + render_text(album, (size[1], y), screen) album_rect = pygame.Rect(size[0], y, size[2], size[3]) album_hover = album_rect.collidepoint(pygame.mouse.get_pos()) - + if album_hover: current_hovered_index = hover_index - render_text(album, (size[1], y), screen) - y += cons[0] - if album_hover and pygame.mouse.get_pressed()[0]: album_name = album if album_name != album: @@ -354,6 +341,8 @@ def render_albums(): return album + y += cons[0] + if current_hovered_index == -1: current_hovered_index = 0 arrow_image = Image((cons[1], 0), (cons[2], size[1] + cons[0] * current_hovered_index + cons[3]), (cons[4], cons[4])) @@ -370,8 +359,6 @@ def album_creation(): pass # SELECT MODE - - class ImageRender: def __init__(self, album_name, initial_index=0): self.album_name = album_name @@ -443,8 +430,6 @@ def reload_chosen(): data_file.write(json.dumps(storage, indent=3)) # GAME MODE - - def timer(elapsed_time): hours = elapsed_time // 3600 minutes = (elapsed_time % 3600) // 60 @@ -453,8 +438,6 @@ def timer(elapsed_time): return timer_text # Puzzle loading and running logic - - def cut_image(image): piece_width = puzzle_size[0] // len(puzzle_matrix[0]) piece_height = puzzle_size[1] // len(puzzle_matrix) @@ -614,8 +597,6 @@ def update_puzzle_data(completed, sorted, current_time, current_moves, real_time data_file.write(json.dumps(storage, indent=3)) # SETTINGS MODE - - def play_music(): music_file = settings_data["music"]["version"] volume = settings_data["music"]["volume"] @@ -635,6 +616,23 @@ def play_sound(): sound.set_volume(volume) pygame.mixer.Sound.play(sound) +def render_settings(): + size_to_y = {"small": 15, "medium": 25, "big": 55} + y = size_to_y[settings_data["size"]] + + for setting in enumerate(settings_data): + render_text(setting[1], (size[1]-20, y), screen) + setting_rect = pygame.Rect(size[0], y, size[2], size[3]) + setting_hover = setting_rect.collidepoint(pygame.mouse.get_pos()) + + if setting_hover and pygame.mouse.get_pressed()[0]: + setting_name = setting + if setting_name != setting: + setting_name = None + + return setting + + y += cons[0] def set_hue(): global hue_value @@ -697,7 +695,7 @@ def stats(): pass -# Buttons +# Buttons (maybe optimise?) if settings_data["size"] == SIZE_CHOICES[0]: px12 = (12, 12) px14 = (14, 14) @@ -718,8 +716,8 @@ if settings_data["size"] == SIZE_CHOICES[0]: to_left_button = Button((0, 30), (33, 136), px14) to_right_button = Button((17, 30), (97, 136), px14) BACKGROUND_IMAGE = Image((0, 64), (0, 0), (WIDTH, HEIGHT)) - ver1_layer = sprite_sheet.get_sprite((147, 64), WIDTH, HEIGHT, color_key=(255, 0, 128)) - ver2_layer = sprite_sheet.get_sprite((294, 64), WIDTH, HEIGHT, color_key=(255, 0, 128)) + ver1_layer = sprite_sheet.get_sprite((147, 64), WIDTH, HEIGHT, transparent) + ver2_layer = sprite_sheet.get_sprite((294, 64), WIDTH, HEIGHT, transparent) elif settings_data["size"] == SIZE_CHOICES[1]: px16 = (16, 16) px20 = (20, 20) @@ -740,8 +738,8 @@ elif settings_data["size"] == SIZE_CHOICES[1]: to_left_button = Button((0, 38), (46, 191), px20) to_right_button = Button((23, 38), (136, 191), px20) BACKGROUND_IMAGE = Image((0, 84), (0, 0), (WIDTH, HEIGHT)) - ver1_layer = sprite_sheet.get_sprite((205, 84), WIDTH, HEIGHT, color_key=(255, 0, 128)) - ver2_layer = sprite_sheet.get_sprite((410, 84), WIDTH, HEIGHT, color_key=(255, 0, 128)) + ver1_layer = sprite_sheet.get_sprite((205, 84), WIDTH, HEIGHT, transparent) + ver2_layer = sprite_sheet.get_sprite((410, 84), WIDTH, HEIGHT, transparent) else: px32 = (32, 32) px40 = (40, 40) @@ -762,12 +760,10 @@ else: to_left_button = Button((0, 70), (107, 372), px40) to_right_button = Button((43, 70), (248, 372), px40) BACKGROUND_IMAGE = Image((0, 156), (0, 0), (WIDTH, HEIGHT)) - ver1_layer = sprite_sheet.get_sprite((399, 156), WIDTH, HEIGHT, color_key=(255, 0, 128)) - ver2_layer = sprite_sheet.get_sprite((798, 156), WIDTH, HEIGHT, color_key=(255, 0, 128)) + ver1_layer = sprite_sheet.get_sprite((399, 156), WIDTH, HEIGHT, transparent) + ver2_layer = sprite_sheet.get_sprite((798, 156), WIDTH, HEIGHT, transparent) path_components = puzzle_data[f'current {puzzle_version}']['selected_image'].split('/')[2:] -print(path_components) -# why there was an error some time ago? current_data = storage["albums"][path_components[0]] for component in path_components[1:]: current_data = current_data[component] @@ -836,7 +832,7 @@ def button_check(pressed_button, run, current_mode, timer_running): win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE) | win32con.WS_EX_LAYERED) -win32gui.SetLayeredWindowAttributes(hwnd, win32api.RGB(*(255, 0, 128)), 0, win32con.LWA_COLORKEY) +win32gui.SetLayeredWindowAttributes(hwnd, win32api.RGB(*transparent), 0, win32con.LWA_COLORKEY) set_shadow_style(hwnd) @@ -860,8 +856,6 @@ def data_check(current_mode): return background_image, current_buttons # Game state - - run = True current_mode = "menu" # Dragging and mouse interaction @@ -869,7 +863,7 @@ dragging = False can_move = False start_pos = (0, 0) pressed_button = None -clicked_piece = None +clicked_piece = False # Select mode clicked_image = False image_display = None @@ -919,10 +913,10 @@ while run: update_puzzle_data(completed, not_shuffled, current_timer_text, current_moves, real_time) reload_chosen() run = False - elif event.type == pygame.MOUSEBUTTONDOWN: + elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: if not non_movable_area.collidepoint(pygame.mouse.get_pos()): can_move = True - if current_mode == "select" and event.button == 1: + if current_mode == "select": clicked_image_rect = ImageRender.image_save(selected_album, current_img) clicked_image = clicked_image_rect.collidepoint(event.pos) if clicked_image: @@ -948,16 +942,13 @@ while run: timer_button.disable() total_paused_time += pygame.time.get_ticks() - timer_start_time - if event.button == 1: - dragging = True - start_pos = pygame.mouse.get_pos() - for button in current_buttons: - if button.rect.collidepoint(start_pos): - pressed_button = button - run, current_mode, timer_running, do_not_save = button_check(pressed_button, run, current_mode, timer_running) - if settings_data["sound"]["on"] is True and current_mode == "game" and non_movable_area.collidepoint(event.pos): - play_sound() - + dragging = True + start_pos = pygame.mouse.get_pos() + for button in current_buttons: + if button.rect.collidepoint(start_pos): + pressed_button = button + run, current_mode, timer_running, do_not_save = button_check(pressed_button, run, current_mode, timer_running) + elif event.type == pygame.MOUSEMOTION and can_move: new_pos = pygame.mouse.get_pos() offset_x = new_pos[0] - start_pos[0] @@ -969,6 +960,7 @@ while run: elif event.type == pygame.MOUSEBUTTONUP: dragging = False pressed_button = None + clicked_piece = False can_move = False if current_mode == "game": @@ -997,7 +989,7 @@ while run: for row in range(len(puzzle_matrix)): for col in range(len(puzzle_matrix[0])): - if puzzle_matrix[row][col] != 0: + if puzzle_matrix[row][col]: piece_x = col * puzzle_size[0] // len(puzzle_matrix[0]) + non_movable_area.x piece_y = row * puzzle_size[1] // len(puzzle_matrix) + non_movable_area.y @@ -1009,10 +1001,14 @@ while run: clicked_row, clicked_col = (mouse_y - non_movable_area.y) // cell_size, (mouse_x - non_movable_area.x) // cell_size if 0 <= clicked_row < len(puzzle_matrix) and 0 <= clicked_col < len(puzzle_matrix[0]): - if puzzle_matrix[clicked_row, clicked_col] != 0: + if puzzle_matrix[clicked_row, clicked_col]: user_win = True current_moves += 1 move_pieces(clicked_row, clicked_col) + clicked_piece = True + if settings_data["sound"]["on"] is True and clicked_piece is True: + print("clicked") + play_sound() if pressed_button == hint_button: screen.blit(original_image, non_movable_area) @@ -1054,6 +1050,9 @@ while run: text_alpha = max(0, text_alpha) pygame.display.flip() pygame.time.delay(16) + + if current_mode == "settings": + render_settings() pygame.display.flip() diff --git a/main_data.json b/main_data.json index e2091ca..5011883 100644 --- a/main_data.json +++ b/main_data.json @@ -3,12 +3,12 @@ "Original images": { "1.png": [ 0, - 1, - 1, - 26, - "00:00:00", - "00:00:00", - 26 + 0, + 0, + 194, + "00:00:09", + "00:00:09", + 13 ], "2.png": [ 0, @@ -94,13 +94,13 @@ }, "Birds": { "1.png": [ - 1, - 1, - 1, - 4, + 0, + 0, + 0, + 0, "00:00:00", "00:00:00", - 2 + 0 ], "2.png": [ 0, diff --git a/main_puzzle.json b/main_puzzle.json index e7a78bb..2e72898 100644 --- a/main_puzzle.json +++ b/main_puzzle.json @@ -1 +1 @@ -{"puzzle 4x4": [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 0]], "puzzle 3x3": [[1, 2, 3], [4, 5, 6], [7, 8, 0]], "current 4x4": {"matrix": [[6, 7, 2, 0], [12, 14, 1, 13], [11, 4, 9, 10], [3, 15, 5, 8]], "selected_image": "images/albums/Birds/1.png"}, "current 3x3": {"matrix": [[3, 6, 7], [5, 4, 1], [0, 8, 2]], "selected_image": "/images/albums/Birds/1.png"}} \ No newline at end of file +{"puzzle 4x4": [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 0]], "puzzle 3x3": [[1, 2, 3], [4, 5, 6], [7, 8, 0]], "current 4x4": {"matrix": [[0, 4, 9, 7], [13, 1, 8, 3], [2, 12, 5, 11], [15, 14, 6, 10]], "selected_image": "images/albums/Original images/1.png"}, "current 3x3": {"matrix": [[3, 6, 7], [5, 4, 1], [0, 8, 2]], "selected_image": "/images/albums/Birds/1.png"}} \ No newline at end of file diff --git a/main_settings.json b/main_settings.json index eb7528d..46ae12a 100644 --- a/main_settings.json +++ b/main_settings.json @@ -1,5 +1,5 @@ { - "size": "small" , + "size": "medium" , "style": "classic", "grid": "4x4", "gui color": [0, 0], diff --git a/main_stats.json b/main_stats.json index 221a4fa..f55c884 100644 --- a/main_stats.json +++ b/main_stats.json @@ -1,12 +1,12 @@ { "stats": { - "overall_time": 0, - "overall_moves": 0, - "overall_completed": 0, - "not_completed": 0, - "quickest_puzzle_time": [null, 0], - "quickest_puzzle_moves": [null, 0], - "longest_puzzle_time": [null, 0], - "longest_puzzle_moves": [null, 0] + "overall time": 0, + "overall moves": 0, + "overall completed": 0, + "not completed": 0, + "quickest puzzle time": [null, 0], + "quickest puzzle_moves": [null, 0], + "longest puzzle time": [null, 0], + "longest puzzle_moves": [null, 0] } } \ No newline at end of file diff --git a/misc/epec_unf.mp3 b/misc/epec_unf.mp3 new file mode 100644 index 0000000..f90da53 Binary files /dev/null and b/misc/epec_unf.mp3 differ