elukjanovica 2024-02-28 19:02:51 +02:00
parent a28063da25
commit 7ef54795e8
2 changed files with 159 additions and 78 deletions

158
main.py
View File

@ -12,13 +12,14 @@ pygame.init()
FPS = 60 FPS = 60
MAIN_PATH = "C:/Users/User/Documents/Coding/Picture Puzzle/" MAIN_PATH = "C:/Users/User/Documents/Coding/Picture Puzzle/"
MAIN_PATH = "C:/Users/RVKG/Documents/My Palettes/Picture Puzzle/" #School: MAIN_PATH = "C:/Users/RVKG/Documents/My Palettes/Picture Puzzle/"
IMAGES_PATH = "/images/albums/" IMAGES_PATH = "/images/albums/"
DATA_FILE = "main_data.json" DATA_FILE = "main_data.json"
PUZZLE_FILE = "main_puzzle.json" PUZZLE_FILE = "main_puzzle.json"
SETTINGS_FILE = "main_settings.json" SETTINGS_FILE = "main_settings.json"
STATS_FILE = "main_stats.json" STATS_FILE = "main_stats.json"
SIZE_PATH = "images/assets/"
# Data loading and saving # Data loading and saving
def load_data(data): def load_data(data):
@ -35,23 +36,21 @@ settings_data = load_data(SETTINGS_FILE)
stats_data = load_data(STATS_FILE) stats_data = load_data(STATS_FILE)
# Configuration # Configuration
SIZE_CHOICES = ["small", "big"] SIZE_CHOICES = ["small", "medium", "big"]
VERSION_CHOICES = ["4x4", "3x3"] STYLE_CHOICES = ["classic", "original", "dark"]
STYLE_CHOICES = ["classic", "original", "sci-fi"] GRID_CHOICES = ["4x4", "3x3"]
MUSIC_ON = [True, False]
MUSIC_CHOICES = ["funky-leap", "serenity", "sunny-day"] MUSIC_CHOICES = ["funky-leap", "serenity", "sunny-day"]
SOUND_ON = [True, False]
SOUND_CHOICES = ["puzzle", "wood", "metal_pipe", "lego_breaking"] SOUND_CHOICES = ["puzzle", "wood", "metal_pipe", "lego_breaking"]
DISPLAY_CHOICES = ["time", "moves"] DISPLAY_CHOICES = ["time", "moves"]
LANGUAGE_CHOICES = ["english", "russian", "latvian"] LANGUAGE_CHOICES = ["english", "russian", "latvian"]
FONTS = ["msreferencesansserif", "arial", "bahnschrift"] FONTS = ["msreferencesansserif", "arial", "bahnschrift"]
if settings_data["gui_style"] == STYLE_CHOICES[0]: if settings_data["style"] == STYLE_CHOICES[0]:
FONT = FONTS[0] FONT = FONTS[0]
STYLE_PATH = "1_" STYLE_PATH = "1_"
text_color = (1, 35, 61) text_color = (1, 35, 61)
timer_color = (255, 255, 255) timer_color = (255, 255, 255)
elif settings_data["gui_style"] == STYLE_CHOICES[1]: elif settings_data["style"] == STYLE_CHOICES[1]:
FONT = FONTS[1] FONT = FONTS[1]
STYLE_PATH = "2_" STYLE_PATH = "2_"
text_color = (255, 255, 255) text_color = (255, 255, 255)
@ -64,7 +63,7 @@ else:
if settings_data["size"] == SIZE_CHOICES[0]: if settings_data["size"] == SIZE_CHOICES[0]:
WIDTH, HEIGHT = 144, 154 WIDTH, HEIGHT = 144, 154
SIZE_PATH = "images/assets/0" INT = 0
if FONT == FONTS[0]: if FONT == FONTS[0]:
FONT_SIZE = 11 FONT_SIZE = 11
elif FONT == FONTS[1]: elif FONT == FONTS[1]:
@ -75,10 +74,14 @@ if settings_data["size"] == SIZE_CHOICES[0]:
timer_area = pygame.Rect(22, 1, 55, 12) timer_area = pygame.Rect(22, 1, 55, 12)
puzzle_size = (128, 128) puzzle_size = (128, 128)
win_area = pygame.Rect(55, 70, 55, 12) win_area = pygame.Rect(55, 70, 55, 12)
y = 25
size = [20, 25, 100, 15]
cons = [15, 195, 12, 3, 9]
scaled_size = (18, 21, 108, 108)
else: elif settings_data["size"] == SIZE_CHOICES[1]:
WIDTH, HEIGHT = 202, 216 WIDTH, HEIGHT = 202, 216
SIZE_PATH = "images/assets/1" INT = 1
if FONT == FONTS[0]: if FONT == FONTS[0]:
FONT_SIZE = 15 FONT_SIZE = 15
elif FONT == FONTS[1]: elif FONT == FONTS[1]:
@ -89,8 +92,30 @@ else:
win_area = pygame.Rect(71, 98, 55, 12) win_area = pygame.Rect(71, 98, 55, 12)
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)
y = 35
size = [30, 35, 110, 25]
cons = [25, 247, 18, 3, 13]
scaled_size = (22, 26, 158, 158)
puzzle_version = settings_data["version"] else:
WIDTH, HEIGHT = 202, 216
INT = 2
if FONT == FONTS[0]:
FONT_SIZE = 15
elif FONT == FONTS[1]:
FONT_SIZE = 17
elif FONT == FONTS[2]:
FONT_SIZE = 16
puzzle_size = (180, 180)
win_area = pygame.Rect(71, 98, 55, 12)
non_movable_area = pygame.Rect(11, 26, 180, 180)
timer_area = pygame.Rect(27, 2, 86, 16)
y = 45
size = [40, 45, 120, 35]
cons = [35, 270, 18, 3, 15]
scaled_size = (22, 26, 158, 158)
puzzle_version = settings_data["grid"]
# Seting screen and other stuff # Seting screen and other stuff
programIcon = pygame.image.load('icon.png') programIcon = pygame.image.load('icon.png')
@ -119,7 +144,19 @@ class SpriteSheet:
return image return image
sprite_sheet = SpriteSheet(SIZE_PATH + STYLE_PATH + "sprites.png") def set_hue(self, hue):
for x in range(self.sheet.get_width()):
for y in range(self.sheet.get_height()):
color = self.sheet.get_at((x, y))
h, s, v, a = pygame.Color(color)
h = (h + hue) % 360
new_color = pygame.Color(0, 0, 0, 0)
new_color.hsva = (h, s, v, a)
self.sheet.set_at((x, y), new_color)
sprite_sheet = SpriteSheet(SIZE_PATH + str(INT) + STYLE_PATH + "sprites.png")
class Image: class Image:
def __init__(self, sprite_position, window_position, size): def __init__(self, sprite_position, window_position, size):
@ -136,6 +173,35 @@ class Image:
def draw(self, screen): def draw(self, screen):
screen.blit(self.img, self.rect) screen.blit(self.img, self.rect)
class Slider:
def __init__(self, line_size, button_size, position):
self.line_size = line_size
self.button_size = button_size
self.position = position
self.value = 0
self.button_rect = pygame.Rect(self.position[0], self.position[1] - (self.button_size[1] - self.line_size[1]) // 2,
self.button_size[0], self.button_size[1])
self.slider_rect = pygame.Rect(self.position[0], self.position[1], self.line_size[0], self.line_size[1])
def update(self):
button_x = self.position[0] + (self.value / 360) * (self.line_size[0] - self.button_size[0])
self.button_rect.topleft = (button_x, self.button_rect.y)
def draw(self, screen):
pygame.draw.rect(screen, (200, 200, 200), self.slider_rect)
pygame.draw.rect(screen, (0, 0, 255), self.button_rect)
def handle_event(self, event):
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
if self.button_rect.collidepoint(event.pos):
self.dragging = True
elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
self.dragging = False
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]))
self.value = int(((mouse_x - self.position[0]) / (self.line_size[0] - self.button_size[0])) * 360)
self.update()
class Button: class Button:
def __init__(self, sprite_position, window_position, size): def __init__(self, sprite_position, window_position, size):
self.sprite_sheet = sprite_sheet self.sprite_sheet = sprite_sheet
@ -237,14 +303,6 @@ def quick_game():
def render_albums(): def render_albums():
global current_mode, album_name global current_mode, album_name
current_hovered_index = -1 current_hovered_index = -1
if settings_data["size"] == SIZE_CHOICES[0]:
y = 25
size = [20, 25, 100, 15]
cons = [15, 195, 12, 3, 9]
else:
y = 35
size = [30, 35, 110, 25]
cons = [25, 247, 18, 3, 13]
for hover_index, album in enumerate(storage["albums"]): for hover_index, album in enumerate(storage["albums"]):
album_rect = pygame.Rect(size[0], y, size[2], size[3]) album_rect = pygame.Rect(size[0], y, size[2], size[3])
@ -320,11 +378,6 @@ class ImageRender:
@staticmethod @staticmethod
def image_save(selected_album, current_img): def image_save(selected_album, current_img):
if settings_data["size"] == SIZE_CHOICES[0]:
scaled_size = (18, 21, 108, 108)
else:
scaled_size = (22, 26, 158, 158)
for album in storage["albums"].values(): for album in storage["albums"].values():
for image in album.values(): for image in album.values():
image[0] = 0 image[0] = 0
@ -377,7 +430,7 @@ def cut_image(image):
piece_layer = pygame.Surface((piece_width, piece_height), pygame.SRCALPHA) piece_layer = pygame.Surface((piece_width, piece_height), pygame.SRCALPHA)
if puzzle_version == VERSION_CHOICES[0]: if puzzle_version == GRID_CHOICES[0]:
layer_path = pygame.image.load("images/assets/piece32.png").convert_alpha() layer_path = pygame.image.load("images/assets/piece32.png").convert_alpha()
else: else:
layer_path = pygame.image.load("images/assets/piece45.png" if settings_data["size"] == SIZE_CHOICES[0] else "images/assets/piece60.png").convert_alpha() layer_path = pygame.image.load("images/assets/piece45.png" if settings_data["size"] == SIZE_CHOICES[0] else "images/assets/piece60.png").convert_alpha()
@ -394,7 +447,7 @@ def cut_image(image):
def load_puzzle(): def load_puzzle():
global puzzle_matrix, original_matrix, empty_position, puzzle_pieces, shuffled_pieces, puzzle_size, directions, cell_size, number_of_rows, original_image global puzzle_matrix, original_matrix, empty_position, puzzle_pieces, shuffled_pieces, puzzle_size, directions, cell_size, number_of_rows, original_image
puzzle_version = settings_data["version"] puzzle_version = settings_data["grid"]
image_path = puzzle_data[f'current {puzzle_version}']['selected_image'] image_path = puzzle_data[f'current {puzzle_version}']['selected_image']
puzzle_image = pygame.image.load(MAIN_PATH + image_path) puzzle_image = pygame.image.load(MAIN_PATH + image_path)
@ -517,33 +570,60 @@ def update_puzzle_data(completed, sorted, current_time, current_moves, real_time
# SETTINGS MODE # SETTINGS MODE
def play_music(): def play_music():
music_file = settings_data["selected_music"] music_file = settings_data["music"]["version"]
volume = settings_data["music_volume"] volume = settings_data["music_volume"]
pygame.mixer.music.load("misc/" + music_file + ".mp3") pygame.mixer.music.load("misc/" + music_file + ".mp3")
pygame.mixer.music.set_volume(volume) pygame.mixer.music.set_volume(volume)
pygame.mixer.music.play(-1) pygame.mixer.music.play(-1)
if settings_data["music"] == MUSIC_ON[0]: if settings_data["music"]["on"] is True:
play_music() play_music()
def play_sound(): def play_sound():
sound_file = settings_data["selected_sound"] sound_file = settings_data["sound"]["version"]
volume = settings_data["sound_volume"] volume = settings_data["sound"]["volume"]
sound = pygame.mixer.Sound("misc/" + sound_file + ".ogg") sound = pygame.mixer.Sound("misc/" + sound_file + ".ogg")
sound.set_volume(volume) sound.set_volume(volume)
pygame.mixer.Sound.play(sound) pygame.mixer.Sound.play(sound)
def set_hue(): def set_hue():
if settings_data["gui_style"] == STYLE_CHOICES[0]: global hue_value
hue = 204 if settings_data["style"] == STYLE_CHOICES[0]:
elif settings_data["gui_style"] == STYLE_CHOICES[2]: hue_value = settings_data["gui color"][0]
hue = 255 # ??? x = 0
elif settings_data["style"] == STYLE_CHOICES[2]:
hue_value = settings_data["gui color"][1]
x = 1
keys = pygame.key.get_pressed() keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]: if keys[pygame.K_LEFT]:
hue = (hue - 1) % 360 hue_value = (hue_value - 1) % 360
if keys[pygame.K_RIGHT]: if keys[pygame.K_RIGHT]:
hue = (hue + 1) % 360 hue_value = (hue_value + 1) % 360
sprite_sheet.set_hue(hue_value)
pygame.image.save(sprite_sheet.sheet, MAIN_PATH + SIZE_PATH + str(INT) + STYLE_PATH + "spritesheet.png")
settings_data["gui color"][x] = hue_value
with open(SETTINGS_FILE, "w") as settings_file:
settings_file.write(json.dumps(settings_data))
def change_hue(image, hue):
new_image = image.copy()
for x in range(new_image.get_width()):
for y in range(new_image.get_height()):
color = new_image.get_at((x, y))
h, s, v, a = pygame.Color(color)
h = (h + hue) % 360
new_color = pygame.Color(0, 0, 0, 0)
new_color.hsva = (h, s, v, a)
new_image.set_at((x, y), new_color)
return new_image
def export(): def export():
# Export data function, not finished yet # Export data function, not finished yet
@ -790,7 +870,7 @@ while run:
if button.rect.collidepoint(start_pos): if button.rect.collidepoint(start_pos):
pressed_button = button 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 = button_check(pressed_button, run, current_mode, timer_running)
if settings_data["sound"] == SOUND_ON[0] and current_mode == "game" and non_movable_area.collidepoint(event.pos): if settings_data["sound"]["on"] is True and current_mode == "game" and non_movable_area.collidepoint(event.pos):
play_sound() play_sound()
elif event.type == pygame.MOUSEMOTION and can_move: elif event.type == pygame.MOUSEMOTION and can_move:

View File

@ -1,18 +1,19 @@
{ {
"size": "big" , "size": "big" ,
"version": "4x4", "style": "classic",
"gui_style": "classic", "grid": "4x4",
"gui_color": [ "gui color": [0, 0],
255, "sensitivity": 1,
0, "music": {
0 "on": true,
], "volume": 0.03,
"music": true, "version": "serenity"
"music_volume": 0.03, },
"selected_music": "serenity", "sound": {
"sound": true, "on": true,
"sound_volume": 0.04, "volume": 0.04,
"selected_sound": "wood", "version": "wood"
},
"display": "time", "display": "time",
"language": "english", "language": "english",
"keybinds": { "keybinds": {