Compare commits
20 Commits
Author | SHA1 | Date |
---|---|---|
|
908015040c | |
|
0edd1500da | |
|
c6f3ee519c | |
|
e77dd66b2f | |
|
f2669c59b1 | |
|
2ed0b17c52 | |
|
6d889686a7 | |
|
f7212f320d | |
|
9694a271d6 | |
|
1e8f1e3fa7 | |
|
6e8ce4b544 | |
|
1f2e610ac9 | |
|
52902e988c | |
|
eced480e23 | |
|
482562da4c | |
|
6c5d62dedc | |
|
0f96015f5d | |
|
40668745ac | |
|
247cd76f1b | |
|
f5fab463db |
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python: Main",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/main.py",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
2
TODO
|
@ -6,7 +6,7 @@ TODO main:
|
|||
[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
|
||||
[x] add small notes on button hover
|
||||
[ ] add functionality in select and menu mode
|
||||
[sorta] add settings, info and stats with full functionality
|
||||
[meh] optimise code as possible
|
||||
|
|
BIN
icon.png
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 270 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 10 KiB |
335
main.py
|
@ -6,13 +6,14 @@ import ctypes
|
|||
import json
|
||||
from tkinter import Tk, filedialog
|
||||
import numpy as np
|
||||
import os
|
||||
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# INITIALIZATION
|
||||
pygame.init()
|
||||
FPS = 60
|
||||
|
||||
MAIN_PATH = "C:/Users/User/Documents/Coding/Picture_Puzzle/"
|
||||
# School: MAIN_PATH = "C:/Users/RVKG/Documents/My Palettes/Picture Puzzle/"
|
||||
IMAGES_PATH = "images/albums/"
|
||||
SIZE_PATH = "images/assets/"
|
||||
|
||||
|
@ -96,14 +97,25 @@ if current_size == SIZE_CHOICES[0]:
|
|||
# --> timer_area[1] (1) - position y for timer area
|
||||
# --> timer_area[2] (55) - width of timer area
|
||||
# --> timer_area[3] (12) - heigth of timer area
|
||||
win_area = pygame.Rect(74, 78, 128, 128)
|
||||
win_area = pygame.Rect(74, 78, 128, 128) # "You win !!" area positioning
|
||||
# --> win_area[0] (74) - position x for "You win !!" text area in game mode
|
||||
# --> win_area[1] (78) - position y for "You win !!" text area
|
||||
# --> win_area[2] (128) - width of "You win !!" text area
|
||||
# --> win_area[3] (128) - heigth of "You win !!" text area
|
||||
size = [20, 25, 116, 15]
|
||||
cons = [15, 195, 12, 3, 9]
|
||||
# size and cons (constants) are too complicated, I cant remember what each element was, sorry :(
|
||||
size = [20, 25, 116, 15] # album name positioning
|
||||
# --> size[0] (20) - x position of clickable area
|
||||
# --> size[1] (25) - x position of album name
|
||||
# --> size[2] (116) - width of clickable area
|
||||
# --> size[3] (15) - height of clickable area
|
||||
cons = [15, 195, 12, 3, 9] # constants, reffering to arrow
|
||||
# --> cons[0] (15) - spacing between album names
|
||||
# --> cons[1] (195) - position x for element in spritesheet
|
||||
# --> cons[2] (12) - x position of arrow
|
||||
# --> cons[3] (3) - aligned y position of arrow next to album name
|
||||
# --> cons[4] (9) - size of arrow
|
||||
checkbox = [233, 9] # checkbox positioning
|
||||
# --> checkbox[0] (233) - position x for arrow in spritesheet
|
||||
# --> checkbox[1] (9) - size of checkbox in spritesheet
|
||||
scaled_size = (18, 21, 108, 108)
|
||||
# --> scaled_size[0] (18) - x position for image in select mode
|
||||
# --> scaled_size[1] (21) - y position for image
|
||||
|
@ -117,16 +129,16 @@ if current_size == SIZE_CHOICES[0]:
|
|||
# --> spaces[2] (20) - space between setting names, increasing
|
||||
# --> spaces[3] (30) - space between slider and non_movable_area edge, decreasing
|
||||
# --> spaces[4] (8) - space between setting names and non_movable_area edge, increasing
|
||||
f_line = [92, 30, 80, 12]
|
||||
s_line = [92, 45, 80, 12]
|
||||
s_button = [175, 30, 10, 16]
|
||||
f_line = [92, 30, 80, 12] # first line positioning
|
||||
s_line = [92, 45, 80, 12] # second line positioning
|
||||
s_button = [175, 30, 10, 16] # second button positioning
|
||||
# for list in f_line, s_line and s_button:
|
||||
# --> list[0] (135, 135, 218) - position x for element in spritesheet
|
||||
# --> list[1] (38, 53, 38) - position y for element in spritesheet
|
||||
# --> list[2] (80, 80, 10) - width of element in settings mode
|
||||
# --> list[3] (12, 12, 16) - heigth of element
|
||||
arrow1 = (261, 0, 10, 13)
|
||||
arrow2 = (274, 0, 10, 13)
|
||||
arrow1 = (207, 0, 10, 13)
|
||||
arrow2 = (220, 0, 10, 13)
|
||||
spaces2 = [4, 5, 2, 5, 60, 42]
|
||||
spaces3 = [10, 20, 23]
|
||||
|
||||
|
@ -148,15 +160,16 @@ elif current_size == SIZE_CHOICES[1]:
|
|||
win_area = pygame.Rect(104, 108, 180, 180)
|
||||
size = [30, 35, 161, 25]
|
||||
cons = [25, 247, 18, 3, 13]
|
||||
checkbox = [296, 13]
|
||||
scaled_size = (22, 26, 158, 158)
|
||||
area = (100, 200)
|
||||
spaces = [14, 30, 30, 40, 8]
|
||||
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]
|
||||
arrow1 = (263, 0, 13, 17)
|
||||
arrow2 = (280, 0, 13, 17)
|
||||
spaces2 = [4, 3, 3, 5, 60, 42]
|
||||
spaces3 = [10, 20, 23]
|
||||
if current_style == STYLE_CHOICES[2]:
|
||||
spaces2[1] = 2
|
||||
|
@ -179,14 +192,15 @@ else:
|
|||
win_area = pygame.Rect(200, 214, 360, 360)
|
||||
size = [50, 58, 328, 35]
|
||||
cons = [35, 455, 26, 10, 26]
|
||||
checkbox = [565, 27]
|
||||
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]
|
||||
arrow1 = (485, 0, 21, 32)
|
||||
arrow2 = (509, 0, 21, 32)
|
||||
arrow1 = (506, 0, 26, 34)
|
||||
arrow2 = (536, 0, 26, 34)
|
||||
spaces2 = (4, 0, 2, 5, 60, 80)
|
||||
spaces3 = [50, 40, 43]
|
||||
if current_style == STYLE_CHOICES[2]:
|
||||
|
@ -254,13 +268,17 @@ class Image:
|
|||
|
||||
|
||||
class Button:
|
||||
def __init__(self, sprite_position, window_position, size):
|
||||
def __init__(self, sprite_position, window_position, size, popup_text=None):
|
||||
self.sprite_sheet = sprite_sheet
|
||||
self.sprite_position = sprite_position
|
||||
self.window_position = window_position
|
||||
self.size = size
|
||||
self.popup_text = popup_text
|
||||
self.hovered = False
|
||||
self.disabled = False
|
||||
self.popup_timer = 0
|
||||
self.popup_duration = 3000
|
||||
self.popup_surface = None
|
||||
self.update_images()
|
||||
|
||||
def update_images(self):
|
||||
|
@ -288,9 +306,37 @@ class Button:
|
|||
def update(self, mouse_pos):
|
||||
self.hovered = self.is_hovered(mouse_pos)
|
||||
|
||||
if self.popup_text is not None and self.hovered:
|
||||
self.popup_timer += FPS
|
||||
if self.popup_timer >= self.popup_duration:
|
||||
self.show_popup(mouse_pos)
|
||||
else:
|
||||
self.popup_timer = 0
|
||||
self.popup_surface = None
|
||||
|
||||
def show_popup(self, mouse_pos):
|
||||
font = pygame.font.Font(None, 24)
|
||||
text_surface = font.render(self.popup_text, True, (0, 0, 0), (255, 255, 225))
|
||||
text_rect = text_surface.get_rect(center=mouse_pos)
|
||||
|
||||
popup_width = text_rect.width + 14
|
||||
popup_height = text_rect.height + 14
|
||||
|
||||
popup_x = min(mouse_pos[0], WIDTH - popup_width - 1)
|
||||
popup_y = min(mouse_pos[1] + 20, HEIGHT - popup_height - 1)
|
||||
|
||||
self.popup_surface = pygame.Surface((popup_width, popup_height), pygame.SRCALPHA)
|
||||
pygame.draw.rect(self.popup_surface, (255, 255, 255), self.popup_surface.get_rect())
|
||||
pygame.draw.rect(self.popup_surface, (0, 0, 0), self.popup_surface.get_rect(), 1)
|
||||
self.popup_surface.blit(text_surface, (7, 7))
|
||||
|
||||
self.popup_rect = self.popup_surface.get_rect(topleft=(popup_x, popup_y))
|
||||
|
||||
def draw(self, screen):
|
||||
if not self.disabled:
|
||||
screen.blit(self.hover_image if self.hovered else self.img, self.rect)
|
||||
if self.popup_surface:
|
||||
screen.blit(self.popup_surface, self.popup_rect)
|
||||
else:
|
||||
screen.blit(self.img, self.rect)
|
||||
|
||||
|
@ -371,45 +417,126 @@ def quick_game():
|
|||
|
||||
|
||||
def render_albums():
|
||||
global current_mode, album_name
|
||||
global current_mode, album_name, delete_mode, accepted, albums_to_delete
|
||||
current_hovered_index = -1
|
||||
size_to_y = {"small": 25, "medium": 35, "big": 65}
|
||||
y = size_to_y[current_size]
|
||||
|
||||
for hover_index, album in enumerate(storage["albums"]):
|
||||
for hover_index, album in enumerate(list(storage["albums"].keys())):
|
||||
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
|
||||
|
||||
if album_hover and pygame.mouse.get_pressed()[0]:
|
||||
album_name = album
|
||||
if album_name != album:
|
||||
album_name = None
|
||||
|
||||
if album_name is not None:
|
||||
current_mode = "select"
|
||||
current_hovered_index = update_hover_index(current_hovered_index, album_hover, hover_index)
|
||||
|
||||
album = handle_album_interaction(album_hover, album)
|
||||
if album:
|
||||
return album
|
||||
|
||||
if delete_mode:
|
||||
albums_to_delete = delete_albums_mode(y, album_rect, current_hovered_index, hover_index)
|
||||
|
||||
y += cons[0]
|
||||
|
||||
if accepted and albums_to_delete:
|
||||
delete_albums(albums_to_delete)
|
||||
delete_mode = False
|
||||
accepted = False
|
||||
|
||||
if delete_mode is False:
|
||||
draw_arrow(current_hovered_index)
|
||||
|
||||
if typing:
|
||||
album_creation(y)
|
||||
|
||||
|
||||
def update_hover_index(current_hovered_index, album_hover, hover_index):
|
||||
if album_hover:
|
||||
current_hovered_index = hover_index
|
||||
return current_hovered_index
|
||||
|
||||
|
||||
def handle_album_interaction(album_hover, album):
|
||||
global current_mode, album_name
|
||||
|
||||
if album_hover and pygame.mouse.get_pressed()[0]:
|
||||
album_name = album
|
||||
if album_name is not None:
|
||||
current_mode = "select"
|
||||
return album
|
||||
|
||||
return None
|
||||
|
||||
|
||||
albums_to_delete = []
|
||||
|
||||
def delete_albums_mode(y, album_rect, current_hovered_index, hover_index):
|
||||
global albums_to_delete
|
||||
checkbox_rect = pygame.Rect(cons[2], y + cons[3], checkbox[1], checkbox[1])
|
||||
checkbox_hover = checkbox_rect.collidepoint(pygame.mouse.get_pos())
|
||||
|
||||
for event in event_list:
|
||||
if checkbox_hover and event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
||||
pygame.time.wait(100)
|
||||
cursor_pos = pygame.mouse.get_pos()
|
||||
adjusted_pos = (cursor_pos[0] + 20, cursor_pos[1])
|
||||
album_hover = album_rect.collidepoint(adjusted_pos)
|
||||
index = update_hover_index(current_hovered_index, album_hover, hover_index)
|
||||
album = list(storage["albums"].keys())[index]
|
||||
|
||||
if album_rect.collidepoint(adjusted_pos):
|
||||
|
||||
if album not in albums_to_delete:
|
||||
albums_to_delete.append(album)
|
||||
|
||||
|
||||
elif album in albums_to_delete:
|
||||
albums_to_delete.remove(album)
|
||||
|
||||
|
||||
return albums_to_delete
|
||||
|
||||
checkbox_image = Image((checkbox[0], 0), (cons[2], y + cons[3]), (checkbox[1], checkbox[1]))
|
||||
if list(storage["albums"].keys())[hover_index] in albums_to_delete:
|
||||
checkbox_image = Image((checkbox[0] + checkbox[1] + 3, 0), (cons[2], y + cons[3]), (checkbox[1], checkbox[1]))
|
||||
checkbox_image.draw(screen)
|
||||
return albums_to_delete
|
||||
|
||||
|
||||
def delete_albums(albums_to_delete):
|
||||
for album in albums_to_delete:
|
||||
if album in storage["albums"]:
|
||||
del storage["albums"][album]
|
||||
|
||||
with open(DATA_FILE, 'w') as data_file:
|
||||
data_file.write(json.dumps(storage, indent=3))
|
||||
|
||||
|
||||
def draw_arrow(current_hovered_index):
|
||||
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]))
|
||||
arrow_image.draw(screen)
|
||||
|
||||
|
||||
def album_deletion():
|
||||
# Not finished yet
|
||||
pass
|
||||
def album_creation(y):
|
||||
global user_text, typing
|
||||
|
||||
render_text(user_text, (size[1], y), screen)
|
||||
|
||||
def album_creation():
|
||||
# Not finished yet
|
||||
pass
|
||||
if pygame.time.get_ticks() % 1000 < 500:
|
||||
caret_x = size[1] + pygame.font.SysFont(FONT, FONT_SIZE).size(user_text)[0] - 2
|
||||
render_text("|", (caret_x, y), screen)
|
||||
|
||||
mouse_clicked = pygame.mouse.get_pressed()[0]
|
||||
keys = pygame.key.get_pressed()
|
||||
if (user_text and mouse_clicked) or (user_text and keys[pygame.K_RETURN]):
|
||||
if user_text not in storage["albums"]:
|
||||
storage["albums"][user_text] = {}
|
||||
with open(DATA_FILE, 'w') as data_file:
|
||||
data_file.write(json.dumps(storage, indent=3))
|
||||
typing = False
|
||||
user_text = ''
|
||||
|
||||
# SELECT MODE
|
||||
class ImageRender:
|
||||
|
@ -428,7 +555,7 @@ class ImageRender:
|
|||
return
|
||||
|
||||
self.current = image_names[self.index]
|
||||
selected_image = pygame.image.load(MAIN_PATH + IMAGES_PATH + self.album_name + "/" + self.current)
|
||||
selected_image = pygame.image.load(IMAGES_PATH + self.album_name + "/" + self.current)
|
||||
self.scaled_image = pygame.transform.scale(selected_image, (self.scaled_size[2], self.scaled_size[3]))
|
||||
current_img = self.current
|
||||
current_album = self.album_name
|
||||
|
@ -517,7 +644,9 @@ def load_puzzle():
|
|||
|
||||
puzzle_version = settings_data["grid"]
|
||||
image_path = puzzle_data[f'current {puzzle_version}']['selected_image']
|
||||
puzzle_image = pygame.image.load(MAIN_PATH + image_path)
|
||||
path_parts = image_path.split('/')
|
||||
real_image_path = os.path.abspath(os.path.join(script_dir, *path_parts))
|
||||
puzzle_image = pygame.image.load(real_image_path)
|
||||
|
||||
directions = {"up": [4, 8, 12],
|
||||
"down": [],
|
||||
|
@ -616,7 +745,8 @@ def save_puzzle_state():
|
|||
|
||||
|
||||
def update_puzzle_data(completed, sorted, current_time, current_moves, real_time):
|
||||
path_components = puzzle_data[f'current {puzzle_version}']['selected_image'].split('/')[2:]
|
||||
number = 2 if puzzle_version == '4x4' else 3
|
||||
path_components = puzzle_data[f'current {puzzle_version}']['selected_image'].split('/')[number:]
|
||||
current_data = storage["albums"][path_components[0]]
|
||||
for component in path_components[1:]:
|
||||
if component in current_data:
|
||||
|
@ -718,7 +848,7 @@ def data_set(setting, value):
|
|||
settings_data[gui] = value
|
||||
elif setting == music:
|
||||
if isinstance(value, str):
|
||||
settings_data[sound]["version"] = value
|
||||
settings_data[music]["version"] = value
|
||||
else:
|
||||
settings_data[music]["volume"] = value
|
||||
update_music_volume()
|
||||
|
@ -732,6 +862,7 @@ def data_set(setting, value):
|
|||
with open(SETTINGS_FILE, "w") as settings_file:
|
||||
json.dump(settings_data, settings_file, indent=2)
|
||||
|
||||
|
||||
def play_music():
|
||||
music_file = settings_data[music]["version"]
|
||||
music_file = music_file.replace(" ", "_")
|
||||
|
@ -777,7 +908,7 @@ def set_hue():
|
|||
|
||||
sprite_sheet.set_hue(hue_value)
|
||||
|
||||
pygame.image.save(sprite_sheet.sheet, MAIN_PATH + SIZE_PATH + str(INT) + STYLE_PATH + "spritesheet.png")
|
||||
pygame.image.save(sprite_sheet.sheet, SIZE_PATH + str(INT) + STYLE_PATH + "spritesheet.png")
|
||||
|
||||
settings_data[gui][x] = hue_value
|
||||
with open(SETTINGS_FILE, "w") as settings_file:
|
||||
|
@ -841,7 +972,6 @@ def render_text_in_rect(long_text, rect_area):
|
|||
|
||||
return text_surfaces, text_rects
|
||||
|
||||
# Example usage
|
||||
rect_area = non_movable_area.copy()
|
||||
rect_area.x += text_size[1]
|
||||
rect_area.width -= text_size[1]
|
||||
|
@ -853,26 +983,26 @@ long_text = (
|
|||
)
|
||||
|
||||
text_surfaces, text_rects = render_text_in_rect(long_text, rect_area)
|
||||
|
||||
names = ("Pause", "Menu", "Hint", "Shuffle", "Close", "Delete", "Continue", "Settings", "Quick game", "Add new", "Info", "Stats")
|
||||
|
||||
# Buttons (maybe optimise?)
|
||||
if current_size == SIZE_CHOICES[0]:
|
||||
px12 = (12, 12)
|
||||
px14 = (14, 14)
|
||||
timer_button = Button((0, 0), (7, 3), px12)
|
||||
menu_button = Button((15, 0), (80, 3), px12)
|
||||
hint_button = Button((30, 0), (95, 3), px12)
|
||||
shuffle_button = Button((45, 0), (110, 3), px12)
|
||||
close_button = Button((60, 0), (125, 3), px12)
|
||||
timer_button = Button((0, 0), (7, 3), px12, names[0])
|
||||
menu_button = Button((15, 0), (80, 3), px12, names[1])
|
||||
hint_button = Button((30, 0), (95, 3), px12, names[2])
|
||||
shuffle_button = Button((45, 0), (110, 3), px12, names[3])
|
||||
close_button = Button((60, 0), (125, 3), px12, names[4])
|
||||
finished_button = Button((75, 0), (7, 3), px12)
|
||||
not_finished_button = Button((90, 0), (7, 3), px12)
|
||||
delete_button = Button((105, 0), (95, 3), px12)
|
||||
continue_button = Button((120, 0), (110, 3), px12)
|
||||
settings_button = Button((135, 0), (7, 3), px12)
|
||||
quick_add_button = Button((34, 30), (22, 3), (55, 12))
|
||||
new_button = Button((150, 0), (80, 3), px12)
|
||||
info_button = Button((165, 0), (7, 3), px12)
|
||||
stats_button = Button((180, 0), (95, 3), px12)
|
||||
delete_button = Button((105, 0), (95, 3), px12, names[5])
|
||||
continue_button = Button((120, 0), (110, 3), px12, names[6])
|
||||
settings_button = Button((135, 0), (7, 3), px12, names[7])
|
||||
quick_add_button = Button((34, 30), (22, 3), (55, 12), names[8])
|
||||
new_button = Button((150, 0), (80, 3), px12, names[9])
|
||||
info_button = Button((165, 0), (7, 3), px12, names[10])
|
||||
stats_button = Button((180, 0), (95, 3), px12, names[11])
|
||||
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))
|
||||
|
@ -881,20 +1011,20 @@ if current_size == SIZE_CHOICES[0]:
|
|||
elif current_size == SIZE_CHOICES[1]:
|
||||
px16 = (16, 16)
|
||||
px20 = (20, 20)
|
||||
timer_button = Button((0, 0), (8, 4), px16)
|
||||
menu_button = Button((19, 0), (118, 4), px16)
|
||||
hint_button = Button((38, 0), (138, 4), px16)
|
||||
shuffle_button = Button((57, 0), (158, 4), px16)
|
||||
close_button = Button((76, 0), (178, 4), px16)
|
||||
timer_button = Button((0, 0), (8, 4), px16, names[0])
|
||||
menu_button = Button((19, 0), (118, 4), px16, names[1])
|
||||
hint_button = Button((38, 0), (138, 4), px16, names[2])
|
||||
shuffle_button = Button((57, 0), (158, 4), px16, names[3])
|
||||
close_button = Button((76, 0), (178, 4), px16, names[4])
|
||||
finished_button = Button((95, 0), (8, 4), px16)
|
||||
not_finished_button = Button((114, 0), (8, 4), px16)
|
||||
delete_button = Button((133, 0), (138, 4), px16)
|
||||
continue_button = Button((152, 0), (158, 4), px16)
|
||||
settings_button = Button((171, 0), (8, 4), px16)
|
||||
quick_add_button = Button((46, 38), (28, 4), (86, 16))
|
||||
new_button = Button((190, 0), (118, 4), px16)
|
||||
info_button = Button((209, 0), (8, 4), px16)
|
||||
stats_button = Button((228, 0), (138, 4), px16)
|
||||
delete_button = Button((133, 0), (138, 4), px16, names[5])
|
||||
continue_button = Button((152, 0), (158, 4), px16, names[6])
|
||||
settings_button = Button((171, 0), (8, 4), px16, names[7])
|
||||
quick_add_button = Button((46, 38), (28, 4), (86, 16), names[8])
|
||||
new_button = Button((190, 0), (118, 4), px16, names[9])
|
||||
info_button = Button((209, 0), (8, 4), px16, names[10])
|
||||
stats_button = Button((228, 0), (138, 4), px16, names[11])
|
||||
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))
|
||||
|
@ -903,20 +1033,20 @@ elif current_size == SIZE_CHOICES[1]:
|
|||
else:
|
||||
px32 = (32, 32)
|
||||
px40 = (40, 40)
|
||||
timer_button = Button((0, 0), (12, 6), px32)
|
||||
menu_button = Button((35, 0), (241, 6), px32)
|
||||
hint_button = Button((72, 0), (278, 6), px32)
|
||||
shuffle_button = Button((105, 0), (315, 6), px32)
|
||||
close_button = Button((140, 0), (352, 6), px32)
|
||||
timer_button = Button((0, 0), (12, 6), px32, names[0])
|
||||
menu_button = Button((35, 0), (241, 6), px32, names[1])
|
||||
hint_button = Button((72, 0), (278, 6), px32, names[2])
|
||||
shuffle_button = Button((105, 0), (315, 6), px32, names[3])
|
||||
close_button = Button((140, 0), (352, 6), px32, names[4])
|
||||
finished_button = Button((175, 0), (12, 6), px32)
|
||||
not_finished_button = Button((210, 0), (8, 6), px32)
|
||||
delete_button = Button((245, 0), (278, 6), px32)
|
||||
continue_button = Button((280, 0), (315, 6), px32)
|
||||
settings_button = Button((315, 0), (12, 6), px32)
|
||||
quick_add_button = Button((86, 70), (49, 6), (187, 32))
|
||||
new_button = Button((350, 0), (241, 6), px32)
|
||||
info_button = Button((385, 0), (12, 6), px32)
|
||||
stats_button = Button((420, 0), (278, 6), px32)
|
||||
delete_button = Button((245, 0), (278, 6), px32, names[5])
|
||||
continue_button = Button((280, 0), (315, 6), px32, names[6])
|
||||
settings_button = Button((315, 0), (12, 6), px32, names[7])
|
||||
quick_add_button = Button((86, 70), (49, 6), (187, 32), names[8])
|
||||
new_button = Button((350, 0), (241, 6), px32, names[9])
|
||||
info_button = Button((385, 0), (12, 6), px32, names[10])
|
||||
stats_button = Button((420, 0), (278, 6), px32, names[11])
|
||||
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))
|
||||
|
@ -925,7 +1055,8 @@ else:
|
|||
|
||||
|
||||
def load_data():
|
||||
path_components = puzzle_data[f'current {puzzle_version}']['selected_image'].split('/')[2:]
|
||||
number = 2 if puzzle_version == '4x4' else 3
|
||||
path_components = puzzle_data[f'current {puzzle_version}']['selected_image'].split('/')[number:]
|
||||
current_data = storage["albums"][path_components[0]]
|
||||
for component in path_components[1:]:
|
||||
current_data = current_data[component]
|
||||
|
@ -954,8 +1085,8 @@ settings_buttons = [info_button, menu_button, stats_button, continue_button, clo
|
|||
do_not_save = False
|
||||
|
||||
|
||||
def button_check(pressed_button, run, current_mode, timer_running):
|
||||
global completed, not_shuffled, current_timer_text, current_moves, real_time
|
||||
def button_check(pressed_button, run, current_mode, timer_running, delete_mode):
|
||||
global completed, not_shuffled, current_timer_text, current_moves, real_time, accepted, typing, albums_to_delete
|
||||
do_not_save = False
|
||||
if pressed_button == close_button:
|
||||
run = False
|
||||
|
@ -971,12 +1102,15 @@ def button_check(pressed_button, run, current_mode, timer_running):
|
|||
current_mode = "game"
|
||||
elif pressed_button == delete_button:
|
||||
if current_mode == "menu":
|
||||
album_deletion()
|
||||
if delete_mode is False:
|
||||
delete_mode = True
|
||||
elif albums_to_delete and accepted is False:
|
||||
accepted = True
|
||||
else:
|
||||
# Not finished yet
|
||||
pass
|
||||
delete_mode = False
|
||||
elif pressed_button == new_button:
|
||||
album_creation()
|
||||
if current_mode == "menu":
|
||||
typing = True
|
||||
elif pressed_button == quick_add_button:
|
||||
quick_game()
|
||||
current_mode = "game"
|
||||
|
@ -992,7 +1126,7 @@ def button_check(pressed_button, run, current_mode, timer_running):
|
|||
elif pressed_button == stats_button:
|
||||
current_mode = "stats"
|
||||
|
||||
return run, current_mode, timer_running, do_not_save
|
||||
return run, current_mode, timer_running, do_not_save, delete_mode
|
||||
|
||||
|
||||
win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE,
|
||||
|
@ -1025,6 +1159,8 @@ def data_check(current_mode):
|
|||
# Game state
|
||||
run = True
|
||||
current_mode = "menu"
|
||||
delete_mode = False
|
||||
accepted = False
|
||||
# Dragging and mouse interaction
|
||||
dragging = False
|
||||
can_move = False
|
||||
|
@ -1033,6 +1169,9 @@ pressed_button = None
|
|||
slider_moving = False
|
||||
setting = None
|
||||
arrow = None
|
||||
user_text = ''
|
||||
typing = False
|
||||
checkbox_clicked = False
|
||||
# Select mode
|
||||
clicked_image = False
|
||||
image_display = None
|
||||
|
@ -1074,11 +1213,18 @@ while run:
|
|||
selected_album = render_albums()
|
||||
|
||||
if current_mode == "select":
|
||||
try:
|
||||
if image_display is None or current_album != selected_album:
|
||||
selected_image = ImageRender(selected_album)
|
||||
image_display = True
|
||||
|
||||
selected_image.render(screen)
|
||||
except (AttributeError, NameError):
|
||||
pass
|
||||
|
||||
for button in current_buttons:
|
||||
if button.popup_surface:
|
||||
screen.blit(button.popup_surface, button.popup_rect.topleft)
|
||||
|
||||
event_list = pygame.event.get()
|
||||
|
||||
|
@ -1092,6 +1238,7 @@ while run:
|
|||
if not non_movable_area.collidepoint(pygame.mouse.get_pos()):
|
||||
can_move = True
|
||||
if current_mode == "select":
|
||||
try:
|
||||
clicked_image_rect = ImageRender.image_save(selected_album, current_img)
|
||||
clicked_image = clicked_image_rect.collidepoint(event.pos)
|
||||
if clicked_image:
|
||||
|
@ -1121,6 +1268,8 @@ while run:
|
|||
if to_right_button.is_hovered(event.pos):
|
||||
selected_image.update_index(1)
|
||||
last_image_switch_time = current_time
|
||||
except NameError:
|
||||
quick_game()
|
||||
|
||||
elif current_mode == "game":
|
||||
if non_movable_area.collidepoint(event.pos) and not timer_running:
|
||||
|
@ -1137,7 +1286,7 @@ while run:
|
|||
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)
|
||||
run, current_mode, timer_running, do_not_save, delete_mode = button_check(pressed_button, run, current_mode, timer_running, delete_mode)
|
||||
|
||||
elif event.type == pygame.MOUSEMOTION and can_move:
|
||||
new_pos = pygame.mouse.get_pos()
|
||||
|
@ -1162,6 +1311,14 @@ while run:
|
|||
scroll_offset += 20
|
||||
scroll_offset = min(scroll_offset, max_scroll_offset)
|
||||
|
||||
elif typing and event.type == pygame.KEYDOWN:
|
||||
|
||||
if event.key == pygame.K_BACKSPACE:
|
||||
user_text = user_text[0:-1]
|
||||
elif len(user_text) < 15 and event.key != pygame.K_RETURN:
|
||||
user_text += event.unicode
|
||||
|
||||
|
||||
if current_mode == "game":
|
||||
if timer_running:
|
||||
current_time = pygame.time.get_ticks() - timer_start_time
|
||||
|
@ -1194,6 +1351,9 @@ while run:
|
|||
piece_y = row * puzzle_size[1] // len(puzzle_matrix) + non_movable_area.y
|
||||
screen.blit(puzzle_pieces[puzzle_matrix[row][col] - 1][0], (piece_x, piece_y))
|
||||
|
||||
for button in current_buttons:
|
||||
button.draw(screen)
|
||||
|
||||
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
||||
mouse_x, mouse_y = pygame.mouse.get_pos()
|
||||
|
||||
|
@ -1227,7 +1387,6 @@ while run:
|
|||
|
||||
surface = pygame.Surface((non_movable_area.width, non_movable_area.height), pygame.SRCALPHA)
|
||||
surface.fill((0, 0, 0, alpha))
|
||||
print(alpha)
|
||||
screen.blit(surface, (non_movable_area.x, non_movable_area.y))
|
||||
|
||||
render_text("You win !!", (win_area.x, win_area.y), screen, (255, 255, 255, text_alpha), True)
|
||||
|
|
|
@ -3,48 +3,48 @@
|
|||
"Original images": {
|
||||
"1.png": [
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
99,
|
||||
"00:01:11",
|
||||
"00:00:46",
|
||||
6
|
||||
9,
|
||||
"00:00:02",
|
||||
"00:00:02",
|
||||
0
|
||||
],
|
||||
"2.png": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
111,
|
||||
"00:01:00",
|
||||
"00:01:00",
|
||||
3
|
||||
0,
|
||||
"00:00:00",
|
||||
"00:00:00",
|
||||
0
|
||||
],
|
||||
"3.png": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
23,
|
||||
"00:00:13",
|
||||
"00:00:13",
|
||||
3
|
||||
0,
|
||||
"00:00:00",
|
||||
"00:00:00",
|
||||
0
|
||||
],
|
||||
"4.png": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
11,
|
||||
"00:00:11",
|
||||
"00:00:11",
|
||||
0,
|
||||
"00:00:00",
|
||||
"00:00:00",
|
||||
0
|
||||
],
|
||||
"5.png": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
5,
|
||||
"00:00:03",
|
||||
"00:00:03",
|
||||
5
|
||||
0,
|
||||
"00:00:00",
|
||||
"00:00:00",
|
||||
0
|
||||
],
|
||||
"6.png": [
|
||||
0,
|
||||
|
@ -87,8 +87,8 @@
|
|||
0,
|
||||
0,
|
||||
0,
|
||||
"00:00:34",
|
||||
"00:00:04",
|
||||
"00:00:00",
|
||||
"00:00:00",
|
||||
0
|
||||
]
|
||||
},
|
||||
|
@ -96,28 +96,28 @@
|
|||
"1.png": [
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
9,
|
||||
"00:00:06",
|
||||
"00:00:00",
|
||||
0
|
||||
0,
|
||||
17,
|
||||
"00:00:10",
|
||||
"00:00:10",
|
||||
8
|
||||
],
|
||||
"2.png": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
"00:00:16",
|
||||
"00:00:16",
|
||||
3
|
||||
0,
|
||||
"00:00:00",
|
||||
"00:00:00",
|
||||
0
|
||||
],
|
||||
"3.png": [
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
57,
|
||||
"00:00:20",
|
||||
"00:00:20",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"00:00:00",
|
||||
"00:00:00",
|
||||
0
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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, 13, 10, 2], [4, 3, 5, 12], [11, 14, 8, 15], [1, 7, 9, 0]], "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"}}
|
||||
{"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": [[1, 7, 4, 3], [5, 2, 6, 8], [0, 9, 10, 14], [13, 11, 15, 12]], "selected_image": "images/albums/Original images/1.png"}, "current 3x3": {"matrix": [[4, 0, 3], [1, 7, 6], [5, 8, 2]], "selected_image": "/images/albums/Birds/1.png"}}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"size": "big",
|
||||
"style": "dark",
|
||||
"size": "small",
|
||||
"style": "classic",
|
||||
"grid": "4x4",
|
||||
"gui color": 0,
|
||||
"music": {
|
||||
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"sound": {
|
||||
"on": true,
|
||||
"volume": 12,
|
||||
"volume": 4,
|
||||
"version": "wood"
|
||||
},
|
||||
"display": "time",
|
||||
|
|