From 160953b4ba0709a9bb90c229b7b8056fbe2addcc Mon Sep 17 00:00:00 2001 From: Nikolaj Gade Date: Thu, 16 Jan 2025 21:17:08 +0100 Subject: [PATCH] :sparkles: --- main.py | 127 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 111 insertions(+), 16 deletions(-) diff --git a/main.py b/main.py index 0f20bc9..26e3edd 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dataclasses import dataclass from enum import Enum import json @@ -20,11 +22,11 @@ PAGE_MARGIN = 20 PAGE_BORDER_RADIUS = 40 PAGE_BORDER_WIDTH = 20 -TAB_WIDTH = 150 +TAB_WIDTH = 80 TAB_HEIGHT = 80 WORD_WIDTH = 228 -WORD_HEIGHT = 60 +WORD_HEIGHT = 55 WORD_MARGIN = 16 WORD_BORDER_RADIUS = 30 WORD_BORDER_WIDTH = 6 @@ -32,7 +34,7 @@ WORD_FONT_SIZE = 30 WORD_SHADOW_SIZE = 5 GRID_WIDTH = 5 -GRID_HEIGHT = 10 +GRID_HEIGHT = 18 WORD_PAGE_WIDTH = PAGE_BORDER_WIDTH*2+(WORD_WIDTH+WORD_MARGIN)*GRID_WIDTH+WORD_MARGIN WORD_PAGE_HEIGHT = SCREEN_HEIGHT-PAGE_MARGIN*2 @@ -42,12 +44,12 @@ TEXT_PAGE_WIDTH = SCREEN_WIDTH-(WORD_PAGE_WIDTH+PAGE_MARGIN*3) TEXT_PAGE_HEIGHT = SCREEN_HEIGHT-(TAB_HEIGHT+PAGE_MARGIN*3) TEXT_MARGIN = 20 -TEXT_TOP_MARGIN = 30 +TEXT_TOP_MARGIN = 35 TEXT_WIDTH = TEXT_PAGE_WIDTH - TEXT_MARGIN*2 TEXT_HEIGHT = TEXT_PAGE_HEIGHT - TEXT_MARGIN*2 WORD_SLOT_SPACING = " "*12 -WORD_SLOT_NUDGING = 15 +WORD_SLOT_NUDGING = 22 class WordColor(Enum): Red = 0 # Names @@ -77,8 +79,12 @@ class Page(): class Word(): word: str color: WordColor - page: Page + page: None|Page position: Vector2 + slot: None|WordSlot = None + + def copy(self): + return Word(self.word,self.color,self.page,self.position,self.slot) @dataclass class WordSlot(): @@ -136,7 +142,10 @@ def draw_word_slot(word_slot: WordSlot, screen: pygame.surface.Surface): ) def draw_word(word: Word, screen: pygame.surface.Surface, font: pygame.font.Font): - pos = word.page.position+word.position + if word.page is not None: + pos = word.page.position+word.position + else: + pos = word.position pygame.draw.rect( screen, @@ -205,6 +214,8 @@ def main(data: dict): else: visible_page = 0 + held_word = None + word_slots: list[WordSlot] = [] for y in range(GRID_HEIGHT): for x in range(GRID_WIDTH): @@ -237,37 +248,113 @@ def main(data: dict): new_text = add_to_text(new_text,"") for slot in res: - new_text = add_to_text(new_text,WORD_SLOT_SPACING+slot[2],"") + new_text = add_to_text(new_text,WORD_SLOT_SPACING,"") height = WORD_FONT_SIZE*len(new_text) width, _ = font.size(new_text[-1]) + new_text = add_to_text(new_text,slot[2],"") pos = Vector2( TEXT_MARGIN + width - WORD_WIDTH, TEXT_MARGIN + height - WORD_HEIGHT//2 + TEXT_TOP_MARGIN*len(new_text) ) - print(new_text[-1] != WORD_SLOT_SPACING+slot[2]) - if new_text[-1] != WORD_SLOT_SPACING+slot[2]: - pos.x += WORD_SLOT_NUDGING - else: - print(len(new_text[-1]),width) + # if new_text[-1] != WORD_SLOT_SPACING+slot[2]: + pos.x += WORD_SLOT_NUDGING word_slots.append(WordSlot(WordColor(int(slot[1])),p,pos)) p.text = new_text - words = [] + words: list[Word] = [] for i,w in enumerate(data["words"]): slot = word_slots[i] word = Word(w[0],WordColor(w[1]),word_page,Vector2(slot.position.x,slot.position.y)) slot.word = word + word.slot = slot words.append(word) + def focused(): + x, y = pygame.mouse.get_pos() + ratio_x = (screen.get_width() / drawer.get_width()) + ratio_y = (screen.get_height() / drawer.get_height()) + scaled_xy = (x/ratio_x,y/ratio_y) + for w in words: + if w.page is None: + return w + pos = w.page.position+w.position + rect = pygame.Rect( + pos.x - WORD_MARGIN, + pos.y - WORD_MARGIN, + WORD_WIDTH + WORD_MARGIN*2, + WORD_HEIGHT + WORD_MARGIN*2 + ) + if rect.collidepoint(scaled_xy): + return w + + return None + + def click(): + nonlocal held_word + slot = None + x, y = pygame.mouse.get_pos() + ratio_x = (screen.get_width() / drawer.get_width()) + ratio_y = (screen.get_height() / drawer.get_height()) + scaled_xy = (x/ratio_x,y/ratio_y) + for w in word_slots: + pos = w.page.position+w.position + rect = pygame.Rect( + pos.x - WORD_MARGIN, + pos.y - WORD_MARGIN, + WORD_WIDTH + WORD_MARGIN*2, + WORD_HEIGHT + WORD_MARGIN*2 + ) + if rect.collidepoint(scaled_xy): + slot = w + break + + if slot is None: + return + + if held_word is None and slot.word is not None: + if slot.color is None: + held_word = slot.word + held_word.page = None + else: + words.remove(slot.word) + slot.word = None + elif held_word is not None and slot.word is None: + if slot.color is not None and slot.color != held_word.color: + return + + slot.word = held_word + if slot.color is not None: + new_word = slot.word.copy() + new_word.page = slot.word.slot.page + new_word.position = slot.word.slot.position + new_word.slot = slot.word.slot + new_word.slot.word = new_word + words.append(new_word) + slot.word.position = slot.position + slot.word.page = slot.page + slot.word.slot = slot + held_word = None + + while running: for event in pygame.event.get(): - if event.type == pygame.QUIT: + if event.type == pygame.MOUSEBUTTONUP: + click() + elif event.type == pygame.QUIT: running = False # fill the screen with a color to wipe away anything from last frame drawer.fill("#4d2905") + # Held word + if held_word is not None: + x, y = pygame.mouse.get_pos() + ratio_x = (screen.get_width() / drawer.get_width()) + ratio_y = (screen.get_height() / drawer.get_height()) + scaled_xy = (x/ratio_x,y/ratio_y) + held_word.position = Vector2(scaled_xy) - Vector2(WORD_WIDTH//2,WORD_HEIGHT//2) + # RENDER YOUR GAME HERE for p in pages: if not p.visible: @@ -284,15 +371,23 @@ def main(data: dict): # drawing words for w in words: - if not w.page.visible: + if w.page is not None and not w.page.visible and w != held_word: continue draw_word(w, drawer, font) + if held_word is not None: + draw_word(held_word, drawer, font) + # Draw everything to the screen frame = pygame.transform.scale(drawer,screen.get_size()) screen.blit(frame,frame.get_rect()) + if focused() is not None: + pygame.mouse.set_cursor(*pygame.cursors.tri_left) + else: + pygame.mouse.set_cursor(*pygame.cursors.arrow) + # flip() the display to put your work on screen pygame.display.flip()