from dataclasses import dataclass from enum import Enum import json import pygame from pygame import Vector2 # Colors BACKGROUND_COLOR = "#FCF5E5" PAGE_BORDER_COLOR = "#756A4F" WORD_BORDER_COLOR = "#FAE7A2" # Drawing constants SCREEN_WIDTH = 1280 SCREEN_HEIGHT = 720 PAGE_MARGIN = 10 PAGE_BORDER_RADIUS = 20 PAGE_BORDER_WIDTH = 10 WORD_WIDTH = 125 WORD_HEIGHT = 35 WORD_MARGIN = 8 WORD_BORDER_RADIUS = 15 WORD_BORDER_WIDTH = 3 WORD_FONT_SIZE = 15 GRID_WIDTH = 4 GRID_HEIGHT = 10 WORD_PAGE_WIDTH = PAGE_BORDER_WIDTH*2+(WORD_WIDTH+WORD_MARGIN)*GRID_WIDTH+WORD_MARGIN WORD_PAGE_HEIGHT = SCREEN_HEIGHT-PAGE_MARGIN*2 class WordColor(Enum): Red = 0 # Names Green = 1 # Nouns Lime = 2 # Numbers and such Blue = 3 # Verbs Grey = 4 # Other def color(self): return [ "#ff0000", "#00bb00", "#00ff00", "#0000ff", "#aaaaaa" ][self.value] @dataclass class Page(): visible: bool color: str text: None|str position: Vector2 size: Vector2 @dataclass class Word(): word: str color: WordColor page: Page position: Vector2 @dataclass class WordSlot(): color: None|WordColor page: Page position: Vector2 word: None|Word = None def draw_page(page: Page, screen: pygame.surface.Surface): pygame.draw.rect( screen, page.color, pygame.Rect( page.position.x + PAGE_BORDER_WIDTH, page.position.y + PAGE_BORDER_WIDTH, page.size.x - PAGE_BORDER_WIDTH*2, page.size.y - PAGE_BORDER_WIDTH*2 ) ) pygame.draw.rect( screen, PAGE_BORDER_COLOR, pygame.Rect(page.position.x,page.position.y,page.size.x,page.size.y), PAGE_BORDER_WIDTH, PAGE_BORDER_RADIUS ) def draw_word_slot(word_slot: WordSlot, screen: pygame.surface.Surface): pos = word_slot.page.position+word_slot.position if word_slot.color is None: color = "#00000000" else: color = word_slot.color.color() pygame.draw.rect( screen, color, pygame.Rect( pos.x + WORD_BORDER_WIDTH, pos.y + WORD_BORDER_WIDTH, WORD_WIDTH - WORD_BORDER_WIDTH*2, WORD_HEIGHT - WORD_BORDER_WIDTH*2 ), border_radius=WORD_BORDER_RADIUS ) pygame.draw.rect( screen, WORD_BORDER_COLOR, pygame.Rect( pos.x, pos.y, WORD_WIDTH,WORD_HEIGHT ), WORD_BORDER_WIDTH, WORD_BORDER_RADIUS ) def draw_word(word: Word, screen: pygame.surface.Surface, font: pygame.font.Font): pos = word.page.position+word.position pygame.draw.rect( screen, word.color.color(), pygame.Rect( pos.x + WORD_BORDER_WIDTH, pos.y + WORD_BORDER_WIDTH, WORD_WIDTH - WORD_BORDER_WIDTH*2, WORD_HEIGHT - WORD_BORDER_WIDTH*2 ), border_radius=WORD_BORDER_RADIUS ) pygame.draw.rect( screen, WORD_BORDER_COLOR, pygame.Rect( pos.x, pos.y, WORD_WIDTH,WORD_HEIGHT ), WORD_BORDER_WIDTH, WORD_BORDER_RADIUS ) text = font.render(word.word,False,"#ffffff") x,y = text.get_size() screen.blit(text,( pos.x+(WORD_WIDTH-x)//2, pos.y+(WORD_HEIGHT-y)//2+1 )) def main(data: dict): pygame.init() pygame.font.init() font = pygame.font.SysFont("Comic Code",WORD_FONT_SIZE,True) screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT),pygame.RESIZABLE) clock = pygame.time.Clock() running = True word_page = Page(True,BACKGROUND_COLOR,None,Vector2(PAGE_MARGIN,PAGE_MARGIN),Vector2(WORD_PAGE_WIDTH,WORD_PAGE_HEIGHT)) pages = [word_page] word_slots: list[WordSlot] = [] for y in range(GRID_HEIGHT): for x in range(GRID_WIDTH): word_slots.append(WordSlot( None, word_page, Vector2( PAGE_BORDER_WIDTH+WORD_MARGIN+(WORD_WIDTH+WORD_MARGIN)*x, PAGE_BORDER_WIDTH+WORD_MARGIN+(WORD_HEIGHT+WORD_MARGIN)*y ) )) words = [] 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 words.append(word) # print(words) while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # fill the screen with a color to wipe away anything from last frame screen.fill("#4d2905") # RENDER YOUR GAME HERE for p in pages: if not p.visible: continue draw_page(p, screen) # drawing word slots for w in word_slots: if not w.page.visible or w.color is None: continue draw_word_slot(w, screen) # drawing words for w in words: if not w.page.visible: continue draw_word(w, screen, font) # flip() the display to put your work on screen pygame.display.flip() clock.tick(60) # limits FPS to 60 pygame.quit() if __name__ == "__main__": with open("data.json","r") as file_pointer: data = json.load(file_pointer) main(data)