This commit is contained in:
2025-01-16 21:17:08 +01:00
parent 6d36d494c3
commit 160953b4ba

127
main.py
View File

@@ -1,3 +1,5 @@
from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum from enum import Enum
import json import json
@@ -20,11 +22,11 @@ PAGE_MARGIN = 20
PAGE_BORDER_RADIUS = 40 PAGE_BORDER_RADIUS = 40
PAGE_BORDER_WIDTH = 20 PAGE_BORDER_WIDTH = 20
TAB_WIDTH = 150 TAB_WIDTH = 80
TAB_HEIGHT = 80 TAB_HEIGHT = 80
WORD_WIDTH = 228 WORD_WIDTH = 228
WORD_HEIGHT = 60 WORD_HEIGHT = 55
WORD_MARGIN = 16 WORD_MARGIN = 16
WORD_BORDER_RADIUS = 30 WORD_BORDER_RADIUS = 30
WORD_BORDER_WIDTH = 6 WORD_BORDER_WIDTH = 6
@@ -32,7 +34,7 @@ WORD_FONT_SIZE = 30
WORD_SHADOW_SIZE = 5 WORD_SHADOW_SIZE = 5
GRID_WIDTH = 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_WIDTH = PAGE_BORDER_WIDTH*2+(WORD_WIDTH+WORD_MARGIN)*GRID_WIDTH+WORD_MARGIN
WORD_PAGE_HEIGHT = SCREEN_HEIGHT-PAGE_MARGIN*2 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_PAGE_HEIGHT = SCREEN_HEIGHT-(TAB_HEIGHT+PAGE_MARGIN*3)
TEXT_MARGIN = 20 TEXT_MARGIN = 20
TEXT_TOP_MARGIN = 30 TEXT_TOP_MARGIN = 35
TEXT_WIDTH = TEXT_PAGE_WIDTH - TEXT_MARGIN*2 TEXT_WIDTH = TEXT_PAGE_WIDTH - TEXT_MARGIN*2
TEXT_HEIGHT = TEXT_PAGE_HEIGHT - TEXT_MARGIN*2 TEXT_HEIGHT = TEXT_PAGE_HEIGHT - TEXT_MARGIN*2
WORD_SLOT_SPACING = " "*12 WORD_SLOT_SPACING = " "*12
WORD_SLOT_NUDGING = 15 WORD_SLOT_NUDGING = 22
class WordColor(Enum): class WordColor(Enum):
Red = 0 # Names Red = 0 # Names
@@ -77,8 +79,12 @@ class Page():
class Word(): class Word():
word: str word: str
color: WordColor color: WordColor
page: Page page: None|Page
position: Vector2 position: Vector2
slot: None|WordSlot = None
def copy(self):
return Word(self.word,self.color,self.page,self.position,self.slot)
@dataclass @dataclass
class WordSlot(): 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): 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( pygame.draw.rect(
screen, screen,
@@ -205,6 +214,8 @@ def main(data: dict):
else: else:
visible_page = 0 visible_page = 0
held_word = None
word_slots: list[WordSlot] = [] word_slots: list[WordSlot] = []
for y in range(GRID_HEIGHT): for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH): for x in range(GRID_WIDTH):
@@ -237,37 +248,113 @@ def main(data: dict):
new_text = add_to_text(new_text,"") new_text = add_to_text(new_text,"")
for slot in res: 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) height = WORD_FONT_SIZE*len(new_text)
width, _ = font.size(new_text[-1]) width, _ = font.size(new_text[-1])
new_text = add_to_text(new_text,slot[2],"")
pos = Vector2( pos = Vector2(
TEXT_MARGIN + width - WORD_WIDTH, TEXT_MARGIN + width - WORD_WIDTH,
TEXT_MARGIN + height - WORD_HEIGHT//2 + TEXT_TOP_MARGIN*len(new_text) 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]:
if new_text[-1] != WORD_SLOT_SPACING+slot[2]: pos.x += WORD_SLOT_NUDGING
pos.x += WORD_SLOT_NUDGING
else:
print(len(new_text[-1]),width)
word_slots.append(WordSlot(WordColor(int(slot[1])),p,pos)) word_slots.append(WordSlot(WordColor(int(slot[1])),p,pos))
p.text = new_text p.text = new_text
words = [] words: list[Word] = []
for i,w in enumerate(data["words"]): for i,w in enumerate(data["words"]):
slot = word_slots[i] slot = word_slots[i]
word = Word(w[0],WordColor(w[1]),word_page,Vector2(slot.position.x,slot.position.y)) word = Word(w[0],WordColor(w[1]),word_page,Vector2(slot.position.x,slot.position.y))
slot.word = word slot.word = word
word.slot = slot
words.append(word) 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: while running:
for event in pygame.event.get(): for event in pygame.event.get():
if event.type == pygame.QUIT: if event.type == pygame.MOUSEBUTTONUP:
click()
elif event.type == pygame.QUIT:
running = False running = False
# fill the screen with a color to wipe away anything from last frame # fill the screen with a color to wipe away anything from last frame
drawer.fill("#4d2905") 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 # RENDER YOUR GAME HERE
for p in pages: for p in pages:
if not p.visible: if not p.visible:
@@ -284,15 +371,23 @@ def main(data: dict):
# drawing words # drawing words
for w in 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 continue
draw_word(w, drawer, font) draw_word(w, drawer, font)
if held_word is not None:
draw_word(held_word, drawer, font)
# Draw everything to the screen # Draw everything to the screen
frame = pygame.transform.scale(drawer,screen.get_size()) frame = pygame.transform.scale(drawer,screen.get_size())
screen.blit(frame,frame.get_rect()) 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 # flip() the display to put your work on screen
pygame.display.flip() pygame.display.flip()