elukjanovica 2024-03-02 01:21:46 +02:00
parent 4c0f817be3
commit cf157fce85
4 changed files with 129 additions and 73 deletions

7
TODO
View File

@ -1,10 +1,11 @@
TODO main: TODO main:
[x] fix image loading from last album [x] fix image loading from last album
[ ] add settings - move pieses = slow/normal/fast/instant
[ ] fix quick game window moving thing
[x] fix image choosing [x] fix image choosing
[ ] add proper image loading from storage [x] add proper image loading from storage
[ ] add setting - move pieses = slow/normal/fast/instant
[ ] fix quick game window moving thing
[ ] add popup when loading time - load previous or reset
[ ] add small notes on button hover [ ] add small notes on button hover
[ ] add functionality in select and menu mode [ ] add functionality in select and menu mode
[ ] add settings, info and stats with full functionality [ ] add settings, info and stats with full functionality

129
main.py
View File

@ -71,10 +71,13 @@ if settings_data["size"] == SIZE_CHOICES[0]:
INT = 0 INT = 0
if FONT == FONTS[0]: if FONT == FONTS[0]:
FONT_SIZE = 11 FONT_SIZE = 11
FONT_SIZE2 = 10
elif FONT == FONTS[1]: elif FONT == FONTS[1]:
FONT_SIZE = 12 FONT_SIZE = 12
FONT_SIZE2 = 11
elif FONT == FONTS[2]: elif FONT == FONTS[2]:
FONT_SIZE = 11 FONT_SIZE = 11
FONT_SIZE2 = 10
puzzle_size = (128, 128) puzzle_size = (128, 128)
non_movable_area = pygame.Rect(8, 19, 128, 128) non_movable_area = pygame.Rect(8, 19, 128, 128)
timer_area = pygame.Rect(22, 1, 55, 12) timer_area = pygame.Rect(22, 1, 55, 12)
@ -89,10 +92,13 @@ elif settings_data["size"] == SIZE_CHOICES[1]:
INT = 1 INT = 1
if FONT == FONTS[0]: if FONT == FONTS[0]:
FONT_SIZE = 15 FONT_SIZE = 15
FONT_SIZE2 = 13
elif FONT == FONTS[1]: elif FONT == FONTS[1]:
FONT_SIZE = 17 FONT_SIZE = 17
FONT_SIZE2 = 15
elif FONT == FONTS[2]: elif FONT == FONTS[2]:
FONT_SIZE = 16 FONT_SIZE = 16
FONT_SIZE2 = 14
puzzle_size = (180, 180) puzzle_size = (180, 180)
non_movable_area = pygame.Rect(11, 26, 180, 180) non_movable_area = pygame.Rect(11, 26, 180, 180)
timer_area = pygame.Rect(27, 2, 86, 16) timer_area = pygame.Rect(27, 2, 86, 16)
@ -107,10 +113,13 @@ else:
INT = 2 INT = 2
if FONT == FONTS[0]: if FONT == FONTS[0]:
FONT_SIZE = 24 FONT_SIZE = 24
FONT_SIZE2 = 21
elif FONT == FONTS[1]: elif FONT == FONTS[1]:
FONT_SIZE = 22 FONT_SIZE = 22
FONT_SIZE2 = 19
elif FONT == FONTS[2]: elif FONT == FONTS[2]:
FONT_SIZE = 21 FONT_SIZE = 21
FONT_SIZE2 = 18
puzzle_size = (360, 360) puzzle_size = (360, 360)
non_movable_area = pygame.Rect(18, 48, 360, 360) non_movable_area = pygame.Rect(18, 48, 360, 360)
timer_area = pygame.Rect(49, 5, 86, 32) timer_area = pygame.Rect(49, 5, 86, 32)
@ -182,33 +191,38 @@ class Image:
class Slider: class Slider:
def __init__(self, line_size, button_size, position): def __init__(self, white_line, blue_line, slider_button, position, value_range):
self.line_size = line_size self.white_line = white_line
self.button_size = button_size self.blue_line = blue_line
self.slider_button = slider_button
self.position = position self.position = position
self.value = 0 self.value_range = value_range
self.button_rect = pygame.Rect(self.position[0], self.position[1] - (self.button_size[1] - self.line_size[1]) // 2, self.value = value_range[0]
self.button_size[0], self.button_size[1]) self.dragging = False
self.slider_rect = pygame.Rect(self.position[0], self.position[1], self.line_size[0], self.line_size[1])
def update(self): def update_position(self, position):
button_x = self.position[0] + (self.value / 360) * (self.line_size[0] - self.button_size[0]) self.position = position
self.button_rect.topleft = (button_x, self.button_rect.y) self.white_line.position = position
self.blue_line.position = position
self.slider_button.window_position = (position[0], position[1] + (self.slider_button.size[1] - self.white_line.rect.height) // 2)
def draw(self, screen): def blit(self, screen):
pygame.draw.rect(screen, (200, 200, 200), self.slider_rect) screen.blit(self.white_line.img, self.white_line.rect)
pygame.draw.rect(screen, (0, 0, 255), self.button_rect) screen.blit(self.blue_line.img, self.blue_line.rect)
self.slider_button.draw(screen)
def handle_event(self, event): def handle_event(self, event):
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
if self.button_rect.collidepoint(event.pos): if self.slider_button.rect.collidepoint(event.pos):
self.dragging = True self.dragging = True
elif event.type == pygame.MOUSEBUTTONUP and event.button == 1: elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
self.dragging = False self.dragging = False
elif event.type == pygame.MOUSEMOTION and self.dragging: elif event.type == pygame.MOUSEMOTION and self.dragging:
mouse_x = max(self.position[0], min(event.pos[0], self.position[0] + self.line_size[0])) mouse_x = max(self.white_line.rect.x, min(event.pos[0], self.white_line.rect.x + self.white_line.rect.width))
self.value = int(((mouse_x - self.position[0]) / (self.line_size[0] - self.button_size[0])) * 360) value = ((mouse_x - self.white_line.rect.x) / (self.white_line.rect.width - self.slider_button.rect.width)) * 360
self.update() self.white_line.update_value(value)
self.blue_line.update_value(value)
self.slider_button.rect.x = mouse_x - self.slider_button.rect.width // 2
class Button: class Button:
@ -288,6 +302,16 @@ def render_text(text, position, screen, color=text_color, centered=False):
else: else:
screen.blit(text_render, position) screen.blit(text_render, position)
def render_settings_text(text, value, position, screen, color=text_color, centered=True):
font = pygame.font.SysFont(FONT, FONT_SIZE2-1)
text_render = font.render(f"{text}: {value}", True, color)
if centered:
text_rect = text_render.get_rect(center=position)
screen.blit(text_render, text_rect.topleft)
else:
screen.blit(text_render, position)
# MENU MODE # MENU MODE
def browse(): def browse():
root = Tk() root = Tk()
@ -405,12 +429,6 @@ class ImageRender:
with open(DATA_FILE, 'w') as data_file: with open(DATA_FILE, 'w') as data_file:
data_file.write(json.dumps(storage, indent=3)) data_file.write(json.dumps(storage, indent=3))
image_rect = pygame.Rect(scaled_size) image_rect = pygame.Rect(scaled_size)
hover = image_rect.collidepoint(pygame.mouse.get_pos())
if hover and pygame.mouse.get_pressed()[0]:
puzzle_data[f'current {puzzle_version}']["selected_image"] = IMAGES_PATH + selected_album + "/" + current_img
with open(PUZZLE_FILE, 'w') as puzzle_file:
puzzle_file.write(json.dumps(puzzle_data))
load_puzzle()
return image_rect return image_rect
def image_deletion(self): def image_deletion(self):
@ -591,7 +609,7 @@ def update_puzzle_data(completed, sorted, current_time, current_moves, real_time
formatted_time = f"{hours:02d}:{minutes:02d}:{seconds:02d}" formatted_time = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
current_data = [initial_chosen, initial_completed, initial_sorted, initial_moves, formatted_time, current_time, current_moves] current_data = [initial_chosen, initial_completed, initial_sorted, initial_moves, formatted_time, current_time, current_moves]
print(current_data) print(current_data, path_components)
storage["albums"][path_components[0]][path_components[1]] = current_data storage["albums"][path_components[0]][path_components[1]] = current_data
with open(DATA_FILE, 'w') as data_file: with open(DATA_FILE, 'w') as data_file:
data_file.write(json.dumps(storage, indent=3)) data_file.write(json.dumps(storage, indent=3))
@ -746,6 +764,18 @@ else:
ver1_layer = sprite_sheet.get_sprite((399, 156), WIDTH, HEIGHT, transparent) ver1_layer = sprite_sheet.get_sprite((399, 156), WIDTH, HEIGHT, transparent)
ver2_layer = sprite_sheet.get_sprite((798, 156), WIDTH, HEIGHT, transparent) ver2_layer = sprite_sheet.get_sprite((798, 156), WIDTH, HEIGHT, transparent)
settings_x_position = 50
settings_y_offset = 10
slider_size = (80, 12)
button_size = (10, 16)
space_between_settings = 20
gui_color_slider = Slider(slider_size, button_size, (settings_x_position, 10), (0, 360))
sensitivity_slider = Slider(slider_size, button_size, (settings_x_position, 58), (0, 100))
music_volume_slider = Slider(slider_size, button_size, (settings_x_position, 106), (0, 1))
sound_volume_slider = Slider(slider_size, button_size, (settings_x_position, 154), (0, 1))
def load_data(): def load_data():
path_components = puzzle_data[f'current {puzzle_version}']['selected_image'].split('/')[2:] path_components = puzzle_data[f'current {puzzle_version}']['selected_image'].split('/')[2:]
current_data = storage["albums"][path_components[0]] current_data = storage["albums"][path_components[0]]
@ -758,6 +788,7 @@ def load_data():
current_timer_text = timer_text current_timer_text = timer_text
displayed_current_moves = current_data[6] displayed_current_moves = current_data[6]
current_moves = 0 current_moves = 0
print("loaded from -", current_data, path_components)
return completed, not_shuffled, timer_text, current_timer_text, displayed_current_moves, current_moves return completed, not_shuffled, timer_text, current_timer_text, displayed_current_moves, current_moves
@ -845,7 +876,7 @@ def data_check(current_mode):
scroll_offset = 0 scroll_offset = 0
space_between_settings = 5 space_between_settings = 5
settings_x_position = size[1] - 18 settings_x_position = puzzle_size[0]
settings_y_offset = 5 settings_y_offset = 5
total_settings_height = len(settings_data) * (cons[0] + space_between_settings) total_settings_height = len(settings_data) * (cons[0] + space_between_settings)
max_scroll_offset = max(0, total_settings_height - non_movable_area.height) max_scroll_offset = max(0, total_settings_height - non_movable_area.height)
@ -916,12 +947,21 @@ while run:
clicked_image = clicked_image_rect.collidepoint(event.pos) clicked_image = clicked_image_rect.collidepoint(event.pos)
if clicked_image: if clicked_image:
clicked = True clicked = True
current_mode = "game"
update_puzzle_data(completed, not_shuffled, current_timer_text, current_moves, real_time) update_puzzle_data(completed, not_shuffled, current_timer_text, current_moves, real_time)
print(current_timer_text) puzzle_data[f'current {puzzle_version}']["selected_image"] = IMAGES_PATH + selected_album + "/" + current_img
with open(PUZZLE_FILE, 'w') as puzzle_file:
puzzle_file.write(json.dumps(puzzle_data))
completed, not_shuffled, timer_text, current_timer_text, displayed_current_moves, current_moves = load_data() completed, not_shuffled, timer_text, current_timer_text, displayed_current_moves, current_moves = load_data()
print(current_timer_text) elapsed_time = 0
current_moves = 0
shuffle_pieces(puzzle_pieces) shuffle_pieces(puzzle_pieces)
load_puzzle()
current_mode = "game"
timer_running = False
timer_start_time = 0
real_time = elapsed_time
total_paused_time = 0
timer_button.disable()
clicked = None clicked = None
last_click_time = pygame.time.get_ticks() last_click_time = pygame.time.get_ticks()
@ -1011,7 +1051,6 @@ while run:
if 0 <= clicked_row < len(puzzle_matrix) and 0 <= clicked_col < len(puzzle_matrix[0]): if 0 <= clicked_row < len(puzzle_matrix) and 0 <= clicked_col < len(puzzle_matrix[0]):
if puzzle_matrix[clicked_row, clicked_col] and clicked is None: if puzzle_matrix[clicked_row, clicked_col] and clicked is None:
moved = move_pieces(clicked_row, clicked_col) moved = move_pieces(clicked_row, clicked_col)
print(current_mode, clicked)
if settings_data["sound"]["on"] is True and moved is not None: if settings_data["sound"]["on"] is True and moved is not None:
current_moves += 1 current_moves += 1
user_win = True user_win = True
@ -1059,16 +1098,32 @@ while run:
pygame.display.flip() pygame.display.flip()
pygame.time.delay(16) pygame.time.delay(16)
if current_mode == "settings": if current_mode == "settings":
clipped_rect = pygame.Rect(settings_x_position, non_movable_area.y, size[2], non_movable_area.height) clipped_rect = pygame.Rect(non_movable_area.x, non_movable_area.y, settings_x_position, non_movable_area.height)
screen.set_clip(clipped_rect) screen.set_clip(clipped_rect)
for index, setting_name in enumerate(settings_data): for index, setting_name in enumerate(settings_data):
y = size[1] - scroll_offset + index * (cons[0] + space_between_settings) if setting_name != "keybinds":
render_text(setting_name, (settings_x_position, y - settings_y_offset), screen) y = slider_size[1] - scroll_offset + index * (cons[0] + space_between_settings)
value = settings_data[setting_name]
render_settings_text(setting_name.upper(), value,
(settings_x_position // 2 + 9, y - settings_y_offset), screen)
screen.set_clip(None) if setting_name == "gui color":
gui_color_slider.update_position((settings_x_position, y + 10))
gui_color_slider.blit(screen)
elif setting_name == "sensitivity":
sensitivity_slider.update_position((settings_x_position, y + 10))
sensitivity_slider.blit(screen)
elif setting_name == "music":
music_volume_slider.update_position((settings_x_position, y + 10))
music_volume_slider.blit(screen)
elif setting_name == "sound":
sound_volume_slider.update_position((settings_x_position, y + 10))
sound_volume_slider.blit(screen)
pygame.display.flip() screen.set_clip(None)
pygame.display.flip()
pygame.quit() pygame.quit()

View File

@ -5,46 +5,46 @@
0, 0,
0, 0,
0, 0,
16, 42,
"00:00:11", "00:00:44",
"00:00:11", "00:00:19",
16 6
], ],
"2.png": [ "2.png": [
0, 0,
0, 0,
0, 0,
0, 56,
"00:00:00", "00:00:23",
"00:00:00", "00:00:23",
0 7
], ],
"3.png": [ "3.png": [
0, 0,
0, 0,
0, 0,
0, 23,
"00:00:00", "00:00:13",
"00:00:00", "00:00:13",
0 3
], ],
"4.png": [ "4.png": [
0, 0,
0, 0,
0, 0,
0, 7,
"00:00:00", "00:00:08",
"00:00:00", "00:00:08",
0 7
], ],
"5.png": [ "5.png": [
0, 0,
0, 0,
0, 0,
0, 5,
"00:00:00", "00:00:03",
"00:00:00", "00:00:03",
0 5
], ],
"6.png": [ "6.png": [
0, 0,
@ -96,9 +96,9 @@
"1.png": [ "1.png": [
0, 0,
0, 0,
0, 1,
0, 9,
"00:00:00", "00:00:06",
"00:00:00", "00:00:00",
0 0
], ],
@ -106,19 +106,19 @@
0, 0,
0, 0,
0, 0,
0, 3,
"00:00:00", "00:00:16",
"00:00:00", "00:00:16",
0 3
], ],
"3.png": [ "3.png": [
0, 0,
1, 1,
1, 1,
56, 57,
"00:00:02", "00:00:20",
"00:00:02", "00:00:20",
20 0
] ]
} }
} }

View File

@ -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": [[12, 15, 10, 4], [14, 11, 9, 5], [2, 6, 1, 0], [7, 8, 3, 13]], "selected_image": "images/albums/Original images/3.png"}, "current 3x3": {"matrix": [[3, 6, 7], [5, 4, 1], [0, 8, 2]], "selected_image": "/images/albums/Birds/1.png"}} {"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, 3, 0, 15], [4, 13, 11, 9], [10, 8, 7, 5], [2, 14, 12, 1]], "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"}}