# ispirato dall'esempio della documentazione # https://brython.info/static_doc/3.13/en/cookbook/drag_drop.html # import di brython per manipolare il documento HTML from browser import document, html, timer, window # libreria brySVG per costruire poligoni import brySVG.fullcanvas as SVG import random grid_size = 8 grid = [["green" for _ in range(grid_size)]for _ in range(grid_size)] countdown= 16 punti = 0 colori = ["#03fce8","#690259","#07f572","#0723f5","#ffb53d","#d9d202","#e00b2f","purple","#0a108a"] poligoni = [] def p(poligono, x, y, z): poligoni.append([poligono, x, y, z]) # pannello/finestra base dove inseriamo tutto il resto panel = html.DIV( # DIV e' un oggetto senza nessuna proprieta' particolare id="panel", # nome per identificarlo nel documento style={ "height": "340px", # altezza "width": "600px", # larghezza "background-color": "yellow", # colore dello sfondo "z-index": "1", # "profondita'", piu' il numero e' alto piu' sopra # piu' sopra e' l'oggetto. Questo rimane in fondo. }, ) # destinazione del blocco, posso trascinarlo solo all'interno di questo spazio dest = html.DIV( id="dest", style={ "position": "absolute", # posiziona in modo assoluto rispetto al # contenitore in cui e' inserito (panel in # questo caso) "height": "320px", "width": "320px", "background-color": "gray", # questo e' verde! cosi' capite # cosa e' cosa "z-index": "2", # deve essere sopra il panel chiaramente }, ) panel <= dest dest_text = html.DIV( id="dest_text", style={ "position": "absolute", "top": "340px", "left": "10px", "color": "black", # colore del testo, non dello sfondo "z-index": "3", }, ) panel <= dest_text points = html.DIV( id="points", style={ "position": "absolute", "top": "330px", "left": "10px", "color": "black", # colore del testo, non dello sfondo "z-index": "5", }, ) panel <= points def disegna_grid(): global dest del document ["dest"] del document["dest_text"] del document["points"] # destinazione del blocco, posso trascinarlo solo all'interno di questo spazio dest = html.DIV( id="dest", style={ "position": "absolute", # posiziona in modo assoluto rispetto al # contenitore in cui e' inserito (panel in # questo caso) "height": "320px", "width": "320px", "background-color": "gray", # questo e' verde! cosi' capite # cosa e' cosa "z-index": "2", # deve essere sopra il panel chiaramente }, ) canvas_griglia = SVG.CanvasObject( # oggetto di tipo quadro 320, # larghezza 320, # altezza colour="transparent", # trasparente, non vogliamo che il quadro sia # colorato. Solamente il poligono al suo interno objid="canvas_griglia", # nome dell'oggetto nel documento, e' la stessa cosa di # "id=" degli esempi sopra ) larghezza = 40 for i in range(8): x = i * larghezza rettangolo = SVG.PolygonObject( # oggetto di tipo poligono, puo' stare solo in quadro # lista dei punti del poligono. L'origine e' in alto a sinistra. Puo' # aiutare fare un disegno per capire come viene fuori. pointlist=[(x, 0), (x, 320), (x+2, 320), (x+2, 0)], fillcolour="black", # poligono rosso linewidth=0, # nessun contorno ) canvas_griglia <= rettangolo for i in range(grid_size): for j in range(grid_size): colore = grid[i][j] x = larghezza*i y = larghezza*j rettangolo = SVG.PolygonObject( # oggetto di tipo poligono, puo' stare solo in quadro # lista dei punti del poligono. L'origine e' in alto a sinistra. Puo' # aiutare fare un disegno per capire come viene fuori. pointlist=[(x, y), (x, y+larghezza), (x+larghezza, y+larghezza), (x+larghezza, y)], fillcolour=colore, linewidth=0.1, # nessun contorno ) canvas_griglia <= rettangolo dest <= canvas_griglia # testo dentro la destinazione dest_text = html.DIV( id="dest_text", style={ "position": "absolute", "top": "320px", "left": "10px", "color": "black", # colore del testo, non dello sfondo "z-index": "3", }, ) points = html.DIV( id="points", style={ "position": "absolute", "top": "300px", "left": "10px", "color": "black", # colore del testo, non dello sfondo "z-index": "5", }, ) points <= "Punteggio: " + str(punti) panel <= points # imposto il testo dest_text <= "Tempo: " + str(countdown) # lo inserisco dentro lo spazio della destinazione panel <= dest panel <= dest_text dest.style.top = panel.abs_top + 10 dest.style.left = panel.abs_left + 270 # spazio del poligono/quadro. Utile per gestire a livello logico dove si trova # il poligono e gestire gli eventi del mouse. source = html.DIV( id="source", style={ "position": "absolute", "z-index": "4", }, ) # poligono a forma di L elle = SVG.PolygonObject( # oggetto di tipo poligono, puo' stare solo in quadro # lista dei punti del poligono. L'origine e' in alto a sinistra. Puo' # aiutare fare un disegno per capire come viene fuori. pointlist=[(0, 0), (0, 80), (80, 80), (80, 40), (40, 40), (40, 0)], fillcolour=random.choice(colori), # poligono rosso linewidth=0, # nessun contorno ) p(elle, 80, 80, [(0,0),(0,1),(1,1)]) quadrato_piccolo = SVG.PolygonObject( pointlist=[(0,0), (0,80), (80,80), (80,0)], fillcolour=random.choice(colori), linewidth=0, ) p(quadrato_piccolo, 80, 80, [(0,0),(1,0),(0,1),(1,1)]) quadrato_medio = SVG.PolygonObject( pointlist=[(0,0), (0,120), (120,120), (120,0)], fillcolour=random.choice(colori), linewidth=0, ) p(quadrato_medio, 120, 120, [(0,0),(1,0),(2,0),(0,1),(1,1),(2,1),(0,2),(1,2),(2,2)]) scala_3 = SVG.PolygonObject( pointlist=[(0,0),(0,120),(120,120),(120,80),(80,80),(80,40),(40,40),(40,0)], fillcolour=random.choice(colori), linewidth=0, ) p(scala_3, 120, 120, [(0,0),(0,1),(1,1),(0,2),(1,2),(2,2)]) linea_6_o = SVG.PolygonObject( pointlist=[(0,0),(0,40),(240,40),(240,0)], fillcolour=random.choice(colori), linewidth=0, ) p(linea_6_o, 240, 40, [(0,0),(1,0),(2,0),(3,0),(4,0),(5,0)]) linea_6_v = SVG.PolygonObject( pointlist=[(0,0),(0,240),(40,240),(40,0)], fillcolour=random.choice(colori), linewidth=0, ) p(linea_6_v, 40, 240, [(0,0),(0,1),(0,2),(0,3),(0,4),(0,5)]) rettangolo_2_3_o = SVG.PolygonObject( pointlist=[(0,0),(0,80),(120,80),(120,0)], fillcolour=random.choice(colori), linewidth=0, ) p(rettangolo_2_3_o, 120, 80, [(0,0),(0,1),(1,0),(1,1),(2,0),(2,1)]) rettangolo_2_3_v = SVG.PolygonObject( pointlist=[(0,0),(80,0),(80,120),(0,120)], fillcolour=random.choice(colori), linewidth=0, ) p(rettangolo_2_3_v, 80, 120, [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)]) rettangolo_3_4_o = SVG.PolygonObject( pointlist=[(0,0),(0,120),(160,120),(160,0)], fillcolour=random.choice(colori), linewidth=0, ) p(rettangolo_3_4_o, 160, 120, [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2),(3,0),(3,1),(3,2)]) rettangolo_3_4_v = SVG.PolygonObject( pointlist=[(0,0),(120,0),(120,160),(0,160)], fillcolour=random.choice(colori), linewidth=0, ) p(rettangolo_3_4_v, 120, 160, [(0,0),(0,1),(0,2),(0,3),(1,0),(1,1),(1,2),(1,3),(2,0),(2,1),(2,2),(2,3)]) elle_3_o = SVG.PolygonObject( pointlist=[(0,0),(0,120),(120,120),(120,80),(40,80),(40,0)], fillcolour=random.choice(colori), linewidth=0, ) p(elle_3_o, 120, 120, [(0,0),(0,1),(0,2),(1,2),(2,2)]) elle_3_v = SVG.PolygonObject( pointlist=[(0,0),(0,120),(40,120),(40,40),(120,40),(120,0)], fillcolour=random.choice(colori), linewidth=0, ) p(elle_3_v, 120, 120, [(0,0),(0,1),(0,2),(1,0),(2,0)]) k_o = SVG.PolygonObject( pointlist=[(0,40),(0,80),(120,80),(120,40),(80,40),(80,0),(40,0),(40,40)], fillcolour=random.choice(colori), linewidth=0, ) p(k_o, 120, 80, [(0,1),(1,1),(2,1),(1,0)]) k_v = SVG.PolygonObject( pointlist=[(0,0),(0,120),(40,120),(40,80),(80,80),(80,40),(40,40),(40,0)], fillcolour=random.choice(colori), linewidth=0, ) p(k_v, 80, 120, [(0,0),(0,1),(0,2),(1,1)]) k_rov = SVG.PolygonObject( pointlist=[(0,0),(0,40),(40,40),(40,80),(80,80),(80,40),(120,40),(120,0)], fillcolour=random.choice(colori), linewidth=0, ) p(k_rov, 120, 80,[(0,0),(1,0),(2,0),(1,1)]) # selezione randomica del poligono polygon = 0 def caso(): global polygon polygon = random.choice(poligoni) canvas = SVG.CanvasObject( # oggetto di tipo quadro polygon[1], # larghezza polygon[2], # altezza colour="transparent", # trasparente, non vogliamo che il quadro sia # colorato. Solamente il poligono al suo interno objid="canvas", # nome dell'oggetto nel documento, e' la stessa cosa di # "id=" degli esempi sopra ) canvas <= polygon[0] source <= canvas caso() # aggiungo gli elementi al pannello panel <= source # aggiungo il pannello alla finestra/documento document <= panel #del document["panel"] # disegno piu' visuale per capire come sono messe le cose disegna_grid() # document (la vostra finestra del browser) # ------------------------------ # | panel (pannello del gioco) | # | ----------------------- | # | | source destination | | # | | ---- ---------- | | # | | |X | | | | | # | | |XX| | | | | # | | ---- ---------- | | # | ----------------------- | # ------------------------------ # sorgente a (10, 10) dall'angolo in alto a sinistra del pannello source.style.top = panel.abs_top + 10 source.style.left = panel.abs_left + 10 # rendi il contenitore trascinabile source.draggable = True # destinazione (quadrato verde) a (10, 290) dal pannello def mouseover(ev): # quando il mouse passa sopra print('mouse sul poligono!') # rendi il cursore la mano ev.target.style.cursor = "pointer" # quando il mouse e' sopra a "source" chiama in automatico il codice qua sopra source.bind("mouseover", mouseover) def dragstart(ev): # chiamata quando trascini l'oggetto # salviamo il nome dell'oggetto da usare dopo ev.dataTransfer.setData("text", ev.target.id) # salviamo la posizione relativa del mouse all'interno del poligono # ev.x e' la posizione del mouse e ev.target.left e' la posizione del # lato sinistro del poligono # quindi ev.x - ev.target.left da la distanza del mouse dal bordo del # poligono ev.dataTransfer.setData("pos_x", ev.x - ev.target.left) ev.dataTransfer.setData("pos_y", ev.y - ev.target.top) # chiama il codice sopra quando inizi a trascinare source.bind("dragstart", dragstart) def dragover(ev): # fine di trascinare # togli comportamento standard perche' definiamo il nostro ev.preventDefault() # ora dopo dradover devo riportare il blocco all inizio cancellaarlo e poi farne uno nuovo. # chiama il codice sopra quando smetti di trascinare panel.bind("dragover", dragover) def drop(ev): # quando rilasci l'oggetto # recuperiamo i dati che abbiamo salvato prima src_id = ev.dataTransfer.getData('text') # questo sono convertiti in stringa quando vengono salvati. Dobbiamo # riconvertirli in integer per poter fare i calcoli pos_x = int(ev.dataTransfer.getData("pos_x")) pos_y = int(ev.dataTransfer.getData("pos_y")) # dato il nome dell'oggetto nel documento recupera l'oggetto stesso elt = document[src_id] # ev.x ed ev.y sono la posizione del mouse. Per sapere l'oggetto dove deve # andare dobbiamo sottrarre la distanza dai bordi dell'oggetto che avevamo # calcolato prima new_x = ev.x - pos_x new_y = ev.y - pos_y print("nuova posizione:", new_x, new_y) griglia_occupata = [] posto_occupato = False tolleranza = 10 # controlliamo la posizione del poligono e' all'interno dell'area verde if new_x < dest.abs_left - tolleranza or new_x > dest.abs_left + dest.width - elt.width + tolleranza: #impostare la con- #dizione basandosi sulla larghezza del poligono scelto # se non e' all'interno rimetti il poligono nella posizione iniziale elt.style.left = panel.abs_left + 10 elt.style.top = panel.abs_top + 10 elif new_y < dest.abs_top - tolleranza or new_y > dest.abs_top + dest.height - elt.height + tolleranza: #impostare la con- #dizione basandosi sull'altezza del poligono scelto # se non e' all'interno rimetti il poligono nella posizione iniziale elt.style.left = panel.abs_left + 10 elt.style.top = panel.abs_top + 10 else: global countdown # se invece e' nell'area imposta le nuove coordinate elt.style.left = panel.abs_left + 10 elt.style.top = panel.abs_top + 10 #arrotondamento posizione new_x -= dest.abs_left new_y -= dest.abs_top print (new_x,new_y) def_x = new_x / 40 def_x = round(def_x) def_y = new_y / 40 def_y = round(def_y) print (def_y,def_x) for i in polygon[3]: x_ = i[0] + def_x y_ = i[1] + def_y if grid[x_][y_] == "red": posto_occupato = True if posto_occupato == False: countdown = 16 for i in polygon[3]: x_ = i[0] + def_x y_ = i[1] + def_y griglia_occupata.append(i) grid[x_][y_] = "red" global punti punti += 100 for riga in grid: riga_piena = True for cella in riga: if cella == "red": pass else: riga_piena = False break if riga_piena == True: for i in range(8): riga[i] = "green" for nr_colonna in range(8): colonna_piena = True testo = "" for nr_riga in range(8): cella = grid[nr_riga][nr_colonna] if cella == "red": pass else: colonna_piena = False testo += cella + " " print(testo, colonna_piena) if colonna_piena == True: for i in range(8): grid[i][nr_colonna] = "green" disegna_grid() del document["canvas"] caso() else: elt.style.left = panel.abs_left + 10 elt.style.top = panel.abs_top + 10 #Fare la griglia per il posizionamento # chiama il codice sopra quando lasci un oggetto panel.bind("drop", drop) def gameover(): gameover_text = html.DIV( id="gameover_text", style={ "position": "absolute", "top": "170px", "left": "13px", "color": "black", # colore del testo, non dello sfondo "z-index": "10", "font-size" :"50px" }, ) gameover_text <= "Hai perso pippa, ricarica per ricominciare" panel <= gameover_text source.draggable = False def count(): global countdown print(countdown) if countdown == 0: gameover() else: countdown = countdown-1 document ["dest_text"].text= "Tempo: " + str(countdown) timer.set_interval(count,1000) # funzione per barare e aggiungere punti def cheat_points(i): print("aggiungo", i, "punti") global punti punti += i disegna_grid() # rendi la funzione chiamabile dalla console del browser window.points = cheat_points