elukjanovica 2024-03-04 00:37:28 +02:00
parent c61ccf2549
commit dc3eed681b
7 changed files with 188 additions and 60 deletions

12
TODO
View File

@ -3,14 +3,14 @@ TODO main:
[x] fix image loading from last album
[x] fix image choosing
[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
[meh] add setting - move pieses = slow/normal/fast/instant
[meh] fix quick game window moving thing
[meh] add popup when loading time - load previous or reset
[ ] add small notes on button hover
[ ] add functionality in select and menu mode
[ ] add settings, info and stats with full functionality
[ ] optimise code as possible
[ ] add splash screen
[sorta] add settings, info and stats with full functionality
[meh] optimise code as possible
[no] add splash screen
[ ] add keybinds
TODO additional:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

214
main.py
View File

@ -51,9 +51,9 @@ current_style = settings_data["style"]
SIZE_CHOICES = ["small", "medium", "big"]
STYLE_CHOICES = ["classic", "original", "dark"]
GRID_CHOICES = ["4x4", "3x3"]
MUSIC_CHOICES = ["funky-leap", "serenity", "sunny-day"]
SOUND_CHOICES = ["puzzle", "wood", "metal_pipe", "lego_breaking"]
DISPLAY_CHOICES = ["time", "moves"]
MUSIC_CHOICES = ["funky leap", "serenity", "sunny day"]
SOUND_CHOICES = ["puzzle", "wood", "metal pipe", "lego breaking"]
DISPLAY_CHOICES = ["time", "moves", "none"]
LANGUAGE_CHOICES = ["english", "russian", "latvian"]
FONTS = ["msreferencesansserif", "arial", "bahnschrift"]
@ -150,6 +150,11 @@ elif current_size == SIZE_CHOICES[1]:
f_line = [135, 38, 100, 16]
s_line = [135, 58, 100, 16]
s_button = [238, 38, 12, 20]
arrow1 = (261, 0, 10, 13)
arrow2 = (274, 0, 10, 13)
spaces2 = [4, 5, 2, 5, 60, 42]
if current_style == STYLE_CHOICES[2]:
spaces2[1] = 2
else:
WIDTH, HEIGHT = 396, 425
@ -168,15 +173,18 @@ else:
timer_area = pygame.Rect(49, 5, 86, 32)
win_area = pygame.Rect(200, 214, 360, 360)
size = [50, 58, 328, 35]
cons = [35, 455, 26, 8, 26]
cons = [35, 455, 26, 10, 26]
scaled_size = (43, 48, 310, 310)
area = (197, 390)
spaces = [24, 34, 50, 84, 8]
f_line = [276, 70, 200, 32]
s_line = [276, 105, 200, 32]
s_button = [479, 70, 24, 40]
if current_style == STYLE_CHOICES[0]:
cons[3] = 10
arrow1 = (261, 0, 10, 13)
arrow2 = (274, 0, 10, 13)
spaces2 = (4, 5, 2, 5, 60, 42)
if current_style == STYLE_CHOICES[2]:
cons[3] = 8
puzzle_version = settings_data["grid"]
@ -318,7 +326,7 @@ def render_text(text, position, screen, color=text_color, centered=False):
screen.blit(text_render, position)
def render_settings_text(text, position, screen, value=None,color=text_color):
font = pygame.font.SysFont(FONT, FONT_SIZE2-1)
font = pygame.font.SysFont(FONT, FONT_SIZE2-1, italic=True)
if value is not None:
text_render = font.render(f"{text}: {value}", True, color)
else:
@ -643,14 +651,10 @@ def slider(position, value_range, value, active_slider, setting):
value_pos = second_x - s_button[2] / 2
first_line = Image((f_line[0], f_line[1]), (position[0], position[1]), (f_line[2], f_line[3]))
second_line = Image((s_line[0], s_line[1]), (position[0], position[1]), (second_x, s_line[3]))
slider_button = Image((s_button[0], s_button[1]), (position[0] + value_pos, position[1] + gap), (s_button[2], s_button[3]))
mouse_buttons = pygame.mouse.get_pressed()
if active_slider[setting] and mouse_buttons[0]:
slider_button = Button((s_button[0], s_button[1]), (position[0] + value_pos, position[1] + gap), (s_button[2], s_button[3]))
if active_slider[setting] and pygame.mouse.get_pressed()[0]:
mouse_pos = pygame.mouse.get_pos()
if mouse_buttons[0] and slider_button.rect.inflate(100, 25).collidepoint(mouse_pos):
mouse_pos = pygame.mouse.get_pos()
if slider_button.rect.inflate(100, 25).collidepoint(mouse_pos):
mouse_x = mouse_pos[0]
min_x = position[0] - s_button[2] / 2
max_x = position[0] + s_line[2] - s_button[2] / 2
@ -663,15 +667,63 @@ def slider(position, value_range, value, active_slider, setting):
return first_line, second_line, slider_button
active_selects = {"size": False, "style": False, "grid": False, "music_version": False, "sound_version": False}
def arrows(position, setting, value, choices, event_list):
index = choices.index(value)
arrow_width = arrow1[2]
font = pygame.font.SysFont(FONT, FONT_SIZE)
text_render = font.render(value, True, text_color)
text_rect = text_render.get_rect()
text_x = position[0] + (arrow_width + spaces2[0]) / 2 - text_rect.width / 2 + spaces2[5]
text_y = position[1] - spaces2[1]
value_text = screen.blit(text_render, (text_x, text_y))
first_arrow = Button((arrow1[0], arrow1[1]), (text_x - arrow_width - spaces2[0], position[1]), (arrow_width, arrow1[3]))
second_arrow_x = text_x + text_rect.width + spaces2[2]
second_arrow = Button((arrow2[0], arrow2[1]), (second_arrow_x , position[1]), (arrow2[2], arrow2[3]))
for event in event_list:
if event.type == pygame.MOUSEBUTTONDOWN:
if first_arrow.rect.collidepoint(event.pos):
index -= 1
if index < 0:
index = len(choices) - 1
value = choices[index]
data_set(setting, value)
elif second_arrow.rect.collidepoint(event.pos):
index += 1
if index >= len(choices):
index = 0
value = choices[index]
data_set(setting, value)
return first_arrow, value_text, second_arrow
def data_set(setting, value):
if setting == gui:
if setting == "size":
settings_data["size"] = value
elif setting == "style":
settings_data["style"] = value
elif setting == "grid":
settings_data["grid"] = value
elif setting == gui:
settings_data[gui] = value
elif setting == music:
settings_data[music]["volume"] = value
update_music_volume()
if isinstance(value, str):
settings_data[sound]["version"] = value
else:
settings_data[music]["volume"] = value
update_music_volume()
elif setting == sound:
settings_data[sound]["volume"] = value
update_sound_volume()
if isinstance(value, str):
settings_data[sound]["version"] = value
else:
settings_data[sound]["volume"] = value
update_sound_volume()
with open(SETTINGS_FILE, "w") as settings_file:
json.dump(settings_data, settings_file, indent=2)
@ -750,16 +802,49 @@ def reset():
# Reset all data function, not finished yet
pass
def info():
# Not finished yet
pass
# STATS MODE
# Stats
def stats():
# Not finished yet
pass
#INFO MODE
text_size = [3, 5]
def render_text_in_rect(long_text, rect_area):
font = pygame.font.SysFont(FONT, FONT_SIZE-text_size[0])
lines = []
words = long_text.split()
current_line = ""
for word in words:
test_line = current_line + word + " "
if font.size(test_line)[0] <= rect_area.width:
current_line = test_line
else:
lines.append(current_line.strip())
current_line = word + " "
lines.append(current_line.strip())
line_height = font.get_linesize()
text_surfaces = []
text_rects = []
for i, line in enumerate(lines):
text_render = font.render(line, True, pygame.Color(*text_color))
text_rect = text_render.get_rect(topleft=(rect_area.x, rect_area.y + i * line_height))
text_surfaces.append(text_render)
text_rects.append(text_rect)
return text_surfaces, text_rects
# Example usage
rect_area = non_movable_area
rect_area.x += text_size[1]
rect_area.width -= text_size[1]
long_text = (
"Picture Puzzle, once a feature in Windows Vista and 7's 'Desktop Gadgets,' "
"faced an end in 2012 due to security concerns. This game is a remake of original "
"Picture Puzzle with modified and upgraded functionality. Music autor is SmugBurger, "
"sounds taken from open sources."
)
text_surfaces, text_rects = render_text_in_rect(long_text, rect_area)
# Buttons (maybe optimise?)
@ -896,9 +981,9 @@ def button_check(pressed_button, run, current_mode, timer_running):
# Not finished yet
pass
elif pressed_button == info_button:
info()
current_mode = "info"
elif pressed_button == stats_button:
stats()
current_mode = "stats"
return run, current_mode, timer_running, do_not_save
@ -935,11 +1020,12 @@ run = True
current_mode = "menu"
# Dragging and mouse interaction
dragging = False
slider_moving = False
setting = None
can_move = False
start_pos = (0, 0)
pressed_button = None
slider_moving = False
setting = None
arrow = None
# Select mode
clicked_image = False
image_display = None
@ -987,7 +1073,9 @@ while run:
selected_image.render(screen)
for event in pygame.event.get():
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
save_puzzle_state()
update_puzzle_data(completed, not_shuffled, current_timer_text, current_moves, real_time)
@ -1058,7 +1146,7 @@ while run:
pressed_button = None
can_move = False
setting = None
elif event.type == pygame.MOUSEBUTTONDOWN and current_mode == "settings":
if event.button == 4:
scroll_offset -= 20
@ -1107,7 +1195,7 @@ while run:
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:
moved = move_pieces(clicked_row, clicked_col)
if settings_data[sound]["on"] is True and moved is not None:
if settings_data[sound]["on"] and moved is not None:
current_moves += 1
user_win = True
print("clicked:", current_moves)
@ -1160,18 +1248,39 @@ while run:
for index, setting_name in enumerate(settings_data):
if setting_name != "keybinds":
y = f_line[3] - scroll_offset + index * (cons[0] + spaces[2]) - spaces[1]
y = f_line[3] - scroll_offset + index * (cons[0] + spaces[2]) + spaces[1]
value = settings_data[setting_name]
if setting_name in [gui, music, sound]:
if setting_name in [music, sound]:
value = value["volume"]
render_settings_text(setting_name.upper(),
(settings_x_position // 2 + spaces[4], y), screen, value)
else:
render_settings_text(setting_name.upper(),
(settings_x_position // 2 + spaces[4], y), screen)
value = settings_data[setting_name]["volume"]
value2 = settings_data[setting_name]["version"]
if setting_name == gui:
if setting_name == "size":
render_settings_text(setting_name.upper(),(settings_x_position // 2 + spaces[4], y), screen)
size_choosing = arrows((settings_x_position // 2 - spaces[3], y + spaces[0]), setting_name, value, SIZE_CHOICES, event_list)
size_choosing[0].update(mouse_pos)
size_choosing[2].update(mouse_pos)
size_choosing[0].draw(screen)
size_choosing[2].draw(screen)
active_selects["size"] = True
elif setting_name == "style":
render_settings_text(setting_name.upper(),(settings_x_position // 2 + spaces[4], y), screen)
style_choosing = arrows((settings_x_position // 2 - spaces[3], y + spaces[0]), setting_name, value, STYLE_CHOICES, event_list)
style_choosing[0].update(mouse_pos)
style_choosing[2].update(mouse_pos)
style_choosing[0].draw(screen)
style_choosing[2].draw(screen)
active_selects["style"] = True
elif setting_name == "grid":
render_settings_text(setting_name.upper(),(settings_x_position // 2 + spaces[4], y), screen)
grid_choosing = arrows((settings_x_position // 2 - spaces[3], y + spaces[0]), setting_name, value, GRID_CHOICES, event_list)
grid_choosing[0].update(mouse_pos)
grid_choosing[2].update(mouse_pos)
grid_choosing[0].draw(screen)
grid_choosing[2].draw(screen)
active_selects["grid"] = True
elif setting_name == gui:
render_settings_text(setting_name.upper(),(settings_x_position // 2 + spaces[4], y), screen, value)
gui_color_slider = slider((settings_x_position // 2 - spaces[3], y + spaces[0]), 360, value, active_sliders, setting_name)
for slider_part in gui_color_slider:
slider_part.draw(screen)
@ -1181,6 +1290,7 @@ while run:
elif not dragging:
active_sliders[gui] = False
elif setting_name == music:
render_settings_text(setting_name.upper(),(settings_x_position // 2 + spaces[4], y), screen, value)
music_volume_slider = slider((settings_x_position // 2 - spaces[3], y + spaces[0]), 100, value, active_sliders, setting_name)
for slider_part in music_volume_slider:
slider_part.draw(screen)
@ -1189,8 +1299,16 @@ while run:
setting = setting_name
elif not dragging:
active_sliders[music] = False
music_choosing = arrows((settings_x_position // 2 - spaces[3], y + spaces[0]+24), setting_name, value2, MUSIC_CHOICES, event_list)
music_choosing[0].update(mouse_pos)
music_choosing[2].update(mouse_pos)
music_choosing[0].draw(screen)
music_choosing[2].draw(screen)
active_selects["music_version"] = True
elif setting_name == sound:
sound_volume_slider = slider((settings_x_position // 2 - spaces[3], y + spaces[0]), 100, value, active_sliders, setting_name)
render_settings_text(setting_name.upper(),(settings_x_position // 2 + spaces[4], y+20), screen, value)
y += spaces2[5]
sound_volume_slider = slider((settings_x_position // 2 - spaces[3], y-10), 100, value, active_sliders, setting_name)
for slider_part in sound_volume_slider:
slider_part.draw(screen)
if dragging and sound_volume_slider[2].rect.collidepoint(mouse_pos):
@ -1198,8 +1316,18 @@ while run:
setting = setting_name
elif not dragging:
active_sliders[sound] = False
sound_choosing = arrows((settings_x_position // 2 - spaces[3], y + spaces[0]), setting_name, value2, SOUND_CHOICES, event_list)
sound_choosing[0].update(mouse_pos)
sound_choosing[2].update(mouse_pos)
sound_choosing[0].draw(screen)
sound_choosing[2].draw(screen)
active_selects["sound_version"] = True
screen.set_clip(None)
if current_mode == "info":
for text_surface, text_rect in zip(text_surfaces, text_rects):
screen.blit(text_surface, text_rect)
pygame.display.flip()

View File

@ -5,19 +5,19 @@
0,
0,
0,
93,
"00:01:05",
"00:00:40",
0
99,
"00:01:11",
"00:00:46",
6
],
"2.png": [
0,
0,
0,
57,
"00:00:23",
"00:00:23",
1
85,
"00:00:40",
"00:00:40",
0
],
"3.png": [
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": [[13, 2, 9, 12], [4, 1, 6, 8], [5, 3, 10, 15], [14, 7, 11, 0]], "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"}}
{"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": [[10, 2, 5, 12], [13, 4, 3, 15], [6, 14, 8, 0], [11, 1, 7, 9]], "selected_image": "images/albums/Original images/2.png"}, "current 3x3": {"matrix": [[3, 6, 7], [5, 4, 1], [0, 8, 2]], "selected_image": "/images/albums/Birds/1.png"}}

View File

@ -1,5 +1,5 @@
{
"size": "big",
"size": "medium",
"style": "classic",
"grid": "4x4",
"gui color": 0,
@ -10,7 +10,7 @@
},
"sound": {
"on": true,
"volume": 16,
"volume": 12,
"version": "wood"
},
"display": "time",